Standard pipe subprocess output to variable

I want to run a command in pythong using a subprocess module and store the output in a variable. However, I do not want the output of the command to be printed to the terminal. For this code:

 def storels(): a = subprocess.Popen("ls",shell=True) storels() 

I get a list of directories in the terminal, instead of storing it in a . I also tried:

  def storels(): subprocess.Popen("ls > tmp",shell=True) a = open("./tmp") [Rest of Code] storels() 

This also outputs ls output to my terminal. I even tried this command with the somewhat outdated os.system method, since running ls > tmp in the terminal does not print ls to the terminal at all, but saves it in tmp . However, the same thing happens.

Edit:

I get the following error after the following marcog recommendations, but only when running a more complex command. cdrecord --help . Python spits it out:

 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 
+62
python subprocess pipe
Dec 22 '10 at 23:45
source share
3 answers

To get ls output, use stdout=subprocess.PIPE .

 >>> proc = subprocess.Popen('ls', stdout=subprocess.PIPE) >>> output = proc.stdout.read() >>> print output bar baz foo 

The cdrecord --help command prints to stderr, so you need to connect this node. You should also split the command into a list of tokens, as I did below, or an alternative is to pass the shell=True argument, but it launches a completely bloated shell, which can be dangerous if you do not control the contents of the command line.

 >>> 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 stdout and stderr, and you want to combine them, you can do this by going stderr to stdout and then catching stdout.

 subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) 

As mentioned by Chris Morgan , you should use proc.communicate() instead of 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 #. ... 
+96
Dec 22 '10 at 23:49
source share

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') 

You can use the following to redirect stderr:

 output = subprocess.check_output('ls', stderr=subprocess.STDOUT) 



In case you want to pass parameters to the command, you can either use the list or use the shell call and use one line.

 output = subprocess.check_output(['ls', '-a']) output = subprocess.check_output('ls -a', shell=True) 
+21
Mar 16 '12 at 18:25
source share

With a = subprocess.Popen("cdrecord --help",stdout = subprocess.PIPE) you need to either use a list or use shell=True ;

Any of them will work. The first is preferable.

 a = subprocess.Popen(['cdrecord', '--help'], stdout=subprocess.PIPE) a = subprocess.Popen('cdrecord --help', shell=True, stdout=subprocess.PIPE) 

In addition, instead of Popen.stdout.read / Popen.stderr.read you should use .communicate() (refer to the subprocess documentation for what).

 proc = subprocess.Popen(['cdrecord', '--help'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = proc.communicate() 
+8
Dec 23 2018-10-12T00:
source share



All Articles