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

23

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

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

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

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

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

Сакиб Али
источник

Ответы:

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

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

Это та bashоболочка, которую мы хотим убить, и мы только что узнали ее 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 %
Десерт
источник
5

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

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

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

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

code_dredd
источник
2
Вы также можете использовать, topчтобы завершить процесс, нажав k, затем введя PID, а затем дважды нажав ввод.
luk3yx
-1

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

Dr4ke B4Dass
источник
-3

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

любознательный
источник
3
Использование bg/ fgне будет работать после отсоединения терминала bash. Не сможет подключиться с помощью, reptyrпотому что bashимеет дочерние процессы ( sleep).
Xiota
Он закрыл терминал, потому что он убьет этот процесс. Поэтому в следующий раз он будет использовать fg, чтобы закрыть программу. Простой
Любопытный
@ Любопытно, что в следующий раз. Но ОП спрашивает об этом времени.
RonJohn