Understanding Bash Script Debugging: What Does #!/bin/bash -xe Do?


2 views

When you see #!/bin/bash -xe at the top of a shell script, you're looking at two powerful debugging options combined:

-x  # Print commands and their arguments as they are executed (xtrace)
-e  # Exit immediately if a command exits with non-zero status (errexit)

Consider this example script with -xe enabled:

#!/bin/bash -xe

echo "Starting process..."
mkdir /tmp/test_dir
cd /tmp/test_dir || exit
touch sample_file.txt
ls -l
rm sample_file.txt
cd ..
rmdir /tmp/test_dir
echo "Process completed"

When running this script:

  • -x will print each command before execution with expanded arguments
  • -e will cause the script to abort if any command fails (non-zero exit status)

These flags are particularly useful for:

  • CI/CD pipelines where you need visibility into script execution
  • Troubleshooting complex deployment scripts
  • Ensuring scripts fail fast when errors occur

You can also enable these options within the script body:

#!/bin/bash
set -xe

# Rest of your script...

These options are documented in the bash man page under "SHELL BUILTIN COMMANDS" for set:

  • man bash → search for "set [-abefhkmnptuvxBCEHPT]"
  • GNU Bash manual section on "The Set Builtin"

While extremely useful for debugging, be cautious about:

  • Exposing sensitive information through command echoing (-x)
  • Overusing -e in scripts where you expect and handle certain failures

When you see #!/bin/bash -xe at the top of a shell script, these two flags modify how Bash executes your script:


#!/bin/bash -xe
# -x : Print commands and their arguments as they are executed
# -e : Exit immediately if a command exits with a non-zero status

Let's examine how these flags behave in different scenarios:


#!/bin/bash -xe

# Example 1: -x showing command execution
echo "Starting script"
ls /nonexistent_directory  # This will fail
echo "This line won't execute because of -e"

The combination is particularly useful for:

  • Debugging scripts (thanks to -x)
  • Ensuring script fails fast when errors occur (-e)
  • CI/CD pipelines where you want strict error checking

You can also enable these flags within the script:


#!/bin/bash

set -xe  # Equivalent to using them in shebang

# Rest of your script...

While powerful, these flags have some caveats:


#!/bin/bash -xe

# Problem case: -e with commands that use exit codes
grep "pattern" file.txt || true  # Workaround for commands with expected failures

These flags are documented in the Bash man page:

  • -x: "Print a trace of simple commands"
  • -e: "Exit immediately if a pipeline returns non-zero"