Убить фоновые процессы в Linux
Я пытаюсь создать стартовый скрипт и скрипт остановки для моего проекта. Мне нужно запустить sass auto-compiler, а также сервер, и перенаправить вывод обоих в файл. я использую lite-server
а также sass --watch
за это.
Чтобы эти процессы выполнялись одновременно, я использую &
на задний план процессов. Это создает проблему остановки сценариев, я не могу остановить использование сценариев Ctrl+C
как обычно. Я думал, что смогу преодолеть это, сохранив идентификаторы процесса в текстовом файле.
Я придумал следующий "стартовый" скрипт:
# Start a sass watcher and a server running simultaneously. Store the PIDs in a
# text file so that the processes can be easily stopped.
(
lite-server &
echo $! > .pids.txt &
sass --watch sass:css --style=compressed &
echo $! >> .pids.txt &
) &> log.txt
cat .pids.txt
Затем, чтобы остановить процессы, я использую
kill $(cat .pids.txt)
Запись идентификаторов процесса в текстовый файл выглядит несколько странно. Есть ли лучший способ выполнить то, что я пытаюсь сделать?
4 ответа
Вы можете хранить их в массиве, если это не то, что вы бы назвали хакером.
РЕДАКТИРОВАТЬ: Другой способ просто выполнить:
kill $(jobs -p)
Это убивает все фоновые процессы (jobs -p выводит PID всех фоновых процессов на стандартный вывод, которые затем передаются для уничтожения).
Я могу предпочесть grep для процесса и убить процесс вместо того, чтобы хранить PID в файле.
ps -ef | grep lite-server | awk '{print $2}' | kill -9
Я предполагаю, что второй столбец в выводе ps -ef
это PID процесса lite-server
на вашем сервере.
Вы должны добавить, какой тип "kill" вы хотите.., например: kill -9 $(cat .pids.txt)
Я нашел Выполнить несколько команд и убить их как одну в bash, а также более подробную статью Как создать группу процессов в Linux и убить всех ее дочерних элементов .
Суммируя:
setsid sh -c 'command1 & command2 & command3 & wait'
process_group_id=$!
# and/or save to a file like '.pgid'
echo $process_group_id > .pgid
# to kill everything in that process group (mind the dash):
kill -TERM -$process_group_id
Примечание
Убийство сkill $process_group_id
НЕ убьет всю группу! Должен быть предшествующий-
при убийстве всей группы процессов по id.
Кроме того, вы должны передать соответствующий сигнал , используяkill
. Чтобы распечатать все сигналы, запустите:
kill -l
1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP
6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1
11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM
16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP
21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ
26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR
31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3
38) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8
43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7
58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2
63) SIGRTMAX-1 64) SIGRTMAX
Таким образом, принудительное убийство будет:
kill -9 -$process_group_id
# OR
kill -SIGKILL -$process_group_id
Но если у команд есть способ обработки SIGTERM :
kill -15 -$process_group_id
# OR
kill -TERM -$process_group_id
# OR
kill -SIGTERM -$process_group_id
В kill есть еще кое-что : отправьте сигнал процессам, если вы используете GNU coreutils. Если нет, может бытьman kill
илиinfo kill
могли бы помочь лучше.