Date: Sat, 8 Sep 2001 05:57:56 +0300 From: Giorgos Keramidas <charon@labs.gr> To: Jamie Bowden <ragnar@sysabend.org> Cc: chat@FreeBSD.ORG Subject: Re: cat(1) strangeness when '-' and options are combined Message-ID: <20010908055755.A16153@hades.hell.gr> In-Reply-To: <Pine.BSF.4.10.10109071914420.41287-100000@moo.sysabend.org>; from ragnar@sysabend.org on Fri, Sep 07, 2001 at 07:16:16PM -0700 References: <20010908010405.A13448@hades.hell.gr> <Pine.BSF.4.10.10109071914420.41287-100000@moo.sysabend.org>
next in thread | previous in thread | raw e-mail | index | archive | help
From: Jamie Bowden <ragnar@sysabend.org> Subject: Re: cat(1) strangeness when '-' and options are combined Date: Fri, Sep 07, 2001 at 07:16:16PM -0700 > On Sat, 8 Sep 2001, Giorgos Keramidas wrote: > > :The manpage of cat(1) says that an argument of '-' is interpreted as > :the filename of 'stdin'. The cat(1) source uses getopt() to parse its > :args, and '-' has a special meaning for getopt too. This makes cat(1) > :act in a seemingly strange manner in the following cases: > : > :-:- Running cat(1) without *any* command line switches > : > :-:- Running cat(1) with similar command line including some switches > : > :This is not a bug, since it is the documented way that getopt() works. > :However, it seems to be somewhat confusing :-( > : > :What do the standards-people have to say about this? > > It works exactly as I'd expect it to, see below: > > 7:14pm moo /home/ragnar %cat -- /etc/fstab > # Device Mountpoint FStype Options Dump > Pass# > /dev/wd0s1b none swap sw 0 0 > /dev/wd0s1a / ufs rw 1 1 > /dev/wd0s1f /usr ufs rw 2 2 > /dev/wd0s1e /var ufs rw 2 2 > proc /proc procfs rw 0 0 > > Like many utilies, you need the -- because a single - is a valid filename > in unix. Nope, there was absolutely no place where I used a 'double' dash. Please read again what I wrote. I think you're somehow missing the point I tried to make. A single '-' is internally interpreted by the code in src/bin/cat/cat.c as a valid filename referring to "stdin". 220 if (*argv) { 221 if (!strcmp(*argv, "-")) 222 fd = fileno(stdin); 223 else if ((fd = open(*argv, O_RDONLY, 0)) < 0) { ... 228 } 229 filename = *argv++; That interpretation, however, changes slightly when at least one switch has been given that starts with '-' because getopt seems to eat the first '-' and stops at the first command line arg that does /not/ start with '-'. I was probably unclear in what I said. If you invoke cat like this: % cat - /etc/fstab - you have to press ^D *twice*. The first '-' is left intact by getopt() [probably because it isn't followed by any 'switches'] and then translated as a reference to "stdin" by cat. When you press ^D once, /etc/fstab is printed, and a second '-' is again assumed to be stdin. Pressin ^D again stops that too, and the command finishes successfully. If at least one option is given to cat though before the first '-', then cat stops waiting for input from stdin, and upon a *single* press of ^D /etc/fstab is printed and cat terminates. A sample of this can be seen when you try running: % cat -n - /etc/fstab - What I meant to ask (hopefully more clear this time) is: Is this something that one can rely upon as 'standard' getopt() / cat behavior. One of those '-' arguments is interpreted in different ways depending on whether at least one switch has been passed to cat. Of course I can always use: % cat -n -- - /etc/fstab - and have the exact same behavior as the first command (plus the extra feature of having all line snumbered), but the difference in those two first commands still exists. I am going to have access to a GNU/Linux box in a few minutes, and test it there too with their getopt() and cat. /me hides again, still puzzled -giorgos To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-chat" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20010908055755.A16153>