【发布时间】:2011-07-08 20:37:24
【问题描述】:
我对 subprocess.Popen 以及我认为是管道的问题有疑问。我有以下代码块,从 cli 运行时 100% 的时间都没有问题:
p = subprocess.Popen("psexec \\\\" + serverName.get() + " cmd /c \
ver & \
echo %USERDOMAIN% & \
dir /a C:\pagefile.sys | find \"pagefile.sys\" & \
dir C:\ | find \"bytes free\" & \
dir D:\ | find \"bytes free\" ", \
stdin=None, stdout=subprocess.PIPE, stderr=None)
### Assign the results from the Popen
results = p.communicate()[0]
rc = p.returncode
print 'results: ' + str(results)
sys.exit()
输出:
PsExec v1.90 - Execute processes remotely
Copyright (C) 2001-2007 Mark Russinovich
Sysinternals - www.sysinternals.com
The device is not ready.
cmd exited on XXXXXXX with error code 1.
Microsoft Windows XP [Version 5.1.2600]
PROD
02/23/2011 09:37 AM 1,610,612,736 pagefile.sys
49 Dir(s) 17,104,437,248 bytes free
我已经完成了这个程序,但是一旦我用 py2exe 编译它,它就会挂起或崩溃。我将此问题追溯到 py2exe 不喜欢子进程中未定义的标准输入、输出或错误。然后我修改了我的代码如下:
p = subprocess.Popen("psexec \\\\" + serverName.get() + " cmd /c \
ver & \
echo %USERDOMAIN% & \
dir /a C:\pagefile.sys | find \"pagefile.sys\" & \
dir C:\ | find \"bytes free\" & \
dir D:\ | find \"bytes free\" ", \
stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
p.stdin.close()
### Assign the results from the Popen
results = p.communicate()[0]
rc = p.returncode
print 'results: ' + str(results)
sys.exit()
这段代码也可以 100% 工作,但是当我打印结果时,它只显示标准 psexec 消息,而不是执行命令的输出。
输出:
results:
PsExec v1.90 - Execute processes remotely
Copyright (C) 2001-2007 Mark Russinovich
Sysinternals - www.sysinternals.com
cmd exited on XXXXXXX with error code 1.
我试图通过在子进程选项中添加 shell=true 来解决这个问题,但是当我这样做时,程序只会挂起 99% 的时间。它实际上会运行 1% 的时间。我注意到,当程序挂起时,如果我进入任务管理器并手动终止 psexec 进程,则会显示所需的输出。这让我发疯,我一直在寻找,但没有找到任何东西。该代码在 WinXP python v2.7 上运行。如果您有任何问题或需要任何其他信息,请告诉我。
挂码:
p = subprocess.Popen("psexec \\\\" + serverName.get() + " cmd /c \
ver & \
echo %USERDOMAIN% & \
dir /a C:\pagefile.sys | find \"pagefile.sys\" & \
dir C:\ | find \"bytes free\" & \
dir D:\ | find \"bytes free\" ", \
stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True)
p.stdin.close()
### Assign the results from the Popen
results = p.communicate()[0]
rc = p.returncode
print 'results:' + str(results)
sys.exit()
从任务管理器中杀死 psexec.exe 后所需的输出:
results:
PsExec v1.90 - Execute processes remotely
Copyright (C) 2001-2007 Mark Russinovich
Sysinternals - www.sysinternals.com
PROD
02/23/2011 09:37 AM 1,610,612,736 pagefile.sys
49 Dir(s) 17,102,487,552 bytes free
The device is not ready.
【问题讨论】:
-
您正尝试在远程机器上执行一系列命令,在每个命令之间使用
&。现在,如果您不使用shell=True,那么所有命令都作为参数传递给psexec,并在远程机器上执行。但是如果你做 使用shell=True,shell 将单独执行每个命令,所以cmd /c ver在远程机器上执行,但echo %USERDOMAIN%和其余命令在本地执行 机器! (注意杀死psexec后ver命令的输出不会出现) -
另外,当我尝试复制您的结果时,
psexec命令会在我设置stdin = subprocess.PIPE时挂起。shell的值似乎不相关。 -
可能会被License提示挂起。请看链接stackoverflow.com/questions/5151034/…
-
它是由许可协议提供的。请看链接:stackoverflow.com/questions/5151034/…
标签: python subprocess pipe py2exe psexec