我正在努力寻找有关该trap
命令如何工作的清晰、明确的信息。
特别是, local 的效果trap
是否出现在脚本中?我一直认为情况确实如此,但我看到过相反的说法。是否trap
会影响从当前脚本调用的其他 shell 脚本?它会影响二进制程序吗?
答案1
您可以足够快地测试它:
$ cat test.sh
trap : INT HUP USR1
sleep 10h
$ ./test.sh &
[1] 29668
$ grep SigCgt /proc/$(pgrep test.sh)/status
SigCgt: 0000000000010203
$ grep SigCgt /proc/$(pgrep sleep)/status
SigCgt: 0000000000000000
所以trap
不影响二进制文件。
脚本呢?
$ cat blah.sh
#! /bin/bash
grep SigCgt /proc/$$/status
$ cat test.sh
#! /bin/bash
trap : INT HUP USR1
./blah.sh
$ ./test.sh
SigCgt: 0000000000010002
所以有东西被抓住了。可是等等!
$ ./blah.sh
SigCgt: 0000000000010002
看起来这些信号无论如何都会得到处理。
这联机帮助页有这样说:
When a simple command other than a builtin or shell function is to be
executed, it is invoked in a separate execution environment that
consists of the following. Unless otherwise noted, the values are
inherited from the shell.
...
· traps caught by the shell are reset to the values inherited from
the shell's parent, and traps ignored by the shell are ignored
如果您想将该位掩码转换为一组信号,请尝试:
HANDLED_SIGS=$(awk '/SigCgt/{print "0x"$2}' /proc/$PID/status)
for i in {0..31}
do
(( (1 << i) & $HANDLED_SIGS )) && echo $((++i)) $(/bin/kill --list=$i);
done | column
在这种情况下,无需处理的信号集trap
是:
$ HANDLED_SIGS=0x0000000000010002
$ for i in {0..31}; do (( (1 << i) & $HANDLED_SIGS )) && echo $((++i)) $(/bin/kill --list=$i); done | column
2 INT 17 CHLD
答案2
这不是一个答案,但是......
$ cat Trap.sh
#!/bin/bash
echo "Trap.sh is PID $$"
trap -p
grep Sig /proc/$$/status
trap 'echo SIGINT' SIGINT
trap -p
grep Sig /proc/$$/status
trap 'echo SIGTERM' SIGTERM
trap -p
grep Sig /proc/$$/status
trap 'echo SIGUSR1' SIGUSR1
trap -p
grep Sig /proc/$$/status
$ ./Trap.sh
Trap.sh is PID 13887
SigQ: 0/63517
SigPnd: 0000000000000000
SigBlk: 0000000000010000
SigIgn: 0000000000000004
SigCgt: 0000000043817efb
trap -- 'echo SIGINT' SIGINT
SigQ: 0/63517
SigPnd: 0000000000000000
SigBlk: 0000000000010000
SigIgn: 0000000000000004
SigCgt: 0000000043817efb
trap -- 'echo SIGINT' SIGINT
trap -- 'echo SIGTERM' SIGTERM
SigQ: 0/63517
SigPnd: 0000000000000000
SigBlk: 0000000000010000
SigIgn: 0000000000000004
SigCgt: 0000000043817efb
trap -- 'echo SIGINT' SIGINT
trap -- 'echo SIGUSR1' SIGUSR1
trap -- 'echo SIGTERM' SIGTERM
SigQ: 0/63517
SigPnd: 0000000000000000
SigBlk: 0000000000010000
SigIgn: 0000000000000004
SigCgt: 0000000043817efb
我不懂这啥意思。我的猜测是 Bash 捕获所有内容,然后决定在陷阱例程内做什么。