简体   繁体   English

使用python运行其他程序

[英]Using python to run other programs

I have a command that works great on the command line. 我有一个在命令行上运行良好的命令。 It has lots of arguments like cmd --thing foo --stuff bar -ab input output 它有很多参数,比如cmd --thing foo --stuff bar -ab input output

I want to run this from python and block waiting for it to complete. 我想从python运行它并阻塞等待它完成。 As the script prints things to stdout and stderr I want it to be immediately shown to the user. 当脚本将内容打印到stdoutstderr我希望它立即显示给用户。

What is the right module for this? 什么是正确的模块?

I've tried: 我试过了:


import commands
output = commands.getoutput("cmd --thing foo --stuff bar -a b input output")
print output

this works great except the stdout isn't returned until the end. 除了stdout直到最后才返回,这个工作得很好。


import os
os.system("cmd --thing foo --stuff bar -a b input output")

this prints all the output when the cmd is actually finished. 这将在cmd实际完成时打印所有输出。


import subprocess
subprocess.call(["cmd", "--thing foo", "--stuff bar", "-a b", "input", "output"])

this doesn't pass the parameters correctly somehow (I haven't been able to find the exact problem, but cmd is rejecting my input). 这不会以某种方式正确传递参数(我无法找到确切的问题,但cmd拒绝我的输入)。 If I put echo as the first parameter, it prints out the command which works perfectly when I paste it directly into the terminal. 如果我将echo作为第一个参数,它会打印出当我将其直接粘贴到终端时完美运行的命令。


import subprocess
subprocess.call("cmd --thing foo --stuff bar -a b input output")

exactly the same as above. 与上面完全相同。

You have to quote each field separately, ie. 你必须分别引用每个字段,即。 split the options from their arguments. 从他们的参数中拆分选项。

import subprocess
output = subprocess.call(["cmd", "--thing", "foo", "--stuff", "bar", "-a", "b", "input", "output"])

otherwise you are effectively running cmd like this 否则你就像这样有效地运行cmd

$ cmd --thing\ foo --stuff\ bar -a\ b input output

To get the output into a pipe you need to call it slightly differently 要将输出输入管道,您需要稍微改变它

import subprocess
output = subprocess.Popen(["cmd", "--thing", "foo", "--stuff", "bar", "-a", "b", "input", "output"],stdout=subprocess.PIPE)
output.stdout   #  <open file '<fdopen>', mode 'rb'>

If you don't need to process the output in your code, only to show it to the user as it happens (it's not clear from your Q, and it seems that way from your own self-answer), simplest is: 如果您不需要在代码中处理输出,只是在发生时将其显示给用户(从您的Q中看不清楚,并且从您自己的回答中看起来似乎这样),最简单的是:

rc = subprocess.call(
    ["cmd", "--thing", "foo", "--stuff", "bar", 
     "-a", "b", "input", "output"])
print "Return code was", rc

ie, just avoid any use of pipes -- let stdout and stderr just show on the terminal. 即,只是避免使用管道 - 让stdout和stderr只显示在终端上。 That should avoid any problem with buffering. 这应该避免缓冲的任何问题。 Once you put pipes in the picture, buffering generally is a problem if you want to show output as it happens (I'm surprised your self-answer doesn't have that problem;-). 一旦你把管道放在图片中,如果你想在输出时显示输出,缓冲通常一个问题(我很惊讶你的自我答案没有那个问题;-)。

For both showing and capturing, BTW, I always recomment pexpect (and wexpect on Windows) exactly to work around the buffering issue. 对于显示捕获,BTW,我总是建议pexpect (和Windows上的wexpect )完全解决缓冲问题。

Wouldn't commands.getstatusoutput() work? command.getstatusoutput()不会工作吗? It'll return your status right away pretty sure. 它会立即恢复您的状态。

A coworker just showed me this: 一位同事刚给我看了这个:

import os
import sys
for line in os.popen("cmd --thing foo --stuff bar -a b input output", "r"):
    print line
    sys.stdout.flush()

and it is working :) 它正在工作:)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM