I have a very simple piece of code
import subprocess
print(subprocess.check_output(["pidof","ffmpeg"]))
that should print the PID(s) of processes named ffmpeg (see here). However, I always get the following error:
subprocess.CalledProcessError: Command '['pidof', 'ffmpeg']' returned non-zero exit status 1
for python2 and python3. What am I doing wrong?
From man pidof:
EXIT STATUS
0 At least one program was found with the requested name.
1 No program was found with the requested name.
You just don't have any process named ffmpeg.
you can use try except to avoid the execution from blocking
use this
import subprocess
try:
print(subprocess.check_output(["pidof","ffmpeg"]))
except subprocess.CalledProcessError:
print("no process named ffmpeg")
you are getting error because if pidof ffmpeg gives no output and using
print(subprocess.check_output(["pidof","ffmpeg"])) we are expecting output from that command.
also you can use
print(subprocess.getoutput("pidof ffmpeg"))
which will give no error even if output from that command is none
if you check the library method check_output you can find this
def check_output(*popenargs, timeout=None, **kwargs):
r"""Run command with arguments and return its output.
If the exit code was non-zero it raises a CalledProcessError. The
CalledProcessError object will have the return code in the returncode
attribute and output in the output attribute.
The arguments are the same as for the Popen constructor.... """
Related
I am trying to create a function that can run any shell command and return the stdout of that command, without worrying about any exceptions that could be thrown. When testing the code written below with incorrect commands like xyz testing, I get a FileNotFoundError rather that the CalledProcessError even though the command xyz testing returns a non-zero return code when I ran it in the shell. But, when I run the same function with a similar invalid command like ls -xyz I get a CalledProcessError as expected. Does anyone know why the exception is not being thrown in a consistent manner.
try:
cmd_result = subprocess.run(
cmd,
capture_output=True,
text=True,
check=True,
)
except subprocess.CalledProcessError as exc:
click.echo(exc.stderr)
click.echo(cmd)
sys.exit(1)
Thank you
I tried putting the shell=True option, and then the error situation swaps (xyz testing) passes and ls -xyz fails.
I have been stuck on what else I can try.
A couple of things are happening. With check=True, subprocess raises CalledProcessError if the command is executed and returns a non-zero exit status. When shell=False, the file to execute couldn't be found, so you got the FileNotFound error code. The program wasn't run, there was no exit code to examine, so CalledProcessError was not an option.
When shell=True, subprocess runs an intermediate shell. Now its the shell return code that matters and that can be different than the called process. Subprocess found the intermediate shell, so there is no FileNotFound error, but couldn't find the program so returned a non-zero value, generating the other exception. Consider the command "xyz testing;exit 0" this would not generate a called process error even though xyz does not exist. That's because the shell returned a 0 exit code.
I am currently trying to get the process id of a process started with subprocess.check_call.
i.e.
from subprocess import check_output
# I want to retrieve the PID of this process:
try:
p = check_output(['some broken program'])
except:
if CalledProcessError: # but Popen does not throw me a CalledProcessError even if program crashes
print("triage some stuff")
print(p.pid) # this doesn't work unless its Popen
I have tried using Popen which works perfectly, however, it doesn't seem to be able to catch when a program is terminated i.e. CalledProcessError.
Can anyone advise, whether there is a way to get around either problem? Thanks!
You have to import CalledProcessError too. Code (with check_output): from subprocess import check_output, CalledProcessError
To detect a specific exception you have to use the following syntax:
try:
statement
except ExceptionName:
another_statement
In your situation:
try:
p = check_output(['some broken program'])
except CalledProcessError:
print("triage some stuff")
You cannot reference p inside the except block as p may be undefined.
Moreover, as stated in this post, subprocess.run() is recommended over subprocess.check_output()
Is there a doc somewhere which indicates what the different return codes of python's subprocess check_output() command means? I'm seeing the returncode equal 3, and I have no idea what is setting that value and/or what it means.
Example code:
try:
output = subprocess.check_output(cmd,
stderr=subprocess.STDOUT)
except subprocess.CalledProcessError as e:
print e.returncode
This code is printing 3.
The Python subprocess.check_output() doesn't itself return a code, it returns the output of the command being run. The doco can be found here.
If you're seeing an error code in that string, it's almost certainly specific to whatever you're trying to run, not a result of subprocess itself.
If, however, you're capturing the CalledProcessError exception caused by a non-zero return code (which can be extracted from the returncode attribute), that's still specific to whatever you're running.
In both cases, the documentation you need to check is that of whatever tool subprocess is running.
I am working with an automated Blender python script and I would like to know how to terminate it with an Exit Code 1 when an Exception occurs.
The problem seems to be that the exit code from blender is always 0 even if the python script fails.
The following script definately produces a non-zero exit code, but blender sets exit code to 0
def main():
raise Exception("Fail")
sys.exit(1)
I also tried the --python-exit-code command line argument but to no effect:
C:\blender.exe --python-exit-code 2 --disable-abort-handler -P bake.py
this gives a slightly better result, because I get the following message:
Error: script failed, file: 'bake.py', exiting with code 2.
Unfortunately the exit code is still 0.
Can anyone enlighten me with some explanations or solutions on how I can exit the process with the correct exit code?
Thanks a lot for any hints!
--python-exit-code as stated in the documentation sets the exit code if the command line script called with --python raises an exception, not when it exits with a non-zero code.
Set the exit-code in [0..255] to exit if a Python exception is raised (only for scripts executed from the command line), zero disables.
Thus the only solution is to do your checking, and raise an exception manually, then catch it and exit in the except block. (If you don't exit right away, the exit code reverts to 0.
This code worked for me when doing unit tests inside a blender addon.
import unittest
from tests.my_test import MyTest
import sys
def run():
suite = unittest.defaultTestLoader.loadTestsFromTestCase(MyTest)
success = unittest.TextTestRunner().run(suite).wasSuccessful()
if not success:
raise Exception('Tests Failed')
try:
run()
except Exception:
sys.exit(1)
I am trying to run unoconv to convert a set of documents in a folder like so:
import subprocess
try:
subprocess.check_call(['unoconv', "/home/foo/ve/pdf/pdf/pdf_media/" + <filename parameter>)
except subprocess.CalledProcessError as e:
print "conversion error: ", e
Now, I run the above code within a django view - and it runs as expects all the time i.e converts the document to PDF, but, sometimes, the above code throws me the following exception:
Command '['unoconv', u'/home/foo/ve/pdf/pdf/pdf_media/WgYozM7.doc']' returned non-zero exit status -8
However, when I go to the folder, I see that the conversion has happened and the PDF generated as expected.
I fail to understand what this exit code means (I searched the docs of unoconv but couldnt find any exit code 8).
It looks to me that your subprocess has a negative exit-code. This is not an application code, but caused by the OS terminating your program. The negative number is the signal-number the process received. On my mac, -8 stands for SIGFPE.