When I issue cat
, the terminal hangs waiting for stdin input. However, when less
is issued, I get Missing filename ("less --help" for help)
. It is known that both less
and cat
accepts stdin input. What is the difference? How is this reflected in the man pages?
2 Answers
less
runs the following code when it's not given any filename arguments:
if (isatty(fd0))
{
error("Missing filename (\"less --help\" for help)", NULL_PARG);
quit(QUIT_OK);
}
return (edit("-"));
It's complaining when standard input is a terminal. If standard input is an ordinary file or pipe, it's OK with that.
It presumably does this because it needs to read responses from the terminal at the end of each page, and there'd be no way to distinguish the data that is being paged and the responses.
This isn't mentioned in the man page. Maybe it should be.
cat
doesn't page its output, and doesn't read responses from the terminal. It doesn't have any restrictions as far as stdin being a terminal.
-
Couldn't you open /dev/tty for responses and still use stdin for data? A simple way of making input out of band Jan 20, 2015 at 1:58
-
@RichHomolka
less
actually does open/dev/tty
, but opening that device just gives the process another descriptor to the actual tty device, and with two descriptors to the same device, theread
s would compete over the same queue of input characters. Jan 20, 2015 at 20:23
My guess is that less
calls isatty(3)
on file descriptor 0. Another alternative would be to call fstat(2)
on file descriptor 0 and interpret the values of the st_ino
and st_rdev
fields. Either way, the point is a program can tell something about a file descriptor, and stdin is just file descriptor 0.
As far as why less
exits and cat
does not, you need to look at the purpose of the two different programs. less
is the GNU pager, a reaction to the BSD pager more
(note the punny name). It doesn't exactly make sense to paginate input from a terminal, but it just might make sense to paginate input from a pipe. Either could be stdin. Coding a special case in less
makes sense. Coding a special case in cat
does not make sense, and reduces its usefulness. Even in the late 1980s, people had windowing systems and would type in cat > somefile
then paste a large chunk of text into "somefile".
-
Thanks @Bruce Ediger for the answer. I did not follow some of the points made in the 2nd paragraph. You said "Coding a special case in cat does not make sense..." Is the special case the tty input? Jan 8, 2015 at 1:36
-
1@boxofchalk1 - for
cat
, the special case would be checking if file descriptor 0 represents a TTY device, and exiting if it is. If thecat
program doesn't find any file names in argv[], it just reads file descriptor 0 until end-of-file.– user732Jan 8, 2015 at 14:37 -
I agree with this answer. You can do whatever you want tech wise, but paging stdin doesn't make design sense so you detect it and call it an error. Cat is used in a variety of places where cat stdin makes sense. '(echo header; cat -;echo footer) > /tmp/somefile.txt'. I've also used cat > /proc/whatever Jan 20, 2015 at 1:56
[filename]
which would imply that it was an optional argument.less
implementation? Which distribution are you using and which version of the package?less --v
givesless 436
. Would you know why 436 doesn't exist here: ftp.gnu.org/gnu/less/?C=M;O=D ?