You wrote a script that took a filename as a parameter and it seemed to work, but then one time your script failed. The filename, it turns out, had an embedded blank.
You’ll need to be careful to quote any shell parameters that might contain filenames. When referring to a variable, put the variable reference inside double quotes.
Thanks a lot, Apple! Trying to be user friendly, they popularized the concept of space characters as valid characters in filenames, so users could name their files with names like My Report and Our Dept Data instead of the ugly and unreadable MyReport and Our_Dept_Data. (How could anyone possibly understand what those old-fashioned names meant?) Well, that makes life tough for the shell, because the space is the fundamental separator between words, and so filenames were always kept to a single word. Not so anymore.
So how do we handle this?
Where a shell script once had simply ls
-l $1
, it is better to write ls -l
"$1"
with quotes around the parameter. Otherwise, if the parameter has an
embedded blank, it will be parsed into separate words, and only part of
the name will be in $1
. Let’s show
you how this doesn’t work:
$ cat simpls.sh # simple shell script ls -l ${1} $ $ ./simple.sh Oh the Waste ls: Oh: No such file or directory $
When we don’t put any quotes around the filename as we invoke the script, then
bash sees three arguments and substitutes the first
argument (Oh) for $1
. The
ls command runs with Oh
as its only argument and can’t find that
file.
So now let’s put quotes around the filename when we invoke the script:
$ ./simpls.sh "Oh the Waste" ls: Oh: No such file or directory ls: the: No such file or directory ls: Waste: No such file or directory $
Still not good. bash has taken the three-word
filename and substituted it for $1
on
the ls command line in our script. So far so good.
Since we don’t have quotes around the variable reference in our script, however,
ls sees each word as a separate argument, i.e., as
separate filenames. It can’t find any of them.
Let’s try a script that quotes the variable reference:
$ cat quoted.sh # note the quotes ls -l "${1}" $ $ ./quoted.sh "Oh the Waste" -rw-r--r-- 1 smith users 28470 2007-01-11 19:22 Oh the Waste $
When we quoted the reference "${1}"
it was treated as a single word (a
single file-name), and the ls then had only one
argument—the filename—and it could complete its task.
Chapter 19 for common goofs
Appendix C for more information on command-line processing
13.58.216.74