If I set -x
in my bash session ( v4.1.2(2) – CentOS 6.10), I get :
$ ls /root
+ ls --color=auto /root
ls: cannot open directory /root: Permission denied
Great, it echo’s the command I ran and prints out the terminal. This is expected. Now if I redirect both stdout
and stderr
to the another file.
$ ls /root &> stuff.txt
+ ls --color=auto /root
It still prints the command to the terminal.
QUESTION
Where is set -x
having bash print to if it isn’t stderr
or stdout
?
2
Answers
The
set -x
command prints tracing information tostderr
.When you run this command…
You’re only redirecting
stdout
andstderr
for thels
command. You’re not changing either for your current shell, which is where you have runset -x
.As Mad Physicist points out, the technical answer is “it logs to
BASH_XTRACEFD
“, which defaults tostderr
. You can redirect trace logging for the current shell to another file by doing something like:When you execute a command, you can redirect the standard output (known as
/dev/stdout
) of the command directly to the file. Also if the command generates error-output (generally send to/dev/stderr
) you can also redirect it to a file as:When you execute the command
set -x
, you ask it to generate a trace of the commands being executed. It does this by sending messages to/dev/stderr
. In contrast to a normal command, you cannot easily redirect this in a similar way as with a normal command. This is becausebash
executes the script and at the same time generates the trace to/dev/stderr
. So if you would like to catch the trace, you would have to redirect the error output ofbash
directly. This can be done by the commandnote: this will at the same time also contain all the error output of any command executed in the script.
Examples:
This sends all output and error output to the terminal
This sends the output of
command
and the trace of bash to the terminal but catches the error output ofcommand
in a fileThis sends the output of
command
to the terminal, the error output ofcommand
to a file, and the trace of the script to/path/to/trace.err
This sends the output of
command
to the terminal, the trace and the error ofcommand
to a file.