Спи за какое -то время петля получает свой собственный пид
-
10-10-2019 - |
Вопрос
У меня есть сценарий Bash, который делает некоторую параллельную обработку в цикле. Я не хочу, чтобы параллельный процесс вспыхнул процессор, поэтому я использую команду сна. Вот упрощенная версия.
(while true;do sleep 99999;done)&
Поэтому я выполняю вышеупомянутую строку из приглашения Bash и получаю что -то вроде:[1] 12345
Где [1]
номер работы и 12345
это идентификатор процесса (PID) из цикла while. Я делаю kill 12345
и получить:
[1]+ Terminated ( while true; do sleep 99999; done )
Похоже, весь сценарий был прекращен. Однако я делаю ps aux|grep sleep
И обнаружите, что команда сна все еще становится сильной, но со своим собственным пидом! Я могу убить sleep
И все кажется в порядке. Однако, если бы я сначала убить сон, то Where Lop начинает новый sleep
пид. Это такой удивление для меня, так как сон не параллелен петле. Сам цикл - это единственный путь исполнения.
Итак, у меня есть два вопроса:
- Почему команда Sleep получила свой собственный идентификатор процесса?
- Как мне легко убить петлю и сон?
Решение
- Сон получает свой собственный
PID
Потому что это процесс работает и просто ожидает. Пытатьсяwhich sleep
Чтобы увидеть, где это. - Вы можете использовать
ps -uf
Чтобы увидеть дерево процесса в вашей системе. Оттуда вы можете определить, чтоPPID
(родительский пид) оболочки (та, которая работает в петле).
Другие советы
Вы пробовали сделать kill %1
, куда 1
Номер, который вы получаете после запуска команды в фоновом режиме?
Я сделал это прямо сейчас после запуска (while true;do sleep 99999;done)&
и это правильно прекратило его.
"PS -PPPID" выбирает все процессы с указанным родительским PID, например:
$ (while true;do sleep 99999;done)&
[1] 12345
$ ppid=12345 ; kill -9 $ppid $(ps --ppid $ppid -o pid --no-heading)
Вы можете убить группу процессов.
Чтобы найти группу процесса вашего процесса запуска:
ps --no-headers -o "%r" -p 15864
Затем убейте группу процессов, используя:
kill -- -[PGID]
Вы можете сделать все это в одной команде. Попробуем:
$ (while true;do sleep 99999;done)&
[1] 16151
$ kill -- -$(ps --no-headers -o "%r" -p 16151)
[1]+ Terminated ( while true; do
sleep 99999;
done )
Потому что «сон»-это процесс, а не встроенная функция или аналогичная
Вы могли бы сделать следующее:
(while true;do sleep 99999;done)& whilepid=$! kill -- -$whilepid
Приведенный выше код убивает группу процессов, потому что PID определяется как отрицательное число (например, -123 вместо 123). Кроме того, он использует переменную $!
, который хранит пид самого последнего выполненного процесса.
ПРИМЕЧАНИЕ. Когда вы выполняете любой процесс в фоне в интерактивном режиме (т.е. с помощью подсказки командной строки), он создает новую группу процессов, что происходит с вами. Таким образом, относительно легко «убить их всех», потому что вам просто нужно убить всю группу процессов. Однако, когда то же самое сделано в сценарии, он не создает никакой новой группы, потому что все новые процессы принадлежат PID сценария, даже если они выполняются в фоновом режиме (управление заданиями отключено по умолчанию). Чтобы включить управление заданиями в сценарии, вам просто нужно поставить следующее в начале сценария:
#!/bin/bash
set -m
Убить while
петля и sleep
с использованием $!
Вы также можете использовать trap
обработчик сигнала внутри подборной.
(trap 'kill ${!}; exit' TERM; while true; do sleep 99999 & wait ${!}; done)&
kill -TERM ${!}