Christian Mayer's Weblog

Do not put everything into Bash Variables

The bash tips drawings by Julia Evans caused me to test all my Bash scripts using ShellCheck.

I found good tips how to programm better Bash scripts.

Except for always quote your variables:

$ shellcheck script.sh 

In script.sh line xyz:
sudo $RM $dir
     ^-- SC2086: Double quote to prevent globbing and word splitting.

I changed this without thinking about it to

sudo "$RM" $dir

This is bad because RM looked like this: RM="rm -rfd".

Running the script then caused this error:

sudo: rm -rfd: command not found

The programm Bash like to execute in this case is rm -rfd. But there is no programm called rm -rfd. The programm to execute is rm. Not rm -rfd. -rfd are only programm arguments. A better way could be this:

RM="rm"
RM_OPTS="-rfd"
...
sudo "${RM}" ${RM_OPTS} $dir

Note that ${RM_OPTS} has no quotes. Otherwise it would not work with RM_OPTS="-r -f -d" and double-quoted ${RM_OPTS} like this: sudo "${RM}" "${RM_OPTS}" $dir. It’s the same problem. This would cause Bash to give -r -f -d as one single argument. But rm like to have each argument separated.

Anyway, unless you need it that complex do not do it.

I changed everything to like this:

sudo rm -rfd "$dir"

It always depends on the usecase:

git add $files

While files is a string with multiple files like file1 file2, I do not want to double quote $files. Each file must be a separate argument.

If you have a Git Commit Message in a variable you want double quotes:

msg="This is my commit message."
git commit -m "$msg"

My conclusion about this: always quote your variables is not for general usage. It’s a good approach for some variables holding paths, but it always depends on the usecase. You should not pack too much stuff into variables. Even if there are many usages and duplicate code. Keep it simple.

Posted on by Christian Mayer.
Categories: Programming. Tags: Shell, Bash, Script.

Imprint | Usage | Archive | Categories | Feed
Copyright © 2006 by