[comp.unix.shell] weird csh thing

bagchi@eecs.umich.edu (Ranjan Bagchi) (01/06/91)

anyone care to explain??  (I`m in csh)


$ set p = "w | tail +3 "
$ echo $p
w | tail +3
$ $p
Usage: w [ -hlsuw ] [ user ]
$ w | tail +3
benjo    ttyp3    10:13pm           41      4  -sh 
benjo    ttyp4    10:17pm         3:22      4  -csh 
$ exit
$ exit

Process shell finished


shouldn't "$p" have the same effect as "w | tail +3" ?

	-rj
--
--------------------------------------------------------------------------------
Ranjan Bagchi - At Large.  Well Kinda.  |  what kind of person
bagchi@[eecs                            |  would want to count syllables
        caen,                           |  just to write haiku?
	math.lsa].umich.edu     	|  
--------------------------------------------------------------------------------

boehme@unvax.union.edu (Eric M. Boehm) (01/07/91)

bagchi@eecs.umich.edu (Ranjan Bagchi) writes:

>$ set p = "w | tail +3 "
>$ echo $p
>w | tail +3
>$ $p
>Usage: w [ -hlsuw ] [ user ]
>$ w | tail +3
>benjo    ttyp3    10:13pm           41      4  -sh
>benjo    ttyp4    10:17pm         3:22      4  -csh
>$ exit
>$ exit

>shouldn't "$p" have the same effect as "w | tail +3" ?

No, it should not. It has to do with the way the C Shell parses the
command line. The following is taken from "The UNIX C Shell Field
Guide, Gail Anderson, Paul Anderson, Prentice Hall, 1986, ISBN
0-13-937468-X", pages 262-266. (I highly recommend it).

1. History substitution - i.e.,interpret ! and ^.
2. Finding words - character strings delimited by blanks or tabs.
   Treat special characters &, |, ;, >, <, (, ), &&, ||, >>, << as words
   unless quoted.
3. Update the history list - after breaking command into words, put on
   history list.
4. Parse sequence of words in the following order:
   a. Quoting with ' and "
   b. Alias substitution
   c. I/O redirection, background execution, and pipes (recognized but
      not processed)
   d. Variable substitution
   e. Command substitution
   f. Filename expansion
5. Execute each command

Relevant to your example:
% set out = '>> ~/vault/words'
% cat dict1 >> ~/vault/words # try to replace with the following
% cat dict1 $out
[contents of dict1 appear here]
cat: cannot open >>

"What went wrong? We wanted the C shell to expand $out to specify
redirection. Unfortunately, since it has already handled redirection,
it simply passes >> to the cat command as a filename argument. Note
the importance of knowing precedence here."

"The C shell executes a subshell to process command substitution; that
is, the instance of the C shell that parses the command substitution
is distinct from the one that evaluates the text inside command
substitution marks."

In your case, since the shell has already handled redirection, it
passes | to w as an argument.
--
Eric M. Boehm
boehme@unvax.Union.EDU
BOEHME@UNION.BITNET

mju@mudos.ann-arbor.mi.us (Marc Unangst) (01/08/91)

bagchi@eecs.umich.edu (Ranjan Bagchi) writes:
> $ set p = "w | tail +3 "
[...]
> shouldn't "$p" have the same effect as "w | tail +3" ?

No.  The pipe character is not interpreted specially by the shell when
you run "$p"; therefore, you are calling the "w" command with the
arguments "|", "tail", and "+3".

Try "eval $p".

--
Marc Unangst               |
mju@mudos.ann-arbor.mi.us  | "Bus error: passengers dumped"
...!umich!leebai!mudos!mju | 

fpb@ittc.wec.com (Frank P. Bresz) (01/08/91)

In article <BAGCHI.91Jan6000722@snarf.eecs.umich.edu> bagchi@eecs.umich.edu (Ranjan Bagchi) writes:

>anyone care to explain??  (I`m in csh)

>$ set p = "w | tail +3 "
>$ echo $p
>w | tail +3
>$ $p
>Usage: w [ -hlsuw ] [ user ]
>$ w | tail +3
>benjo    ttyp3    10:13pm           41      4  -sh
>benjo    ttyp4    10:17pm         3:22      4  -csh
>$ exit
>$ exit

>Process shell finished

>shouldn't "$p" have the same effect as "w | tail +3" ?

>	-rj

Well,
	I'll take a shot at an explanation.

	By saying:

		set p = "w | tail +3 "

	You have effectively escaped the normal behavior of | which is to
run a pipe to the next command in line.  Thereby passing the | to the 'w'
command as the first argument.  'w' does not understand what the '|'
symbol means so it spits out it's usage command.  This command shows what I
mean:

ittc% w \| tail +3
Usage: w [ -hlsuw ] [ user ]

	Had you instead said :

	eval $p

	You would have received the 'w' portion only the 'tail' would not
execute,  (at least it didn't under my csh SunOS4.1, why I don't know).
This scenario worked for both bash and sh.

$ p="w | tail +3"
$ $p
Usage: w [ -hlsuw ] [ user ]
$ eval $p
fpb      console  12:44pm  6:15   9:32   9:27  sv_xv_sel_svc
young    ttyh5    12:40pm  5:54                telnet wssi3
young    ttyha    11:29am  6:46      5      5  telnet wssi3
miller   ttyhc     2:33pm  3:33      3         -csh
fpb      ttyp0    12:44pm    28                /emacs/sun4/etc/bash
fpb      ttyp3     6:26pm            9      1  w
mance    ttyp9     3:10pm  3:49                -


	In CSH however I tried and received : 


ittc% set p = " w | tail +3 "
ittc% $p
Usage: w [ -hlsuw ] [ user ]
ittc% echo $p
w | tail +3
ittc% eval $p
  7:03pm  up 2 days, 12:04,  6 users,  load average: 1.60, 2.24, 2.05
User     tty       login@  idle   JCPU   PCPU  what
fpb      console  12:44pm  6:19   9:45   9:40  sv_xv_sel_svc
young    ttyh5    12:40pm  5:58                telnet wssi3
young    ttyha    11:29am  6:50      5      5  telnet wssi3
miller   ttyhc     2:33pm  3:37      3         -csh
fpb      ttyp0    12:44pm    32                /emacs/sun4/etc/bash
fpb      ttyp3     6:26pm           10      1  w
mance    ttyp9     3:10pm  3:54                -
ittc%

	Clearly the tail failed.  Any CSH wizards know why.  I received
bash about 4 months ago and haven't touched csh since.  Out of pure
inquisitiveness what is wrong with : 

	alias p "w | tail +3"
	p
--
| ()  ()  () | Frank P. Bresz   | Westinghouse Electric Corporation
|  \  /\  /  | fpb@ittc.wec.com | ITTC Simulators Department
|   \/  \/   | uunet!ittc!fpb   | Those who can, do. Those who can't, simulate.
| ---------- | +1 412 733 6749  | My opinions are mine, WEC don't want 'em.

allbery@NCoast.ORG (Brandon S. Allbery KB8JRR) (01/08/91)

As quoted from <BAGCHI.91Jan6000722@snarf.eecs.umich.edu> by bagchi@eecs.umich.edu (Ranjan Bagchi):
+---------------
| anyone care to explain??  (I`m in csh)
| $ echo $p
| w | tail +3
| $ $p
| Usage: w [ -hlsuw ] [ user ]
| $ w | tail +3
| benjo    ttyp3    10:13pm           41      4  -sh 
| benjo    ttyp4    10:17pm         3:22      4  -csh 
+---------------

You'll find that sh does the same thing.

The reason is that variables are handled *after* the line is broken into
commands.  Since | is a command separator, it is parsed relatively early.
After sh or csh does command parsing, it expands variables... and since it's
too late to handle |, it's passed literally.  Similarly, < > is (I think)
parsed *but not necessarily executed* before variable substitution.  I also
seem to remember redirecting into the output of a command working under sh but
not under csh....

Shells are *weird* beasties.

++Brandon
-- 
Me: Brandon S. Allbery			    VHF/UHF: KB8JRR on 220, 2m, 440
Internet: allbery@NCoast.ORG		    Packet: KB8JRR @ WA8BXN
America OnLine: KB8JRR			    AMPR: KB8JRR.AmPR.ORG [44.70.4.88]
uunet!usenet.ins.cwru.edu!ncoast!allbery    Delphi: ALLBERY

rickert@mp.cs.niu.edu (Neil Rickert) (01/08/91)

In article <BAGCHI.91Jan6000722@snarf.eecs.umich.edu> bagchi@eecs.umich.edu (Ranjan Bagchi) writes:
>anyone care to explain??  (I`m in csh)
>
>$ set p = "w | tail +3 "
>
>shouldn't "$p" have the same effect as "w | tail +3" ?
>
 I suppose someone should point out that, taken literally, "$p" does
have the same effect as "w | tail +3 ".

% set p="w | tail +3 "
% "w | tail +3 "
w | tail +3 : Command not found.
% "$p"
w | tail +3 : Command not found.

 Of course this wasn't what you intended, but it also demonstrates that
quoting does effect the meaning of shell commands.

-- 
=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
  Neil W. Rickert, Computer Science               <rickert@cs.niu.edu>
  Northern Illinois Univ.
  DeKalb, IL 60115                                   +1-815-753-6940

christos@batcomputer.tn.cornell.edu (Christos S. Zoulas) (01/08/91)

In article <1991Jan7.142732.28884@unvax.union.edu> boehme@unvax.union.edu (Eric M. Boehm) writes:
>bagchi@eecs.umich.edu (Ranjan Bagchi) writes:
>
>>$ set p = "w | tail +3 "
>>$ echo $p
>>w | tail +3
>>$ $p
>>Usage: w [ -hlsuw ] [ user ]
>>$ w | tail +3
>>benjo    ttyp3    10:13pm           41      4  -sh
>>benjo    ttyp4    10:17pm         3:22      4  -csh
>>$ exit
>>$ exit
>
>>shouldn't "$p" have the same effect as "w | tail +3" ?
>
>No, it should not. It has to do with the way the C Shell parses the
>command line. The following is taken from "The UNIX C Shell Field
>Guide, Gail Anderson, Paul Anderson, Prentice Hall, 1986, ISBN
>0-13-937468-X", pages 262-266. (I highly recommend it).
> ... lines deleted...

The above information is correct. On the other hand:

$ eval $p

should work, but it does not because eval in csh is broken.

christos
-- 
+------------------------------------------------------------------------+
| Christos Zoulas         | 389 Theory Center, Electrical Engineering,   |
| christos@ee.cornell.edu | Cornell University, Ithaca NY 14853.         |
| christos@crnlee.bitnet  | Phone: Disconnected  |   Fax: (607) 254 4565 |

greywolf@unisoft.UUCP (The Grey Wolf) (01/09/91)

In article <BAGCHI.91Jan6000722@snarf.eecs.umich.edu> bagchi@eecs.umich.edu (Ranjan Bagchi) writes:
>anyone care to explain??  (I`m in csh)
>
>
>$ set p = "w | tail +3 "
>$ echo $p
>w | tail +3
>$ $p
>Usage: w [ -hlsuw ] [ user ]
>$ w | tail +3
>benjo    ttyp3    10:13pm           41      4  -sh 
>benjo    ttyp4    10:17pm         3:22      4  -csh 
>$ exit
>$ exit
>
>Process shell finished
>
>
>shouldn't "$p" have the same effect as "w | tail +3" ?
>
>	-rj

Try:

% eval $p

Reasoning:

In csh, while the arguments remain individual in the case of variable
substitution, it is as though each argument has been quoted; specifically,
it is though you have requested the following command line to be executed:

% "w" "|" "tail" "+3"

The pipe is never seen by the shell.  To understand this one, try the
following:

% set p = "echo | & < >"
% $p

The same result occurs when one tries:
% set p = ( echo | & < > )
% $p

eval seems to be the only way to work around this problem.

-- 
On the 'Net:  Why are more and more fourth-level wizard(-wannabe)s trying to
invoke ninth-level magic, instead of taking the time to climb the other
(quite essential) thirteen levels so they can do this properly?
...!{ucbvax,acad,uunet,amdahl,pyramid}!unisoft!greywolf

speelmo@bronze.ucs.indiana.edu (Lance Speelmon -- UCS) (01/11/91)

In article <BAGCHI.91Jan6000722@snarf.eecs.umich.edu> bagchi@eecs.umich.edu (Ranjan Bagchi) writes:
>anyone care to explain??  (I`m in csh)
>
Try:
set p = `w | tail +3`

i think that should fix it...

Lance

>
>$ set p = "w | tail +3 "
>$ echo $p
>w | tail +3
>$ $p
>Usage: w [ -hlsuw ] [ user ]
>$ w | tail +3
>benjo    ttyp3    10:13pm           41      4  -sh 
>benjo    ttyp4    10:17pm         3:22      4  -csh 
>$ exit
>$ exit
>
-- 
==============================================================================
| Lance Speelmon                      |  University Computing Services       | 
| speelmo@bronze.ucs.indiana.edu      |  Network Operations Center           |
==============================================================================

allbery@NCoast.ORG (Brandon S. Allbery KB8JRR) (01/12/91)

As quoted from <1991Jan10.182958.21295@bronze.ucs.indiana.edu> by speelmo@bronze.ucs.indiana.edu (Lance Speelmon -- UCS):
+---------------
| In article <BAGCHI.91Jan6000722@snarf.eecs.umich.edu> bagchi@eecs.umich.edu (Ranjan Bagchi) writes:
| >anyone care to explain??  (I`m in csh)
| Try:
| set p = `w | tail +3`
| i think that should fix it...
+---------------

Ah, no.  This will set "p" to the output of "w | tail +3"... once and only
once.  Ranjan is trying to use a variable as an alias.

++Brandon
-- 
Me: Brandon S. Allbery			    VHF/UHF: KB8JRR on 220, 2m, 440
Internet: allbery@NCoast.ORG		    Packet: KB8JRR @ WA8BXN
America OnLine: KB8JRR			    AMPR: KB8JRR.AmPR.ORG [44.70.4.88]
uunet!usenet.ins.cwru.edu!ncoast!allbery    Delphi: ALLBERY