On Fri, Nov 13, 2015 at 8:45 AM, Linda Walsh <b...@tlinx.org> wrote: > > I'd like to be able to record stdout and stderr > without using any temp files into bash array files, AND > record the status of the command executed. >
You can use coproc processes that would act as buffers. Obvious Note: Avoid it if you're conservative about some undocumented areas that would look too hacky to you. Concept: #!/bin/bash function sponge { while read -r __ && [[ $__ != __EOF__ ]]; do ## Or use a keyword that's more unusual. Closing one end of the input pipe seems unreliable. I also tried using traps for flushing output; didn't work so well. (But you can try those ideas. I haven't tested how adding `sleep` affects them.) LINES+=("$__") done printf '%s\n' "${LINES[@]}" exec sleep 1 } function run_with_captured_output { local C0 C1 P0 P1 R __ exec 4>&2 2>/dev/null ## Avoid warning. coproc C0 (sponge) P0=$! coproc C1 (sponge) P1=$! exec 2>&- 2>&4 4>&- disown "$P0" "$P1" ## This may be needed or not. "$@" >&"${C0[1]}" 2>&"${C1[1]}" R=$? __A0=() __A1=() echo __EOF__ >&"${C0[1]}" while read -u "${C0[0]}" -t 0.1 __; do __A0+=("$__") done echo __EOF__ >&"${C1[1]}" while read -u "${C1[0]}" -t 0.1 __; do __A1+=("$__") done # TODO: Not sure how a proper coproc cleanup is done. Closing FDs does funny things. Perhaps it's automatic, but not sure how disown affects it. We could examine the source code but not sure if that would be reliable enough for all versions of bash including the upcoming ones. return "$R" } function create_random_output { local I for (( I = 0; I < 5; ++I )); do echo "OUT: $RANDOM" echo "ERR: $RANDOM" >&2 done } run_with_captured_output create_random_output echo "Returned status: $?" printf 'Stdout: %s\n' "${__A0[@]}" printf 'Stderr: %s\n' "${__A1[@]}" Output: Returned status: 0 Stdout: OUT: 26079 Stdout: OUT: 21138 Stdout: OUT: 17971 Stdout: OUT: 8460 Stdout: OUT: 7185 Stderr: ERR: 19874 Stderr: ERR: 4559 Stderr: ERR: 18830 Stderr: ERR: 19818 Stderr: ERR: 21562