[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Unexpected behaviour when using process substitution with stdout and
From: |
Alex fxmbsw7 Ratchev |
Subject: |
Re: Unexpected behaviour when using process substitution with stdout and stderr |
Date: |
Sun, 11 Jul 2021 12:38:36 +0200 |
you printf basically to stdout from stderr, ..maybe its that
if you'd change your stderr printf to >&2 maybe works, ..just saying, maybe
or change the order to 2> and then >
..maybe..
peace
On Sun, Jul 11, 2021, 12:09 earnestly <zibeon@googlemail.com> wrote:
> GNU bash, version 5.1.8(1)-release (x86_64-pc-linux-gnu)
>
> I have attempted to use process substitution in order to feed the
> output of a command into two filters, one for handling stdout and the
> other for stderr.
>
> Prior to this I was using POSIX sh and named pipes to achieve this but
> decided to try bash with its >() and <() notation.
>
> Perhaps I am misunderstanding how this works because I found them to be
> unusable in this context.
>
> What appears to be happening is that the output from standard error is
> being mixed into the function handling standard out, even more
> surprisingly that xtrace output is also being consumed and filtered as
> well.
>
> I don't quite know how to describe what's happening so I have provided a
> small demonstration/reproducer instead:
>
> #!/bin/bash --
>
> generate() {
> for ((i=0; i<10; ++i)); do
> if ((RANDOM % 2)); then
> printf 'generate to stdout\n'
> else
> printf 'generate to stderr\n' >&2
> fi
> done
> }
>
> stdout() {
> local line
>
> while read -r line; do
> printf 'from stdout: %s\n' "$line"
> done
> }
>
> stderr() {
> local line
>
> while read -r line; do
> printf 'from stderr: %s\n' "$line"
> done
> }
>
> # Using process substitution.
> unexpected() {
> # This is particularly dangerous when the script is executed under
> `bash -x'
> # as the xtrace output is read as standard input to the `stdout'
> function.
> generate > >(stdout) 2> >(stderr)
> wait
>
> # Example output:
> # from stdout: generate to stdout
> # from stdout: generate to stdout
> # from stdout: from stderr: generate to stderr
> # from stdout: from stderr: generate to stderr
> # from stdout: from stderr: generate to stderr
> # from stdout: generate to stdout
> # from stdout: from stderr: generate to stderr
> # from stdout: generate to stdout
> # from stdout: from stderr: generate to stderr
> # from stdout: from stderr: generate to stderr
> }
>
> # Using named pipes.
> expected() {
> mkfifo a b
> trap 'rm a b' EXIT
>
> generate > a 2> b &
>
> stdout < a &
> stderr < b &
> wait
>
> # Example output:
> # from stdout: generate to stdout
> # from stderr: generate to stderr
> # from stdout: generate to stdout
> # from stderr: generate to stderr
> # from stdout: generate to stdout
> # from stdout: generate to stdout
> # from stderr: generate to stderr
> # from stdout: generate to stdout
> # from stdout: generate to stdout
> # from stderr: generate to stderr
> }
>
>