Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bash signal capture not detecting variables changed after declaration of 'trap' block

I have a bunch of generic cleanup code that needs to be done whenever a certain bash script exits, whether it exited normally or was interrupted. I figured I'd use the trap "..." EXIT pseudosignal to achieve this.

In addition to the generic cleanup stuff, there's also one piece of specific cleanup that should only be done if the script completes normally. I thought I could trigger this by having the 'trap' block test a variable, like so:

#!/bin/bash
done=false;
trap "{        
           #generic cleanup code goes here.
           if $done
           then
               #cleanup to be done only on completion goes here.
               echo Test;
           fi
       }" EXIT
#main script goes here
done=true;

However, this doesn't work. Running the following code will never echo "Test". Adding an explicit exit call after done=true; doesn't change anything. What am I missing?

Cheers!

like image 576
Zac B Avatar asked Feb 10 '12 15:02

Zac B


People also ask

How do I trap a signal in a shell script?

To trap a signal any time during the execution of a shell script, define a trap statement at the start of the script. Alternatively, to trap a signal only when certain command lines are to be executed, you can turn on the trap statement before the appropriate command lines and turn off the trap statement after the command lines have been executed.

What is trap command in Bash?

A built-in bash command that is used to execute a command when the shell receives any signal is called `trap`. When any event occurs then bash sends the notification by any signal. Many signals are available in bash. The most common signal of bash is SIGINT (Signal Interrupt).

How do I trap a SIGTERM signal in Linux?

Set `trap` command for SIGTERM in a script SIGTERM signal is used to terminate the process immediately by releasing its resources. Create a bash file named ‘ trapscript.sh ’ with the following code. An infinite for loop is declared in the script that will print a text continuously until SIGTERM signal occurs.

What happens if you don't use a trap statement in shell script?

Without a trap statement the shell prints an error message and exits the script. You can avoid this problem by using a trap statement, which is shown in the next section.


1 Answers

The trap is being interpolated, and is using the value of $done at the time the trap is being defined rather than when it is executed. You can use single quotes around the trap definition, or define a function. Defining a function is probably cleaner:

#!/bin/sh
done=false
cleanup() { if test "$done" = true; then echo Test; fi; }
trap cleanup EXIT
done=true

This works because the expansion of variables in the function is deferred until the function is called, rather than when the function is defined.

like image 77
William Pursell Avatar answered Sep 24 '22 21:09

William Pursell