Убить фоновые процессы в 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могли бы помочь лучше.

Другие вопросы по тегам