2012-03-07 68 views
4

我正在使用一個科學軟件(稱爲vasp),只能在bash中工作,並使用Python創建一個腳本,將爲我運行多個運行。當我使用subprocess.check_call來正常調用函數時,它工作正常,但是當我添加'| tee tee_output'它不起作用。如何使用|調用多個bash函數在python

subprocess.check_call('vasp') #this works 
subprocess.check_call('vasp | tee tee_output') #this doesn't 

我是一個noobie python和編程完全。

回答

4

試試這個。它通過shell執行命令(作爲字符串傳遞),而不是直接執行命令。 (這是調用shell本身與-c標誌的等價物,即Popen(['/bin/sh', '-c', args[0], args[1], ...])):

subprocess.check_call('vasp | tee tee_output', shell=True) 

但出席在docs有關該方法的警告。

+0

我覺得工作。謝謝:) shell = True是做什麼的? – mrkent 2012-03-07 21:39:32

+0

@ user1255726:它[使用shell執行命令](http://docs.python.org/library/subprocess.html#frequently-used-arguments)。 – 2012-03-07 21:42:06

+0

@ user1255726,我以你的名字告訴你,你的軟件「僅適用於bash」。如果這不是真的,那麼出於安全原因,其他答案之一會更可取。讓我知道如果是這樣的話。 – senderle 2012-03-08 02:55:26

2

你可以這樣做:

vasp = subprocess.Popen('vasp', stdout=subprocess.PIPE) 
subprocess.check_call(('tee', 'tee_output'), stdin=vasp.stdout) 

這通常比使用shell=True,特別是如果你不能信任的輸入更安全。

注意check_call將檢查返回代碼的tee,而不是vasp,看它是否應該提出一個CalledProcessError。 (shell=True方法將執行相同的操作,因爲它與shell管道的行爲相匹配。)如果需要,可以通過調用vasp.poll()自行檢查返回碼vasp。 (另一種方法不會讓你這樣做。)

2

不要使用shell = True,它有很多安全漏洞。相反,做這樣的事情

cmd1 = ['vasp'] 
cmd2 = ['tee', 'tee_output'] 

runcmd = subprocess.Popen(cmd1, stdout=subprocess.PIPE) 
runcmd2 = subprocess.Popen(cmd2, stdin=runcmd.stdout, stdout=subprocess.PIPE) 

runcmd2.communicate() 

我知道它更長,但它更安全。