我使用過的Linux命令之trap - 在指令碼中處理訊號

hai0808發表於2017-11-26

用途說明

trap是一個shell內建命令,它用來在指令碼中指定訊號如何處理。比如,按Ctrl+C會使指令碼終止執行,實際上系統傳送了SIGINT訊號給指令碼程式,SIGINT訊號的預設處理方式就是退出程式。如果要在Ctrl+C不退出程式,那麼就得使用trap命令來指定一下SIGINT的處理方式了。trap命令不僅僅處理Linux訊號,還能對指令碼退出(EXIT)、除錯(DEBUG)、錯誤(ERR)、返回(RETURN)等情況指定處理方式。

常用引數

       trap [-lp] [[arg] sigspec ...]

 

格式:trap "commands" signals

當shell接收到signals指定的訊號時,執行commands命令。(The  command arg is to be read and executed when the shell receives signal(s) sigspec. )

 

格式:trap signals

如果沒有指定命令部分,那麼就將訊號處理復原。比如 trap INT 就表明恢復Ctrl+C退出。(If arg is absent (and there is a single sigspec) or -, each specified signal is reset to its  original  disposition  (the value  it  had  upon  entrance  to  the  shell). )

 

格式:trap "" signals

忽略訊號signals,可以多個,比如 trap "" INT 表明忽略SIGINT訊號,按Ctrl+C也不能使指令碼退出。又如 trap "" HUP 表明忽略SIGHUP訊號,即網路斷開時也不能使指令碼退出。(If arg is the null string the signal specified by each sigspec is ignored by the shell and by the commands it invokes. )

 

格式:trap -p

格式:trap -p signal

把當前的trap設定列印出來。(If arg is not present and -p  has  been supplied,  then  the trap commands associated with each sigspec are displayed.  If no arguments are supplied or if only -p is given, trap prints the list of commands associated  with  each  signal.)

 

格式:trap -l

把所有訊號列印出來。(The  -l option  causes  the shell to print a list of signal names and their corresponding numbers.  Each sigspec is either a signal name defined in <signal.h>, or a signal number.  Signal names  are  case  insensitive and  the  SIG prefix is optional.) 

 

格式:trap "commands" EXIT

指令碼退出時執行commands指定的命令。(If a sigspec is EXIT (0) the command arg is executed on exit from the shell.)

 

格式:trap "commands" DEBUG

在指令碼執行時列印除錯資訊,比如列印將要執行的命令及引數列表。(If a sigspec is DEBUG, the command arg is executed before every  simple  command,  for  command, case  command,  select command, every arithmetic for command, and before the first command executes in a shell function (see SHELL GRAMMAR above).  Refer to the description of the extdebug option to the  shopt builtin  for  details of its effect on the DEBUG trap.)

 

格式:trap "commands" ERR

當命令出錯,退出碼非0,執行commands指定的命令。(If a sigspec is ERR, the command arg is executed whenever a simple command has a non-zero exit status, subject to the following conditions.  The ERR trap is not executed if the failed command is part of the command list immediately following a while or until keyword, part of the test in an if statement, part of a && or ┅Ι│ list, or if the command’s return  value is  being  inverted via !.  These are the same conditions obeyed by the errexit option.)

 

格式:trap "commands" RETURN

當從shell函式返回、或者使用source命令執行另一個指令碼檔案時,執行commands指定的命令。(If a sigspec is RETURN, the command arg is executed each time a shell function or a script executed with the . or source    builtins  finishes  executing.   Signals  ignored  upon  entry  to the shell cannot be trapped or reset. Trapped signals that are not being ignored are reset to their original values in a child process when it is created.  The return status is false if any sigspec is invalid; otherwise trap returns true.)

 

使用示例

示例一

[root@new55 ~]# trap -p 
[root@new55 ~]# trap "echo hello" INT 
[root@new55 ~]# trap -p 
trap -- 'echo hello' SIGINT
[root@new55 ~]# trap -p INT 
trap -- 'echo hello' SIGINT
[root@new55 ~]# trap -p QUIT

[root@new55 ~]# Ctrl+C

[root@new55 ~]# hello 

[root@new55 ~]#

 

示例二

[root@new55 ~]# trap -l 
 1) SIGHUP       2) SIGINT       3) SIGQUIT      4) SIGILL
 5) SIGTRAP      6) SIGABRT      7) SIGBUS       8) SIGFPE
 9) SIGKILL     10) SIGUSR1     11) SIGSEGV     12) SIGUSR2
13) SIGPIPE     14) SIGALRM     15) SIGTERM     16) SIGSTKFLT
17) SIGCHLD     18) SIGCONT     19) SIGSTOP     20) SIGTSTP
21) SIGTTIN     22) SIGTTOU     23) SIGURG      24) SIGXCPU
25) SIGXFSZ     26) SIGVTALRM   27) SIGPROF     28) SIGWINCH
29) SIGIO       30) SIGPWR      31) SIGSYS      34) SIGRTMIN
35) SIGRTMIN+1  36) SIGRTMIN+2  37) SIGRTMIN+3  38) SIGRTMIN+4
39) SIGRTMIN+5  40) SIGRTMIN+6  41) SIGRTMIN+7  42) SIGRTMIN+8
43) SIGRTMIN+9  44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12
47) SIGRTMIN+13 48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14
51) SIGRTMAX-13 52) SIGRTMAX-12 53) SIGRTMAX-11 54) SIGRTMAX-10
55) SIGRTMAX-9  56) SIGRTMAX-8  57) SIGRTMAX-7  58) SIGRTMAX-6
59) SIGRTMAX-5  60) SIGRTMAX-4  61) SIGRTMAX-3  62) SIGRTMAX-2
63) SIGRTMAX-1  64) SIGRTMAX
[root@new55 ~]#

 

示例三 在指令碼中使用

下面的指令碼用於檢查和啟動java程式。

第7行:找出正在執行的符合指定特徵的程式;

第11行:如果找到了這樣的程式,就殺掉;

第22行:以後臺方式啟動java程式;

第24行:得到剛啟動的程式的pid;

第28行:對SIGTERM訊號設定處理方式:結束啟動的java程式;

第30行:等待後臺程式結束。

 

Bash程式碼  收藏程式碼
  1. #!/bin/sh  
  2.   
  3. #2007.05.06/07  
  4. # 增加了殺掉LAST_PID功能  
  5. # 增加了指令碼退出時殺掉THIS_PID功能  
  6.   
  7. LAST_PID=$(ps -ef|grep 'java.*Zhenjiang'|grep -v grep|awk '{print $2}')  
  8.   
  9. echo "LAST_PID=$LAST_PID"  
  10.   
  11. if [ -n "$LAST_PID" ] &&  [ "$LAST_PID" -gt 0 ]; then  
  12.     echo "LAST PROCESS NOT EXIT, NOW KILL IT!"  
  13.     kill $LAST_PID  
  14.     sleep 1  
  15. fi  
  16.   
  17. if ! cd ../opt/zhenjiang; then  
  18.     echo "CHANGE DIRECTORY FAILED"  
  19.     exit 1  
  20. fi  
  21.   
  22. java -classpath .:./cpinterfaceapi.jar:./log4j-1.2.14.jar:./hyjc.jar:./smj.client.jar Zhenjiang &  
  23.   
  24. THIS_PID=$!  
  25.   
  26. echo "THIS_PID=$THIS_PID"  
  27.   
  28. trap "kill $THIS_PID" TERM  
  29.   
  30. wait  

相關文章