linux trap命令详解

用途说明

rap是一个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.)

 

使用示例

示例一

[]# trap -p 

[]# trap "echo hello" INT 

[]# trap -p 

trap -- 'echo hello' SIGINT

[]# trap -p INT 

trap -- 'echo hello' SIGINT

[]# trap -p QUIT

[]# Ctrl+C

[]# hello 

 

[]#

 

示例二

[]# 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

[]#

 

示例三 在脚本中使用

下面的脚本用于检查和启动java程序。

第7行:找出正在运行的符合指定特征的进程;

第11行:如果找到了这样的进程,就杀掉;

第22行:以后台方式启动java程序;

第24行:得到刚启动的程序的pid;

第28行:对SIGTERM信号设置处理方式:结束启动的java程序;

第30行:等待后台进程结束。

#!/bin/sh

 

########################################################

#2007.05.06/07

# 增加了杀掉LAST_PID功能

# 增加了脚本退出时杀掉THIS_PID功能

 

LAST_PID=$(ps -ef|grep 'java.*Zhenjiang'|grep -v grep|awk '{print $2}')

 

echo "LAST_PID=$LAST_PID"

 

if [ -n "$LAST_PID" ] &&  [ "$LAST_PID" -gt 0 ]; then

echo "LAST PROCESS NOT EXIT, NOW KILL IT!"

kill $LAST_PID

sleep 1

fi

 

if ! cd ../opt/zhenjiang; then

echo "CHANGE DIRECTORY FAILED"

exit 1

fi

 

java -classpath .:./cpinterfaceapi.jar:./log4j-1.2.14.jar:./hyjc.jar:./smj.client.jar Zhenjiang &

 

THIS_PID=$!

 

echo "THIS_PID=$THIS_PID"

 

trap "kill $THIS_PID" TERM

 

wait

########################################################

扩展

========================================================

在有些情况下,我们不希望自己的shell脚本在运行时刻被中断,比如说我们写得shell脚本设为某一用户的默认shell,使这一用户进入系统后只能作某一项工作,如数据库备份, 我们可不希望用户使用ctrl+C之类便进入到shell状态,做我们不希望做的事情。这便用到了信号处理。 

通常我们需要忽略的信号有四个,即:HUP, INT, QUIT, TSTP,也就是信号1, 2, 3, 24 

使用这样的语句可以使这些中断信号被忽略: 

trap "" 1 2 3 24 或 trap "" HUP INT QUIT TSTP 

用 trap :1 2 3 24 或 trap HUP INT QUIT TSTP使其回复默认值。 

用stty -a可以列出中断信号与键盘的对应,分别执行上面的命令后,运行 

tail -f /etc/passwd, 然后尝试用键盘中断,试试两种情况(默认和忽略)下有何不同。 

########################################################

[]#~/Script/test$ stty -a

speed 38400 baud; rows 17; columns 99; line = 0;

intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>; eol2 = <undef>;

swtch = <undef>; 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 -iutf8

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

########################################################

 

更方便的是我们可以用在shell中用trap定义我们自己的信号处理程序,就象在c中用signal一样, 

 

如:trap “echo 'GO Away'” INT 

eg:

########################################################

[]#~/Script/test$ cat reboot.sh 

#/bin/bash

 

i=0;

while(( 1 ))

do

echo "hello $i"

sleep 1

(( i++ ))

trap "bash $0 && kill $$" QUIT

done

echo haha

[]#~/Script/test$ ./reboot.sh 

hello 0

hello 1

hello 2

hello 3

Quit

hello 0

hello 1

hello 2

Quit

hello 

########################################################

这样^\就可以reboot程序了^_^不知道linux重启是不是trap到某个信号了就这样...

附:

Linux信号简介  

1) SIGHUP 本信号在用户终端连接(正常或非正常)结束时发出, 通常是在终端的控制进程结束时, 通知同一session内的各个作业, 这时它们与控制终端不再关联.   

2) SIGINT 程序终止(interrupt)信号, 在用户键入INTR字符(通常是Ctrl-C)时发出   

3) SIGQUIT 和SIGINT类似, 但由QUIT字符(通常是Ctrl-\)来控制. 进程在因收到SIGQUIT退出时会产生core文件, 在这个意义上类似于一个程序错误信号.   

4) SIGILL 执行了非法指令. 通常是因为可执行文件本身出现错误, 或者试图执行数据段. 堆栈溢出时也有可能产生这个信号.   

5) SIGTRAP 由断点指令或其它trap指令产生. 由debugger使用.   

6) SIGABRT 程序自己发现错误并调用abort时产生.   

7) SIGIOT 在PDP-11上由iot指令产生, 在其它机器上和SIGABRT一样.   

8) SIGBUS 非法地址, 包括内存地址对齐(alignment)出错. eg: 访问一个四个字长的整数, 但其地址不是4的倍数.   

9) SIGFPE 在发生致命的算术运算错误时发出. 不仅包括浮点运算错误, 还包括溢出及除数为0等其它所有的算术的错误.   

10) SIGKILL 用来立即结束程序的运行. 本信号不能被阻塞, 处理和忽略.   

11) SIGUSR1 留给用户使用   

12) SIGSEGV 试图访问未分配给自己的内存, 或试图往没有写权限的内存地址写数据.   

13) SIGUSR2 留给用户使用   

14) SIGPIPE Broken pipe   

15) SIGALRM 时钟定时信号, 计算的是实际的时间或时钟时间. alarm函数使用该信号.   

16) SIGTERM 程序结束(terminate)信号, 与SIGKILL不同的是该信号可以被阻塞和处理. 通常用来要求程序自己正常退出. shell命令kill缺省产生这个信号.   

17) SIGCHLD 子进程结束时, 父进程会收到这个信号.   

18) SIGCONT 让一个停止(stopped)的进程继续执行. 本信号不能被阻塞. 可以用一个handler来让程序在由stopped状态变为继续执行时完成特定的工作. 例如, 重新显示提示符   

19) SIGSTOP 停止(stopped)进程的执行. 注意它和terminate以及interrupt的区别: 该进程还未结束, 只是暂停执行. 本信号不能被阻塞, 处理或忽略.   

20) SIGTSTP 停止进程的运行, 但该信号可以被处理和忽略. 用户键入SUSP字符时(通常是Ctrl-Z)发出这个信号   

21) SIGTTIN 当后台作业要从用户终端读数据时, 该作业中的所有进程会收到SIGTTIN信号. 缺省时这些进程会停止执行.   

22) SIGTTOU 类似于SIGTTIN, 但在写终端(或修改终端模式)时收到.   

23) SIGURG 有紧急数据或out-of-band数据到达socket时产生.   

24) SIGXCPU 超过CPU时间资源限制. 这个限制可以由getrlimit/setrlimit来读取/改变   

25) SIGXFSZ 超过文件大小资源限制.   

26) SIGVTALRM 虚拟时钟信号. 类似于SIGALRM, 但是计算的是该进程占用的CPU时间.   

27) SIGPROF 类似于SIGALRM/SIGVTALRM, 但包括该进程用的CPU时间以及系统调用的时间.   

28) SIGWINCH 窗口大小改变时发出.   

29) SIGIO 文件描述符准备就绪, 可以开始进行输入/输出操作.   

30) SIGPWR Power failure

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值