Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Proper way to use a trap to exit a shell-script in ZSH?

I'm having trouble getting a trap function in a Zshell-script to work without exiting the shell. I have a simple countdown timer that I want to be able to interrupt using ^C, and when I do I want the trap to change the cursor status in the terminal.

My syntax is:

#!/bin/zsh

trap 'tput cnorm; exit' INT TERM

I've also tried:

trap 'tput cnorm; kill -9 $$' INT TERM

Both interrupts exit the shell entirely. How do I only exit the script and return to the command line?

Any guidance will be most appreciated!

like image 602
Le_Prometheen Avatar asked Jan 25 '20 17:01

Le_Prometheen


1 Answers

Handling Signals With Trap

TRAPINT() {
    echo "TRAPINT() called: ^C was pressed"
}

TRAPQUIT() {
    echo "TRAPQUIT() called: ^\\ was pressed"
}

TRAPTERM() {
    echo "TRAPTERM() called: a 'kill' command was aimed at this program's process ID"
}

TRAPEXIT() {
    echo "TRAPEXIT() called: happens at the end of the script no matter what"
}

for i in {1..9}; do
    echo ${i}
    sleep 1
done

For all of these TRAP[NAL]() functions, if the final command is return 0 (or if there is no return statement at all, then code execution will continue where the program left off, as if the signal was accepted, caught, and handled. If the return status of this function is non-zero, then the return status of the trap is retained, and the command execution that was previously taking place will be interrupted. You can do return $((128+$1)) to return the same status as if the signal had not been trapped

As to why your shell is getting killed, it's because calling kill -9 $$ will send the the signal 9 to the process ID associated with your shell. Signal #9, or SIGKILL is the one signal that can't be handled with traps. It's sort of a "kill of last resort" if a program truly needs to stop immediately, with no cleanup permitted.

like image 142
chahu418 Avatar answered Nov 15 '22 07:11

chahu418