Search code examples
bashshellcygwinwaitbackground-process

cygwin bash not waiting for background scripts to finish


I've encountered an issue with waiting for background jobs; I have two scripts set up with the following basic structure:

Main script:

cat list_of_names.txt | while read name; do

  ./my_script_1.sh $name &

done

wait

./other_process.exe

my_script_1.sh:

name=$1

./prog_1.exe $name
./prog_2.exe $name
./prog_3.exe $name

The program other_process.exe can only be run once all the backgrounded instances of myscript.sh have finished running. The problem is that the call to wait doesn't wait for these background processes to finish, instead the main script immediately runs other_process.exe (which fails).

While attempting to debug this, I have found that calling jobs within the while loop correctly displays all of the background instances of myscript.sh that are running. However, calling jobs outside of the loop just before the wait command returns nothing. As far as I can tell, once the main script has finished the while loop it can no longer see any of the child processes that were started by it.


Solution

  • This isn't cygwin specific. The pipe in bash starts its commands in subshells. Therefore, the background processes are children of the subshell, not the main shell. Avoid the pipe, replace it with the process substitution <( ... ):

    #!/bin/bash
    while read x ; do
        ( echo Start $x ; sleep $x ; echo Done $x ) &
    done < <( echo $'1\n2' )
    echo Done start
    wait
    echo Done all