使用Python运行其他程序
我有一个命令,在命令行上运行得很好。这个命令有很多参数,比如 cmd --thing foo --stuff bar -a b input output
我想从 Python 里运行这个命令,并且希望它在完成之前一直等待。这个脚本在输出信息到 stdout
和 stderr
时,我希望这些信息能立刻显示给用户。
我该用哪个模块呢?
我试过:
import commands
output = commands.getoutput("cmd --thing foo --stuff bar -a b input output")
print output
这个方法很好用,但 stdout
的输出要等到最后才返回。
import os
os.system("cmd --thing foo --stuff bar -a b input output")
这个方法在命令真正完成时才会打印所有输出。
import subprocess
subprocess.call(["cmd", "--thing foo", "--stuff bar", "-a b", "input", "output"])
这个方法好像没有正确传递参数(我还没找到具体的问题,但 cmd
拒绝了我的输入)。如果我把 echo
放在第一个参数,它会打印出这个命令,而直接在终端里粘贴这个命令是完全可以正常工作的。
import subprocess
subprocess.call("cmd --thing foo --stuff bar -a b input output")
和上面的一样。
4 个回答
2
使用 commands.getstatusoutput() 这个方法不行吗?我觉得它会立刻给你返回状态信息。
7
你需要把每个字段单独用引号括起来,也就是说,要把选项和它们的参数分开。
import subprocess
output = subprocess.call(["cmd", "--thing", "foo", "--stuff", "bar", "-a", "b", "input", "output"])
否则你实际上是在这样运行命令
$ cmd --thing\ foo --stuff\ bar -a\ b input output
为了把输出放入管道中,你需要稍微改变一下调用方式
import subprocess
output = subprocess.Popen(["cmd", "--thing", "foo", "--stuff", "bar", "-a", "b", "input", "output"],stdout=subprocess.PIPE)
output.stdout # <open file '<fdopen>', mode 'rb'>
4
如果你不需要在代码中处理输出,只是想把它展示给用户(从你的问题来看,这点不是很明确,似乎你自己回答的时候也是这么想的),最简单的方法就是:
rc = subprocess.call(
["cmd", "--thing", "foo", "--stuff", "bar",
"-a", "b", "input", "output"])
print "Return code was", rc
也就是说,尽量不要使用管道——让标准输出和错误输出直接在终端上显示。这样可以避免缓冲的问题。一旦你使用了管道,缓冲通常会成为一个问题,特别是当你想实时显示输出的时候(我很惊讶你自己回答的时候没有遇到这个问题;-)。
顺便提一下,如果你想同时显示和捕获输出,我总是推荐使用 pexpect
(在Windows上用 wexpect
),这正好可以解决缓冲的问题。