我有一个在命令行上运行良好的命令。它有很多参数,如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")
这将在cmd实际完成时打印所有输出。
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")
与上面完全相同。
答案 0 :(得分:7)
你必须分别引用每个字段,即。从他们的论点中分离选项。
import subprocess
output = subprocess.call(["cmd", "--thing", "foo", "--stuff", "bar", "-a", "b", "input", "output"])
否则你就像这样有效地运行cmd
$ 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'>
答案 1 :(得分:3)
如果您不需要在代码中处理输出,只是在发生时向用户显示输出(从您的Q中看不清楚,并且从您自己的回答中看起来似乎这样),最简单的是:
rc = subprocess.call(
["cmd", "--thing", "foo", "--stuff", "bar",
"-a", "b", "input", "output"])
print "Return code was", rc
即,只是避免使用管道 - 让stdout和stderr只显示在终端上。这应该避免缓冲的任何问题。一旦你在图片中放置了管道,如果你想在输出时显示输出,那么缓存一般是一个问题(我很惊讶你的自我答案没有那个问题; - )。
对于显示和捕获的BTW,我总是推荐pexpect
(以及Windows上的wexpect
)来解决缓冲问题。
答案 2 :(得分:2)
command.getstatusoutput()不会有效吗?它会马上回复你的状态。
答案 3 :(得分:1)
一位同事刚给我看了这个:
import os
import sys
for line in os.popen("cmd --thing foo --stuff bar -a b input output", "r"):
print line
sys.stdout.flush()
它正在工作:)