-1

In this example I have three commands running in parallel.

sleep 1 && echo 'one' &
sleep 2 && echo 'two'&
sleep 1 && echo 'three'&
sleep 2 && echo 'four' & 
wait

echo "done"

When I exit / quit the command with a keyboard shortcut the command still seems to be outputting.

➜  example: ✗ sh ./scripts.sh
three
one
two
four
done
➜  example: ✗ sh ./scripts.sh
^C%➜  example: ✗ one
three
two
four

How can I cleanly exit?

ThomasReggi
  • 55,053
  • 85
  • 237
  • 424

2 Answers2

1

By default signals handled by Kernal, but i have seen reference saying all signals except kill can be handled by program also,we can capture CNTRL + C signal using trap like below for instance,

finish(){
    < code to kill child process goes here >
}
trap finish EXIT

sleep 1 && echo 'one' &
sleep 2 && echo 'two' &
sleep 1 && echo 'three'&
sleep 2 && echo 'four' &

wait

for more , stackoverflow or redsymbol.net

Jithin Scaria
  • 1,271
  • 1
  • 15
  • 26
0

With @JithinScarla's help and this other stackoverflow post I made I put this together which seems to get the job done.

process_ids=( )

finish(){
    for i in "${process_ids[@]}"; do
        kill -9 $i > /dev/null 2> /dev/null || :
    done
}

append() { process_ids+=( "$1" ); }       # POSIX-standard function declaration syntax

{ sleep 1 && echo 'one'; } & append $!
{ sleep 5 && echo 'two'; } & append $!
{ sleep 1 && echo 'three'; } & append $!
{ sleep 5 && echo 'four'; } & append $!

echo "Background processes:"              # Demonstrate that our array was populated
printf ' - %s\n' "${process_ids[@]}"

trap finish EXIT

wait

Or here even a bit cleaner:

function runParallel {
    process_ids=( )
    finish(){
        for i in "${process_ids[@]}"; do
            kill -9 $i > /dev/null 2> /dev/null || :
        done
    }
    append() { process_ids+=( "$1" ); }       # POSIX-standard function declaration syntax
    processes=( "$@" )
    for i in "${processes[@]}"; do
        { eval $i; } & append $!
    done
    trap finish EXIT
    wait
}

runParallel \
    "sleep 1 && echo 'one'" \
    "sleep 5 && echo 'two'" \
    "sleep 1 && echo 'three'" \
    "sleep 5 && echo 'four'"
ThomasReggi
  • 55,053
  • 85
  • 237
  • 424