bug-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Writing to /dev/stderr overwrites xtrace data


From: Andrew Church
Subject: Re: Writing to /dev/stderr overwrites xtrace data
Date: Thu, 31 Oct 2019 12:48:00 +0900

>    I enabled xtrace to try and debug a bash script running on a validation
>    server. The script stored its stdout and stderr to a log file. I expected
>    to see trace data in the log file, but instead found a single log 
> statement,
>    a bunch of NULL bytes, and the line '+ exit 1'. 

This is expected behavior given the your example script.

>echo "#!/usr/bin/env bash" > script.sh
>echo "set -o xtrace" >> script.sh
>echo "echo to_stderr > /dev/stderr" >> script.sh

This command causes the shell to open a new file descriptor for
/dev/stderr with the O_TRUNCATE flag, truncating the file to empty.

>chmod 755 script.sh
>./script.sh 2> stderr_output

Since the script is run with stderr redirected to a file, /dev/stderr
is a symbolic link to that file:

$ (stat -c%N /dev/stderr /proc/self/fd/2) 2>/tmp/stderr_output
'/dev/stderr' -> '/proc/self/fd/2'
'/proc/self/fd/2' -> '/tmp/stderr_output'

So the echo command in the generated script truncates the file
"stderr_output" before writing "to_stderr\n", and you lose any xtrace
log lines which were previously written.  Bash still has an open file
descriptor to stderr, which has its own seek position, so if you add
another command (like "exit 1") to the generated script after the echo,
the xtrace line generated by that command will be written at that
position in the file, with the intervening space filled by null bytes.

The solution is to use ">&2" rather than explicitly referencing
/dev/stderr.

  --Andrew Church
    http://achurch.org/



reply via email to

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