bug-bash
[Top][All Lists]
Advanced

[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
>



reply via email to

[Prev in Thread] Current Thread [Next in Thread]