2012-10-15 41 views
1

我是學習Python的新手,並在命令行中工作,例如,管道。子進程 - 使用幾個命令行工具

我讀過這個子進程是鼓勵方式而不是os.system。我正在創建一個調用shell的腳本,我無法使用子進程來完成它。使用使用os.system是易如反掌,但:

os.system("cut -f1-4 " + temp1.name + "| uniq --count | sort -rn > " + temp2.name) 

我已經成功地使用了其他命令的子進程,而不是那些以組合多個工具「|」。讀取子進程的python文檔令人困惑,對我沒有幫助。我也試着尋找其他問題,但找不到類似於我的問題的東西。這是我試過什麼(失敗):

subprocess.call = (["cut", "-f1-4", temp1.name, "|", "uniq", "--count", "|", "sort". "-rn"], stdout = open(temp2.name, 'w')) 

我也試圖與sp.Popen代sp.call,但未能成功。任何人都可以請幫助一些清晰的例子和解釋? 謝謝!

+0

'subprocess.call =(...' - 你剛剛更換的庫函數用爲什麼你期望這個工作?你需要調用函數... – poke

+0

對不起,我不確定你的意思。你能解釋一下嗎?我已經通過調用項目成功地使用了subprocess.call在列表中,如subprocess.call([「程序」,輸入文件,輸出文件]) – jonoave

回答

2

如果你想使用管道應添加shell=True

subprocess.check_output("cut -f1-4 " + temp1.name + "| uniq --count | sort -rn > " + temp2.name, shell=True) 

請注意,如果來自不受信任來源temp1.nametemp2.name(例如,從用戶在Web應用程序提供的數據)使用shell=True是是安全風險。

+0

+1:爲了描述安全含義 –

+0

謝謝@hans!工作!!但我不清楚爲什麼使用sp.check_output想要讀取輸出,而不僅僅是c嘿,如果命令有效?這很混亂。無論如何,由於temp1.name和temp2.​​name文件是由腳本根據特定的用戶輸入生成的,所以安全風險很小。 – jonoave

+0

對不起,添加到混亂。如果你只想檢查返回值,你可以簡單地使用'call'。這是習慣的力量讓我輸入'check_output'。 –

2

值得看看偉大的圖書館python sh,它是一個全面的Python子程序接口,可以讓你像調用函數一樣調用任何程序,更重要的是,它是令人愉快的pythonic。

對於在這種情況下,您的特定需求,它提供了一些「先進的管道」功能,這樣的某物:

# the inner command executes first, then sends its data to the outer command 
from sh import * 
sort(uniq(cut("-f1-4", _in="temp1.name"), "--count"), "-rn", _out="temp2.name") 
+0

謝謝@ chuchao333,我會看看它。 – jonoave