Here is the list of all the Bash debugging posts:
This debugging tool is useful in your Bash scripts and also in any Bash one-liners that you write.
The echo
tool will print any input you give it. Most importantly, it will not execute any commands that are included in the input you give it but it will expand variables, wildcards, etc to show you everything that would happen when you run that command.
The following Bash script will create 5 directories in a for
loop:
#!/bin/bash
for i in {1..5}; do
mkdir "$i"
done
Or as a one-liner:
for i in {1..5}; do mkdir "$i"; done
Both the script and the one-liner will execute silently by default and create the 5 directories. If you are making significant changes to or including rm
in your script then it is always useful to see exactly what the script will do before you run it.
Simply insert echo
before the command (mkdir
) and echo
will print everything that will happen, e.g.:
#!/bin/bash
for i in {1..5}; do
echo mkdir "$i"
done
Or
for i in {1..5}; do echo mkdir "$i"; done
These now do the following:
$ for i in {1..5}; do echo mkdir $i; done
mkdir 1
mkdir 2
mkdir 3
mkdir 4
mkdir 5
Crucially, the mkdir
is not executed, and no changes are made to your system, but you can see every command that would have been executed.
This becomes a very healthy sanity check in case you make a typo or populate a variable with something problematic.
Take, for example, the following script (DO NOT RUN THIS SCRIPT!!!):
#!/bin/bash
DIRS="/ working/tmp"
rm -rf "$DIRS"
If you run this script as root the space in the variable, "/ working/tmp"
will delete your entire filesystem.
This is because Bash will parse the space as indicating two directories to delete recursively and run the following two commands rm -rf /
and rm -rf working/tmp
. Executing rm -rf /
will start at the root of your filesystem and proceed to delete everything.
It’s obvious in this short scrip but can be much less obvious in a long script especially where variables are populated from the system or another script.
Changing this script, on a test run, to:
#!/bin/bash
DIRS="/ working/tmp"
echo rm -rf "$DIRS"
Will quickly let you know exactly which directories will get deleted without actually deleting anything.