Я позволю адмиралу Акбару ответить на этот вопрос.
#!/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
kill
всем им (${PIDS[*]
) ) когда ваш сценарий получает сигнал SIGINT
( Ctrl + C ), а затем wait
s для всех процессов, которые необходимо завершить.
И я заранее упомяну, что "kill ${PIDS[*]}"
расширяется PIDS
при создании trap
; если вы измените двойные кавычки ("
) на одинарные кавычки ('
), они будут расширены при выполнении trap
, что означает, что вы можете добавить больше процессов к PIDS
после установки trap
и это убьет их тоже.
Если у вас есть упрямый процесс, который не хочет завершать работу после Ctrl + C (SIGINT
), вам может потребоваться отправить ему более сильный сигнал уничтожения - SIGTERM
или даже SIGKILL
(используйте это в качестве крайней меры, это безоговорочно убивает процесс, не давая ему возможности очиститься). Сначала попробуйте изменить строку trap
на эту:
trap "kill -TERM ${PIDS[*]}" SIGINT
Если он не отвечает на SIGTERM
, сохраните pid этого процесса отдельно, скажем, в STUBBORN_PID
, и используйте это:
trap "kill ${PIDS[*]}; kill -KILL $STUBBORN_PID" SIGINT
Запомните, этот не позволит упрямому процессу очиститься, но если ему нужно умереть, а может и нет, вам все равно придется его использовать.