Как остановить bash во время цикла в фоновом режиме?

Я запустил цикл while следующим образом:

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

Обратите внимание на &,

Я думал, что когда я убью терминал, этот цикл while прекратится. Но это все еще продолжается. Прошло несколько часов с тех пор, как я убил терминальную сессию.

Как мне остановить этот цикл?

4 ответа

Решение

Я начал

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, идентификатор процесса родительского процесса, а второе - PID, идентификатор самого процесса. Это из-за этого 9411 появляется в обоих рядах здесь:

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

Это bash subshell мы хотим убить, и мы только что узнали его PID, так что теперь все, что остается, это просто

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

и надоедливая подоболочка ушла навсегда.

1: обозначение как grep "[y]ad" вместо просто grep yad предотвращает grep сам процесс от отображения в списке результатов.


Если у вас есть терминал все еще открыт

bash предоставляет переменную $!, который "расширяется до идентификатора процесса задания, недавно помещенного в фон", так что следующее просто убивает последний процесс в фоновом режиме:

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 %

Я должен отметить, что когда вы закрываете терминал, где вы ввели эту команду, подкоманда должна была умереть вместе с ней. Попытка воспроизвести это показала это поведение.

Теперь, если предположить, что вы действительно находитесь в ситуации, когда этого не произошло, один из способов убить программу, которую вы оставили в фоновом режиме, был вызван & в конце команды, выглядит следующим образом:

  1. Откройте новую оболочку и запустите echo $$ записать свой текущий PID (идентификатор процесса), чтобы вы не убивали свой собственный сеанс.
  2. Определите PID программы, которая, по вашему мнению, все еще работает; Вы можете сделать это с помощью ps -ef | grep $SHELL Команда, чтобы найти, какие программы работают с оболочкой.
  3. Обратите внимание на 2-й столбец слева и обратите внимание на числовое значение, которое отличается от вашего echo $$ результат выше; это PID, который вы хотите убить.
  4. Запустить kill -SIGTERM <pid> команда, где <pid> это числовое значение, которое вы определили на шаге № 3
  5. Подтвердите, что программа больше не работает, повторив шаг № 2

Вы также можете перезапустить сеанс или компьютер, но вышеизложенное позволит вам избежать этого.

& заставит терминал создать новый процесс и заставить ваш код работать внутри него. Таким образом, ваш код становится независимым от терминального процесса. Даже если вы закроете терминал, новый процесс, в котором выполняется ваш код, не остановится. Так что либо убери & или делать ps -aux, найдите свой процесс и убейте его kill (process id),

Обычно bg для фона fg для переднего плана. Если вы используете & символ, используйте fg, он покажет текущую запущенную программу. Нажмите Ctrl+C, чтобы убить.

Другие вопросы по тегам