How to echo shell commands as they are executed

It is helpful to have a log of the shell commands being executed. It is also a bonus to have the variables expanded and shown. Here're two options to do this.

Option 1

We can use set -x or set -o xtrace in a shell script. This will expand variables and print '+' before the line. Use set +x to turn off this behavior. Here's an example shell script named script.sh:

main.php
script.sh
#!/bin/sh
set -x
ls $PWD;
echo 'Hello world';
set +x;
ls $PWD;

The main.php function runs script.sh and is not the focus of this Answer. However, here's a brief explanation for it:

  • Line 4: Remove the "\r" Windows line-endings from script.sh so that the script can have multiple lines for easier reading.
  • Line 6: Run the script.sh which echoes the output.

Here is what script.sh does:

  • Line 2: Any command after this line will be printed after an '+' and all variables will be expanded.
  • Line 3: We list the files and directories in the PWD variable, which is the current working directory.
  • Line 4: We print Hello world.
  • Line 5: After this line, commands won't be printed anymore.
  • Line 6: Same as in line 3, but we expect the command not to be echoed.

Let's execute the widget. What can we see?

There are two boxes. The red bordered box is the output of the set command and the other box with no border is the output of the other commands.

No border box output:

  • The first ls $PWD command lists the files in the current directory.
  • The Hello world is the result of the echo Hello World command.
  • The second ls $PWD command also lists the files in the current directory.

Red border box output:

  • Commands after set -x until set +x are printed with a '+' prefix. The lines printed include:
    • + ls /usercode . The $PWD is expanded to /usercode.
    • + echo Hello world
    • + set +x . Notice how the second ls command that comes after this line is not printed.

Option 2

We can also use set -v or set -o verbose. However, that doesn't expand the variables. Use set +v to turn off this behavior. We take the previous script and replace lines 2 and 6 with the new commands, as highlighted:

main.php
script.sh
#!/bin/sh
set -v;
ls $PWD;
echo 'Hello world';
set +v;
ls $PWD;

Let's execute the widget. What can we see?

Again, there are two boxes. The red bordered box is the output of the set command and the other box with no border is the output of the other commands.

No border box output:

  • The first ls $PWD command lists the files in the current directory.
  • The Hello world is the result of the echo Hello World command.
  • The second ls $PWD command also lists the files in the current directory.

Red border box output:

  • Commands after set -v until set +v are printed without a prefix. The lines printed include:
    • ls $PWD; . This time, the $PWD is not expanded.
    • echo 'Hello world';
    • set +v; . Notice how the second ls command that comes after this line is not printed.

Free Resources