[net.unix] An odd difference between "cat file" and "cat<file"

rcd@opus.UUCP (Dick Dunn) (04/14/84)

<in>out

I just stepped in a curious one - "sh", at least here, under 4.2, doesn't
expand wildcards in the "word" following > or < .  Why would I care?  I'm
a lazy typist; I was reaching down about three levels for a file and used a
wildcard with an indirection.  It didn't work.  Example:  suppose that
	ibble/gleep/farkle
exists, and that a unique wildcarding of it is
	ib*/gl*/f*
Then,	cat ib*/gl*/f*
will list the file but
	cat <ib*/gl*/f*
gives	ib*/gl*/f*: no such file or directory

(BTW, did I miss some fine print?  Be this buglet or featurette?  I notice
that sh will do expansions in, say, "cd" where it needs a single filename
which is known to exist.)
-- 
"A friend of the devil is a friend of mine."		Dick Dunn
{hao,ucbvax,allegra}!nbires!rcd				(303) 444-5710 x3086

jeff@alberta.UUCP (Jeff Sampson) (04/16/84)

  The reason that ``cat xyz*'' is expanded and ``cat <xyz*''
is not has to do with the C getchar() call.  cat takes any
arguments on the command line that don't start with a ``-'',
expands them, and interprets them as filenames.  However, if
you use the ``<'' before the filename, the filename is actually
used as stdin and the filename is not put on the command line.
Therefore, cat thinks that you are typing in somthing from the
terminal.  Hope this helps.
--
				Curt Jeff Sampson
				  alberta!jeff
"Watch out, Mr. T.  From Tuktoyatuk, it's the ** eh? team **"

jjb@pyuxnn.UUCP (J Bernardis) (04/16/84)

cat doesn't do the file name expansion!!  The shell has that responsibility.
Thus, cat doesn't know if you typed abcd or ab* on the command line.
I frankly don't know why there is a difference between cat ab* and cat <ab*.
It seems to me that file name expansion should be done before anything else.

	Jeff Bernardis, AT&T Technologies @ Piscataway NJ

tag@tty3b.UUCP ("Tom Gloger"3974 97320) (04/17/84)

>  I frankly don't know why there is a difference between cat ab* and cat <ab*.
>  It seems to me that file name expansion should be done before anything else.

So tell me, what would you expect to see if ab* matched two or more files?
-- 
			Tom Gloger
			AT&T Teletype Corporation
			Skokie, Illinois
			ihnp4!ltuxa!tty3b!tag

alan@allegra.UUCP (Alan S. Driscoll) (04/17/84)

>>  I frankly don't know why there is a difference between cat ab* and
>>  cat <ab*.  It seems to me that file name expansion should be done
>>  before anything else.

>  So tell me, what would you expect to see if ab* matched two or more
>  files?

I would have expected an error message, of course.  I would also have
expected an error message after typing

	cat < abc abd

In fact, both sh and csh silently ignore 'abc'.  (Surprise!)

-- 
	Alan S. Driscoll
	AT&T Bell Laboratories

jas@drutx.UUCP (04/18/84)

(Goodness, what a long list of references!)

>>>  I frankly don't know why there is a difference between cat ab* and
>>>  cat <ab*.  It seems to me that file name expansion should be done
>>>  before anything else.

>>  So tell me, what would you expect to see if ab* matched two or more
>>  files?

> I would have expected an error message, of course.  I would also have
> expected an error message after typing
>
>	cat < abc abd
>
> In fact, both sh and csh silently ignore 'abc'.  (Surprise!)

No, sh and csh are NOT silently ignoring 'abc'!  They (or at least sh)
are setting the cat process's standard input to the file 'abc', which is
exactly what they are supposed to do.  cat does not read from file 'abc'
when it is invoked as above for the same reason that it does not read from
your terminal when you say 'cat /etc/passwd':  it only reads its standard
input when it is invoked with no arguments, or if one of its arguments is
'-'.

The position of the I/O redirection instruction on the command line is
immaterial.  Try "< /etc/passwd cat"!

Wild-card expansion after an I/O redirection operator could be handled in
any of these three ways:

(1)  Don't expand after an I/O redirection operator.  (That's the way it
     is now.)  The argument for this approach is that I/O redirection is
     not part of the command line the shell is building, but a meta-instruction
     to the shell.  Since file name expansion is usually used as shorthand
     for multiple file names, and the I/O redirection operators take a
     single file-name operand, file name expansion should not be done here.

(2)  Expand after an I/O redirection operator, but issue an error message
     and don't run the command if it expands to more than one file name.
     The argument in favor is that file name expansion is also used to
     save keystrokes on long file names, and that this will do what most
     people probably want and expect.

(3)  Let file name expansion be a straight textual expansion regardless of
     where it occurs.  The advantage is that it is simple.  The disadvantage
     is that when a filename expands to more than one file, the results may
     not be what the eager typist desired.  (Note that the shell does not
     expand command names, either.  How would you like to see "ca* /etc/passwd"
     handled?)

Jim Shankland
..!ihnp4!druxy!jas

guy@rlgvax.UUCP (Guy Harris) (04/18/84)

     (Note that the shell does not expand command names, either.  How
     would you like to see "ca* /etc/passwd" handled?)

Well, "ca*" would only look in the current directory, but
"/bin/ca* /etc/passwd" might actually work if the first file in "/bin"
beginning with "ca" happened to be "/bin/cat".  In fact, it *does* work
that way, at least with the System III Bourne shell - I tried

	/bin/ca* /etc/passwd

and, by golly, our password file came dribbling out on my terminal!

	Guy Harris
	{seismo,ihnp4,allegra}!rlgvax!guy

presley@mhuxj.UUCP (Joe Presley) (04/18/84)

If you give the Korn Shell# "cmd <*glop*", and *glop* expands to a
single file name, it'll use the name.  If it expands to more than one
name, it'll keep the literal *glop* and you get the message

	sh: *glop*: cannot open

Similar effects for > and >>.
=====
# Yes, I know, it's not available outside AT&T yet.
-- 

   Joe Presley (mhuxj!presley, ihnp4!j.presley)

danny@itm.UUCP (Danny) (04/18/84)

    Just to add more fuel to the fire, let me quote from the UNIX*
Programmer's Manual, Volume 2, "An Introduction to the UNIX Shell",
S. R. Bourne, section 3.7 "Command execution":

...In the following *word* is only subject to parameter and command
substitution.  No file name generation or blank interpretation takes
place so that, for example,

            echo ... > *.c

will write its output into a file whose name is *.c.

    My gosh, maybe it isn't the most user-friendly thing around,
or not what some people want (please don't take that as a personal
affront), but at least IT IS DOCUMENTED!!!  Why issit that people
no read manuals?

* UNIX is a trademark of Bell Laboratories.
S. R. Bourne is an employee of Bell Laboratories.
D. S. Cox is a figment of the imagination of a rather non-descript
          Kowala in the Austrailian out-back.
-- 
				Daniel S. Cox
				(akgua!itm!danny)

allyn@sdcsvax.UUCP (04/18/84)

<>

You are incorrect.  The shell (both csh and sh on our 4.2 BSD system)
does expand commandnames as long as the name you are trying to expand to is 
in your current directory.  Try 'cd /bin' (or wherever you keep it) 
and then 'ca* /etc/passwd'  This works on our system.

-- 
 From the virtual mind of Allyn Fratkin           sdcsvax!allyn@Nosc
                          UCSD Pascal Project     {ucbvax, decvax, ihnp4}
                          U.C. San Diego                  !sdcsvax!allyn

jdd@allegra.UUCP (John DeTreville) (04/18/84)

	From: alan@allegra.UUCP (Alan S. Driscoll)
	Newsgroups: net.unix
	Subject: Re: An odd difference between "cat file" and "cat<file"
	Date: Tue, 17-Apr-84 16:09:48 EST

	>>  I frankly don't know why there is a difference between cat ab* and
	>>  cat <ab*.  It seems to me that file name expansion should be done
	>>  before anything else.

	>  So tell me, what would you expect to see if ab* matched two or more
	>  files?

	I would have expected an error message, of course.  I would also have
	expected an error message after typing

		cat < abc abd

	In fact, both sh and csh silently ignore 'abc'.  (Surprise!)

-- 
		Alan S. Driscoll
		AT&T Bell Laboratories

Well, not really.  Instead of "cat < abc abd", try "echo < abc abd" and
see what happens.

Cheers,
John ("Illusions Destroyed, Cheap") DeTreville
Bell Labs, Murray Hill

wls@astrovax.UUCP (William L. Sebok) (04/18/84)

>>     (Note that the shell does not expand command names, either.  How
>>     would you like to see "ca* /etc/passwd" handled?)

> Well, "ca*" would only look in the current directory, but
> "/bin/ca* /etc/passwd" might actually work if the first file in "/bin"
> beginning with "ca" happened to be "/bin/cat".  In fact, it *does* work
> that way, at least with the System III Bourne shell - I tried
>
>	/bin/ca* /etc/passwd
>
> and, by golly, our password file came dribbling out on my terminal!
>	Guy Harris

Indeed I've just tried with the 4.2 BSD c-shell and the password file
also came dribbling out.
-- 
Bill Sebok			Princeton University, Astrophysics
{allegra,akgua,burl,cbosgd,decvax,ihnp4,kpno,princeton,vax135}!astrovax!wls

ntt@dciem.UUCP (Mark Brader) (04/19/84)

Alan Driscoll (allegra!alan) says:

	I would also have expected an error message after typing
		cat < abc abd
	In fact, both sh and csh silently ignore 'abc'.  (Surprise!)

But look, the following command is perfectly legitimate and useful:
	ed < abc abd
It means to edit file abd according to the script in abc, of course.

Obviously the shell has no business knowing the difference between the
behavior of "cat" and "ed".  And "cat" is behaving according to documentation;
it is supposed to copy the standard input to the standard output only when
no input file names were specified.

Do you want "cat" to give an error message when a file name is specified
and the standard input has been redirected?  Then what happens when "cat file"
occurs in a shell script whose standard input has been redirected?

It ain't broke, don't fix it.
Mark Brader

P.S. I, too, would like to see "cat <ab*" accepted when "ab*" expands
uniquely -- but it looks like too much trouble to me.  What do you do
when the "<" is a ">" and there is no match, by the way?

dgk@ulysses.UUCP (David Korn) (04/22/84)

In the Bourne shell the command
	echo > file file1 file2
means the same as
	echo file1 file2 > file
so that if
	echo >  file*
were allowed then should it be interpretted as
echo > file file1 file2
as described above or as
echo > "file file1 file2"
as if the expansion generated the file name?
The former interepretation is difficult to implement since the command
has bee parsed and io arguments have been separated from command arguments
by the time this decision must be made.

The Bourne shell gets around this ambiguity by not doing file name generation
on i/o arguments, or parameter assignments, just on command arguments.

The Korn shell, ksh , which attempts to be friendlier, will perform the
expansion only if a unique file name is generated.

matt@UCLA-LOCUS.ARPA@sri-unix.UUCP (04/23/84)

From:            Matthew J. Weinstein <matt@UCLA-LOCUS.ARPA>

[Running 4.1 BSD]

In Bourne shell, filename expansion is suppressed after "<" and ">".
	$ cat >*
produces a file named `*'.

	$ cat <*
produces `*: cannot open' (providing * doesn't exists)

In Csh, an `ambiguous' message is emitted if more than one file matches
a pattern in a funny place (first token in line or after "<" or ">").

(Results obtained by experimentation, not code examination.)

					- Matt

priili@ARDC.ARPA (04/25/84)

From:      "Peter A. Riili" (MISD-WAD) <priili@ARDC.ARPA>

Due to the order of command line evaluation by the Shell, this difference
exists for any applicable command:

   cmd file             VS.              cmd < file

where "file" is given with one or more metacharacters: * ? []
This is because I/O redirection is performed BEFORE filename generation
(i.e. metacharacter expansion).

--Pete Riili, U.S. Army ARDC