bash shutdown hook; 或者,在主进程被终止时终止所有后台进程

fab*_*ien 10 bash process

我有一个bash运行无尽的命令作为后台进程:

#!/bin/bash

function xyz() {
  # some awk command
}

endlesscommand "param 1" | xyz &  # async
pids=$!
endlesscommand "param 2" | xyz &  # async
pids="$pids "$!
endlesscommand "param 3" | xyz    # sync so the script doesn't leave
Run Code Online (Sandbox Code Playgroud)

停止此脚本的唯一方法是(必须)Ctrl-C或kill,当发生这种情况时,我需要杀死$ pids变量中列出的所有后台进程.

我怎么做?

如果有可能捕获主进程上的kill信号并在发生这种情况时执行一个函数(shutdown hook),我会做类似的事情:

for $pid in $pids; do kill $pid; done;
Run Code Online (Sandbox Code Playgroud)

但是我找不到怎么做......

phs*_*phs 12

这是一个不需要你跟踪的陷阱pids:

trap 'jobs -p | xargs kill' EXIT
Run Code Online (Sandbox Code Playgroud)

编辑:@Barmar询问这是否适用于非源脚本,其中通常不提供作业控制.确实如此.考虑这个脚本:

$ cat no-job-control
#! /bin/bash

set -e -o pipefail

# Prove job control is off
if suspend
then
  echo suspended
else
  echo suspension failed, job control must be off
fi

echo

# Set up the trap
trap 'jobs -p | xargs kill' EXIT

# Make some work
(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
Run Code Online (Sandbox Code Playgroud)

在运行时,我们会看到三个组领导的pids,然后看到他们被杀:

$ ./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' )
Run Code Online (Sandbox Code Playgroud)

如果我们反而注释掉该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
Run Code Online (Sandbox Code Playgroud)

  • 谢谢,即使使用管道也能很好地工作!:) 它甚至可以更短: trap 'jobs -p | xargs 杀死'退出 (2认同)