我正在努力寻找有关trap
命令如何工作的清晰、明确的信息。
特别是,trap
本地的效果是在脚本出现的地方吗?我一直认为是这种情况,但我看到了相反的陈述。是否trap
影响从当前调用的其他 shell 脚本?它会影响二进制程序吗?
您可以足够快地测试它:
\n\n$ cat test.sh\ntrap : INT HUP USR1\nsleep 10h\n$ ./test.sh &\n[1] 29668\n$ grep SigCgt /proc/$(pgrep test.sh)/status\nSigCgt: 0000000000010203\n$ grep SigCgt /proc/$(pgrep sleep)/status\nSigCgt: 0000000000000000\n
Run Code Online (Sandbox Code Playgroud)\n\n所以trap
不会影响二进制文件。
脚本呢?
\n\n$ cat blah.sh \n#! /bin/bash \ngrep SigCgt /proc/$$/status\n$ cat test.sh \n#! /bin/bash\ntrap : INT HUP USR1\n./blah.sh\n$ ./test.sh \nSigCgt: 0000000000010002\n
Run Code Online (Sandbox Code Playgroud)\n\n所以有东西被抓住了。可是等等!
\n\n$ ./blah.sh \nSigCgt: 0000000000010002\n
Run Code Online (Sandbox Code Playgroud)\n\n看起来这些信号无论如何都会得到处理。
\n\n联机帮助页中有这样的内容:
\n\n When a simple command other than a builtin or shell function is to be\n executed, it is invoked in a separate execution environment that\n consists of the following. Unless otherwise noted, the values are\n inherited from the shell.\n ...\n \xc2\xb7 traps caught by the shell are reset to the values inherited from\n the shell\'s parent, and traps ignored by the shell are ignored\n
Run Code Online (Sandbox Code Playgroud)\n\n如果您想将该位掩码转换为一组信号,请尝试:
\n\nHANDLED_SIGS=$(awk \'/SigCgt/{print "0x"$2}\' /proc/$PID/status)\nfor i in {0..31} \ndo \n (( (1 << i) & $HANDLED_SIGS )) && echo $((++i)) $(/bin/kill --list=$i); \ndone | column\n
Run Code Online (Sandbox Code Playgroud)\n\n在这种情况下,无需处理的信号集trap
是:
$ HANDLED_SIGS=0x0000000000010002\n$ for i in {0..31}; do (( (1 << i) & $HANDLED_SIGS )) && echo $((++i)) $(/bin/kill --list=$i); done | column\n2 INT 17 CHLD\n
Run Code Online (Sandbox Code Playgroud)\n