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 でコンパイルすると、ハングまたはクラッシュするだけでした。サブプロセスで未定義のstdin、out、またはerrを好まない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.