I would like to write a script that runs a few different infinitely running commands, e.g.
run_development_webserver.sh
watch_sass_files_and_compile_them.sh
watch_coffeescript_files_and_compile_them.sh
I'd like to run each of them in parallel, and kill them all by hitting ^C. Is this possible, and if so how can I do this?
Bash break Statement The break statement ends the current loop iteration and exits from the loop. When combined with a condition, break helps provide a method to exit the loop before the end case happens. The Bash break statements always apply to loops. The integer value is optional, and it is 1 by default.
Using Semicolon (;) Operator to Run Multiple Linux commands. The semicolon (;) operator enables you to run one or more commands in succession, regardless of whether each earlier command succeeds or not. For example, run the following three commands on one line separated by semicolons (;) and hit enter.
Infinite while Loop You can also use the true built-in or any other statement that always returns true. The while loop above will run indefinitely. You can terminate the loop by pressing CTRL+C .
I'll let Admiral Ackbar answer this one.
#!/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
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 wait
s 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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With