```html
How to Enable Command Echoing in Bash Scripts
By default, bash scripts execute commands without displaying them in the terminal output. For debugging or logging purposes, you might want to see each command before it's executed.
#!/bin/bash
cd ~/project
ls -la
The most straightforward way is to use the set -x
command at the beginning of your script:
#!/bin/bash
set -x
cd ~/project
ls -la
This will produce output like:
+ cd ~/project
+ ls -la
You can also enable tracing directly in the shebang line:
#!/bin/bash -x
cd ~/project
ls -la
To enable tracing for specific sections only:
#!/bin/bash
# Normal execution
cd ~/project
# Enable tracing
set -x
ls -la
complex_command
set +x
# Back to normal execution
another_command
Customize the trace output prefix using PS4:
#!/bin/bash
export PS4='+ ${BASH_SOURCE}:${LINENO}: '
set -x
cd ~/project
ls -la
Here's a more complete example showing how this works in a real script:
#!/bin/bash -x
# Configuration
LOG_DIR="/var/log/myapp"
CONFIG_FILE="/etc/myapp.conf"
# Create log directory if not exists
[ -d "$LOG_DIR" ] || mkdir -p "$LOG_DIR"
# Verify config exists
if [ ! -f "$CONFIG_FILE" ]; then
echo "Config file missing" >&2
exit 1
fi
# Process config
source "$CONFIG_FILE"
- Debugging complex scripts
- Understanding script flow during development
- Creating verbose logs for auditing
- Troubleshooting scripts run by other users
- Use
set -x
temporarily during debugging - Consider removing it before production deployment
- Combine with
set -e
for better error handling - Use selective tracing for large scripts
When debugging bash scripts or demonstrating script behavior, it's often helpful to see each command before it executes. This is particularly useful in:
- Debugging complex scripts
- Documenting script execution flow
- Teaching bash scripting concepts
- Auditing script behavior
The simplest way to enable command echoing is by using the -x
option:
#!/bin/bash -x
cd ~/hello
ls
Alternatively, you can set it within the script:
#!/bin/bash
set -x # Enable command echoing
cd ~/hello
ls
set +x # Disable command echoing
The PS4
variable controls the prompt prefix for traced commands. Customize it for better debugging:
#!/bin/bash
PS4='+ $BASH_SOURCE:$LINENO: '
set -x
cd ~/hello
ls
For finer control over which commands get echoed:
#!/bin/bash
echo "About to change directory" >&2
cd ~/hello || exit 1
# Only echo the ls command
(set -x; ls)
echo "Done listing contents" >&2
For comprehensive debugging, combine with other options:
#!/bin/bash
set -exo pipefail
# -e: Exit on error
# -x: Print commands
# -o pipefail: Catch pipeline errors
cd ~/hello || exit 1
ls | wc -l
Here's how this applies to a practical build script:
#!/bin/bash -x
# Build and deploy script with full tracing
BUILD_DIR="dist"
SRC_DIR="src"
clean() {
rm -rf "$BUILD_DIR"
}
build() {
mkdir -p "$BUILD_DIR"
cp -r "$SRC_DIR"/* "$BUILD_DIR/"
minify "$BUILD_DIR"/*.js
}
deploy() {
scp -r "$BUILD_DIR" user@server:/var/www/
}
clean
build
deploy
- Use
set -x
temporarily during debugging - Consider adding a debug flag to your scripts:
[[ $DEBUG ]] && set -x
- Redirect trace output to stderr:
exec 2>&1
- Be mindful of sensitive information in echoed commands
If command echoing isn't working as expected:
- Check if another part of the script uses
set +x
- Verify the script has execute permissions
- Ensure you're not redirecting stderr where traces go