Pipe subprocess standard output to a variable [duplicate]
To get the output of ls
, use stdout=subprocess.PIPE
.
>>> proc = subprocess.Popen('ls', stdout=subprocess.PIPE)>>> output = proc.stdout.read()>>> print outputbarbazfoo
The command cdrecord --help
outputs 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=True
argument but this fires up a fully-blown shell which can be dangerous if you don't control the contents of the command string.
>>> proc = subprocess.Popen(['cdrecord', '--help'], stderr=subprocess.PIPE)>>> output = proc.stderr.read()>>> print outputUsage: wodim [options] track1...tracknOptions: -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.
subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
As mentioned by Chris Morgan, you should be using proc.communicate()
instead of proc.read()
.
>>> proc = subprocess.Popen(['cdrecord', '--help'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)>>> out, err = proc.communicate()>>> print 'stdout:', outstdout: >>> print 'stderr:', errstderr:Usage: wodim [options] track1...tracknOptions: -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 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:
output = subprocess.check_output('ls')
To also redirect stderr you can use the following:
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.
output = subprocess.check_output(['ls', '-a'])output = subprocess.check_output('ls -a', shell=True)
With a = subprocess.Popen("cdrecord --help",stdout = subprocess.PIPE)
, you need to either use a list or use 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).
proc = subprocess.Popen(['cdrecord', '--help'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)stdout, stderr = proc.communicate()