Search code examples
bashexecutionfinally

Bash: Finally (Try, Except) Exception


I want to execute some commands on the end of the bash script, even if the user press CTRL+C to cancel its execution.

I know I can run the bash script from inside another programming language (for example, Python), so that I can use the 'finally' (try-finally) block to execute some code.

But knowing that StackOverflow is a center for exchanging fabulous ideas, I'm asking if is there a way to do what I want from inside my bash script.

So, ideas?

EDIT:

What I want is kill every proccess opened within my bash, i.e., selenium and Xvfb proccesses.

I tried writing this to the code:

 trap "selenium_pids=$(ps ux | awk '/selenium/ && !/awk/ {print $2}');for pid in $selenium_pids; do kill -9 $pid;done; xvfb_pids=$(ps ux | awk '/Xvfb/ && !/awk/ {print $2}'); for pid in $xvfb_pids; do kill -9 $pid; done" EXIT

But this oblige me to press "CTRL+C" many times, on each run of subprocess from inside my script, something like:

Testing nsi.bd.helpcenter ...^C:  --  Total time: 0min 0seg
Testing nsi.bibliography ...^C:  --  Total time: 0min 0seg
Testing nsi.digitallibrary ...^C:  --  Total time: 0min 0seg
Testing nsi.digitallibraryinstaller ...^C:  --  Total time: 0min 1seg
Testing nsi.digitallibraryskins ...^C:  --  Total time: 0min 0seg
....#continues

Changing the final of the trap line from EXIT to SIGINT , like this:

trap "selenium_pids=$(ps ux | awk '/selenium/ && !/awk/ {print $2}');for pid in $selenium_pids; do kill -9 $pid;done; xvfb_pids=$(ps ux | awk '/Xvfb/ && !/awk/ {print $2}'); for pid in $xvfb_pids; do kill -9 $pid; done" SIGINT

Makes the same thing.

What now to exit on the first CTRL+C?

Because I tried to add a "exit 1" to the final of the string , like trap "... ;exit 1"

It worked to exit on the first CTRL+C, but didn't killed the processes I wanted.

Ideas?


Solution

  • Got what I wanted with this code:

    finalize_xvfb_and_selenium() {
        selenium_pids=$(ps ux | awk '/selenium/ && !/awk/ {print $2}')
        for pid in $selenium_pids; do 
            kill -9 $pid
        done 
        xvfb_pids=$(ps ux | awk '/Xvfb/ && !/awk/ {print $2}') 
        for pid in $xvfb_pids; do 
            kill -9 $pid
        done
    }
    
    finalize_xvfb_and_selenium_and_exit() {
        finalize_xvfb_and_selenium
        echo -e "\n\nXvfb and seleniumrc finalized. Exiting ..."
        exit 13
    }
    
    #trap (CTRL+C) signal, to finalize proccess running before exit
    trap finalize_xvfb_and_selenium_and_exit SIGINT
    

    I'm aware that there are better resources than using kill -9 everywhere.