2011-03-04 29 views
3

我遇到了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. 
+0

您試圖在每個命令之間使用'&'在遠程計算機上執行一系列命令。現在,如果你不*使用'shell = True',那麼所有的命令都作爲參數傳遞給'psexec'並在遠程機器上執行。但是,如果你使用'shell = True',shell將分別執行每個命令,所以'cmd/c ver'會在遠程機器上執行,但是'echo%USERDOMAIN%',其餘命令在*本地*機器! (請注意,在殺死'psexec'後,'ver'命令的輸出結果是不會出現的) – srgerg 2011-03-07 07:05:37

+0

另外,當我試圖複製結果時,當我設置'stdin = subprocess.PIPE'時,'psexec'命令會掛起。 'shell'的值似乎沒有關係。 – srgerg 2011-03-07 07:06:16

+0

它可能會被許可證提示符掛起。請參閱鏈接 http://stackoverflow.com/questions/5151034/psexec-gets-stuck-on-licence-prompt-when-running-non-interactively – 2014-05-10 08:27:44

回答

0

[這應該是一個評論,但我沒有代表留下意見]

我聽說有很多subprocess.PIPE的問題。嘗試使stdin,stdout和stderr都指向臨時文件。然後你可以使用p.wait()而不是communic()。這似乎工作正常嗎?

0

嘗試運行使用-i 的PSEXEC它爲我工作

p = subprocess.Popen("psexec " "-i " . . . 
0

我已經看到了這個問題,一旦:

  1. 重定向到臨時文件似乎是一個可行的解決方案 - 問題是訪問過程輸出所需的附加代碼 - 但它是一個穩定的解決方案。問題是獲取流程輸出所需的附加代碼(如果要在運行時顯示它 - 如果不想,它只是傾銷文件)
  2. 您還可以檢查fabric's local實現 - 我沒有運行psexec ,但所有其他進程都正常工作(除非它沒有提供超時機制)