Python子进程可以';t调用;宋承宪;

Python子进程可以';t调用;宋承宪;,python,windows,path,subprocess,Python,Windows,Path,Subprocess,我正在使用subprocess模块从Python发送shell命令,具体地说是ssh。以下是一个裸体样本: import subprocess sp = subprocess.run(["ssh"], shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) print(f"stdout: {sp.stdout.decode()} \n\nstderr: {sp.stderr.decode()}&quo

我正在使用subprocess模块从Python发送shell命令,具体地说是
ssh
。以下是一个裸体样本:

import subprocess

sp = subprocess.run(["ssh"], shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
print(f"stdout: {sp.stdout.decode()} \n\nstderr: {sp.stderr.decode()}")
这将从stdout返回ssh命令帮助,而从stderr不返回任何内容。然而,我得到:

stdout:  

stderr: 'ssh' is not recognized as an internal or external command,
operable program or batch file.
我尝试过其他命令,比如
echo
cd
,这些命令都很好用。在shell中手动键入命令时,我也可以使用
ssh
,但当我试图通过子流程执行命令时,它失败了。目录
C:\Windows\System32\OpenSSH
确实存在于我的计算机上(它包含
ssh.exe
),但由于某种奇怪的原因,我无法使用subprocess将其cd到

如果有必要,子流程将使用命令提示符,
cmd.exe
,因为它似乎是默认的

感谢您的帮助。谢谢

--使用注释中的测试进行编辑--

  • 使用绝对路径
    C:/Windows/System32/OpenSSH/ssh.exe
    不起作用,系统无法通过stderr找到指定的路径。
    OpenSSH
    文件夹对于Python来说似乎不可见
  • os.environ[PATH]
    包含
    C:/Windows/System32/
    C:/Windows/System32/OpenSSH/
  • 使用
    shell=False
    (使用绝对路径或仅使用
    ssh
    )运行它会在Python中引发错误:
    FileNotFoundError:[WinError 2]系统找不到指定的文件

您说
C:\Windows\System32\OpenSSH\ssh.exe
存在,但从Python运行时找不到它。这可能是因为安装了32位版本的Python,而不是64位版本


如果路径存在于其他地方,但不适用于Python,则可能会涉及。当您让Python在
C:\Windows\System32
中查找时,它可能看到了
C:\Windows\SysWOW64
。我建议卸载所有Python,并显式安装64位版本,这样它就不受重定向程序的影响,并且可以看到“真实的”
System32

检查:如果使用绝对路径,它是否有效
C:/Windows/System32/OpenSSH/ssh.exe已安装,我可以通过命令提示符成功地使用它,而不是通过子流程从Python使用它。绝对路径没有帮助;“系统找不到指定的路径”。无论出于何种原因,子流程都无法看到OpenSSH文件夹。首先要确定包含OpenSSH二进制文件的目录是否列在
os.environ['PATH']
echo
cd
内置于shell中,因此它们始终可以与
shell=True
一起使用。(请注意,使用
shell=True
通常是一个非常糟糕的主意……但在Windows上,这并不像在其他任何地方那样正确。)
C:/Windows/System32/
C:/Windows/System32/OpenSSH/
都在进行中。哇,谢谢,就是这样。我不知道有一个重定向器是这样工作的。哇+1。不错!你的Windows程序员必须生活在一个比我们其他人更奇怪、更复杂的世界里。@Evarittner:是的,Windows不做大量DLL(DLL是为32位或64位编译的,不是同时为这两个位编译的),所以很多32位程序都认为他们会在
System32
中找到DLL(原名),许多64位程序都是为32位编写的,只是针对64位重新编译,而DLL都有相同的名称。所以微软想出了这个难题,让32位和64位程序都认为
System32
是他们可以找到DLL的地方,它无缝地重定向到引擎盖下的“真实”位置。以牺牲等级疯狂为代价,获得了出色的后卫/前锋同胞。:-)