[comp.unix.wizards] Csh/sh bug or feature?

dave@sdeggo.UUCP (David L. Smith) (01/12/88)

I was playing around with csh the other day and noticed something rather
interesting.  In the string returned by a program called through the
backquotes quotes are ignored, and filename expansion is attempted 
when the variable is set unless noglob is set.  This also happens in sh 
(except, of course, that noglob doesn't exsist in sh).

For example (with csh), if foo contained:

'this is * '

(with the quotes and everything)
and I do:

set foo=`cat foo`

echo $foo returns:
'this is (and here is the contents of the directory I was in when I did the
set)

if I then set noglob, and echo foo again, I get the same thing.
However, if I had done instead

set foo='this is *'

echo $foo gives:
'this is (and the contents of my _current_ directory)

set noglob and echo $foo returns:

'this is *'

The question is, is there any reason for them to be treated differently?  It 
seems as if it would be beneficial for the output to be directly substituted 
for the `` string and be subject to the same rules as if it had been in the 
file all along. 
-- 
David L. Smith
{sdcsvax!jack,ihnp4!jack, hp-sdd!crash, pyramid}!sdeggo!dave
sdeggo!dave@amos.ling.edu 
Sinners can repent, but stupid is forever.

ok@quintus.UUCP (Richard A. O'Keefe) (01/13/88)

In article <170@sdeggo.UUCP>, dave@sdeggo.UUCP (David L. Smith) writes:
> when the variable is set unless noglob is set.  This also happens in sh 
> (except, of course, that noglob doesn't exsist in sh).
It does.  Use
	set -f
Just about every non-trivial shell script I write these days uses it.

shankar@hpclscu.HP.COM (Shankar Unni) (01/14/88)

/ hpclscu:comp.unix.wizards / dave@sdeggo.UUCP (David L. Smith) / 11:56 pm  Jan 11, 1988 /

Oh yes, this is how it is supposed to work.

the `command` syntax evaluates "command" on the spot. It is analogous to the
eval command (which performs a complete globbing). So `cat foo` will read
foo, and then evaluate the wild cards which were in it. Thus the * gets
evaluated right away. On the other hand, setting the var to 'this is *'
prevents the * from being evaluated right away, because it is protected by the
single quotes. It is evaluated only when you do the echo, because by then it is
unprotected by the quotes.

schaefer@ogcvax.UUCP (Barton E. Schaefer) (01/15/88)

In article <sdeggo.170> dave@sdeggo.UUCP (David L. Smith) writes:
>I was playing around with csh the other day and noticed something rather
>interesting.
>
>For example (with csh), if foo contained:
>
>'this is * '
>
>(with the quotes and everything)

So far so good ...

>and I do:
>
>set foo=`cat foo`
>
>echo $foo returns:
>'this is (and here is the contents of the directory I was in when I did the
>set)
>
>if I then set noglob, and echo foo again, I get the same thing.

Assuming that the directory started with two files named "file1" and "file2"
(for example), I take it this means you did something like:

% cat > foo
'this is * '
^D
% set foo=`cat foo`
% echo $foo
'this is file1 file2 foo '
% set noglob
% echo $foo
'this is file1 file2 foo '

Try looking at the output of "set" (no arguments), which shows all variable
settings.  You will see that the * was expanded during execution of the
    set foo=`cat foo`
command.  By the time you are doing the second echo there is no * to be
globbed.

% set
noglob
foo	('this is file1 file2 foo ')

(Other variable settings omitted for clarity.)  Note the parentheses around the
value of "foo".  This means that the value is a WORDLIST, not a single word.

% echo $#foo
6

The 6 words in the word list are:
    (1) 'this
    (2) is
    (3) file1
    (4) file2
    (5) foo
    (6) '

Note that the single quotes (') are treated as "ordinary" characters,
and the `` substitution causes the result of the command to be broken into
words at spaces, tabs, and newlines.  If you don't want this to happen, you
should do:

% set foo="`cat foo`"

(Note the double quotes outside the back quotes.)  This prevents breaking into
words at spaces and tabs, but newlines still cause breaks.  The double quotes
also prevent filename substitution from affecting the result of the ``.

>It
>seems as if it would be beneficial for the output to be directly substituted 
>for the `` string and be subject to the same rules as if it had been in the 
>file all along. 

When you consider that `` can be used to execute almost ANY command (careful
of those that produce LOTS of output!), not just "cat" of a file, you can see
why you might want filename substitution on the output.  However, the reason
that this happens comes from the order that the csh does its substitutions:
    (1) History substitution		!
    (2) Quotations			" and '
    (3) Alias substitution
    (4) Variable substitution		$ and colon modifiers
    (5) Command substitution		`
    (6) Filename substitution		[] ? and *
Note that quotations are looked for BEFORE command substitution, but that
filenames are not expanded until AFTER command substitution.  That's why the
quotes in the file do not protect the * from being expanded.

>David L. Smith
>Sinners can repent, but stupid is forever.

Well, then, we'll give you the benefit of the doubt and say that you "sinned"
by not reading the csh manual ....

-- 
Bart Schaefer			CSNET:	schaefer@cse.ogc.edu
				UUCP:	...{tektronix,verdix}!ogcvax!schaefer
"A band of BIG, DUMB, LOUDMOUTHED, BUNGLING OGRES is a GREAT ASSET to the
neighbohood.  It keeps out the RIFF-RAFF."		-- Wormy