我遇到了subprocess.Popen和我認爲是管道的問題。從CLI運行時,我有這沒有問題工作的時間100%以下代碼塊:Python Popen掛psexec - 意外的結果
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不喜歡未定義的stdin,out或err在子進程中。然後我修改了代碼如下:
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.
我試圖通過添加殼=真正的子選項來解決這個問題,但是當我做,該方案只是掛的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'命令的輸出結果是不會出現的) – srgerg 2011-03-07 07:05:37
另外,當我試圖複製結果時,當我設置'stdin = subprocess.PIPE'時,'psexec'命令會掛起。 'shell'的值似乎沒有關係。 – srgerg 2011-03-07 07:06:16
它可能會被許可證提示符掛起。請參閱鏈接 http://stackoverflow.com/questions/5151034/psexec-gets-stuck-on-licence-prompt-when-running-non-interactively – 2014-05-10 08:27:44