如何停止在后台运行的 bash while 循环?

如何停止在后台运行的 bash while 循环?

我启动了一个 while 循环,如下所示:

while true; do {command}; sleep 180; done &

请注意&

我以为当我关闭终端时,这个 while 循环就会停止。但它仍在继续。自从我关闭终端会话以来已经过去了几个小时。

我如何停止这个 while 循环?

答案1

我已开始

while true; do yad; sleep 60; done &

并关闭终端进行测试,现在我遇到了同样的问题。

如果你已经关闭了终端,你已经开始循环

让我们来概览一下正在运行的进程ps fjx,我的机器上的最后几行显示

 2226 11606 11606 19337 ?           -1 S     1000   0:00  \_ /bin/bash
11606 22485 11606 19337 ?           -1 S     1000   0:00  |   \_ sleep 10
 2226  9411  9411  8383 ?           -1 S     1000   0:00  \_ /bin/bash
 9411 17674  9411  8383 ?           -1 Sl    1000   0:00      \_ yad
    1  2215  2215  2215 ?           -1 Ss    1000   0:00 /lib/systemd/systemd --user
 2215  2216  2215  2215 ?           -1 S     1000   0:00  \_ (sd-pam)

您可以看到yad的子进程/bin/bash,如果我关闭它, 的输出yad将变为。如果树视图太混乱,您还可以按如下方式搜索输出1sleep 60ps

ps fjx | grep "[y]ad"  # or respectively
ps fjx | grep "[s]leep 60"

输出行以两个数字开头,第一个是 PPID,即父进程的进程 ID,第二个是 PID,即进程本身的 ID。这是因为这两9411行都出现了:

2226  9411  9411  8383 ?           -1 S     1000   0:00  \_ /bin/bash
9411 17674  9411  8383 ?           -1 Sl    1000   0:00      \_ yad

这就是bash我们要杀死的子 shell,我们刚刚找到了它的 PID,所以现在剩下的就是简单的

kill 9411  # replace 9411 with the PID you found out!

并且令人厌烦的子外壳已经永远消失。

1:用 而不是 来表示grep "[y]ad"只是grep yad阻止grep进程本身出现在结果列表中。


如果你的终端还打开

bash提供变量$!,该变量“扩展为最近放入后台的作业的进程 ID”,因此以下操作只会终止后台中的最新进程:

kill $!

如果它是不是最新进程,只需使用内置命令即可获取正在运行的作业列表jobs,示例输出:

[1]-  Running                 while true; do
    yad; sleep 60;
done &
[2]+  Stopped                 sleep 10

作业列表中有两个作业,要终止其中一个,您可以使用作业编号或快捷方式访问它%%+(“当前作业”)和%-(“上一个作业”),例如,要终止在后台运行的循环,您可以这样做

kill %1  # or
kill %-

并终止暂停的sleep 10作业:

kill %2  # or
kill %+  # or
kill %

答案2

我需要注意的是,当你关闭输入该命令的终端时,子命令应该会随之消失。尝试重现此情况时,出现了这种行为。

现在,假设您确实处于没有发生这种情况的情况,那么终止由&命令末尾导致的在后台运行的程序的一种方法如下:

  1. 打开一个新的 shell 并运行echo $$以记下您当前的 PID(进程 ID),这样您就不会终止自己的会话。
  2. 识别您认为仍在运行的程序的 PID;您可以使用命令ps -ef | grep $SHELL来查找哪些程序正在运行 shell。
  3. 注意左边第二列,并记下数值不同echo $$上面的结果可以看出,这是您想要终止的 PID。
  4. 运行kill -SIGTERM <pid>命令,其中<pid>是您在步骤#3中确定的数值
  5. 重复步骤 #2,确认程序不再运行

您也可以重新启动会话或计算机,但是上述方法可以让您避免这种情况。

答案3

&将使终端创建一个新进程并让您的代码在其中运行。因此,您的代码将独立于终端进程。即使您关闭终端,运行代码的新进程也不会停止。因此,请删除&或执行ps -aux,找到您的进程并终止它kill (process id)

相关内容