2014-01-08 34 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' 
相关问题