这是一种无需跟踪
pids
的陷阱:
trap 'jobs -p | xargs kill' EXIT
编辑: @Barmar问这个方法是否适用于非源代码脚本,在那里作业控制通常不可用。它是可行的。考虑以下脚本:
$ cat no-job-control
set -e -o pipefail
if suspend
then
echo suspended
else
echo suspension failed, job control must be off
fi
echo
trap 'jobs -p | xargs kill' EXIT
(echo '=> Starting 0'; sleep 5; echo '=> Finishing 0') &
(echo '=> Starting 1'; sleep 5; echo '=> Finishing 1') &
(echo '=> Starting 2'; sleep 5; echo '=> Finishing 2') &
echo "What's in jobs -p?"
echo
jobs -p
echo
echo "Ok, exiting now"
echo
当我们运行时,会看到三个组长的pid,然后看到它们被杀死:
$ ./no-job-control
./no-job-control: line 6: suspend: cannot suspend: no job control
suspension failed, job control must be off
=> Starting 0
What's in jobs -p?
=> Starting 1
54098
54099
54100
Ok, exiting now
=> Starting 2
./no-job-control: line 31: 54098 Terminated: 15 ( echo '=> Starting 0'; sleep 5; echo '=> Finishing 0' )
./no-job-control: line 31: 54099 Terminated: 15 ( echo '=> Starting 1'; sleep 5; echo '=> Finishing 1' )
./no-job-control: line 31: 54100 Terminated: 15 ( echo '=> Starting 2'; sleep 5; echo '=> Finishing 2' )
如果我们将
trap
这一行注释掉并重新运行,三个作业就不会死亡,事实上它们会在几秒钟后打印出它们的最终消息。请注意,返回的提示与最终输出交错。
$ ./no-job-control
./no-job-control: line 6: suspend: cannot suspend: no job control
suspension failed, job control must be off
=> Starting 0
What's in jobs -p?
54110
54111
54112
=> Starting 1
Ok, exiting now
=> Starting 2
$ => Finishing 0
=> Finishing 2
=> Finishing 1
jobs -p
来获取仍在运行的子进程的进程ID。 - chepner