我有以下脚本test.sh
#!/bin/bash
function cleanup() {
echo "calling cleanup"
echo "PIDs associated with $0"
ps aux | grep $0
echo "killing $$ $(jobs -p)"
kill $(jobs -p | xargs)
exit 0
}
function subshell() (
echo "subshell pid $BASHPID"
while true
do
echo "subshell running..."
sleep 5
done
)
function no_subshell() {
echo "no_subshell pid $BASHPID"
while true
do
echo "no_subshell running..."
sleep 10
done
}
# Main
echo "test.sh pid $$"
trap "exit" INT TERM SIGUSR1
trap cleanup EXIT
subshell &
no_subshell &
echo "Waiting..."
jobs -l
wait
我的期望是,如果在父进程上调用 SIGINT,test.sh
则subshell
和no_subshell
函数也应该被清理。然而,在实践中,我观察到的是:
./test.sh
test.sh pid 49199
Waiting...
[1]- 49200 Running subshell &
[2]+ 49201 Running no_subshell &
no_subshell pid 49201
no_subshell running...
subshell pid 49202
subshell running...
^Ccalling cleanup
PIDs associated with ./test.sh
root 49199 0.0 0.0 106144 2896 pts/1 S+ 03:43 0:00 /bin/bash ./test.sh
root 49200 0.0 0.0 106144 232 pts/1 S+ 03:43 0:00 /bin/bash ./test.sh
root 49201 0.0 0.0 106144 2248 pts/1 S+ 03:43 0:00 /bin/bash ./test.sh
root 49202 0.0 0.0 106144 2248 pts/1 S+ 03:43 0:00 /bin/bash ./test.sh
root 49206 0.0 0.0 103488 2184 pts/1 S+ 03:43 0:00 grep ./test.sh
killing 49199 49200
49201
SIGINT 之后,该subshell
函数继续在 PID 49202 下运行,该值未jobs -l
在我的cleanup
函数中列出:
px aux | grep test
root 49202 0.0 0.0 106144 2248 pts/1 S 03:43 0:00 /bin/bash ./test.sh
另外,看起来 subshell 函数是由 PID 49200 跟踪的jobs -p
,由 和 报告(可能已被杀死),但 subshell 函数似乎仍然存在于 PID 49202 中。
如何解释我观察到的这种行为?我如何才能test.sh
清理在后台运行的子 shell 函数?
答案1
仅当进程属于同一进程组 (PPID) 时,kill 命令才会杀死该进程。你的程序PPID似乎是2896,但是subshell和no_subshell PPID是2248。