pythonbashexit-codesysreturn-code

How to return status code in Python without actually exiting the process?


I'm trying to return a status code without exiting the process of my script. Is there an equivalent to sys.exit() that does not stop execution ?

What I'd like to happen :

If no exception is raised, status code is by default 0. For minor exceptions, I want to return status code 1, but keep the process running, unless a more critical error exits the process and returns status code 2 with sys.exit(2). In my case, I'm looping through a bunch of PDF files and if one file has not been anonymised for some reason, I want to return status code 1 while looping through the rest of the files.

In other words, status code should correspond to :

For clarity : by status code I mean, what is returned by the Bash command echo $? after the execution of the script.

What I have done : I have tried using sys.exit(1) to handle minor exceptions but it automatically stops execution, as stated in the library documentation.

To sum up with code snippets :

For a given main.py :

import sys
import os

def anonymiser(file) -> Boolean :
    # Returns True if successfully anonymises the file, False otherwise
    ...

def process_pdf_dir():
    for file in os.listdir('pdf_files/'):
        if file.endswith('.pdf'):
            if anonymiser(file) == False:
                '''
                Here goes the code to change status code to 1 
                but keeps looping through the rest of the files
                unlike `sys.exit(1)` that would stop the execution.
                '''
            if criticalError = True:
                sys.exit(2)             

if __name__ == '__main__':
    process_pdf_dir()

After calling the script on the terminal, and echoing its status like so :

$ python main.py
$ echo $?

If indeed, at least one file has not been anonymised :

Hope this is clear enough. Any help would be greatly appreciated. Thanks.


Solution

  • Wait until the end of your loop to return the 1 exit code. I'd do it like:

    def process_pdf_dir() -> int:
        ret = 0
        for file in os.listdir('pdf_files/'):
            if file.endswith('.pdf'):
    
                if not anonymiser(file):
                    # remember to return a warning
                    ret = 1
    
                if criticalError:
                    # immediately return a failure
                    return 2
        return ret
    
    if __name__ == '__main__':
        sys.exit(process_pdf_dir())
    

    If "critical error" includes uncaught exceptions, maybe put that outside of process_pdf_dir, e.g.:

    if __name__ == '__main__':
        try:
            sys.exit(process_pdf_dir())
        except:
            sys.exit(2)