2014-05-19 147 views
0

我寫了一段簡單的代碼:subprocess.Popen給出隨機結果

import subprocess 
p=subprocess.Popen('mkdir -p ./{a,b,c}', shell=True, stderr=subprocess.STDOUT) 
p.wait() 

不幸的是,它並不總是表現我所希望的方式。也就是說,當我在PC上運行它時,一切正常(ls -l給我三個dirs:a,b和c)。但是當我的同事在桌面上運行它時,他得到了......一個名爲'{a,b,c}'的目錄...我們都使用Python 2.7.3。這是爲什麼?你將如何解決它?

我試圖自己找到答案。根據手冊: 「args應該是程序參數序列或單個字符串,默認情況下,如果args是序列,則要執行的程序是args中的第一個項目。如果args是字符串,則解釋是平臺 - 依賴和下面描述。請參閱shell和可執行參數以獲得與默認行爲的其他差異。除非另有說明,否則建議將args作爲序列傳遞。

於是,我在shell執行代碼:

python -c "import subprocess; p=subprocess.Popen(['mkdir', '-p', './{ea,fa,ga}'], shell=True, stderr=subprocess.STDOUT); p.wait()" 

而且我得到了:

mkdir: missing operand 

我將感謝任何意見

謝謝!

+2

你(和你的同事)在哪個操作系統上運行它?如果兩個linux,你用的是什麼shell? –

+0

不同的殼可能會給出不同的結果。 – dilbert

+0

重複http://stackoverflow.com/questions/16029871/how-to-run-os-mkdir-with-p-option-in-python – endragor

回答

-1

os.mkdir(path,[mode])方法據我所知在使用多平臺項目時更安全。

os.mkdir(os.getcwd()/a) 

然而,它不如採取子過程方法的優雅。

+0

你的代碼不起作用,你需要用引號:'os.getcwd()+「/ a」'。 這也不回答具體OP的問題。 – Darkhogg

2

./{a,b,c}語法是bash語法,不受所有shell的支持。

文檔說:

在Unix與shell=True,殼默認爲/bin/sh。如果args是 字符串,則字符串將指定通過shell執行的命令。

所以,如果/bin/sh被鏈接到支持該語法,像bashzsh殼您的命令纔有效。您的同事可能使用dash或其他不支持此功能的外殼。

你不應該依賴於用戶的默認shell。相反,寫滿整個擴展命令:

p = subprocess.Popen('mkdir -p ./a ./b ./c', shell=True, stderr=subprocess.STDOUT) 
0

這裏有幾個問題。

  • 第一:如果你正在使用的參數的順序,不設個「shell =真」(this is recommended in the Popen manual)其設置爲false,你會看到你的mkdir命令會被接受
  • 「 ./{a,b,c}「是AFAIK bash中的一個特定語法。如果你的同事使用不同的shell,它可能無法工作,或者行爲不同。
  • 您應該使用python「mkdir」命令而不是調用shell命令,它可以在任何服務器/ shell/OS下工作。
0

謝謝大家的回答。 看來,最好的方法是簡單地使用/ bin/sh語法。我更改了我的代碼以使用:

'mkdir -p ./a ./b ./c' 

正如您所建議的。我避免使用mkdir()函數,因爲我正在寫大量系統調用的腳本,並且我想提供優雅的--dry-run選項(以便列出所有命令)。

問題解決 - 謝謝!