
Я хочу завершить все процессы в системе, кроме PID 1.
В настоящее время я использую pgrep -l . | awk "{if (\$1 != 1) print \$1}" | xargs -n 1 kill -s INT
.
awk
используется для исключения процесса с PID 1
Если я запускаю команду в Alpine Linux (которая использует sh
), я получаю:
# pgrep -l . | awk "{if (\$1 != 1) print \$1}" | xargs -n 1 kill -s INT
kill: can't kill pid 265: No such process
Я полагаю, PID 256
что это из awk
.
Есть ли чистый способ (используя утилиты, которые должны быть доступны в большинстве систем Linux) завершить все процессы, кроме PID 1
?
решение1
По крайней мере, в Linux
kill -- -1
Отправит сигнал SIGTERM всем возможным процессам, за исключением вызывающего процесса (то есть процесса, выполняющего эту kill
команду, который может быть оболочкой, если kill
она встроена (обычно это происходит в оболочках POSIX), или процесса, выполняющего отдельную kill
команду) и процесса с pid 1.
Обратите внимание, что это делается как часть системного kill()
вызова, поэтому это надежнее, чем использование команд типа pkill
или killall
(или традиционной killall
команды, которая иногда встречается killall5
в Linux и традиционно используется для этого), которые сначала выводят список процессов, а затем завершают их, поскольку они пропустят процессы, которые были порождены в это время.
Так что это похоже именно на то, что вам нужно.
trap '' TERM # ignore SIGTERM ourselves though it wouldn't be needed
# in most shells
kill -- -1
sleep 1 # leave processes some time to exit cleanly on SIGTERM
kill -s KILL -- -1 # removes the remaining processes or those
# that have started since without giving them
# a chance to clean-up.
exit
Должно убить все, кроме процесса с идентификатором 1.
Вы можете поэкспериментировать с этим, запустив:
unshare --mount-proc -mpf
Это запускает оболочку в отдельном pid и пространстве имен монтирования (с новым /proc (используемым ps
/ pkill
/ killall
)), где эта оболочка имеет pid 1.
За исключением Linux, kill -- -1
должно работать на любой системе, завершая большинство процессов, но список процессов, которые не подлежат завершению, может различаться в зависимости от системы.
решение2
Можетты-да. Долженвы? почти при любых обстоятельствах, нет. Но:
init
игнорирует SIGTERM в Linux, явно. Так что вы можете просто сделать killall -TERM '*'
.