在 shell 脚本中杀死后台进程

Posted

技术标签:

【中文标题】在 shell 脚本中杀死后台进程【英文标题】:killing the background process in a shell script 【发布时间】:2012-09-30 16:52:48 【问题描述】:

我有一个启动后台进程的脚本。

#!/bin/sh

./process1.sh &
./process2.sh &

我需要使用单独的脚本来终止这些进程。 这是我所做的:

#!/bin/sh
# the kill.sh

pid=$(ps | grep './process1.sh' |grep -v grep| awk 'print $1')
kill -9 $pid

提问时间:

    当调用 kill.sh 时,进程会停止。但我得到了消息

    “sh:你需要指定要杀死的人”。 这是为什么呢?

    在我使用所描述的脚本终止进程后,它不会立即停止。有一段时间我看到屏幕上的输出,好像进程仍在运行一样。为什么?

    终止进程的替代解决方案是什么?

值得一提的是,我正在使用busybox,我的实用程序选择有限。

【问题讨论】:

当然,这取决于您编写这些脚本的方式,但您应该允许它们捕获信号(在执行终止时)并执行所需的操作以进行清理 - 或优雅地关闭。另外,只需在后台启动进程时将PID记录为/tmp目录中的临时文件,无需乱用ps命令。 【参考方案1】:

您可以将进程 ID 存储在一个临时文件中,如下所示:

#!/bin/sh

./process1.sh &
echo $! > /tmp/process1.pid
./process2.sh &
echo $! > /tmp/process2.pid

然后使用您的脚本将其删除。 $! 返回最后执行的进程的 PID。

kill -9 `cat /tmp/process*.pid`
rm /tmp/process*.pid

确保在相应脚本完成后删除process*.pid 文件。

【讨论】:

【参考方案2】:

因为您的kill 命令失败,因为pid 为空。

pid=$(ps | grep './process1.sh' |grep -v grep| awk 'print $1')

这不会给你你想要的 pid。当您在后台启动一个进程时,它会在一个新的 shell 中执行,您不会在 ps 输出中看到 process.sh

您可以做的是在启动后台进程时保存 PID 并终止它们:

./process1.sh &
pid1=$!  # Save the previously started background's PID
./process2.sh &
pid2=$!  # Save the previously started background's PID

echo $pid1 " " $pid2 > /tmp/killfile

然后从此文件中获取 PID 并将其传递给 kill

【讨论】:

谢谢你的建议。我会试试的。一个问题。这很奇怪,你告诉我我的 pid 应该是空的,但事实并非如此。我已经对其进行了测试,它保存了我打算杀死的进程的 PID,我确实在 ps 列表中看到了该进程。 在没有任何选项的情况下运行ps,因为您不会显示所有进程。你可以在控制台上运行 ps 并查看你的进程吗? 是的,我只能使用 ps 来查看它们。我认为这是busybox行为的原因。

以上是关于在 shell 脚本中杀死后台进程的主要内容,如果未能解决你的问题,请参考以下文章

安全地杀死在 bash 脚本中启动的后台进程

每天三分钟搞定linux shell脚本24 后台模式运行

linux shell脚本如何启动一个java进程

CentOS下后台运行Python脚本及关闭脚本的一些操作

linux shell脚本执行命令时创建子进程问题(特定的情况,例如后台运行管道分支或子shell等,脚本可能会创建子进程执行命令)

linux shell脚本执行命令时创建子进程问题(特定的情况,例如后台运行管道分支或子shell等,脚本可能会创建子进程执行命令)