Ответ 1
Я позволю адмиралу Акбару ответить на этот вопрос.
#!/bin/bash -e
run_development_webserver.sh &
PIDS[0]=$!
watch_sass_files_and_compile_them.sh &
PIDS[1]=$!
watch_coffeescript_files_and_compile_them.sh &
PIDS[2]=$!
trap "kill ${PIDS[*]}" SIGINT
wait
Это запускает каждую из ваших команд в фоновом режиме (&
), помещает их идентификаторы процесса ($!
) в массив (PIDS[x]=$!
), сообщает bash
to kill
все их (${PIDS[*]
), когда ваш script получает сигнал SIGINT
(Ctrl + C), а затем wait
для всех процессов для выхода.
И я буду активно упоминать, что "kill ${PIDS[*]}"
расширяет PIDS
при создании trap
; если вы смените двойные кавычки ("
) на одинарные кавычки ('
), он будет расширен при выполнении trap
, что означает, что вы можете добавить больше процессов в PIDS
после установки trap
и это тоже убьет их.
Если у вас есть упрямый процесс, который не хочет выходить после Ctrl + C (SIGINT
), вам может потребоваться отправить более сильный сигнал kill - SIGTERM
или даже SIGKILL
(используйте это как последнее средство, он безоговорочно убивает процесс, не давая ему возможности очистить). Сначала попробуйте изменить строку trap
на следующее:
trap "kill -TERM ${PIDS[*]}" SIGINT
Если он не отвечает на SIGTERM
, сохраните этот процесс pid отдельно, скажем в STUBBORN_PID
, и используйте это:
trap "kill ${PIDS[*]}; kill -KILL $STUBBORN_PID" SIGINT
Помните, что этот не позволит упрямому процессу очистить, но если ему нужно умереть, а его нет, вам может понадобиться его использовать.