SIGTERM 不会终止脚本

ser*_*gio 0 sh

我试图理解这个脚本:

#!/usr/bin/env sh

trap "pkill -f sleep" term

sleep 1000
Run Code Online (Sandbox Code Playgroud)

运行脚本后,我想通过发送一个来停止它SIGTERM

# run script in the background
$ ./signals.sh &
[1] 5389

# check if script is running
$ ps aux | grep 'signals.sh\|sleep' | grep -v grep
sergioro  5389  0.0  0.0 216520  3112 pts/0    S    09:07   0:00 sh ./signals.sh
sergioro  5390  0.0  0.0 214984   708 pts/0    S    09:07   0:00 sleep 1000

# send SIGTERM to script
$ pkill -fe signals.sh
sh killed (pid 5389)

# why hasn't the script stopped after receiving SIGTERM?
$ ps aux | grep 'signals.sh\|sleep' | grep -v grep
sergioro  5389  0.0  0.0 216520  3112 pts/0    S    09:07   0:00 sh ./signals.sh
sergioro  5390  0.0  0.0 214984   708 pts/0    S    09:07   0:00 sleep 1000

# send SIGTERM to `sleep` command
$ pkill -fe sleep
sleep killed (pid 5390)
Terminated

# script has stopped
$ ps aux | grep 'signals.sh\|sleep' | grep -v grep

Run Code Online (Sandbox Code Playgroud)

我的问题是如何通过发送SIGTERM到脚本本身而不是sleep命令来停止脚本?为什么trap脚本中的 没有终止 sleep 命令?

Phi*_*ppe 5

shelltrap只能在sleep完成后才能处理。

这可以实现您的预​​期:

#!/usr/bin/env sh

trap "pkill -f sleep" term

sleep 1000 & wait
Run Code Online (Sandbox Code Playgroud)

请参阅手册页的 SIGNALS 部分,尤其是最后一段:

如果 bash 正在等待命令完成并接收到设置了陷阱的信号,则在命令完成之前不会执行陷阱。当 bash 通过 wait 内置函数等待异步命令时,接收到设置了陷阱的信号将导致 wait 内置函数立即返回,退出状态大于 128,然后立即执行陷阱。