[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: BASH_XTRACEFD=1 read variable stdout flushing?
From: |
Emanuele Torre |
Subject: |
Re: BASH_XTRACEFD=1 read variable stdout flushing? |
Date: |
Mon, 16 Jan 2023 20:48:20 +0100 |
Oops.
> And there is no reason to not use it since any bash version that
> supports BASH_XTRACEFD, also supports {var}<&fd syntax.
Of course, I meant to say that there is no reason to use BASH_XTRACEFD=1
over exec {BASH_XTRACEFD}<&1 .
I forgot to change this paragraph after moving the suggestion of using
exec {BASH_XTRACEFD}<&1 to the bottom.
emanuele6
On 16/01/2023, Emanuele Torre <torreemanuele6@gmail.com> wrote:
> On Mon, Jan 16, 2023 at 11:36:18AM -0600, dave.drambus@gmail.com wrote:
>> Description:
>>
>> I have `set -x` and `BASH_XTRACEFD=1` set in a simple script that I have
>> in
>> a cron job. I'd like to see the progress of the script when run
>> manually,
>> hence `set -x`, but I want the output to go to stdout rather than stderr
>> so
>> that cron emails me only when there is an actual failure. With this
>> configuration, the `read` command is erroneously reading the "+" prompt
>> output from `set -x` into the variable. It seems like stdout is not
>> getting
>> flushed propertly.
>
> BASH_XTRACEFD=something is generally not what people want, but it is a
> very common bad pattern people use.
>
> And there is no reason to not use it since any bash version that
> supports BASH_XTRACEFD, also supports {var}<&fd syntax.
>
> Problems with BASH_XTRACEFD=fd:
> 1. Assignments to BASH_XTRACEFD are special, the old value of
> BASH_XTRACEFD implictly gets closed when a new value is assigned to
> it.
> If you e.g. use
>
> #!/bin/bash --
> BASH_XTRACEFD=2
> set -x
> cmd # xtrace behaves like normal, output to stderr (2)
> exec 3> log
> BASH_XTRACEFD=3 # this line sets XTRACEFD to 3, but also closes 2
> cmd # xtrace output written to ./log
> BASH_XTRACEFD=2 # this sets XTRACEFD back to 2, it also
> # implictily closes 3
> cmd # stderr (2) is closed, so there is no xtrace
> # output even if set -x is on
>
> Not your problem, but a common pitfall nonetheless.
>
> 2. BASH_XTRACEFD tells xtrace what fd to write to. BASH_XTRACEFD=1 is
> not interpreted as "write xtrace to the current stdout", but as
> "write xtrace to stdout, whatever stdout is at the time of writing".
> In the case of stdout, this will break stuff like $() or |, etc. as
> you can observe with your problematic script. Unless you do not
> actually want to capture stdout output, do not use BASH_XTRACEFD=1.
>
> Instead, just use exec {BASH_XTRACEFD}<&1 that assigns to
> BASH_XTRACEFD a file descriptor that is a dup of 1.
>
> #!/bin/bash --
> exec {BASH_XTRACEFD}<&1
> set -x
> ...
>
> This way 1) the dup gets closed instead of stdout when BASH_XTRACEFD is
> reassigned/unset; 2) stuff like $() or | redirecting stdout doesn't
> affect xtrace.
>
> Cheers.
> emanuele6
>