It can't be over-emphasized how important it is to wrap expansions, such asĀ $myvar, ${myvar[1]}, and ${myvar##*/}, in double quotes. Failing to do this will lead to bugs down the line when values contain characters that have special meaning to Bash, especially spaces. This is a common problem with code that has been cut and pasted from old documentation, or from bad advice posted on websites or in chat channels.
It only takes a few examples to realize how dangerous a failure to quote properly can be, especially in circumstances where files can be created by other users, and hence might include shell metacharacters. A file named *, for example, is legal, and if expanded incorrectly, can wreak havoc on your scripts:
$ cd ~/important $ myfilename='*' $ echo $myfilename important-document passwords-DO-NOT-DELETE anniversary-plans $ echo "$myfilename" *
Imagine what might have happened if the first echo command here had beenĀ rm in a script instead!
In a few contexts in Bash, an expansion does not strictly require double quotes; none of these cases of myvar here require double quotes, due to their syntactic context:
newvar=$myvar case $myvar in ... [[ $myvar = "$othervar" ]]
However, adding double quotes in each of these cases does not do any harm, either:
newvar="$myvar" case "$myvar" in ... [[ "$myvar" = "$othervar" ]]
Similarly, watch for cases where you need more than one pair of nested quotes:
touch -- "$(basename -- "$filename")"
This might seem strange to those coming from other programming languages; it looks as if the two different sets of double quotes are mismatched. However, because one pair of quotes is inside a command substitution, the double quotes around it don't interfere with the expansion within it.
In summary, if you're in doubt about any given expansion: quote it!
You may occasionally run into objections of this sort: I don't allow files with spaces or asterisks in their names on my system, so I don't need to quote. Don't listen! Always use quoting to make your scripts safer and more robust.