UNIX has signals, various signals. When you’re working on shell scripts, you may need to intercept and deal with them. The syntax for intercepting signals is the trap action SIG1 … SIGN, where depending on your shell the SIG1…SIGN may be specified as an integer (bourne shell, i.e. raw sh), or symbolically as HUP, TERM (ksh, bash, zsh). Of course those of you using csh and tcsh should get a real shell 🙂.
The default signal disposition of a process can be determined using the psig command under Solaris. on a typical shell, you can issue a psig $$, and it will tell you if the signal is blocked, if it is handled, if it is ignored, etc. some example output follows:
18489: zsh HUP caught zhandler 0 INT blocked,caught zhandler 0 QUIT blocked,ignored ILL blocked,default TRAP blocked,default ABRT blocked,default EMT blocked,default FPE blocked,default KILL default BUS blocked,default SEGV blocked,default SYS blocked,default PIPE blocked,default ALRM blocked,caught zhandler 0 TERM blocked,ignored USR1 blocked,default USR2 blocked,default CLD caught zhandler 0 PWR blocked,default WINCH blocked,caught zhandler 0 URG blocked,default POLL blocked,default STOP default TSTP blocked,ignored CONT blocked,default TTIN blocked,ignored TTOU blocked,ignored VTALRM blocked,default PROF blocked,default XCPU blocked,default XFSZ blocked,default WAITING blocked,default LWP blocked,default FREEZE blocked,default THAW blocked,default CANCEL blocked,default LOST blocked,default XRES blocked,default JVM1 blocked,default JVM2 blocked,default RTMIN blocked,default RTMIN+1 blocked,default RTMIN+2 blocked,default RTMIN+3 blocked,default RTMAX-3 blocked,default RTMAX-2 blocked,default RTMAX-1 blocked,default RTMAX blocked,default
In solaris we even see the address of the handler, and if the symbolic name of a function can be resolved that is used. This is really handy for debugging purposes (!!!)
When you are running a process in a shell on a terminal, when you exit the shell it will send a HUP signal to any of the processes that it has under it’s control. This is annoying, as if you forget to launch a process under nohup, you’ll normally end up terminating the program when you exit from the parent shell, because you 9/10 times forget this minor fact.
However you can prevent this from happening by using the ‘disown’ command (bash, zsh); which works from within the shell that you’re using. An alternative in Solaris is the nohup -p command – this takes a process ID and providing you can attach to the process (usual security caveats), it blocks the HUP and QUIT signals from being received by the process specified.
But, you can bypass the need for both of these by setting the shell to ignore the signals itselt using trap. When you pass in an empty string as the handler, it causes the shell to ignore that signal if it’s received. so you can gain the equivalent of nohup using the syntax: trap ” HUP QUIT at the start of your script. If you want to stop the signal being ignored then you can use trap – HUP QUIT , which is neat (temporarily ignoring sugnals).
special signals: EXIT (0)
This signal can be hooked to perform cleanup at the end of a shell’s execution. trap cleanup EXIT HUP QUIT is a common entry found at the start of scripts, and there’s a function definition for cleanup somewhere in the process. There is one minor minor gotcha with the EXIT handler within actual ‘function foo’ definitions on posix shells (ksh, bash), it means that the code is invoked at the end of the function. This comes in handy as a ‘finally’ clause in a function, mind you most of the time it’s a mistake that people tend to miss.
trapped in the office, time to go home.