Skip to content

Instantly share code, notes, and snippets.

@thmsmlr
Created July 1, 2020 05:59
Show Gist options
  • Save thmsmlr/8d5ec2dded13ff91d2863177c3027de9 to your computer and use it in GitHub Desktop.
Save thmsmlr/8d5ec2dded13ff91d2863177c3027de9 to your computer and use it in GitHub Desktop.
A simple way to spin up many blocking bash commands at once, killing all on SIGINT
#!/usr/bin/env bash
#
# This is a basic script to launch multiple programs and kill them
# all at the same time. It does this by launching the first n-1 jobs as
# background jobs, then running the nth job as a foreground job.
#
# It traps the exist signal produced by doing `CTRL-C` on the CLI and
# iterates through the PIDs of the background jobs and runs kill -9 on them.
#
# This script also tries to print our the results of each script with
# some color coding to make the outputs of these scripts somewhat readable.
#
# Requirements:
# - Bash v4 or higher
#
set -e
declare -A PROGRAMS=(
["UI"]="PYTHONUNBUFFERED=TRUE python -m http.server 5001"
["API"]="npx http-server"
)
declare -A PIDS
NUM_PROGRAMS=${#PROGRAMS[@]}
COUNT=0
ESC=$(printf '\033')
# Start the background jobs
for NAME in "${!PROGRAMS[@]}"
do
COUNT=$((COUNT + 1))
COLOR=$((31 + COUNT))
echo "Starting program ${ESC}[${COLOR}m$NAME${ESC}[0m: ${ESC}[2m${PROGRAMS[$NAME]}${ESC}[0m"
if [ "$COUNT" != "$NUM_PROGRAMS" ]
then
eval "${PROGRAMS[$NAME]}" |& sed -e "s/^/${ESC}[${COLOR}m$NAME |${ESC}[0m /" &
PIDS[$NAME]=$!
fi
done
# Trap and kill the background jobs
trap onexit INT
function onexit() {
echo
echo "Shutting down $NAME..."
for NAME in "${!PIDS[@]}"
do
echo "Shutting down $NAME..."
kill -9 "${PIDS[$NAME]}"
done
}
# Start the final foreground job
# NOTE: that $NAME is set to the last value in the loop
eval "${PROGRAMS[$NAME]}" |& sed -e "s/^/${ESC}[${COLOR}m[$NAME]${ESC}[0m /"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment