shell : trap 捕捉信号

linux shell脚本中处理信号的方法

  • trap是一个shell内建命令,它用来在脚本中指定信号如何处理。

常用参数
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 commands signals

现在通过一个例子,展示了如何用trap命令来忽略SIGINT信号,并控制脚本的行为:

#!/bin/bash

#测试信号捕获

trap "echo ' Sorry! I have trapped Ctrl-C'" SIGINT

echo "This is a test script"

count=1
while [ $count -le 10 ]
do 
   echo "Loop #$count"
   sleep 1
   count=$[ $count + 1 ]
done

echo "This is the end of the test script"

结果
在这里插入图片描述

上面的例子中用到了trap命令会在每次检测到SIGINT信号时显示一行简单的文本信息。捕获这些信号会阻止用户用bash shell组合键Ctrl + C来停止程序。每次按下Ctrl + c组合键,脚本都会执行trap命令中指定的echo语句,而不是处理该信号并允许shell停止该脚本。

捕获脚本退出
除了在shell脚本中捕获信号,可以在shell脚本退出时进行捕获。要想捕获shell脚本的退出。只要在trap命令后加上EXIT信号就行。

#!/bin/bash

#捕获脚本退出信号

trap "echo \"Goodbye"\" EXIT

count=1
while [ $count -le 5 ]
do
    echo "Loop #$count"
    sleep 1
    count=$[ $count +1 ]
done

在这里插入图片描述
当脚本运行时,正常退出位置时,会捕获就被触发了,shell会执行在trap命令行指定的命令。如果提前退出脚本,同样能够捕获到EXIT

移出捕获
要想在脚本中不同的位置进行不同的捕获处理,只需要重新使用带有新选项的trap命令

trap -- SIGINT   #终止脚本运行

可以在删除已设置好的捕获。只需要在trap命令与希望默认行为的信号列表之间加上两个破折号就行了。例如:

#!/bin/bash

#Modifying a set trap

trap "echo ' Sorry... Ctrl-C is trapped.'" SIGINT

count=1
while [ $count -le 5 ]
do
   echo "Loop #$count"
   sleep 1
   count=$[ $count + 1 ]
done

trap -- SIGINT
echo "I just removed the trap"
count=1
while [ $count -le 5 ]
do
   echo "Second Loop #$count"
   sleep 1
   count=$[ $count + 1 ]
done


在这里插入图片描述
在移除信号捕获后,脚本按照默认的行为来处理SIGINT信号,也就是终止脚本的运行。但如果信号是在捕获移除前接收到的,那么脚本会按照原先的trap命令中设置进行处理。
在这里插入图片描述
因为信号在捕获被移除前已经接收到了,脚本会按照旧的执行trap中指定的命令。捕获随后被移除,再按下Ctrl +c 就能够提前终止脚本。

总结

Linux 系统运行利用信号来控制shell脚本。当bash shell接受信号,并将它们传递给运行在改=该shell进程中的所有进程。可以在脚本中用trap语句来捕获信号并执行特定命令。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_kerneler

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值