¿Puedo duplicar un descriptor de archivo de entrada y usarlo para escribir datos?

¿Puedo duplicar un descriptor de archivo de entrada y usarlo para escribir datos?

El siguiente comando hace una copia del descriptor del archivo de entrada y usa el descriptor de archivo duplicado para escribir datos desde el echocomando en la terminal.

sh-4.2$ ejecutivo 6<&0
sh-4.2$ echo "hola" >&6
Hola

¿Eso significa que podemos escribir en la terminal usando el descriptor del archivo de entrada?

Respuesta1

¿Eso significa que podemos escribir en la terminal usando el descriptor del archivo de entrada?

Seguro. Puede escribir en una terminal (de hecho, en cualquier archivo, tubería, dispositivo o socket que admita y autorice la escritura) utilizando cualquier descriptor de archivo abierto que tenga para ello. Una versión más simple de su código sería esta:

echo hello >&0

que, como era de esperar, envía "hola\n" a cualquier descriptor de archivo al que apunte 0. Si ese es tu terminal, que así sea.

Respuesta2

Esta es una copia de mi respuesta a unapregunta similaren stackoverflow el año pasado.

Puede escribir en la entrada estándar de su dispositivo terminal debido a una costumbre histórica. Esto es lo que está pasando:

Cuando un usuario inicia sesión en una terminal en un sistema tipo Unix, o abre una ventana de terminal en X11, los descriptores de archivos 0, 1 y 2 se conectan a un dispositivo terminal y cada uno de ellos se abre paratanto leyendo como escribiendo. Este es el casoa pesar de que normalmente solo se lee desde fd 0 y se escribe en fd 1 y 2.

Aquí está el código de7ma edición init.c:

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

Y así es como sshse hace:

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));

(La dup2función duplica arg1 en arg2, cerrando arg2 primero si es necesario).

Y así es como xtermse hace:

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);

información relacionada