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

3

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

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

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

    
por Pankaj Pandey 17.12.2016 / 12:25

2 respostas

2

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

Claro. Você pode escrever para um terminal (na verdade, para qualquer arquivo ou pipe ou dispositivo ou soquete que suporte e autorize a escrita) usando qualquer descritor de arquivo aberto que você tenha para ele. 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. Se esse é o seu terminal, que assim seja.

    
por 17.12.2016 / 13:13
0

Esta é uma cópia da minha resposta a uma pergunta semelhante no stackoverflow do ano passado.

Você pode gravar na entrada padrão do seu dispositivo terminal devido ao histórico personalizado. Veja 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 em X11, os descritores de arquivo 0, 1 e 2 são conectados a um dispositivo terminal e cada um deles é aberto para ler e escrever . Este é o caso apesar do fato de que um normalmente só lê de fd 0 e escreve para fd 1 e 2 .

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

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

E aqui está como ssh faz isso:

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 função dup2 dups arg1 em arg2, fechando arg2 primeiro, se necessário).

E aqui está como xterm faz isso:

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);
    
por 18.12.2016 / 11:59