检索subprocess.call()的输出

我怎样才能得到使用subprocess.call()进程运行的输出?

将一个StringIO.StringIO对象传递给stdout会产生这样的错误:

Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/subprocess.py", line 444, in call return Popen(*popenargs, **kwargs).wait() File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/subprocess.py", line 588, in __init__ errread, errwrite) = self._get_handles(stdin, stdout, stderr) File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/subprocess.py", line 945, in _get_handles c2pwrite = stdout.fileno() AttributeError: StringIO instance has no attribute 'fileno' >>> 

subprocess.call()输出只能被重定向到文件。

你应该使用subprocess.Popen()来代替。 然后,您可以传递subprocess.PIPE stderr,stdout和/或stdin参数,并使用communicate()方法从管道读取:

 from subprocess import Popen, PIPE p = Popen(['program', 'arg1'], stdin=PIPE, stdout=PIPE, stderr=PIPE) output, err = p.communicate(b"input data that is passed to subprocess' stdin") rc = p.returncode 

原因是subprocess.call()使用的类文件对象必须有一个真实的文件描述符,因此实现了fileno()方法。 只要使用任何类似文件的对象都不会成功。

在这里看到更多的信息。

如果你的Python版本大于2.7,你可以使用subprocess.check_output ,它基本上是你想要的(它以字符串的形式返回标准输出)。

正如下面评论你可以找到示例代码和更详细的解释在这个其他的答案 。

我有以下解决方案。 它捕获执行的外部命令的退出代码,stdout和stderr:

 import shlex from subprocess import Popen, PIPE def get_exitcode_stdout_stderr(cmd): """ Execute the external command and get its exitcode, stdout and stderr. """ args = shlex.split(cmd) proc = Popen(args, stdout=PIPE, stderr=PIPE) out, err = proc.communicate() exitcode = proc.returncode # return exitcode, out, err cmd = "..." # arbitrary external command, eg "python mytest.py" exitcode, out, err = get_exitcode_stdout_stderr(cmd) 

我也在这里有一个博客文章。

编辑:该解决方案已更新到一个不需要写入临时。 文件。

我最近才弄明白了如何做到这一点,下面是我的一个当前项目的一些示例代码:

 #Getting the random picture. #First find all pictures: import shlex, subprocess cmd = 'find ../Pictures/ -regex ".*\(JPG\|NEF\|jpg\)" ' #cmd = raw_input("shell:") args = shlex.split(cmd) output,error = subprocess.Popen(args,stdout = subprocess.PIPE, stderr= subprocess.PIPE).communicate() #Another way to get output #output = subprocess.Popen(args,stdout = subprocess.PIPE).stdout ber = raw_input("search complete, display results?") print output #... and on to the selection process ... 

您现在将命令的输出存储在变量“output”中。 “stdout = subprocess.PIPE”告诉类在Popen中创建一个名为“stdout”的文件对象。 从我所知道的()方法,只是作为一个方便的方式来返回输出的元组和从你运行的过程中的错误。 此外,该过程在实例化Popen时运行。

对于Python 3.5+,建议使用子进程模块的运行功能 。 这将返回一个CompletedProcess对象,从中可以轻松获得输出以及返回代码。

 from subprocess import PIPE, run command = ['echo', 'hello'] result = run(command, stdout=PIPE, stderr=PIPE, universal_newlines=True) print(result.returncode, result.stdout, result.stderr) 

Ipython shell中:

 In [8]: import subprocess In [9]: s=subprocess.check_output(["echo", "Hello World!"]) In [10]: s Out[10]: 'Hello World!\n' 

基于萨尔格的答案。 信用sargue。

以下内容捕获一个变量的过程的stdout和stderr。 它是Python 2和3兼容:

 command = ["ls", "-l"] try: output = check_output(command, stderr=STDOUT).decode() success = True except CalledProcessError as e: output = e.output.decode() success = False 

如果你的命令是一个字符串而不是一个数组,那么在前面加上:

 import shlex command = shlex.split(command)