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


23

我开始了一个while循环,如下所示:

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

请注意&

我以为当我杀死终端机时,此while循环将停止。但它仍在继续。自从我终止终端会话以来已经有几个小时了。

如何停止while循环?

Answers:


38

我已开始

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它的变化以sleep 60在输出ps。如果树形视图太令人困惑,您还可以按以下方式搜索输出1

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 %

5

我需要注意的是,当您关闭输入该命令的终端时,该子命令应该已经消失了。尝试重现此行为表明了这种现象。

现在,假设您确实处于这种情况没有发生的情况,那么杀死由后台运行的程序(一种由&命令结尾引起的)的一种方法如下:

  1. 打开一个新的shell并运行echo $$以记下当前的PID(进程ID),以免杀死自己的会话。
  2. 确定您认为仍在运行的程序的PID;您可以使用ps -ef | grep $SHELL命令来执行此操作,以查找正在运行Shell的程序。
  3. 请注意左侧的第二列,并注意echo $$上面的结果不同的数值;这是您要杀死的PID。
  4. 运行kill -SIGTERM <pid>命令,哪里<pid>是您在步骤3中标识的数值
  5. 重复步骤2,确认程序不再运行

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


2
您还可以top通过按k,然后输入PID,然后按Enter两次来终止进程。
luk3yx

-1

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


-3

通常bg为背景,fg为前景。如果使用符号使用fg,它将显示当前正在运行的程序。按Ctrl + C杀死。


3
终端与断开后,使用bg/ fg将无法使用bashreptyr由于bash具有子进程(sleep),将无法重新附加使用。
xiota

他关闭了终端,因为他将终止该进程。因此,下次他将使用fg关闭该程序。简单
好奇

@好奇的是下一次。但是OP正在询问这个时间。
罗恩·约翰
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.