Originally published July 7, 2016 @ 11:10 am

Unlike most other popular scripting languages, Bash has few style-checking utilities. The best one, I think, is ShellCheck – a very cool and useful utility that can greatly  enhance robustness of your scripts. Like that time a Windows user dropped a file with a line break in the name into an SMB share and my backup script exploded all over that filesystem. I could have avoided that unfortunate experience if I had shellcheck to tell me to use read -r and to double-quote just about everything that can be double-quoted.

You can try shellcheck on their site or install it on your local box. Installation is pretty straight-forward for some platforms, but CentOS/RHEL require some finagling. In a nutshell, you need to install Dev tools group and Haskell compiler:

cd /tmp
# Install EPEL
wget http://download.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
rpm -ivh epel-release-6-8.noarch.rpm

# Install Dev tools
yum groupinstall "Development Tools" -y
yum install gmp-devel -y
sudo ln -s /usr/lib64/libgmp.so.3  /usr/lib64/libgmp.so.10

# Download and install Haskell
dir="$(mktemp -d)"
pushd "$dir"
wget https://haskell.org/platform/download/7.10.2/haskell-platform-7.10.2-a-unknown-linux-deb7.tar.gz
tar xvzf haskell-platform-7.10.2-a-unknown-linux-deb7.tar.gz
./install-haskell-platform.sh
popd
rm -r "$dir"

# Install ShellCheck
cabal install shellcheck

# Link shellcheck in /usr/bin
cp .cabal/bin/shellcheck /usr/local/bin

Example:

(root:ncc1701)-(bg:0)-(/var/adm/bin)# shellcheck syscheck.sh

In syscheck.sh line 17:
        this_time=$(date -d "${this_time_db}" +'%Y-%m-%d_%H:%M:%S')
        ^-- SC2034: this_time appears unused. Verify it or export it.


In syscheck.sh line 25:
        this_host_mask=$(/sbin/ifconfig | grep ${this_host_ip} | sort -u | tail -1 | awk -F':' '{print $4}' | awk '{print $1}')
                                               ^-- SC2086: Double quote to prevent globbing and word splitting.

In syscheck.sh line 31:
        this_host_nic=$(/sbin/ifconfig | cut -c1-8 | egrep "[a-z]" | grep -v ^lo | while read nic ; do if [ `/sbin/ifconfig ${nic} | grep -c ${this_host_ip}` -gt 0 ] ; then echo "${nic}" ; break ; fi ; done)
                                                                                         ^-- SC2162: read without -r will mangle backslashes.
                                                                                                            ^-- SC2046: Quote this to prevent word splitting.
                                                                                                            ^-- SC2006: Use $(..) instead of legacy `..`.
                                                                                                                            ^-- SC2086: Double quote to prevent globbing and word splitting.
                                                                                                                                             ^-- SC2086: Double quote to prevent globbing and word splitting.