Python 管道子流程标准输出到变量
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4514751/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Pipe subprocess standard output to a variable
提问by Insomaniacal
I want to run a command in pythong, using the subprocess module, and store the output in a variable. However, I do not want the command's output to be printed to the terminal.
For this code:
我想在 中运行一个命令pythong,使用 subprocess 模块,并将输出存储在一个变量中。但是,我不希望将命令的输出打印到终端。对于此代码:
def storels():
a = subprocess.Popen("ls",shell=True)
storels()
I get the directory listing in the terminal, instead of having it stored in a. I've also tried:
我在终端中获得目录列表,而不是将其存储在a. 我也试过:
def storels():
subprocess.Popen("ls > tmp",shell=True)
a = open("./tmp")
[Rest of Code]
storels()
This also prints the output of ls to my terminal. I've even tried this command with the somewhat dated os.system method, since running ls > tmpin the terminal doesn't print lsto the terminal at all, but stores it in tmp. However, the same thing happens.
这也会将 ls 的输出打印到我的终端。我什至用有点过时的 os.system 方法尝试过这个命令,因为ls > tmp在终端中运行根本不会打印ls到终端,而是将它存储在tmp. 然而,同样的事情也会发生。
Edit:
编辑:
I get the following error after following marcog's advice, but only when running a more complex command. cdrecord --help. Python spits this out:
在遵循 marcog 的建议后,我收到以下错误,但仅在运行更复杂的命令时才出现。cdrecord --help. Python 吐出这个:
Traceback (most recent call last):
File "./install.py", line 52, in <module>
burntrack2("hi")
File "./install.py", line 46, in burntrack2
a = subprocess.Popen("cdrecord --help",stdout = subprocess.PIPE)
File "/usr/lib/python2.6/subprocess.py", line 633, in __init__
errread, errwrite)
File "/usr/lib/python2.6/subprocess.py", line 1139, in _execute_child
raise child_exception
OSError: [Errno 2] No such file or directory
采纳答案by moinudin
To get the output of ls, use stdout=subprocess.PIPE.
要获得 的输出ls,请使用stdout=subprocess.PIPE。
>>> proc = subprocess.Popen('ls', stdout=subprocess.PIPE)
>>> output = proc.stdout.read()
>>> print output
bar
baz
foo
The command cdrecord --helpoutputs to stderr, so you need to pipe that indstead. You should also break up the command into a list of tokens as I've done below, or the alternative is to pass the shell=Trueargument but this fires up a fully-blown shell which can be dangerous if you don't control the contents of the command string.
该命令cdrecord --help输出到 stderr,因此您需要改为通过管道传输。您还应该像我在下面所做的那样将命令分解为一个令牌列表,或者另一种方法是传递shell=True参数,但这会启动一个完全成熟的外壳,如果您不控制它的内容,这可能会很危险命令字符串。
>>> proc = subprocess.Popen(['cdrecord', '--help'], stderr=subprocess.PIPE)
>>> output = proc.stderr.read()
>>> print output
Usage: wodim [options] track1...trackn
Options:
-version print version information and exit
dev=target SCSI target to use as CD/DVD-Recorder
gracetime=# set the grace time before starting to write to #.
...
If you have a command that outputs to both stdout and stderr and you want to merge them, you can do that by piping stderr to stdout and then catching stdout.
如果您有一个输出到 stdout 和 stderr 的命令并且您想合并它们,您可以通过将 stderr 管道传输到 stdout 然后捕获 stdout 来实现。
subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
As mentioned by Chris Morgan, you should be using proc.communicate()instead of proc.read().
正如Chris Morgan所提到的,您应该使用proc.communicate()代替proc.read().
>>> proc = subprocess.Popen(['cdrecord', '--help'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
>>> out, err = proc.communicate()
>>> print 'stdout:', out
stdout:
>>> print 'stderr:', err
stderr:Usage: wodim [options] track1...trackn
Options:
-version print version information and exit
dev=target SCSI target to use as CD/DVD-Recorder
gracetime=# set the grace time before starting to write to #.
...
回答by Chris Morgan
With a = subprocess.Popen("cdrecord --help",stdout = subprocess.PIPE)
, you need to either use a list or use shell=True;
使用a = subprocess.Popen("cdrecord --help",stdout = subprocess.PIPE)
,您需要使用列表或使用shell=True;
Either of these will work. The former is preferable.
这两者中的任何一个都会起作用。前者更可取。
a = subprocess.Popen(['cdrecord', '--help'], stdout=subprocess.PIPE)
a = subprocess.Popen('cdrecord --help', shell=True, stdout=subprocess.PIPE)
Also, instead of using Popen.stdout.read/Popen.stderr.read, you should use .communicate()(refer to the subprocess documentation for why).
此外,您应该使用(请参阅子流程文档了解原因)而不是使用Popen.stdout.read/ 。Popen.stderr.read.communicate()
proc = subprocess.Popen(['cdrecord', '--help'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, stderr = proc.communicate()
回答by amicitas
If you are using python 2.7 or later, the easiest way to do this is to use the subprocess.check_output()command. Here is an example:
如果您使用的是 python 2.7 或更高版本,最简单的方法是使用subprocess.check_output()命令。下面是一个例子:
output = subprocess.check_output('ls')
To also redirect stderr you can use the following:
要重定向 stderr,您可以使用以下命令:
output = subprocess.check_output('ls', stderr=subprocess.STDOUT)
In the case that you want to pass parameters to the command, you can either use a list or use invoke a shell and use a single string.
如果您想将参数传递给命令,您可以使用列表或使用调用 shell 并使用单个字符串。
output = subprocess.check_output(['ls', '-a'])
output = subprocess.check_output('ls -a', shell=True)

