The trap command is used to specify the action to be taken after the signal is received. A common use is to complete the cleanup when the script is interrupted. However, this time I met it because the customer has a requirement: the user who accesses the server from the terminal will automatically run a command after logging on to the server, such as opening the application (the command is written in a file such as. BASHRC, etc.), and finally exiting and disconnecting, while the period is not allowed to exit the application using interrupts such as CTRL + C Return to the shell environment, which may pose a security issue.
Of course, there are many ways to solve this problem, such as shielding the interrupt signal in the application, using the Chroot method access, etc. However, these methods have some limitations, such as the need to modify the application, let telnet and other support chroot mode (SSH can support chroot) and so on. The use of traps is also a better solution.
first, about the signal
Historically, the shell always used numbers to represent the signal, and the new script should use the name of the signal, which was saved in the Signal.h header file included with the # include command, and the sig prefix needed to be omitted when using the signal name.
Both kill and trap can see the signal number and its associated name. "Signal" refers to events that are sent asynchronously to a program. By default, they usually terminate the operation of a program.
# trap-l
1) SIGHUP 2) SIGINT 3) Sigquit 4) Sigill
5) SIGTRAP 6) SIGABRT 7) Sigbus 8) SIGFPE
9) SIGKILL) SIGUSR1 SIGSEGV) SIGUSR2
Sigpipe) sigalrm SIGTERM) SIGCHLD
Sigcont) SIGSTOP SIGTSTP) Sigttin
Sigttou) Sigurg sigxcpu) Sigxfsz
() sigvtalrm) sigprof sigwinch) SIGIO
SIGPWR) Sigsys sigrtmin) sigrtmin+1
sigrtmin+2) sigrtmin+3 (sigrtmin+4) sigrtmin+5
sigrtmin+6) sigrtmin+7 sigrtmin+8) sigrtmin+9
(sigrtmin+10) sigrtmin+11 () sigrtmin+12) sigrtmin+13
SIGRTMIN+14) sigrtmin+15 SIGRTMAX-14) SIGRTMAX-13
SIGRTMAX-12) SIGRTMAX-11 SIGRTMAX-10) SIGRTMAX-9
SIGRTMAX-8) (SIGRTMAX-7) SIGRTMAX-6) SIGRTMAX-5
SIGRTMAX-4) (SIGRTMAX-3) SIGRTMAX-2) SIGRTMAX-1
) Sigrtmax
second, the use of trap
1. Running format
The parameters of the trap command are divided into two parts, the first part is the action to be taken when the specified signal is received, and the latter part is the signal name to be processed.
Trap command Signal
It has three forms corresponding to three different signal response modes.
The first type:
Trap "Commands" signal-list
When the script receives a signal that is listed in the signal-list manifest, the trap command executes the command in double quotation marks.
The second type:
Trap Signal-list
Trap does not specify any command to accept the default action of the signal, the default action is to end the run of the process.
The third type:
Trap "" Signal-list
The trap command specifies an empty command string that allows you to ignore the signal, which is what we use.
※ Remember that scripts are usually interpreted in order from top to bottom, so you must specify the trap command before the part of the code that you want to protect.
2. Testing
According to the user's requirements, we need to block the Hup INT QUIT TSTP several signals. So, you can run:
# trap "" HUP INT QUIT TSTP
At this point, you can try to open a continuous command and then interrupt its operation, for example:
# tail-f/var/log/messages
Then, try Ctrl + C or ctrl+\ to interrupt the trial, the program will not quit.
3. Restore the Signal
If you want to recover, you can use CTRL + Z to put the program in the background, and then run:
# trap:hup INT QUIT TSTP
Then, use PS-EF to see its PID number, BG 1 Let the program continue to run, and finally killed with kill.
4. Other
You can also try running:
# trap "Echo ' Hello World '" HUP INT QUIT TSTP
This way, when you run an interrupt such as CTRL + C, the echo command is automatically run, and the result is the real Hello World string:
Reference
# tail-f/var/log/messages
16:57:54 192.168.228.153 dhcpd:dhcprequest for 192.168.228.221 from 00:1d:72:92:d4:68 via eth0
16:57:54 192.168.228.153 dhcpd:dhcpack on 192.168.228.221 to 00:1d:72:92:d4:68 via eth0
[Email protected] ~]# Hello World
※ Note that this mode does not block interrupts, type CTRL + C and other information, still in the default behavior of the action, that is, quit the program, will only run an additional command.
Third, appendix
1. Interrupt button
Different terminal types, shell versions of the broken keys are different, even customizable, which can be queried by the Stty command:
Reference
# stty-a
Speed 38400 baud; Rows 30; Columns 111; line = 0;
Intr = ^c; Quit = ^\; erase = ^?; Kill = ^u; EOF = ^d; EOL =; Eol2 =; start = ^q; stop = ^s;
Susp = ^z; Rprnt = ^r; Werase = ^w; Lnext = ^v; flush = ^o; min = 1; Time = 0;
-parenb-parodd CS8-HUPCL-CSTOPB cread-clocal-crtscts
-IGNBRK-BRKINT-IGNPAR-PARMRK-INPCK-ISTRIP-INLCR-IGNCR ICRNL Ixon-ixoff-iuclc-ixany-imaxbel
OPOST-OLCUC-OCRNL Onlcr-onocr-onlret-ofill-ofdel nl0 cr0 tab0 bs0 vt0 ff0
Isig Icanon iexten echo echoe echok-echonl-noflsh-xcase-tostop-echoprt echoctl Echoke
^ is the abbreviation for CTRL.
2. Signal details
Reference
Name Default Action description
SIGHUP terminating process terminal line hang-off
SIGINT terminating process Interrupt process
Sigquit establish core file termination process, and generate core file
Sigill Creating a core file illegal directive
SIGTRAP build core file tracking self-trapping
Sigbus establishing a core file bus error
SIGSEGV creating core file Segment Illegal error
SIGFPE creating a core file floating point exception
Sigiot creating a core file to perform I/O self-trapping
SIGKILL Terminate process Kill process
Sigpipe terminating a process writing data to a pipeline that does not have a read process
Sigalarm Terminating process timer to
SIGTERM terminating process software termination signal
SIGSTOP stop signal stop process non-terminal
SIGTSTP stop signal to stop the process terminal
Sigcont ignore signal continue execution of a stopped process
Sigurg ignoring signal I/O emergency signal
SIGIO ignoring the signal descriptor can be I/O
SIGCHLD Ignore signal Notify parent process when child process stops or exits
Sigttou Stop process background process write terminal
Sigttin Stop process background process read Terminal
SIGXGPU terminating process CPU time-out
SIGXFSZ termination process file length too long
Sigwinch ignoring signal window size changes
SIGPROF terminating process statistics distribution graph with timer to time
SIGUSR1 terminating a process user-defined signal 1
SIGUSR2 terminating a process user-defined signal 2
SIGVTALRM terminating process virtual timer to time
1) SIGHUP This signal is issued at the end of the user terminal connection (normal or abnormal), usually at the end of the terminal control process, notify the same session of the various jobs, then they are no longer associated with the control terminal.
2) SIGINT program termination (interrupt) signal, which is emitted when the user types Intr characters (usually ctrl-c)
3) Sigquit and SIGINT are similar, but are controlled by the Quit character (usually ctrl-\). The process generates a core file when it receives a sigquit exit, similar to a program error signal in this sense.
4) Sigill executed an illegal instruction. This is usually due to an error in the executable file itself or an attempt to execute a data segment. This signal can also be generated when a stack overflows.
5) The SIGTRAP is generated by a breakpoint instruction or other trap instruction. Used by debugger.
6) The SIGABRT program itself discovers the error and calls abort when it is generated.
7) Sigiot is generated on PDP-11 by IoT instructions, on other machines and SIGABRT.
8) Sigbus illegal address, including memory address alignment (alignment) error. Eg: accesses an integer with a length of four words, but its address is not a multiple of 4.
9) The SIGFPE is emitted when a fatal arithmetic operation error occurs. This includes not only floating-point arithmetic errors, but also all other arithmetic errors such as overflow and divisor 0.
SIGKILL is used to immediately end the operation of the program. This signal cannot be blocked, processed and ignored.
One) SIGUSR1 leave it to the user
SIGSEGV attempts to access memory that is not allocated to itself, or attempts to write data to a memory address that does not have write permissions.
SIGUSR2 leave it to the user
) Sigpipe Broken Pipe
SIGALRM clock timing signal, which calculates the actual time or clock time. The alarm function uses this signal.
SIGTERM program End (terminate) signal, unlike Sigkill, the signal can be blocked and processed. Usually used to ask the program to exit normally. The shell command kill generates this signal by default.
SIGCHLD the parent process will receive this signal at the end of the child process.
Sigcont let a stop (stopped) process continue execution. This signal cannot be blocked. You can use a handler to get the program to do certain work when the stopped state changes to continue. For example, re-display the prompt.
SIGSTOP the execution of the Stop (stopped) process. Notice the difference between it and terminate and interrupt: The process is not over yet, just pause execution. This signal cannot be blocked, processed or ignored.
SIGTSTP stops the process from running, but the signal can be processed and ignored. This signal is emitted when the user types Susp characters (usually ctrl-z)
Sigttin when a background job reads data from a user terminal, all processes in that job receive a sigttin signal. By default, these processes stop executing.
Sigttou is similar to Sigttin, but is received when writing a terminal (or modifying terminal mode).
Sigurg have emergency data or out-of-band data arrive at the socket.
SIGXCPU exceeds the CPU time resource limit. This limit can be read/changed by Getrlimit/setrlimit.
Sigxfsz exceeds the file size resource limit.
() SIGVTALRM virtual clock signal. is similar to SIGALRM, but calculates the CPU time that is consumed by the process.
Sigprof is similar to SIGALRM/SIGVTALRM, but includes the CPU time used by the process and the time of the system call.
sigwinch) When the window size changes.
) The SIGIO file descriptor is ready to start the input/output operation.
SIGPWR Power Failure
For a good understanding of 2 and 3 semaphores, shield Ctrl + C and ctrl+\. But what exactly does the 1 signal function?
Sighup Signal and control terminal
In UNIX, the process organization is a session that contains a foreground process group and one or more background process groups, and one process group contains multiple processes. A session may have a session first process, and a session header process may have a control terminal. A process group may have a process group first process. The process ID of the process group's first process is equal to the process group ID. Here is possible, under certain circumstances is not. The process that interacts with the terminal is the foreground process, or the background process.
Sighup will be sent to the appropriate process in the following 3 scenarios:
1. When the terminal is closed, the signal is sent to the session first process and the process submitted as the job (i.e. the process submitted with the & symbol)
2. When the session first process exits, the signal is sent to each process in the foreground process group in the session
3. If the parent process exits causing the process to be composed of an orphan process group and a process in the process group is in a stopped state (receiving a sigstop or SIGTSTP signal), the signal is sent to each process in the process group.
The system's default processing of the SIGHUP signal is to terminate the process of receiving the signal. So if the signal is not captured in the program, the process exits when the signal is received.
Here are a few cases where the process exits due to terminal shutdown, where the process exits because the sighup signal is received. The login shell is the session's first process.
First write a test program, the code is as follows:
#include <stdio.h>
#include <signal.h>
Char **args;
void Exithandle (int sig)
... {
printf ("%s:sighup received", args[1]);
}
int main (int argc,char **argv)
... {
args = argv;
Signal (Sighup,exithandle);
Pause ();
return 0;
}
After capturing the SIGHUP signal in the program, a message is printed and pause () pauses the program.
The compiled execution file is sigtest.
1. Command: Sigtest front > Tt.txt
Action: Close the terminal
Results: The content of Tt.txt file is Front:sighup received
Cause: Sigtest is the foreground process, after the terminal closed, according to the 1th case mentioned above, login shell as the session first process, will receive the SIGHUP signal and then exit. According to the 2nd case, Sigtest, as the foreground process, receives a SIGHUP signal from the login shell.
2. Command: Sigtest back > Tt.txt &
Action: Close the terminal
Results: The content of Tt.txt file is Back:sighup received
Reason: Sigtest is the job submitted, according to the 1th case mentioned above, Sigtest will receive sighup signal.
3, Command: Write a shell, the content is [Sigtest &], then execute the shell
Action: Close the terminal
Results: Ps-ef | grep Sigtest will see that the process is still in, the TT file is empty
Cause: When executing the shell, sigtest as the job submission, then the shell exits, causing Sigtest to become an orphan process, no longer the current session of the job, so Sigtest is not the session first process is not a job, will not receive sighup. The orphan process is also a background process, so the login shell will not send sighup to sigtest after exiting because it sends the signal to the foreground process only. 3rd article said that if the process group becomes an orphan process group, if there is a process in the stop state, you will also receive the sighup signal, but sigtest is not in a stopped state, so will not receive sighup signal.
4. Command: Nohup sigtest > TT
Action: Close the terminal
Result: The TT file is empty
Cause: Nohup can prevent the process from receiving the SIGHUP signal
At this point, we know what happens when the terminal is closed and the process exits, in which case it will not exit.
There are several ways that the process does not quit after the terminal is closed, both through the shell:
1, write the shell, the content is as follows
Trap "" SIGHUP #该句的作用是屏蔽SIGHUP信号, trap can block a lot of signals
Sigtest
2, Nohup sigtest can be executed directly at the command line,
If you want to finish this operation and continue with other operations, you can nohup Sigtest &
3, write the shell, the content is as follows
Sigtest &
In fact, any way to turn the process into an orphan process is possible, including the fork stepfather process to exit immediately.
Shell Trap Signal Management