我正在尝试获取 shell 脚本的 PID,以便稍后可以杀死它。
bash "home/lewis/builds/arduino/arduino-1.8.12/arduino" & disown
echo "$!"
上面运行并返回 37977
但
当我跑步时kill 37977
我得到
bash: kill: (37977) - No such process
我认为这是因为脚本/home/lewis/builds/arduino/arduino-1.8.12/arduino
随后生成了 37977 以外的其他进程。
有什么方法可以让我获取 shell 脚本或我运行的任何其他命令的最终 PID,通常它很有效,但这个实例给我带来了一个问题。
我需要一个可以转移到其他命令的解决方案,以防这种情况再次发生。
答案1
如果生成的进程正在启动其他进程然后退出,则新进程都应具有相同的进程组 ID (PGID),并且该 ID 应该是原始进程的 PID(在示例中为 37977)。所以你想要的是一种杀死 PGID 中所有进程的方法。这可以通过负 PID 来完成kill
,如下所述man kill
:
-n where n is larger than 1. All processes in process group
n are signaled. When an argument of the form '-n' is
given, and it is meant to denote a process group, either
a signal must be specified first, or the argument must be
preceded by a '--' option, otherwise it will be taken as
the signal to send.
所以,你所追求的是:
bash "home/lewis/builds/arduino/arduino-1.8.12/arduino" & disown
kill -TERM -"$!"
如果您需要收集各个 PID 列表,您可以执行以下操作:
bash "home/lewis/builds/arduino/arduino-1.8.12/arduino" & disown
ps -eo pgid,pid | awk -v pid=$! '$1==pid{print $2}')
这将返回 PGID 为 的 PID 列表$!
。如果你的 shell 支持数组(bash 支持),你甚至可以这样做:
pids=($(ps -eo pgid,pid | awk -v pid=$! '$1==pid{print $2}'))
for pid in "${pids[@]}"; do echo "Killing $pid"; kill $pid; done
或者您需要的其他任何东西。