Posso duplicar um descritor de arquivo de entrada e usá-lo para gravar dados?

Posso duplicar um descritor de arquivo de entrada e usá-lo para gravar dados?

O comando abaixo faz uma cópia do descritor do arquivo de entrada e usa o descritor de arquivo duplicado para gravar dados do echocomando no terminal.

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

Isso significa que podemos escrever no terminal usando o descritor do arquivo de entrada?

Responder1

Isso significa que podemos escrever no terminal usando o descritor do arquivo de entrada?

Claro. Você pode escrever em um terminal (na verdade, em qualquer arquivo ou canal ou dispositivo ou soquete que suporte e autorize a gravação) usando qualquer descritor de arquivo aberto que você tenha. Uma versão mais simples do seu código seria esta:

echo hello >&0

que, como seria de esperar, envia "hello\n" para qualquer descritor de arquivo 0 apontado. Se esse é o seu terminal, que assim seja.

Responder2

Esta é uma cópia da minha resposta a umpergunta semelhanteno stackoverflow no ano passado.

Você pode escrever na entrada padrão do seu dispositivo terminal devido ao costume histórico. Aqui está o que está acontecendo:

Quando um usuário efetua login em um terminal em um sistema semelhante ao Unix ou abre uma janela de terminal no X11, os descritores de arquivo 0, 1 e 2 são conectados a um dispositivo terminal e cada um deles é aberto paratanto lendo quanto escrevendo. Este é o casoapesar do fato de que normalmente só se lê de fd 0 e escreve em fd 1 e 2.

Aqui está o código de7ª edição init.c:

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

E aqui está como sshfunciona:

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

(A dup2função transforma arg1 em arg2, fechando arg2 primeiro, se necessário.)

E aqui está como xtermfunciona:

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

informação relacionada