0

This is an extension to the question In a shell script: echo shell commands as they are executed.

So we have our command line echo'd either by using set -v (for verbose, before expansions), or set -x (for xtrace, after expansions); or both set -vx. Great.

My question is: how do we redirect those echo'd lines (to a file, for instance)?

If I run the following lines,

BLA='xyz'
set -v
echo $BLA > bla.log

, clearly, bla.log will contain 'xyz', not the echo 'echo $BLA > bla.log'.

I clearly need a better/depper understanding about the shell to see what is going on here; would appreciate very much a deeper explanation besides the 'howto redirect' solution.

Thanks

Brandt
  • 5,058
  • 3
  • 28
  • 46

2 Answers2

2

To send the xtrace output to somewhere else than stderr, you can set BASH_XTRACEFD to the number of an open file descriptor. E.g. this would direct the xtrace output to a file called xtrace:

$ exec 19>xtrace; BASH_XTRACEFD=19; set -x

(I pulled 19 out of a hat, you could use any fd number, provided it's not used to do something else)

ilkkachu
  • 6,221
  • 16
  • 30
  • 1
    In `bash` 4.1 or later, you can have the shell pick an unused descriptor for you: `exec {foo}>xtrace; BASH_XTRACEFD=$foo; set -x`. Starting in `bash` 4.3, you can shorten that to `exec {BASH_XTRACEFD}>xtrace; set -x`. (Note that 4.1 is needed for `BASH_XTRACEFD` anyway.) – chepner Jun 11 '17 at 22:52
1

The text printed as a result of set -x and set -v is being written to stderr. If you want all output to go to bla.log, just do:

exec > bla.log 2>&1
set -v 
echo bla 
William Pursell
  • 204,365
  • 48
  • 270
  • 300