As most of you have done many times, it's convenient to view long text using less
:
some_command | less
Now its stdin is connected to a pipe (FIFO). How can it still read commands like up/down/quit?
less
As most of you have done many times, it's convenient to view long text using less
:
some_command | less
Now its stdin is connected to a pipe (FIFO). How can it still read commands like up/down/quit?
Best Answer
As mentioned by William Pursell,
less
reads the user’s keystrokes from the terminal. It explicitly opens/dev/tty
, the controlling terminal; that gives it a file descriptor, separate from standard input, from which it can read the user’s interactive input. It can simultaneously read data to display from its standard input if necessary. (It could also write directly to the terminal if necessary.)You can see this happen by running
Move around the input, exit
less
, and look at the contents ofless.trace
: you’ll see it open/dev/tty
, and read from both file descriptor 0 and whichever one was returned when it opened/dev/tty
(likely 3).This is common practice for programs wishing to ensure they’re reading from and writing to the terminal. One example is SSH, e.g. when it asks for a password or passphrase.
As explained by schily, if
/dev/tty
can’t be opened,less
will read from its standard error (file descriptor 2).less
’s use of/dev/tty
was introduced in version 177, released on April 2, 1991.If you try running
cat /dev/tty | less
, as suggested by Hagen von Eitzen,less
will succeed in opening/dev/tty
but won’t get any input from it untilcat
closes it. So you’ll see the screen blank, and nothing else until you press CtrlC to killcat
(or kill it in some other way); thenless
will show whatever you typed whilecat
was running, and allow you to control it.