So im trying to save the output from my subprocess.call but I keep getting the following error:
AttributeError: 'int' object has no attribute 'communicate'
Code is as follows:
p2 = subprocess.call(['./test.out', 'new_file.mfj', 'delete1.out'], stdout = PIPE)
output = p2.communicate[0]
You're looking for subprocess.Popen() instead of call().
You also need to change it to p2.communicate()[0].
That's because subprocess.call returns an int:
subprocess.call(args, *, stdin=None, stdout=None, stderr=None, shell=False)
Run the command described by args. Wait for command to complete, then return the returncode attribute.
It looks like you want subprocess.Popen().
Here's a typical piece of code I have to do this:
p = Popen(cmd, stdout=PIPE, stderr=PIPE, bufsize=256*1024*1024)
output, errors = p.communicate()
if p.returncode:
raise Exception(errors)
else:
# Print stdout from cmd call
print output
You should use subprocess
try:
subprocess.check_output(['./test.out', 'new_file.mfj', 'delete1.out'], shell=True, stderr=subprocess.STDOUT)
except subprocess.CalledProcessError as exception:
print exception.output
Related
In windows I have to execute a command like below:
process = subprocess.Popen([r'C:\Program Files (x86)\xxx\xxx.exe', '-n', '#iseasn2a7.sd.xxxx.com:3944#dc', '-d', r'D:\test\file.txt'], shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
process.communicate()
This works fine in python interactive mode, but not at all executing from the python script.
What may be the issue ?
Popen.communicate itself does not print anything, but it returns the stdout, stderr output. Beside that because the code specified stdout=PIPE, stderr=... when it create Popen, it catch the outputs (does not let the sub-process print output directly to the stdout of the parent process)
You need to print the return value manually:
process = ....
output, error = process.communicate()
print output
If you don't want that, don't catch stdout output by omit stdout=PIPE, stderr=....
Then, you don't need to use communicate, but just wait:
process = subprocess.Popen([...], shell=True)
process.wait()
Or, you can use subprocess.call which both execute sub-process and wait its termination:
subprocess.call([...], shell=True)
try:
output = subprocess.check_output(command, shell=True)
except subprocess.CalledProcessError as exc:
logger.error('There was an error while ...: \n%s',
exc.output)
raise
What is the easiest way to do the following:
Call a process using subprocess module.
If the program exited normally, put into output variable its standard output.
If the program exited abnormally, get its standard output and error.
import subprocess
process= subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
process.wait() #wait for the command to finish
output= process.stdout.read()
if process.poll(): #check the error code
error= process.stderr.read()
I'm new to Python and Programming as well. I know from Google's python class how to run external command using:
(status, output) = commands.getstatusoutput(cmd)
if status: ## Error case, print the command's output to stderr and exit
sys.stderr.write(output)
sys.exit(1)
But I perceive that commands module is going obsolete. I want the status and the output, so I can print the output using sys.stderr.write() if there is any error. So, is there any equivalent command in subprocess module? I'm currently using:
subprocess.call(args,shell=False) now.
Thanks!
There is subprocess.getstatusoutput() in Python 3 that could be implemented as:
from subprocess import check_output, CalledProcessError, STDOUT
def getstatusoutput(cmd):
try:
data = check_output(cmd, shell=True, universal_newlines=True, stderr=STDOUT)
status = 0
except CalledProcessError as ex:
data = ex.output
status = ex.returncode
if data[-1:] == '\n':
data = data[:-1]
return status, data
Both return status that is different from the original commands.getstatusoutput(). See Python Issue: Document & unittest the subprocess.getstatusoutput() status value.
It's also possible to do this, with a bit less code
from subprocess import Popen, PIPE
def getstatusoutput(command):
process = Popen(command, stdout=PIPE)
out, _ = process.communicate()
return (process.returncode, out)
code, out = getstatusoutput(["echo", "some text"])
print code
print out
Popen is a nice and easy way to do it:
from subprocess import Popen, PIPE
def local(command):
print 'local', local
process = Popen(command.split(), stdout=PIPE, stderr=PIPE)
out = process.stdout.read()
err = process.stderr.read()
print 'out', out
print 'err', err
returncode = process.wait()
if returncode:
raise Exception(returncode, err)
else:
return out
What getstatusoutput does is gather both stdout and stderr output interleaved in one variable. This will quite closely replicate the actual behaviour of getstatusoutput on those where it does not exist (getstatusoutput and the whole commands module was removed on Python 3 completely), excepting the newline behaviour. The resulting data is in bytes.
def getstatusoutput(cmd):
subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
out, _ = process.communicate()
if out[-1:] == b'\n':
out = out[:-1]
return (process.returncode, out)
This function returns bytes on Python 3 on purpose, as the Python 2 version returns str
I am calling the executable from python script using sub process call. these are the following code I have used:
try:
p = subprocess.Popen([abc.exe], shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()
except Exception as e:
print str(e)
from abc.exe, I have return 1 in failure case and return 0 for success case. But I don't know how to check the return value in python script.
thanks,
Popen.returncode contains the return code when the process has terminated. You can ensure that using Popen.wait.
You've saved as p the output from .communicate(), not Popen object. Perhaps try:
try:
p = subprocess.Popen(['abc.exe'], shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
except OSError as e:
print str(e)
stdoutdata, stderrdata = p.communicate()
retcode = p.returncode
Another way to do this is to use subprocess.check_output() since you mention Python 2.7. This runs the command with the same arguments as Popen. The output of the command is returned as a string. If the command returns a non-zero value, a subprocess.CalledProcessError exception is raised.
So I think you can rework your code to something like this:
try:
output = subprocess.check_output(['abc.exe'], shell=True, stderr=subprocess.STDOUT)
except subprocess.CalledProcessError as ex:
# an error occurred
retcode = ex.returncode
output = ex.output
else:
# no error occurred
process(output)
Note that you can't use the stdout argument in check_output since it is used internally. Here are the docs.
I just want to do something like this:
>>bar, err_value = subprocess.check_output("cat foo.txt", shell=True)
>>print bar
>>Hello, world.
>>print err_value
>>0
But I can't seem to be able to do it. I can either get the stdout, the error code (via .call) or maybe both but needing to use some kind of pipe. What am I missing here? The documentation is very sparse about this (to me) obvious functionality. Sorry if this is a simplistic question.
I take it that you want stdout, sterr and the return code? In that case, you could do this:
import subprocess
PIPE = subprocess.PIPE
proc = subprocess.Popen(cmd, stdout=PIPE, stderr=PIPE)
output, err = proc.communicate()
errcode = proc.returncode
I ended up going with this. Thanks for your help!
def subprocess_output_and_error_code(cmd, shell=True):
import subprocess
PIPE=subprocess.PIPE
STDOUT=subprocess.STDOUT
proc = subprocess.Popen(cmd, stdout=PIPE, stderr=STDOUT, shell=shell)
stdout, stderr = proc.communicate()
err_code = proc.returncode
return stdout, int(err_code)
subprocess.check_output reutrn a value (output string), and does not return exit status. Use following form:
import subprocess
try:
out = subprocess.check_output('cat foo.txt', shell=True)
print out
except subprocess.CalledProcessError, e:
print e