2014-01-08 64 views
0

我試圖在python中運行並讀取time命令的輸出。問題是,time命令的工作方式不同的/bin/sh/bin/bash像這樣:如何在使用`subprocess.check_output`時正確引用python中的bash命令?

sh $ time ls 
.. 
0.00user 0.00system 0:00.00elapsed 0%CPU (0avgtext+0avgdata 3856maxresident)k 
0inputs+0outputs (0major+305minor)pagefaults 0swaps 

/bin/bash版本是:

bash $ time ls 
.. 

real 0m0.003s 
user 0m0.000s 
sys  0m0.000s 

我需要後者,因爲它比以前更精確。

因此我想在check_outputbash -c '<command>'包裹的命令,但它給了我一個錯誤,例如:

>>> s.check_output(["bash", "-c", "'time ls'"])         
bash: time ls: command not found 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "/usr/lib/python2.7/subprocess.py", line 544, in check_output 
    raise CalledProcessError(retcode, cmd, output=output) 
subprocess.CalledProcessError: Command '['bash', '-c', "'time ls'"]' returned non-zero exit status 127 

當我排除多餘的報價,輸出不捕獲計時信息:

>>> s.check_output(['bash', '-c', 'time ls']) 

real 0m0.002s 
user 0m0.000s 
sys  0m0.000s 
'..' 

而最後,當我用executable參數,而不是包裝,輸出沒有捕獲任何:

>>> s.check_output(['time', 'ls'], shell=True, executable='/bin/bash') 

real 0m0.000s 
user 0m0.000s 
sys  0m0.000s 

我該怎麼做?

回答

3

隨着/bin/shtime ls運行外部程序/usr/bin/time(您的路徑可能不同),然後運行ls並報告所述定時信息到它的標準誤差。

/bin/bash隨着,time是其指示bash外殼本身來報告定時信息的ls執行到標準錯誤關鍵字。因此,您需要將shell的標準錯誤(不是命令)重定向到標準輸出,以便check_output可以捕獲它。這有點難看,但

s.check_output('exec 2>&1; time ls >/dev/null 2>&1', executable='/bin/bash', shell=True) 

應該工作。 exec 2>&1是讓check_output捕獲任何東西的部分。 ls之後的重定向將從中捕獲的內容中刪除ls的輸出;如果您想要命令輸出,也可以刪除它們。

2

錯誤是由於你應該將而不是列舉爲列表命令行時引用字符串。事實上:

>>> s.check_output(['bash', '-c', "time ls"]) 

real 0m0.002s 
user 0m0.000s 
sys  0m0.000s 
'some content produced by ls' 

不引發任何異常,而:

>>> s.check_output(['bash', '-c', "'time ls'"]) 
bash: time ls: comando non trovato 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "/usr/lib/python3.3/subprocess.py", line 586, in check_output 
    raise CalledProcessError(retcode, process.args, output=output) 
subprocess.CalledProcessError: Command '['bash', '-c', "'time ls'"]' returned non-zero exit status 127 

引發看到異常。注意回溯前行:

bash: time ls: comando non trovato 

引述'time ls'做出bash搜索程序time ls而不是程序timels作爲參數來運行。

爲什麼不需要引用?簡單:字符串列表指定命令行應該如何拆分。將"time ls"放在列表的單個元素中,已經提供了所需的「引用」。


至於如何獲得所需的輸出,由於bashtimestderr輸出,一個解決方案是重定向stderrstdout(和刪除ls輸出)。

>>> s.check_output(['bash', '-c', "time ls > /dev/null"], stderr=s.STDOUT) 
'\nreal\t0m0.001s\nuser\t0m0.000s\nsys\t0m0.000s\n' 
相關問題