Strangeness in shell

Chris Torek chris at mimsy.UUCP
Mon Jul 24 16:25:08 AEST 1989


Pete Holsberg was going to summarise replies, but I have seen so many
partial and/or wrong answers on the net already that I feel I should
post this.

[Bourne shell]
>>	x='*z'
>>	echo ${x}
>>produces
>>	*z
>>but 
>>	x='* z'
>>	echo ${x}
>>produces
>>	(a list of all the files in the current directory) z

In article <53 at steven.COM> fawcett at steven.COM (fawcett) writes:
>The problem here is that the "set" of x stripped off the single quotes.
>This left only the *, which matches all occourances of one or more
>characters.  Why it looked in your directory for these files I don't know.

(One is tempted to ask, `if you do not know, why do you post?' :-) )  But
this answer is partly right, and the suggested fix (deleted) is correct.

>The fact that the *z echoed simply means that you don't have any files in
>your directory that end in the letter z.

Just so.

The complete answer to the original question can be found in the
manual for sh(1).  (Surprise!)  Perhaps we should have a look:

     Parameter substitution.
     The character $ is used to introduce substitutable parame-
     ters. ... Variables may be set by writing

	  name=value [ name=value ] ...

     ${parameter}
	  A parameter is a sequence of letters, digits or under-
	  scores (a name), a digit, or any of the characters * @
	  # ? - $ !.  The value, if any, of the parameter is sub-
	  stituted.  The braces are required only when parameter
	  is followed by a letter, digit, or underscore that is
	  not to be interpreted as part of its name. ...

     Blank interpretation.
     After parameter and command substitution, any results of
     substitution are scanned for internal field separator char-
     acters (those found in $IFS) and split into distinct argu-
     ments where such characters are found.  Explicit null argu-
     ments ("" or '') are retained.  Implicit null arguments
     (those resulting from parameters that have no values) are
     removed.

     File name generation.
     Following substitution, each command word is scanned for the
     characters *, ? and [. If one of these characters appears,
     the word is regarded as a pattern.  The word is replaced
     with alphabetically sorted file names that match the pat-
     tern.  If no file name is found that matches the pattern,
     the word is left unchanged.  The character . at the start of
     a file name or immediately following a /, and the character
     /, must be matched explicitly.

Now, note in particular the order of evaluation: parameter substitution
is done first (`${x}' is expanded), then blanks are interpreted (`z *'
becomes two distinct arguments while `z*' becomes one distinct argument),
then file names are generated (`*' becomes `all files except those
that start with `.'; `z*' becomes `all files that start with z'; if
neither expands at all, it remains as it was).

We need to read a bit further for solutions:

     Quoting.
     The following characters have a special meaning to the shell
     and cause termination of a word unless quoted.

	  ;   &   (   )   |   <   >   newline   space   tab

     A character may be quoted by preceding it with a \.  \new-
     line is ignored.  All characters enclosed between a pair of
     quote marks (''), except a single quote, are quoted.  Inside
     double quotes ("") parameter and command substitution occurs
     and \ quotes the characters \ ' " and $.

     "$*" is equivalent to "$1 $2 ..." whereas
     "$@" is equivalent to "$1" "$2" ... .

This means that we cannot use '$x' (since single quotes prevent
variable substitution), but we can use "$x" (since double quotes
do not).  This does, however, have the side effect of making the
expansion of $x a single `word' (since the expansion is surrounded
by double quotes, which quote space, tab, and newline, the default
IFS characters).

Quoting filename and/or shell metacharacters without quoting IFS
characters can be a bit of a challenge.  The solution to that remains
as an exercise for the student, as it were.  (Quoting IFS characters
is easy: simply change IFS.)
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris at mimsy.umd.edu	Path:	uunet!mimsy!chris



More information about the Comp.unix.questions mailing list