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.
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 using the following in a script:
try:
subprocess.check_output(file_path,shell=True)
except:
print("Error: Unable to open file.")
This code works mostly as intended with the only problem being that it still throws an exception on successful operations.
I will be using this with Tkinter to display message boxes and don't want my users to receive an error every time they close their successfully opened file. I am a bit of a novice and don't understand the subprocesses as well as I'd like to. I was originally using .Popen but from what I read, check_output is the best way to catch the exception.
Is there something I am missing or an easy way to fix this?
Edit: I checked the error via this method:
try:
subprocess.check_output(file_path, shell=True)
except subprocess.CalledProcessError as e:
print(e.output)
it just returns
b''
When I add print(e), I get this:
Command '<file_path>' returned non-zero exit status 1.
where the <file_path> is the actual path to the file.
I've also tried using .Popen and then .communicate() to view the output and error, but both return none whether-or-not .Popen has a target. If there is no target, I also see this in cmd:
<file_path> is not recognized as an internal or external command,
operable program or batch file.
Basically, I just want to throw an error if the target file path is not valid. If it is valid, I want it to open the file. I don't need to know the error, just that the file doesn't exist.
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.... """
I Have a shell script which in turn runs a python script, I have to exit from the main shell script when an exception is caught in python. Can anyone suggest a way on how to achieve it.
In Python you can set the return value using sys.exit(). Typically when execution completed successfully you return 0, and if not then some non-zero number.
So something like this in your Python will work:
import sys
try:
....
except:
sys.exit(1)
And then, as others have said, you need to make sure your bash script catches the error by either checking the return value explicitly (using e.g. $?) or using set -e.
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)