Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > gnu.bash.bug > #11887 > unrolled thread

Re: redirecting a file descriptor to an array variable? Possible? How? RFE?

Started bykonsolebox <konsolebox@gmail.com>
First post2015-11-16 19:51 +0800
Last post2015-11-16 19:51 +0800
Articles 1 — 1 participant

Back to article view | Back to gnu.bash.bug

This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by below is the oldest one visible, not the original post.


Contents

  Re: redirecting a file descriptor to an array variable? Possible? How? RFE? konsolebox <konsolebox@gmail.com> - 2015-11-16 19:51 +0800

#11887 — Re: redirecting a file descriptor to an array variable? Possible? How? RFE?

Fromkonsolebox <konsolebox@gmail.com>
Date2015-11-16 19:51 +0800
SubjectRe: redirecting a file descriptor to an array variable? Possible? How? RFE?
Message-ID<mailman.41.1447704956.24003.bug-bash@gnu.org>
On Fri, Nov 13, 2015 at 8:45 AM, Linda Walsh <bash@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

[toc] | [standalone]


Back to top | Article view | gnu.bash.bug


csiph-web