我有一个bash脚本,可以在循环中进行一些并行处理。我不希望并行过程尖峰CPU,因此我使用睡眠命令。这是一个简化的版本。

(while true;do sleep 99999;done)&

因此,我通过bash提示执行上述行,并得到类似的内容:[1] 12345

在哪里 [1] 是工作编号和 12345 是while循环的过程ID(PID)。我做一个 kill 12345 并得到:

[1]+  Terminated              ( while true; do
    sleep 99999;
done )

看起来整个脚本都已终止。但是,我做了 ps aux|grep sleep 并找到睡眠命令仍然很强,但有自己的pid!我可以杀死 sleep 一切似乎都很好。但是,如果我先杀死睡眠,那么while循环开始了一个新的 sleep pid。这对我来说是一个惊喜,因为睡眠与时循环不平行。循环本身是执行的单一路径。

所以我有两个问题:

  1. 为什么睡眠命令获得自己的流程ID?
  2. 我如何轻松杀死循环和睡眠?
有帮助吗?

解决方案

  1. 睡眠有自己的 PID 因为这是一个正在运行的过程,只是等待。尝试 which sleep 看看它在哪里。
  2. 您可以使用 ps -uf 查看系统上的过程树。从那里您可以确定什么 PPID 壳的(父pid)(一个运行循环的一个)是睡眠的。

其他提示

你尝试过吗 kill %1, , 在哪里 1 您在后台启动命令后获得的数字是吗?

发射后我现在做到了 (while true;do sleep 99999;done)& 它正确终止了它。

“ PS - PPID”使用指定的父pid选择所有过程,例如:

$ (while true;do sleep 99999;done)&
[1] 12345

$ ppid=12345 ; kill -9 $ppid $(ps --ppid $ppid -o pid --no-heading)

您可以杀死流程组。

要查找流程的流程组运行:

ps --no-headers -o "%r" -p 15864

然后使用:

kill -- -[PGID]

您可以在一个命令中完成所有操作。让我们尝试一下:

$ (while true;do sleep 99999;done)&
[1] 16151

$ kill -- -$(ps --no-headers -o "%r" -p 16151)
[1]+  Terminated              ( while true; do
    sleep 99999;
done )
  1. 因为“睡眠”是一个过程,而不是建造功能或类似的过程

  2. 您可以做以下操作:

    (while true;do sleep 99999;done)&
    whilepid=$!
    kill -- -$whilepid
    

以上代码杀死了过程组,因为PID指定为负数(例如-123而不是123)。另外,它使用变量 $!, ,它存储了最近执行的过程的PID。

注意:当您在交互式模式下执行任何过程(即使用命令行提示符)时,它会创建一个新的进程组,这就是您正在发生的事情。这样,“杀死所有人”相对容易,因为您只需要杀死整个过程组即可。但是,当在脚本中完成相同的操作时,它不会创建任何新组,因为所有新进程都属于脚本PID,即使它们在后台执行(默认情况下是禁用了作业控制)。要在脚本中启用作业控制,您只需要将以下内容放在脚本的开头:

#!/bin/bash

set -m

杀死 while 循环和 sleep 使用 $! 您也可以使用 trap 子壳内部的信号处理程序。

(trap 'kill ${!}; exit' TERM; while true; do sleep 99999 & wait ${!}; done)&
kill -TERM ${!}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top