
O comando abaixo faz uma cópia do descritor do arquivo de entrada e usa o descritor de arquivo duplicado para gravar dados do echo
comando 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 ssh
funciona:
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 dup2
função transforma arg1 em arg2, fechando arg2 primeiro, se necessário.)
E aqui está como xterm
funciona:
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);