Given two background commands, terminate the remaining one when either exits

This starts both processes, waits for the first one that finishes and then kills the other:

#!/bin/bash
{ cd ./frontend && gulp serve; } &
{ cd ./backend && gulp serve --verbose; } &
wait -n
pkill -P $$

How it works

  1. Start:

    { cd ./frontend && gulp serve; } &
    { cd ./backend && gulp serve --verbose; } &
    

    The above two commands start both processes in background.

  2. Wait

    wait -n
    

    This waits for either background job to terminate.

    Because of the -n option, this requires bash 4.3 or better.

  3. Kill

    pkill -P $$
    

    This kills any job for which the current process is the parent. In other words, this kills any background process that is still running.

    If your system does not have pkill, try replacing this line with:

    kill 0
    

    which also kills the current process group.

Easily testable example

By changing the script, we can test it even without gulp installed:

$ cat script.sh 
#!/bin/bash
{ sleep $1; echo one;  } &
{ sleep $2; echo two;  } &
wait -n
pkill -P $$
echo done

The above script can be run as bash script.sh 1 3 and the first process terminates first. Alternatively, one can run it as bash script.sh 3 1 and the second process will terminate first. In either case, one can see that this operates as desired.