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"