100

For example, I have a simple bash file

#!/bin/bash
cd ~/hello
ls

How can I make it display every command before executing it? Just the opposite effect of "@echo off" in windows batch scripting.

codeforester
  • 115
  • 1
  • 1
  • 5
Epeius
  • 1,011
  • 2
  • 9
  • 6
  • 1
    For those looking for what the `set` options are, you can find them [on this man page](http://linuxcommand.org/lc3_man_pages/seth.html). – mkobit Oct 16 '15 at 16:41
  • You can simply extend shebang like this `#!/bin/bash -x` – sobi3ch Mar 22 '16 at 10:48

8 Answers8

127
bash -x script

or

set -x

in the script.

You can unset the option again with set +x. If you just want to do it for a few commands you can use a subshell: `(set -x; command1; command; ...;)

con-f-use
  • 103
  • 5
Steven Parkes
  • 1,385
  • 1
  • 9
  • 4
  • I have always used this to great effect. The output looks a little dirtier than you might first expect. – Scott Pack May 31 '09 at 13:51
  • 3
    By setting `PS4` you can tweak the prompt of `-x`. E.g.: `PS4='Line $LINENO @ $(date +%s.%N): ' bash -x script` (`date` will slow it down, though) – Walter Tross Nov 17 '14 at 11:15
25

These also work:

set -v

or

#!/bin/bash -v

But -v doesn't print the PS4 string before each script line and it doesn't trace the steps of a "for" statement (for example) individually. It does echo comments while -x doesn't.

Here's an example of the output using -v:

#!/bin/bash -v
# this is a comment
for i in {1..4}
do
    echo -n $i
done
1234echo

echo hello
hello

Here's the result of the same script with -x:

+ for i in '{1..4}'
+ echo -n 1
1+ for i in '{1..4}'
+ echo -n 2
2+ for i in '{1..4}'
+ echo -n 3
3+ for i in '{1..4}'
+ echo -n 4
4+ echo

+ echo hello
hello

Note that I included "echo -n" to add emphasis to the differences between -v and -x. Also, -v is the same as "-o verbose", but the latter seems not to work as part of a shebang.

Dennis Williamson
  • 60,515
  • 14
  • 113
  • 148
10

This should also work:

#!/bin/bash -x
cd ~/hello
ls
tomoe
  • 430
  • 2
  • 5
7

This should work:

set -o verbose #echo on
...
set +o verbose #echo off
splattne
  • 28,348
  • 19
  • 97
  • 147
5

set -o xtrace and set +o xtrace are your friends (it is more verbose, than -o verbose, and the output goes to STDERR, as opposed to verbose, which seems to log to STDOUT).

See more tips here

pihentagy
  • 273
  • 3
  • 7
4

There are a few ways.

#!/usr/bin/env bash -x

as the shebang line.

Including set -x in the script itself will enable the functionality while set +x will disable it. Both of these methods will also work with the more portable sh shell.

If I remember correctly perl also has the -x option.

user6784
  • 41
  • 1
1

goes like

language -x script

language = python, perl, bash -x = operator script = filename

hope it helps.

debuggerpk
  • 135
  • 2
0

#! /bin/bash -x does what you want.

Amandasaurus
  • 30,211
  • 62
  • 184
  • 246