Ctrl-C with two simultaneous commands in bash

If you type

command 1 & command 2

this is equal to

command 1 &
command 2

i.e. this will run the first command in background and then runs the second command in foreground. Especially this means, that your echo "done" is printed after command 2 finished even if command 1 is still running.

You probably want

command 1 &
command 2 &
wait
echo "done"

This will run both commands in background and wait for both to complete.


If you press CTRL-C this will only send the SIGINT signal to the foreground process, i.e. command 2 in your version or wait in my version.

I would suggest setting a trap like this:

#!/bin/bash

trap killgroup SIGINT

killgroup(){
  echo killing...
  kill 0
}

loop(){
  echo $1
  sleep $1
  loop $1
}

loop 1 &
loop 2 &
wait

With the trap the SIGINT signal produced by CTRL-C is trapped and replaced by the killgroup function, which kills all those processes.


When putting a command into the background from a script, the PID is not displayed on the screen. You can use the builtin variable $! which stores the PID of the last process so you can capture the PID of command1.

command1 &
echo $!

would echo the PID of command1.

Bash also provides the trap builtin which you can use to register a sequence of commands to run when particular signals are received. You can use this to catch the SIGINT and kill command1 before exiting the main script e.g.

#!/bin/bash

onINT() {
echo "Killing command1 $command1PID too"
kill -INT "$command1PID"
exit
}

trap "onINT" SIGINT
command1 &
command1PID="$!"
comamnd2
echo Done

Now, whilst command 2 is running, hitting Ctrl C will cause both command1 and command2 to be sent SIGINT.


Newer versions of GNU Parallel will do what you want:

parallel ::: "command 1" "command 2"
echo "done"

Or if command remains the same:

parallel command ::: 1 2
echo done

Watch the intro video for a quick introduction: https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1

Walk through the tutorial (man parallel_tutorial). You command line with love you for it.