To get the output of ls, use stdout=subprocess.PIPE.
>>> proc = subprocess.Popen('ls', stdout=subprocess.PIPE)
>>> output = proc.stdout.read()
>>> print output
bar
baz
foo
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 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.
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:', 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 #.
...
Answer from moinudin on Stack OverflowTo get the output of ls, use stdout=subprocess.PIPE.
>>> proc = subprocess.Popen('ls', stdout=subprocess.PIPE)
>>> output = proc.stdout.read()
>>> print output
bar
baz
foo
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 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.
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:', 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 #.
...
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)
Lets say I run:
subprocess.run(["wmctrl", "-l"])
This is great as it lists all open windows! However I can't figure out how to put this output into a variable of some kind so I can do something with it. Any help is appreciated.
You’ll need to use the stdout and/or stderr arguments. https://docs.python.org/3/library/subprocess.html#subprocess.run
Edit: link to #subprocess.run
Thanks for the answers. In the mean time I did get this to work...
import subprocess
output = subprocess.check_output("wmctrl -l", shell=True)
# it returns a byte type so convert it to string
output = str(output)
# split it into a list that makes sense
output = output.split('\\n')
# print out our list of windows
for x in range(len(output)):
print (output[x])
Thanks again! Just thought I'd share what worked for me for other beginners.
python - saving subprocess output in a variable - Stack Overflow
python - Retrieving the output of subprocess.call() - Stack Overflow
Printing output from subprocess.run
python - Redirect subprocess to a variable as a string - Stack Overflow
If you have Python version 2.7 or later, you can use subprocess.check_output which basically does exactly what you want (it returns standard output as a string).
A simple example (Linux version; see the note):
import subprocess
print subprocess.check_output(["ping", "-c", "1", "8.8.8.8"])
Note that the ping command is using the Linux notation (-c for count). If you try this on Windows, remember to change it to -n for the same result.
As commented below, you can find a more detailed explanation in this other answer.
Output from subprocess.call() should only be redirected to files.
You should use subprocess.Popen() instead. Then you can pass subprocess.PIPE for the stderr, stdout, and/or stdin parameters and read from the pipes by using the communicate() method:
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
The reasoning is that the file-like object used by subprocess.call() must have a real file descriptor, and thus implement the fileno() method. Just using any file-like object won't do the trick.
See here for more info.
I'm not getting an error but its not really printed what i wanted
I was trying to get these echo commands to show in either idle or running .py script
import subprocess allscripts = ["./scripty1", "./scripty2", "./scripty3", "./scripty4", "./scripty5"] for x in allscripts: subprocess.run([x], shell=True, capture_output=True) print(subprocess.check_output)
All it prints is this though
λ /bin/python /mnt/Stor2/Media/Share/DevShare/Py/InstallScript/InstallScript.py<function check_output at 0x7f7f2a94c040><function check_output at 0x7f7f2a94c040><function check_output at 0x7f7f2a94c040><function check_output at 0x7f7f2a94c040><function check_output at 0x7f7f2a94c040>
If you're using 2.7, you can use subprocess.check_output():
>>> import subprocess
>>> output = subprocess.check_output(['echo', '640x360'])
>>> print output
640x360
If not:
>>> p = subprocess.Popen(['echo', '640x360'], stdout=subprocess.PIPE)
>>> p.communicate()
('640x360\n', None)
import subprocess
p = subprocess.Popen(["ls", "-al"], stdout=subprocess.PIPE)
out, err = p.communicate()
print out