4

The below command makes a copy of the input file descriptor and use the duplicate file descriptor for writing data from the echo command on to the terminal.

sh-4.2$ exec 6<&0
sh-4.2$ echo "hello" >&6
hello

Does that mean we can write to the terminal using the input file descriptor?

JdeBP
  • 68,745

2 Answers2

3

Does that mean we can write to the terminal using the input file descriptor?

Sure. You can write to a terminal (indeed to any file or pipe or device or socket that supports and authorizes writing) using whatever open file descriptor you have for it. A simpler version of your code would be this:

echo hello >&0

which, as you'd expect, sends "hello\n" to whatever file descriptor 0 points to. If that's your terminal, so be it.

Celada
  • 44,132
  • but the file descriptor '0' is associated with stdin which is the keyboard, so how is it possible to write to the terminal using stdin. – Pankaj Pandey Dec 17 '16 at 12:15
  • 1
    "the file descriptor '0' is associated with stdin which is the keyboard": false. File descriptor 0 points to your terminal, not to your keyboard. The terminal is a device that can be both read and written. – Celada Dec 17 '16 at 12:18
  • thnks for the explanation.. @Celeda – Pankaj Pandey Dec 17 '16 at 12:24
  • @Celeda , when you google about file descriptor , it describes file descriptor 0 i.e. stdin connected to the keyboard(default input device), so when we redirect the output to stdin how does it gets printed on the console(monitor) – Pankaj Pandey Dec 17 '16 at 13:39
  • @PankajPandey, the Google search result you found is not correct. The stdio file descriptors 0, 1, and 2, are typically connected (by default) to the terminal, not to a keyboard (for input) or video card (for output) or anything else of the sort. A "terminal" is a device which is historically a serial port connected to a (real, physical) terminal (perhaps through a modem), but nowadays is much more commonly an abstraction, connected to, say, a terminal application that displays itself as a window in a GUI system or connected to the server-end of an SSH connection. – Celada Dec 18 '16 at 14:04
1

This is a copy of my answer to a similar question on stackoverflow last year.

You can write to your terminal device's standard input due to historical custom. Here's what's happening:

When a user logs into a terminal on a Unix-like system, or opens a terminal window under X11, file descriptors 0, 1, and 2 are connected to a terminal device, and each of them is opened for both reading and writing. This is the case despite the fact that one normally only reads from fd 0 and writes to fd 1 and 2.

Here is the code from 7th edition init.c:

open(tty, 2);
dup(0);
dup(0);
...
execl(getty, minus, tty, (char *)0);

And here is how ssh does it:

ioctl(*ttyfd, TCSETCTTY, NULL);
fd = open("/dev/tty", O_RDWR);
if (fd < 0)
    error("%.100s: %.100s", tty, strerror(errno));
close(*ttyfd);
*ttyfd = fd;
...
/* Redirect stdin/stdout/stderr from the pseudo tty. */
if (dup2(ttyfd, 0) < 0) 
    error("dup2 stdin: %s", strerror(errno));
if (dup2(ttyfd, 1) < 0) 
    error("dup2 stdout: %s", strerror(errno));
if (dup2(ttyfd, 2) < 0) 
    error("dup2 stderr: %s", strerror(errno));

(The dup2 function dups arg1 into arg2, closing arg2 first if necessary.)

And here is how xterm does it:

if ((ttyfd = open(ttydev, O_RDWR)) >= 0) {
    /* make /dev/tty work */
    ioctl(ttyfd, TCSETCTTY, 0);
...
/* this is the time to go and set up stdin, out, and err
 */
{
/* dup the tty */
for (i = 0; i <= 2; i++)
    if (i != ttyfd) {
    IGNORE_RC(close(i));
    IGNORE_RC(dup(ttyfd));
    }
/* and close the tty */
if (ttyfd > 2)
    close_fd(ttyfd);
Mark Plotnick
  • 25,413
  • 3
  • 64
  • 82