专栏首页MyPanda的学习笔记bash 中冷门但非常有用的命令: trap

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

trap 属于bash的内置命令,所以查看帮助用: help trap, 如果用”man trap“则会跳出bash的帮助文档; trap命令的作用是:对捕获到的SIGNAL ,改变原有的处理action为新的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) 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@www ~]# 

B. 如何使用trap来更改原来SIGNAL对应的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命令执行的结果, 但是我们同时看到有"^C" 这个符号的输出又是怎么回事呢? 这个属于 对键盘输入中断 的处理结果;如果纯粹的发送 SIGINT 信号,将看不到"^C"这个符号:

[root@www ~]# bash
[root@www ~]# trap 'echo -e "\nCTRL-C Pressed." ' SIGINT
[root@www ~]# ^C            #按下ctrl+c的回显;
CTRL-C Pressed.

[root@www ~]# kill -s SIGINT $$        #直接发送SIGINT信号

CTRL-C Pressed.

[root@www ~]# 
再看如下的一个例子:
[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/bash
trap "echo CTRL_C Pressed."  SIGINT
sleep 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/bash
trap "exit 5"  SIGINT
sleep 100

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

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

2)取消trap action的设置:

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

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

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 编译、链接到载入、运行的大致过程 ----1. 编译

    对于需要编译的编程语言(c, c++, java, c# ...高级语言),源码写完后,是无法直接运行的;需要有 编译,链接的过程才能生成最终可以执行的二进制文...

    qsjs
  • Linux中find命令的点滴积累

    find 命令在Linux中的作用非常强大,对于初学者来说,可能有很多的参数并不能很熟练的使用,导致无法充分发挥find的强大作用;本文对部分参数做初步的探索:

    qsjs
  • sed的pattern space与hold space应用举例

    对于常常使用的sed命令,我们需要知道如下的内容,才能更好的使用它: A. 模式空间: sed 在处理每一行的时候,首先会把要处理的行存入到模式空间里面;然...

    qsjs
  • 盘点Linux常用运维工具(四)-版本控制篇之SVN

    #实验环境 一台:svn+http服务器 一台:client server客户端服务器

    老油条IT记
  • Sass/SCSS 和纯 CSS 写法的差别

    小胖
  • cron 的配置和说明

    作者:北南南北 来自:LinuxSir.Org 摘要:Linux操作系统中,计划任务通常由cron来承担,了解或掌握cron,能为我们管理服务器带来更多的便利,...

    一见
  • Spring和RabbitMQ消息队列(AMQP)整合详解

    消息中间件利用高效可靠的消息传递机制进行平台无关的数据交流,并基于数据通信来进行分布式系统的集成。通过提供消息传递和消息排队模型,它可以在分布式环境下扩展进程间...

    品茗IT
  • Linux常用工作命令

    心跳包
  • JAVA中的数组

    1 动态初始化 方法:数据类型[] 数组名 = new 数据类型[数组长度] 例如:

    roobtyan
  • LeetCode 222. Count Complete Tree Nodes(二分+位运算)

    题解:DFS 或者BFS都太low,我们可以用O(log(n)^2)的效率解决,n为节点个数,log(n)就是树的高度。

    ShenduCC

扫码关注云+社区

领取腾讯云代金券