安全地杀死在 bash 脚本中启动的后台进程
Posted
技术标签:
【中文标题】安全地杀死在 bash 脚本中启动的后台进程【英文标题】:Safely kill background process started in bash script 【发布时间】:2021-08-12 22:30:55 【问题描述】:假设我在 bash 脚本中启动了一个后台进程,在本例中为 http-server
,我想在脚本退出时终止它。我可能会这样做:
# launch http-server in the background
http-server -p8080 &
# capture PID of background process
HTTP_PID=$!
trap "kill $HTTP_PID" EXIT
# ... more stuff
这似乎是捕获后台进程的PID的推荐方式,但是有一个问题:如果进程无法启动或稍后在任何时候失败,PID可能会被另一个进程回收并使用,其中如果我的kill
会杀死系统上的一些随机进程。
我怎样才能安全地仅杀死在此脚本中启动的进程,如果该进程已经死亡则什么都不做?
【问题讨论】:
【参考方案1】:这应该达到你的预期:
trap "pkill --parent $$ http-server" EXIT
杀死一个特定的pid:
function killpid
local ppid=$1 pid=$2 cmd=$3
local v_pid="$(ps -h --ppid $ppid -o pid,cmd | awk -v pid=$pid -v cmd="$cmd" '$1 == pid && $2 == cmd print pid')"
if test -n "$v_pid"; then
echo "Killing $v_pid..."
kill $v_pid
fi
sleep 2 &
echo "Spawning $!"
sleep 2 &
echo "Spawning $!"
trap "killpid $$ $! sleep" EXIT
测试后用http-server
替换sleep
。
【讨论】:
嗯,不错的方法。使用--exact
可能会更安全一些。很遗憾,pkill
没有 --pid
选项,因为这不允许我针对我启动的http-server
的 特定 实例,尽管在这种情况下我只启动一个.
‘ps’同时具有-pid和-ppid,当你真正杀死一个特定的进程id时,你应该能够验证它们以上是关于安全地杀死在 bash 脚本中启动的后台进程的主要内容,如果未能解决你的问题,请参考以下文章