12

I need a method to run a python script file, and if the script fails with an unhandled exception python should exit with a non-zero exit code. My first try was something like this:

import sys
if __name__ == '__main__':
    try:
        import <unknown script>
    except:
        sys.exit(-1)

But it breaks a lot of scripts, due to the __main__ guard often used. Any suggestions for how to do this properly?

pehrs
  • 1,481
  • 2
  • 15
  • 21
  • 2
    Do you want to *run scripts* or *import modules*? If you want to run scripts, you could use the [`subprocess`](http://docs.python.org/library/subprocess.html) module. – Björn Pollex Mar 28 '11 at 08:05
  • I get an unknown script. I want to run it and get a non-zero exit code if it crashes. Subprocess is not much help, because the python process will happily return 0 even if the script throws an unhandled exception. – pehrs Mar 28 '11 at 08:07

2 Answers2

19

Python already does what you're asking:

$ python -c "raise RuntimeError()"
Traceback (most recent call last):
  File "<string>", line 1, in <module>
RuntimeError
$ echo $?
1

After some edits from the OP, perhaps you want:

import subprocess

proc = subprocess.Popen(['/usr/bin/python', 'script-name'])
proc.communicate()
if proc.returncode != 0:
    # Run failure code
else:
    # Run happy code.

Correct me if I am confused here.

Thanatos
  • 42,585
  • 14
  • 91
  • 146
  • Something is seriously broken with my python or shell then, because my python insists on failing with 0 regardless of what I do. I will see if I can track down what happens. Thanks for the clear explanation of expected behavior. Python exit codes are not documented anywhere I have found! – pehrs Mar 28 '11 at 08:14
  • I took a look and also couldn't find anywhere that the exit code were documented. It could be useful to see more info about your setup (Python version, OS, script that triggers a 0 return code where you think there should be a non-zero code) to see if we can reproduce. – Thanatos Mar 28 '11 at 08:27
  • Ubuntu 10.10, but upgraded several times and a hand compiled and installed python 2.6.0. Even something like foo=0/0 triggered the problem. In the end the solution was as simple as throwing out the old python installation and replacing it the standard Ubuntu package. Thank you for the help! – pehrs Mar 28 '11 at 08:40
3

if you want to run a script within a script then import isn't the way; you could use exec if you only care about catching exceptions:

namespace = {}
f = open("script.py", "r")
code = f.read()
try:
    exec code in namespace
except Exception:
    print "bad code"

you can also compile the code first with

compile(code,'<string>','exec')

if you are planning to execute the script more than once and exec the result in the namespace

or use subprocess as described above, if you need to grab the output generated by your script.

user237419
  • 8,829
  • 4
  • 31
  • 38