Search code examples
bashshellpid

Collecting process ids of parallel process in bash file


Below I have a script that is collecting the process ids of individual commands, and appending them to an array in bash. For some reason as you can see stdout below, the end resulting array just contains one item, the latest id. How can the resulting PROCESS_IDS array at the end of this script contain all four process ids?

PROCESS_IDS=()

function append {
    echo $1
    PROCESS_IDS=("${PROCESS_IDS[@]}" $1)
}

sleep 1 && echo 'one' & append $! &
sleep 5 && echo 'two' & append $! &
sleep 1 && echo 'three' & append $! &
sleep 5 && echo 'four' & append $!
wait

echo "${PROCESS_IDS[@]}"

Here is the stdout:

83873
83875
83879
83882
three
one
four
two
83882

Solution

  • Don't send the append operation itself to the background. Putting an & after the content you want to background but before the append suffices: The sleep and echo are still backgrounded, but the append is not.

    process_ids=( )
    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[@]}"
    
    wait