Wednesday, November 25, 2009

The trap Command








 

 










The trap Command



When you press the Delete[2] or Break key at your terminal during execution of a shell program, normally that program is immediately terminated, and your command prompt returned. This may not always be desirable. For instance, you may end up leaving a bunch of temporary files that won't get cleaned up.



[2] Some Unix systems use Ctrl+c rather than the Delete key for this purpose. You can determine which key sequence is used with the stty command.



The pressing of the Delete key at the terminal sends what's known as a signal to the executing program. The program can specify the action that should be taken on receipt of the signal. This is done with the trap command, whose general format is





trap commands signals



where commands is one or more commands that will be executed whenever any of the signals specified by signals is received.



Numbers are assigned to the different types of signals, and the more commonly used ones are summarized in Table 13.1. A more complete list is given under the trap command in Appendix A, "Shell Summary."





















































Table 13.1. Commonly Used Signal Numbers


Signal





Generated for





0





Exit from the shell





1





Hangup





2





Interrupt (for example, Delete, Ctrl+c key)





15





Software termination signal (sent by kill by default)





As an example of the trap command, the following shows how you can remove some files and then exit if someone tries to abort the program from the terminal:





trap "rm $WORKDIR/work1$$ $WORKDIR/dataout$$; exit" 2



From the point in the shell program that this trap is executed, the two files work1$$ and dataout$$ will be automatically removed if signal number 2 is received by the program. So if the user interrupts execution of the program after this trap is executed, you can be assured that these two files will be cleaned up. The exit that follows the rm is necessary because without it execution would continue in the program at the point that it left off when the signal was received.



Signal number 1 is generated for hangup: Either someone intentionally hangs up the line or the line gets accidentally disconnected. You can modify the preceding trap to also remove the two specified files in this case by adding signal number 1 to the list of signals:





trap "rm $WORKDIR/work1$$ $WORKDIR/dataout$$; exit" 1 2



Now these files will be removed if the line gets hung up or if the Delete key gets pressed.



The commands specified to trap must be enclosed in quotes if they contain more than one command. Also note that the shell scans the command line at the time that the trap command gets executed and also again when one of the listed signals is received. So in the preceding example, the value of WORKDIR and $$ will be substituted at the time that the trap command is executed. If you wanted this substitution to occur at the time that either signal 1 or 2 was received (for example, WORKDIR may not have been defined yet), you can put the commands inside single quotes:





trap 'rm $WORKDIR/work1$$ $WORKDIR/dataout$$; exit' 1 2



The trap command can be used to make your programs more user friendly. In the next chapter, when we revisit the rolo program, the signal generated by the Delete key is caught by the program and brings the user back to the main menu. In this way, this key can be used to abort the current operation without exiting from the program.



trap with No Arguments



Executing trap with no arguments results in the display of any traps that you have changed.





$ trap 'echo logged off at $(date) >>$HOME/logoffs' 0

$ trap List changed traps

trap � 'echo logged off at $(date) >>$HOME/logoffs' EXIT

$ Ctrl+d Log off

login: steve Log back in

Password:

$ cat $HOME/logoffs See what happened

logged off at Wed Oct 2 15:11:58 EDT 2002

$



A trap was set to be executed whenever signal 0 was received by the shell. This signal is generated whenever the shell is exited. Because this was set in the login shell, the trap will be taken when you log off. The purpose of this trap is to write the time you logged off into the file $HOME/logoffs. The command is enclosed in single quotes to prevent the shell from executing date when the trap is defined.



The trap command is then executed with no arguments, which results in the display of the changed action to be taken for signal 0 (EXIT). Next, steve logs off and then back on again to see whether the trap works. Displaying the contents of $HOME/logoffs verifies that the echo command was executed when steve logged off.



Ignoring Signals



If the command listed for trap is null, the specified signal will be ignored when received. For example, the command





trap "" 2



specifies that the interrupt signal is to be ignored. You might want to ignore certain signals when performing some operation that you don't want interrupted.



Note that the first argument must be specified for a signal to be ignored and is not equivalent to writing the following, which has a separate meaning of its own:





trap 2



If you ignore a signal, all subshells also ignore that signal. However, if you specify an action to be taken on receipt of a signal, all subshells will still take the default action on receipt of that signal. For the signals we've described, this means that the subshells will be terminated.



Suppose that you execute the command





trap "" 2



and then execute a subshell, which in turn executes other shell programs as subshells. If an interrupt signal is then generated, it will have no effect on the shells or subshells that are executing because they will all ignore the signal.



If instead of executing the previous trap command you execute





trap : 2



and then execute your subshells, then on receiving the interrupt signal the current shell will do nothing (it will execute the null command), but all active subshells will be terminated (they will take the default action�termination).



Resetting Traps



After you've changed the default action to be taken on receipt of a signal, you can change it back again with trap if you simply omit the first argument; so





trap 1 2



resets the action to be taken on receipt of signals 1 or 2 back to the default.












     

     


    No comments: