FWIW, something like this works currently. This pattern is useful in a bunch of situations where the shell wants to assign to a fixed variable name. (getopts being another).
~ $ bash /dev/fd/9 9<<\EOF function mkProcs { typeset -n COPROC ref=$1 set -- "${ref[@]}" for COPROC; do coproc { typeset status=$((RANDOM%255)) echo "${!COPROC} status: $status" return "$status" } COPROC[2]=$COPROC_PID done for COPROC; do echo "${!COPROC}: $(cat <&"${COPROC[0]}"; wait "${COPROC[2]}") $?" done } typeset -a coprocs=({a..f}) "${coprocs[@]}" mkProcs coprocs EOF /dev/fd/9: line 4: warning: execute_coproc: coproc [7768:COPROC] still exists /dev/fd/9: line 4: warning: execute_coproc: coproc [7769:COPROC] still exists /dev/fd/9: line 4: warning: execute_coproc: coproc [7770:COPROC] still exists /dev/fd/9: line 4: warning: execute_coproc: coproc [7771:COPROC] still exists /dev/fd/9: line 4: warning: execute_coproc: coproc [7772:COPROC] still exists a: a status: 216 216 b: b status: 90 90 c: c status: 196 196 d: d status: 87 87 e: e status: 191 191 /dev/fd/9: line 13: "${COPROC[0]}": Bad file descriptor f: 154 ... Not sure why that last iteration always fails. I might want to experiment with reducing the limitation that makes this only work within a function on for loops over positional parameters. I know that's how it is in ksh but I've never found that it's necessary.