In Bash, how can I run multiple infinitely-running commands and cancel them all with ^C? In Bash, how can I run multiple infinitely-running commands and cancel them all with ^C? bash bash

In Bash, how can I run multiple infinitely-running commands and cancel them all with ^C?


I'll let Admiral Ackbar answer this one.

trap

#!/bin/bash -erun_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[*]}" SIGINTwait

This starts each of your commands in the background (&), puts their process ids ($!) into an array (PIDS[x]=$!), tells bash to kill them all (${PIDS[*]) when your script gets a SIGINT signal (Ctrl+C), and then waits for all the processes to exit.

And I'll proactively mention that "kill ${PIDS[*]}" expands PIDS when you create the trap; if you change the double quotes (") to single quotes ('), it will be expanded when the trap is executed, which means you can add more processes to PIDS after you set the trap and it will kill them too.

If you have a stubborn process that doesn't want to quit after a Ctrl+C (SIGINT), you may need to send it a stronger kill signal - SIGTERM or even SIGKILL (use this as a last resort, it unconditionally kills the process without giving it a chance to clean up). First, try changing the trap line to this:

trap "kill -TERM ${PIDS[*]}" SIGINT

If it doesn't respond to the SIGTERM, save that process's pid separately, say in STUBBORN_PID, and use this:

trap "kill ${PIDS[*]}; kill -KILL $STUBBORN_PID" SIGINT

Remember, this one won't let the stubborn process clean up, but if it needs to die and isn't, you may need to use it anyway.