TL;DR Add set -ex
on your second line to debug (But wait, there’s more)
The Basics
When you write a bash script at some point you are forced to solve a problem. First install shellcheck
to see if the script is made correctly and there are no obvious error.
Things will still not always five you the correct outcome, even when there are no error. Here is an example where you would want to show the files and directories of /tmp with the sub directories. The wrong code here is:
#!/bin/bash ShowDir () { ls -AlF "$DIR" } DIR=tmp ShowDir
So we run it and what do we get?
user@linux ~: script.sh ls: cannot access 'tmp': No such file or directory
So clearly something is something wrong. The answer is that it should be /tmp
and not tmp
. If this is a larger script, this can be hard to find as you have no idea what goes on. To see what goes on you add set -x as the second line on your script or set -ex. The -x will start showing things. The -e will stop when an error is seen
#!/bin/bash set -x ShowDir () { ls -AlF "$DiR" } DIR=tmp ShowDIr
The output now is
+ DIR=tmp + ShowDir + ls -AlF tmp ls: cannot access 'tmp': No such file or directory
So you now no only see the outcome, but also that it did ls -AlF tmp
and that DIR was tmp
not /tmp
as it should have been. This will already help you a lot with debugging.
More details
When you have a longer scrip, make it set -ex instead, so it stops when there is an error. That way yuu can see the last few lines and not let the script run on and on for a LONG time. That will make it hard to read.
You can send the output to a file with script.sh > script.log
to read later. But when you have a lot of functions, it can become a bit up and down. You will also want to know what line things happen and obviously you will want some color. (Well, perhaps not. I add it anyway). We change the script to
#!/bin/bash DEBUG=YES #### Start of debugging #### if [ "$DEBUG" == "YES" ] then txtbld=$(tput bold) # Bold txtgrn=$(tput setaf 2) # Green txtblu=$(tput setaf 4) # Blue txtoff=$(tput sgr0) # Text reset SPACES=$(printf "%$(tput cols)s") PS4='+${txtbld}\ ${txtgrn}${SPACES:0:$((5-${#LINENO}))}$LINENO \ ${txtblu}${FUNCNAME:-${SPACES:0:12}}${FUNCNAME:+${SPACES:0:$((12 - ${#FUNCNAME}))}}\ ${txtoff}' set -ex fi ##### End of debugging ##### # Start of the script ShowDir () { ls -AlF $DIR } DIR=tmp ShowDir
When you run it now, you see the colors. The first number you see is the line number. The second column is the function and the third the information.
+ 23 DIR=tmp + 24 ShowDir + 20 ShowDir ls -AlF tmp
Add this to every script you have and just change the DEBUG=YES
to DEBUG=NO
, or anything or comment it out and you have your standard script. Use it as a default for each new script.