在使用“subprocess.check_output”时,如何正确引用python中的bash命令?
我试图在python中运行并读取在使用“subprocess.check_output”时,如何正确引用python中的bash命令?,python,bash,shell,time,subprocess,Python,Bash,Shell,Time,Subprocess,我试图在python中运行并读取time命令的输出。问题是time命令在/bin/sh和/bin/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 .. r
time
命令的输出。问题是time
命令在/bin/sh
和/bin/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\u output
中用bash-c'
包装命令,但它给出了一个错误:
>>> 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
最后,当我使用executable
参数而不是包装时,输出不会捕获任何内容:
>>> s.check_output(['time', 'ls'], shell=True, executable='/bin/bash')
real 0m0.000s
user 0m0.000s
sys 0m0.000s
如何执行此操作?使用
/bin/sh
,时间ls
运行外部程序/usr/bin/time
(您的路径可能会有所不同),然后运行ls
,并将计时信息报告到其标准错误
对于/bin/bash
,time
是一个关键字,它指示bash
shell本身将执行ls
的计时信息报告为标准错误。因此,您需要将shell的标准错误(而不是命令)重定向到标准输出,以便check\u output
可以捕获它。有点难看,但是
s.check_output('exec 2>&1; time ls >/dev/null 2>&1', executable='/bin/bash', shell=True)
应该有用。
exec 2>&1
是允许检查输出的部分
捕获任何内容。ls
之后的重定向用于从捕获的内容中删除ls
的输出;如果需要命令输出,也可以删除它们。使用/bin/sh
,time ls
运行外部程序/usr/bin/time
(您的路径可能会有所不同),然后运行ls
,并将计时信息报告到其标准错误
对于/bin/bash
,time
是一个关键字,它指示bash
shell本身将执行ls
的计时信息报告为标准错误。因此,您需要将shell的标准错误(而不是命令)重定向到标准输出,以便check\u output
可以捕获它。有点难看,但是
s.check_output('exec 2>&1; time ls >/dev/null 2>&1', executable='/bin/bash', shell=True)
应该有用。
exec 2>&1
是允许检查输出的部分
捕获任何内容。ls
之后的重定向用于从捕获的内容中删除ls
的输出;如果需要命令输出,也可以将其删除。错误是由于在将列表证明为命令行时不应引用字符串。事实上:
>>> 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
引用'time ls'
使bash
搜索程序time ls
,而不是以ls
作为参数运行的程序time
为什么不需要引用?简单:字符串列表指定如何拆分命令行。将“time ls”
放在列表的单个元素中已经提供了所需的“quoting”
至于如何获得所需的输出,由于
bash
的时间
在stderr
上输出,解决方案是将stderr
重定向到stdout
(并删除ls
输出)
该错误是由于在将列表证明为命令行时不应引用字符串而导致的。事实上:
>>> 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
引用'time ls'
使bash
搜索程序time ls
,而不是以ls
作为参数运行的程序time
为什么不需要引用?简单:字符串列表指定如何拆分命令行。将“time ls”
放在列表的单个元素中已经提供了所需的“quoting”
至于如何获得所需的输出,由于
bash
的时间
在stderr
上输出,解决方案是将stderr
重定向到stdout
(并删除ls
输出)