Por que tocar em um dispositivo TTY captura apenas todos os outros caracteres?

1

Então, me deparei com a função ttyname ( unistd.h ) e tive que testá-la.

#include <unistd.h>
#include <stdio.h>

int main(void) {
  printf("%s\n", ttyname(0));
  return 0;
}

Na minha máquina, ele ecoa em /dev/ttys011 . Eu descobri que é um dispositivo!

echo "Hello" > /dev/ttys011

Woah, rodando isso de outro terminal produzido Hello no terminal original eu executei meu programa ttyname

Então, o que acontece quando eu cat /dev/ttys011 ? Bem, eu recebo todos os outros caracteres digitados. Oh sim; quebra a sessão TTY original também.

Então, tento o seguinte:

cat /dev/ttys011 | tee /dev/ttys011

Bem, tudo aparece no terminal original, mas meu terminal "tap" (aquele no qual o comando acima está sendo executado) ainda está recebendo todos os outros caracteres .

Ah, sim, meu terminal original ainda está quebrado (os personagens aparecem, mas apenas todos os outros personagens chegam ao meu shell).

Por exemplo, digitar ls rende ls no terminal, l no terminal "tap" e a execução me dá 'l' is not a command .

O que está acontecendo aqui? Eu esperaria um comportamento estranho, mas por que todos os outros personagens estão sendo capturados?

    
por Qix 20.01.2015 / 06:41

1 resposta

4

Seu shell, ou o processo que estava em primeiro plano, já estava lendo o terminal ao qual estava anexado, que era /dev/ttys011 . Então você iniciou outro processo, um cat também lendo o mesmo terminal ao mesmo tempo.

Agora, há dois processos competindo pela mesma entrada do terminal. Cada vez que você digita uma chave no terminal, ela é entregue a um dos processos em espera. O outro processo também está interessado em ler, mas quando se torna a sua vez de ler, não resta mais nada para ler. Mesmo que você pareça observar uma alternância regular de quais caracteres vão para qual processo, é realmente imprevisível quais partes da entrada irão para qual processo: pode ser toda entrada para uma, todas entradas para a outra, ou qualquer coisa entre elas.

Se você deseja que o processo cat receba toda a entrada, é necessário providenciar que nada mais esteja lendo do mesmo dispositivo ao mesmo tempo. Uma maneira fácil de fazer isso é executar algo como sleep 999 no terminal. sleep espera que o atraso expire, mas enquanto estiver aguardando, ele não deve tentar ler nada.

O comando:

cat /dev/ttys011 | tee /dev/ttys011

não restaura nenhuma entrada capturada por cat em seu local original. Ou seja, tee não o entrega para qualquer processo que estivesse originalmente interessado em lê-lo (como seu shell), ele apenas o envia para a saída do terminal, o que faz com que seja exibido.

A propósito: você não precisa de um programa C e da função ttyname() para obter o nome do seu terminal; tudo que você precisa fazer é digitar tty e pressionar enter no prompt do shell.

    
por 20.01.2015 / 07:27

Tags