I read up on the functions provided by subprocess - call, check_call, check_output, and understand how each works and differs in functionality from one another. I am currently using check_output, so I can have access to the stdout, and used "try block" to catch the exception, as follows:
# "cmnd" is a string that contains the command along with it's arguments.
try:
cmnd_output = check_output(cmnd, stderr=STDOUT, shell=True, timeout=3, universal_newlines=True);
except CalledProcessError:
print("Status : FAIL")
print("Output: \n{}\n".format(cmnd_output))
The issue I am running into is when an exception is thrown, "cmnd_output" is not initialized and don't have access to stderr, and I get the following error message:
print("Output: \n{}\n".format(cmnd_output))
UnboundLocalError: local variable 'cmnd_output' referenced before assignment
I think thats because the exception causes the "check_output" to bail immediately without any further processing, aka assignment to "cmnd_output", in the try block. Please correct me if I am wrong.
Is there any way I can get access to stderr (it's ok if it's sent to stout) and have access to the exit code. I can manually check for pass/fail based on exit code with out the exception being throuwn.
Thank you, Ahmed.
Try this version:
This way you will print the output only if the call was successful. In case of a
CalledProcessError
you print the return code and the output.The accepted solution covers the case in which you are ok mixing
stdout
andstderr
, but in cases in which the child process (for whatever reason) decides to usestderr
IN ADDITION tostdout
for a non failed output (i.e. to output a non-critical warning), then the given solution may not desirable.For example, if you will be doing additional processing on the output, like converting to JSON, and you mix in the
stderr
, then the overall process will fail since the output will not be pure JSON because of the addedstderr
output.I've found the following to work in that case:
why not initialize the varible cmnd_output before the try statement? That way it will work the way you expect it to. Following line would work, just add it above try statement :
Both of the proposed solutions either mix the stdout/stderr, or use
Popen
which isn't quite as simple to use ascheck_output
. However, you can accomplish the same thing, and keep stdout/stderr separate, while usingcheck_output
if you simply capture stderr by using a pipe:In this example, since we captured stderr, it's available in the exception's
stderr
attribute (without capturing with the pipe, it would just beNone
).