A path a script needs more than once is kept in a variable. A space in such a path breaks the command if you forget the quotes.
In backup-notes.sh the paths are stored in the variables src and dest. The count.sh script keeps the path to the old reports directory the same way and counts the files in it — there are three.
Count the files in a directory with a space
In ~/script-lab, print count.sh, run it with bash and check it with the shellcheck command.
First, predict
The «old reports» directory holds three files. Which number will bash count.sh print on its last line?
Now start the exercise, run the command and compare your prediction with the output.
The line dir="$HOME/script-lab/old reports" is an assignment: the variable's name, the = sign and the value. There are no spaces around =: with them, bash reads the line as a command. The quotes keep a value with a space in one piece. Without them, dir=$HOME/script-lab/old reports means something else: dir gets its value only for the duration of a command called reports, and bash answers reports: command not found.
$dir is an expansion: bash replaces it with the variable's value. In echo "Directory: $dir" the expansion sits inside double quotes, and the path came out whole. In find $dir there are no quotes: bash splits the expanded value at spaces into separate arguments, so find got …/old and reports. "$dir" in double quotes is the value as one argument. Hence the rule: expand a variable inside double quotes.
shellcheck is a program that looks for such spots in scripts. Its note SC2086 reads "Double quote to prevent globbing and word splitting", and the Did you mean line under it shows the fixed command.
A script has two lines: dest = /tmp/backup and echo "$dest". What does it print when run with bash?
-
echo prints the value of the
destvariable, and it never got one: the line with spaces is a command call, so echo prints an empty line. -
The line's syntax is fine — it is a call to the command
dest. bash looks for it, does not find it and writesline 1: dest: command not found. -
With spaces around
=the line calls a command nameddestwith the arguments=and/tmp/backup. There is no such command, the variable stays unset, and echo prints an empty line.
With spaces around = bash reads the line as a command dest with two arguments. There is no such command — dest: command not found — the variable stays empty, and echo prints an empty line.