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
?
The set -x
command prints tracing information to stderr
.
When you run this command...
ls /root &> stuff.txt
You're only redirecting stdout
and stderr
for the ls
command. You're not changing either for your current shell, which is where you have run set -x
.
As Mad Physicist points out, the technical answer is "it logs to BASH_XTRACEFD
", which defaults to stderr
. You can redirect trace logging for the current shell to another file by doing something like:
# open a new file descriptor for logging
exec 4> trace.log
# redirect trace logs to fd 4
BASH_XTRACEFD=4
# enable tracing
set -x
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:
$ command > /path/to/output.txt 2> /path/to/error.txt
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 because bash
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 of bash
directly. This can be done by the command
exec 2> /path/to/trace.txt
note: this will at the same time also contain all the error output of any command executed in the script.
Examples:
#!/usr/bin/env bash
set -x
command
This sends all output and error output to the terminal
#!/usr/bin/env bash
set -x
command 2> /path/to/command.err
This sends the output of command
and the trace of bash to the terminal but catches the error output of command
in a file
#!/usr/bin/env bash
set -x
exec 2> /path/to/trace.err
command 2> /path/to/command.err
This sends the output of command
to the terminal, the error output of command
to a file, and the trace of the script to /path/to/trace.err
#!/usr/bin/env bash
set -x
exec 2> /path/to/trace_and_command.err
command
This sends the output of command
to the terminal, the trace and the error of command
to a file.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With