Gnouc makes an important point without stressing it:
whenever you reference a shell variable ($identifier
, e.g., $futur
)
or a positional parameter ($digit
, e.g., $1
),
you should enclose it in double quotes
(e.g., "$1"
) unless you have a good reason not to
and you’re very sure you know what you’re doing.
Constant strings with no special characters (e.g., A
, foo
, or bar
)
don’t need to be quoted, but it doesn’t hurt.
Quoted strings can be concatenated and combined;
e.g., "foo""bar"
is equivalent to "foobar"
,
and A"$1"
is equivalent to "A""$1"
and hence "A$1"
.
Quotes preserve the existence of empty strings.
As Gnouc explains, if your script said
if ( $1 == "" )
and you invoke it without arguments,
LIST
or with an explicit empty string argument,
LIST ""
then the if
statement will be “expanded” as
if ( == "" )
which causes a syntax error.
Quotes preserve the integrity of strings with spaces or special characters.
If you invoke your script with an argument containing a space,
LIST "foo bar"
then the if
statement (if ( A$1 == A )
) will be expanded as
if ( Afoo bar == A )
which causes a syntax error.
Similar results happen if you invoke your script with an argument containing a quoted wildcard:
LIST "foo*"
But nobody has explained why the script doesn’t just say
if ( "$1" == "" )
In previous versions of csh
, if you invoke your script with this argument,
LIST ==
then the if
statement will be expanded as
if ( "==" == "" )
which also caused a syntax error.
People wrote their if
statements with protection for positional parameters
(and, when appropriate, shell variables / environment variables),
like A$1
or "A$1"
, to prevent arguments (operands) from looking like operators
(particularly /
, also +
, -
, and *
) and causing the parser to be confused.
This seems to have been fixed (at least in some versions of csh
/ tcsh
).
I just tried this in my (Cygwin’s) version of tcsh
:
$ if ( == == "" ) echo yes
if: Expression Syntax.
$ if ( == == == ) echo yes
if: Expression Syntax.
$ if ( "==" == "" ) echo yes
<--- (no output)
$ if ( "==" == "==" ) echo yes
yes
$ if ( / == / ) echo yes
Division by 0.
$ if ( "/" == "/" ) echo yes
yes
so,
- Quotes can tell the
if
command in tcsh
that an argument is an operand
and not an operator.
== ""
). I believe a null string is what triggers the( == "")
error you're mentioning in your answer (undefined variable, perhaps?). I don't know how things are handled by bash internally, so this is nothing more than an assumption. – John WH Smith Aug 28 '14 at 18:14LIST
andLIST ""
are going to be treated the same by any of the code currently on this page. Telling them apart requires looking at$#argv
(in csh) or$#
(in bash), or doing even trickier stuff that I won't get into here. – G-Man Says 'Reinstate Monica' Aug 28 '14 at 18:59