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
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