Как остановить 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 %
Я должен отметить, что когда вы закрываете терминал, где вы ввели эту команду, подкоманда должна была умереть вместе с ней. Попытка воспроизвести это показала это поведение.
Теперь, если предположить, что вы действительно находитесь в ситуации, когда этого не произошло, один из способов убить программу, которую вы оставили в фоновом режиме, был вызван & в конце команды, выглядит следующим образом:
- Откройте новую оболочку и запустите
echo $$записать свой текущий PID (идентификатор процесса), чтобы вы не убивали свой собственный сеанс. - Определите PID программы, которая, по вашему мнению, все еще работает; Вы можете сделать это с помощью
ps -ef | grep $SHELLКоманда, чтобы найти, какие программы работают с оболочкой. - Обратите внимание на 2-й столбец слева и обратите внимание на числовое значение, которое отличается от вашего
echo $$результат выше; это PID, который вы хотите убить. - Запустить
kill -SIGTERM <pid>команда, где<pid>это числовое значение, которое вы определили на шаге № 3 - Подтвердите, что программа больше не работает, повторив шаг № 2
Вы также можете перезапустить сеанс или компьютер, но вышеизложенное позволит вам избежать этого.
& заставит терминал создать новый процесс и заставить ваш код работать внутри него. Таким образом, ваш код становится независимым от терминального процесса. Даже если вы закроете терминал, новый процесс, в котором выполняется ваш код, не остановится. Так что либо убери & или делать ps -aux, найдите свой процесс и убейте его kill (process id),
Обычно bg для фона fg для переднего плана. Если вы используете & символ, используйте fg, он покажет текущую запущенную программу. Нажмите Ctrl+C, чтобы убить.