bash 中冷门但非常有用的命令: trap

作者 : 开心源码 本文共2486个字,预计阅读时间需要7分钟 发布时间: 2022-05-13 共154人阅读

trap 属于bash的内置命令,所以查看帮助用: help trap, 假如用”man trap“则会跳出bash的帮助文档;
trap命令的作用是:对捕获到的SIGNAL ,添加新的解决action; 而对于被捕获的SIGNAL原有的解决action不做变更;
A. 支持哪些信号呢? trap -l 可以列出所有支持的signal.

[root@www ~]# trap -l 1) SIGHUP   2) SIGINT   3) SIGQUIT  4) SIGILL   5) SIGTRAP 6) SIGABRT  7) SIGBUS   8) SIGFPE   9) SIGKILL 10) SIGUSR111) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM16) SIGSTKFLT   17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP21) SIGTTIN 22) SIGTTOU 23) SIGURG  24) SIGXCPU 25) SIGXFSZ26) SIGVTALRM   27) SIGPROF 28) SIGWINCH    29) SIGIO   30) SIGPWR31) SIGSYS  34) SIGRTMIN    35) SIGRTMIN+1  36) SIGRTMIN+2  37) SIGRTMIN+338) SIGRTMIN+4  39) SIGRTMIN+5  40) SIGRTMIN+6  41) SIGRTMIN+7  42) SIGRTMIN+843) SIGRTMIN+9  44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+1348) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-1253) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9  56) SIGRTMAX-8  57) SIGRTMAX-758) SIGRTMAX-6  59) SIGRTMAX-5  60) SIGRTMAX-4  61) SIGRTMAX-3  62) SIGRTMAX-263) SIGRTMAX-1  64) SIGRTMAX    [root@www ~]# 

B. 如何使用trap来对特定信号增加额外的action ?
语法格式: trap COMMAND SIGNAL_DEFINATION

看下面的例子:
[root@www ~]# trap 'echo -e "\nCTRL_C PRESSED"' SIGINT[root@www ~]# ^C       #此处是同时按下: CTRL+C 的结果,并不是输入^C CTRL_C PRESSED[root@www ~]# 

上面例子就是捕获CTRL+C, 当CTRL+C 按下的时候会产生SIGINT信号,trap捕获这个SIGINT信号,并执行 ‘echo -e “\nCTRL_C PRESSED”’这个命令,最终输出echo命令执行的结果, 同时对于原有的由CTRL+C引发的SIGINT的解决行为不做变更,上面的例子是:输出了^C, 同时执行了换行操作;

再看如下的一个例子:
[root@www ~]# trap 'echo -e "\nCTRL_C PRESSED"' SIGINT[root@www ~]# sleep 1000^C[root@www ~]# 
在这个例子中,当sleep的时候,按下了CTRL+C, 却没有成功捕获SIGINT 信号,为什么呢?

trap以及sleep运行的时候,各自分别产生了一个child process , 把trap对应的child process 记作A, sleep 对应的child process 记作为B. 而trap只是对其父进程起作用,而对父进程的子进程并不起作用,而B进程(sleep)属于A的父进程的子进程;所以trap命令无法对sleep命令的SIGINT起作用;
而假如把着两条命令放到一个脚本中,则会起作用,由于当运行脚本的时候, 按下ctrl+c触发的SIGINT信号被发送到了bash脚本对应的进程,而trap作为脚本中的一条命令,它本身是脚本的子进程,所以其父进程就是脚本进程;因而trap捕获到了SIGINT信号,此时trap捕获的是 发送给脚本的SIGINT信号,而不是发送给sleep的SIGINT信号;也就是说trap不可能捕获发送给sleep的任何信号;

[root@www ~]# cat test.sh #!/bin/bashtrap "echo CTRL_C Pressed."  SIGINTsleep 100[root@www ~]# bash -x test.sh+ trap 'echo CTRL_C Pressed.' SIGINT+ sleep 100^C++ echo CTRL_C Pressed.CTRL_C Pressed.[root@www ~]# 

C.
从上述详情的trap可以捕获signal的范围来讲,trap的使用基本都是在 bash服务脚本中:

  1. 接受到特定信号的时候,用于kill 进程;比方:
    trap “kill $THIS_PID” SIGTERM , 这样保证当脚本收到SIGTERM信号的时候,可以结束特定的服务进程;
  2. 用于清除运行中的临时文件,比方: 假如客户按下了ctrl+c, 或者者shell脚本收到了sigterm信号等,这时候可能有临时文件没有被移除,可以通过 trap来清除临时文件;
  3. 对于特定的SIGNAL, 可以返回指定的”exit code’, 比方 下面的例子,假如按下ctrl+c, 那么$?的值为5.
#!/bin/bashtrap "exit 5"  SIGINTsleep 100

D.
关于trap命令的扩展:
1)显示特定SIGNAL的trap action:

[root@www ~]# trap -p SIGINT SIGTERMtrap -- 'echo 123' SIGINTtrap -- 'echo 123' SIGTERM[root@www ~]# 

2)取消trap action的设置:

[root@www ~]# trap  SIGINT [root@www ~]# trap  SIGTERM[root@www ~]# trap -p SIGINT SIGTERM[root@www ~]# 

本文原创,转载请著名出处

说明
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是摆设,本站源码仅提供给会员学习使用!
7. 如遇到加密压缩包,请使用360解压,如遇到无法解压的请联系管理员
开心源码网 » bash 中冷门但非常有用的命令: trap

发表回复