Exit codes in Python
I got a message saying script xyz.py returned exit code 0 . What does this mean? What do the exit codes in Python mean? How many are there? Which ones are important?
16 Answers 16
You’re looking for calls to sys.exit() in the script. The argument to that method is returned to the environment as the exit code.
It’s fairly likely that the script is never calling the exit method, and that 0 is the default exit code.
Not sure at all. In Unix/Linux, the standard is: exit 0 in the case everything was ok. Type a command, then echo $?: if you read 0, it returned without an error. The idea is to have standard tests. If the code xyz.py did not encounter any error, it SHOULD return 0!
If you would like to change the exit code, prefer to exit cleanly using the exit builtin, see this answer
@vidstige: The exit() «built-in» (it’s not actually a built-in all the time; e.g. it won’t exist when Python is run with the -S switch) is the wrong solution; you want sys.exit() (which does in fact exit cleanly/consistently), not exit() (which is allowed to be replaced with weird things by tools, where sys.exit is generally supposed to stay untouched). The «unclean exit» function is os._exit() , which does terminate abruptly (it’s used largely to kill workers in fork -based multiprocessing scenarios to avoid invoking cleanup that the parent process set up before the fork ).
From the documentation for sys.exit :
The optional argument arg can be an integer giving the exit status (defaulting to zero), or another type of object. If it is an integer, zero is considered “successful termination” and any nonzero value is considered “abnormal termination” by shells and the like. Most systems require it to be in the range 0-127, and produce undefined results otherwise. Some systems have a convention for assigning specific meanings to specific exit codes, but these are generally underdeveloped; Unix programs generally use 2 for command line syntax errors and 1 for all other kind of errors.
One example where exit codes are used are in shell scripts. In Bash you can check the special variable $? for the last exit status:
me@mini:~$ python -c ""; echo $? 0 me@mini:~$ python -c "import sys; sys.exit(0)"; echo $? 0 me@mini:~$ python -c "import sys; sys.exit(43)"; echo $? 43
Personally I try to use the exit codes I find in /usr/include/asm-generic/errno.h (on a Linux system), but I don’t know if this is the right thing to do.
How do you implement ‘EXIT_CODES’ in python?
But than I’ve realized that I’ll have to know exactly the total number of EXIT_CODES, so that I can pass it to the range() function. Let’s suppose I’ll have 87 (arbitrary) EXIT_CODES. I don’t want to count to 87 (not that it’s hard) but I am looking for a more elegant solution. Any suggestions ? EDIT: EXIT_CODE is a negative int that will be passed to sys.exit . Instead of writing the number I prefer to use some sort of constants (something like #defines or enums in C, or enums in Java).
Just a note — you don’t need the backslashes in parentheses. It doesn’t really matter, but they’re superfluous, and not really «Pythonic».
5 Answers 5
Sounds like what you want is the Python equivalent of an enumeration in C# or other similar languages. How can I represent an ‘Enum’ in Python? provides several solutions, though they still require the number of items you have. EDIT: How can I represent an ‘Enum’ in Python? looks way better.
Or you could try something like this (probably not the best solution, though):
class _ExitCode: _exit_codes=["EXIT_CODE","EXIT_CODE_TWO"] def __getattr__(self, name): if name in _ExitCode._exit_codes: return -(_ExitCode._exit_codes.index(name)+1) raise AttributeError("Exit code %s not found" % name) ExitCode=_ExitCode() print ExitCode.EXIT_CODE #-1
Maybe I don’t understand the question, but why don’t you simply make a dictionary of exit codes and implement the desired behaviour in a function?
EXIT_CODES = dict(SUCCESS=0, USER_NAME_INVALID=-1, OTHER_ERROR=-2) def exit(code): try: return EXIT_CODES[code] except KeyError: raise KeyError("exit code %s is not implemented" % code)
# some computation goes here return exit("SUCCESS")
And if you want to make «automatic» assignment of numbers (I don’t recommend this) you can simply create a list of exit codes and return the negative of the index:
EXIT_CODES = ['SUCCESS', 'ERROR_1', 'ERROR_2'] return -EXIT_CODES.index('ERROR_1') # will return -1
(for the last one, you can implement a function similar to the dictionary-based one)
The problem is with auto incremenation of the values contained by the dict. I don’t want to write 0, -1, -2, . -87 manually and then realize i have to regroup them.
I must note that it’s not at all certain a negative status makes sense for sys.exit(); at least on Linux, it will be interpreted as an unsigned 8-bit value (range 0-255). As for an enumerated type, it’s possible to do something like:
class ExitStatus: pass for code, name in enumerate("Success Failure CriticalFailure".split()): setattr(ExitStatus, name, code)
Resulting in something like:
The predefined values in normal Unix systems are EXIT_FAILURE=1 and EXIT_SUCCESS=0.
Addendum: Considering the concern about IDE identification of identifiers, one could also do something like:
class EnumItem: pass def adjustEnum(enum): value=0 enumdict=enum.__dict__ for k,v in enumdict.items(): if isinstance(v,int): if v>=value: value=v+1 for k,v in enumdict.items(): if v is EnumItem: enumdict[k]=value value+=1 class ExitStatus: Success=0 Failure=EnumItem CriticalFailure=EnumItem adjustEnum(ExitStatus)
Second edit: Couldn’t keep away. Here’s a variant that assigns the values in the order you’ve written the names.
class EnumItem: serial=0 def __init__(self): self.serial=self.__class__.serial self.__class__.serial+=1 def adjustEnum(enum): enumdict=enum.__dict__ value=0 unknowns=<> for k,v in enumdict.items(): if isinstance(v,int): if v>=value: value=v+1 elif isinstance(v,EnumItem): unknowns[v.serial]=k for i,k in sorted(unknowns.items()): enumdict[k]=value value+=1 return enum @adjustEnum class ExitStatus: Success=0 Failure=EnumItem() CriticalFailure=EnumItem()
Obviously the growing complexity is inelegant, but it does work.
Python Exit Codes
If you have ever worked on a Unix system, you are probably familiar with the concept of an exit code. If you are not, let’s do a quick recap. An exit code refers to a specific exit code returned by a command, script, or program upon execution. A unique code is used to indicate the status of the process after it has completed execution. The status of the process could be successful, failure, or other condition. Therefore, the role of exit codes is to indicate how the process behaved.
With that out of the way, let us explore Python exit codes, how they work, and how you can use them in your programs.
Python Standard Exit Codes
Python has only two standard codes, i.e., a one and a zero. The exit code of 0 means that the process has been executed and exited successfully. This means no error was encountered. On the other hand, an error code of 1 indicates that the process exited with a failure. Let us take a look at a very simple program that just prints the string “Welcome to linuxhint!”.
As you can guess, if we run the program above, it will execute successfully.
We can see that the program does return the desired output. On Unix systems, we can use the echo command followed by the environment variable ?. This environment variable allows you to get the exit code of the last executed command.
In our case, the last command is the Python program:
Notice that the command above returns 0. This shows that our Python program executes successfully.
Have you ever customized your shell, and it returns a red symbol if the previous command fails? Yes, it uses the exit code to do this.
Now let’s take another example:
Notice something wrong with the program above?
In the above example, the code above is missing the closing bracket for the print function. Hence, if we run the program above, it will fail and return an error.
File «/Users/username/exit_codes.py» , line 2
SyntaxError : unexpected EOF while parsing
Here, we can clearly see that the program fails and returns an error.
Let’s now check the exit code.
You guessed it; the command returns an exit code 1. This shows that the previous program failed miserably.
Python Custom Exit Codes – The SYS Module
One of the most useful modules that I encourage fellow Python geeks to learn is the SYS module.
It is a great module that is built-in Python’s standard library but provides exceptional system functionalities.
Enough praises; we can use one of the functions from the SYS module to create custom exit codes in our Python programs.
The function is called exit() and has syntax as the one shown below:
As you can tell, the function has a relatively simple syntax.
It allows you to specify the arg parameter, which is optional. It can be an integer or any supported object.
If the provided argument is an integer zero or None, it is considered a successful execution. For any other value above zero, it indicates abnormal termination.
Although it will depend on the system, the value of the exit code can range from 0 -127.
You can also pass a string which will be displayed when the program exits.
Take the example program below that returns an exit code of 125.
print ( «Welcome to linuxhint» )
In the example program above, we start by importing the exit function from the sys module.
We then use the print statement to print some text on the screen.
For the important part, we use the exit function and pass the exit code as 125.
NOTE: As soon as Python encounters the exit() function, it will immediately terminate the program and return the exit code or message specified.
We can verify this by running the program as:
We can see from the above output that the second print statement does not execute.
Let’s check the exit code as:
We can see that the exit code is 125, as specified in our program.
Consider the example below that prints a string instead of an exit code.
exit ( «Program terminated unexpectedly» )
print ( «Welcome to linuxhint» )
In this case, we are using a string literal as the arg parameter inside the function. Once we run the program:
Program terminated unexpectedly
We can see that the program prints the message before the exit function and the one in the exit function.
Can you guess what the exit code of the program above is? Let’s see:
Yes, it’s one. Any abnormal terminations of the program that do not provide their own custom codes will be assigned an exit code of 1.
NOTE: Use the exit function when you need to terminate your program immediately.
Conclusion
And with that, we have come to the end of our tutorial. In this article, we learned how Python exit codes work and how to create custom exit codes using the sys module.
Happy coding, and as always, Thanks for reading!!
About the author
John Otieno
My name is John and am a fellow geek like you. I am passionate about all things computers from Hardware, Operating systems to Programming. My dream is to share my knowledge with the world and help out fellow geeks. Follow my content by subscribing to LinuxHint mailing list