0

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?

4
  • Indeed the less(1) manpage says [filename] which would imply that it was an optional argument. Jan 7, 2015 at 22:08
  • Where did you get your less implementation? Which distribution are you using and which version of the package? Jan 7, 2015 at 22:12
  • @PavelŠimerda It came with CentOS. less --v gives less 436. Would you know why 436 doesn't exist here: ftp.gnu.org/gnu/less/?C=M;O=D ? Jan 8, 2015 at 1:33
  • Interesting, I found greenwoodsoftware.com/less which is used by Linux From Scratch and is also linked by Wikipedia as the official home page. Jan 10, 2015 at 17:59

2 Answers 2

7

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.

2
  • 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, the reads would compete over the same queue of input characters. Jan 20, 2015 at 20:23
4

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".

3
  • 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 the cat program doesn't find any file names in argv[], it just reads file descriptor 0 until end-of-file.
    – user732
    Jan 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

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .