0

command < file is used to redirect content from a file into a command.

On virtual terminal 1 (/dev/tty1), I run less < file. Then on another virtual terminal, I run lsof -p <pid of the less process> and see the (trimmed) output:

FD    name
----------------
0r    /root/file
1u    /dev/tty1
2u    /dev/tty1
3r    /dev/tty

I interpret this as:

  1. stdin is /root/file. The process can only read from /root/file.
  2. stdout is /dev/tty1. The process can read from and write to /dev/tty1 (though I don't know why the process needs to read from its own output...)
  3. stderr is /dev/tty1. The process can read from and write to /dev/tty1 (again, why does the process needs the permission to read from the error logs that it outputs?)
  4. The last line is a non-standard stream. I don't know what it is for, but the process can only read from it.

The question: Even though the stdin is /root/file, I can still interact with the less process (ex. typing '/' to enter search mode and search for a word). This means the process still accepts input from the current virtual terinal (/dev/tty1). I thought that since the stdin is not /dev/tty1, I should not be able to interact with the less process via typing on the keyboard?

  • 1
    Guess: less has detected that you redirected stdin, and is using the "current controlling terminal device" /dev/tty at FD 3 for input because of this. Or it even always does it that way, even if you give it a file as an argument, doing the redirection itself. – dirkt Oct 2 '18 at 10:21
2

stdin is /root/file. The process can only read from /root/file.

stdout is /dev/tty1. The process can read from and write to /dev/tty1 (though I don't know why the process needs to read from its own output...)

stderr is /dev/tty1. The process can read from and write to /dev/tty1 (again, why does the process needs the permission to read from the error logs that it outputs?)

Both "stdout" and "stderr" point to the same file object, the same "stdin" was pointing to before it was redirected from /root/file, namely /dev/tty1. They were all obtained by dup(2)ing the same file descriptor, and share all their properties (modes: O_RDWR, file pointer, etc). You should think of file descriptors as indexes in a array of (reference counted) pointers, where more than one can point to the same structure. The shell didn't bother to change the access modes of "stdout" and "stderr" with fcntl(fd, F_SETFL, O_WRONLY) when it redirected stdin from file -- that would be pointless.

The last line is a non-standard stream. I don't know what it is for, but the process can only read from it.

That's the one less is using for user interaction.

The question: Even though the stdin is /root/file, I can still interact with the less process (ex. typing '/' to enter search mode and search for a word). This means the process still accepts input from the current virtual terinal (/dev/tty1). I thought that since the stdin is not /dev/tty1, I should not be able to interact with the less process via typing on the keyboard?

/dev/tty is a magic path that will always open the controlling terminal; in your case, /dev/tty and /dev/tty1 refer to the same device (which may be a virtual device -- a pseudo-terminal)

1

You are showing a special situation. While less works on an input stream on fd 0, it needs an input channel to interact with the user. So it opens another file, here fd 3, to read from the keyboard. This definitely in NOT stdin. Aside (memories...): On OpenVMS by DEC they - by default - differentiated between SYS$INPUT and SYS$COMMAND, which sort of reflects the situation presented...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.