Marty <[EMAIL PROTECTED]> writes: > I need to catch exceptions thrown by programs started by the os.system > function, as indicated by a non-zero return code (e.g. the mount > utility).
That's not an exception. It's referred to as an "exit status" or (often) some short form or variation of that term. Python can make available the exit status value of an external process, but isn't going to interpret them to the point of raising exceptions that you can catch. The exit status is always available to the parent process, but the *meaning* of any given value of that status is highly dependent on the program that was running. If you want to respond to particular values, you'll have to do so by explicitly testing the exit status against values to which you've assigned meaning -- hopefully meanings documented in the manual page for the program which generates the exit status. > For example, if I get the following results in a bash > shell: > > $mount test > mount: can't find /home/marty/test in /etc/fstab or /etc/mtab > > then I want to catch the same exception What's happening isn't an exception. It's a message being emitted to an output stream (likely the stderr stream of the mount process, though some programs will put error messages on stdout), followed by an exit of that process. The parent of that process will receive an exit status from the process when it terminates; it will also (on Unix-like systems) receive a separate value indicating the OS signal that caused the process to exit. Python's 'os.system' function makes both these values available as the return value of the function. <URL:http://docs.python.org/lib/os-process.html#l2h-2761> > from the corresponding os.system() call, i.e. "os.system('mount > test')", but it doesn't work as expected: > > > >>> import os, sys > >>> try: os.system('mount test') > ... except: print 'error' > ... > mount: can't find /home/marty/test in /etc/fstab or /etc/mtab > 256 > >>> The statement within the 'try' block executes the 'os.system()' call; since you're running inside the interpreter, the return value from that function is displayed. The return value, as documented in the 'os.system' documentation, encodes both the signal number (the low 8 bits, in this case (256 & 0x0F) == 0) and, since the signal number is zero ("no signal received") the exit status value (the high 8 bits, in this case (256 >> 8) == 1). No exception is being raised, so the 'try' block completes successfully and the 'except' block is not invoked. So, instead of testing for an exception, you should instead be testing the exit status code returned by the 'os.system' call. First, read the documentation for the command you're running:: $ man mount [...] Unfortunately the 'mount(8)' manual page doesn't (on my system) mention possible values for the exit status. So, you'll just have to deduce it, or go with the common convention of "zero status == success, non-zero status == error". MountFailedError = OSError import os return_value = os.system('mount test') signal_number = (return_value & 0x0F) if not signal_number: exit_status = (return_value >> 8) if exit_status: raise MountFailedError("Oh no!") Why isn't this standardised? Because the process-call interface is inconsistent between operating systems, and there's even less consistency in the implementations of the programs that return these values. The Zen of Python says: "In the face of ambiguity, refuse the temptation to guess." Thus, Python can do little more than present the values it received from the process call; anything further would be guessing. -- \ "I bought some batteries, but they weren't included; so I had | `\ to buy them again." -- Steven Wright | _o__) | Ben Finney -- http://mail.python.org/mailman/listinfo/python-list