Eu me odeio por dizer isso, mas
There’s more than one way to skin a cat
.
Por que eu quero dizer, há entrada padrão e, em seguida, há entrada padrão.
Ou está lendo no teclado (terminal)
e depois há a leitura do teclado. Experimente
less < afilename
Funciona exatamente como
less afilename
que significa que less
deve ter alguma maneira de ler no teclado
além de ler a entrada padrão.
Veja outro comando que funciona, mesmo que você não espere:
less afilename < /dev/null
Veja o comando tty
.
Ele relata o nome do tty (terminal) conectado à entrada padrão.
Ele funciona chamando a função de biblioteca ttyname
com um argumento de 0
(o descritor de arquivo da entrada padrão).
less
provavelmente está chamando ttyname(1)
para obter o nome do tty (terminal) conectado à saída padrão.
Em seguida, ele abre esse arquivo para leitura e aceita comandos dele.
Não lê comandos da entrada padrão; isso é apenas para dados.
Então, o que temos são dois processos quase independentes ( cat
e less
)
independentemente (concorrentemente) lendo no teclado
(isto é, o tty / terminal) em dois descritores de arquivos independentes.
Esta é uma situação confusa e é uma espécie de “condição de corrida”.
Eu acho isso um pouco análogo ao funcionamento de uma máquina de pinball ,
em que existem muitas pistas, ou caminhos, que a bola pode levar -
e sempre leva um ; nunca pode demorar mais do que um. Similarmente,
quando vários processos estão lendo do mesmo terminal simultaneamente,
cada linha digitada (se o terminal estiver no modo de linha)
ou cada caractere digitado (se o terminal estiver no modo de caractere)
vai para exatamente um processo.
E a seleção é arbitrária, não diferente da ação do fliperama.
Não é totalmente "aleatório", assim como o agendamento de processos é aleatório;
mas é essencialmente imprevisível.
Então, eis o que acontece:
-
cat
lê sua entrada padrão, que, por padrão, é o terminal,
e grava em sua saída padrão, que é o canal para less
.
- Em algum momento,
less
chama ttyname(1)
,
obtém o nome do terminal em que está e abre para leitura.
-
less
lê uma tela cheia de dados (ou seja, 24 linhas ou qualquer outra coisa)
a partir de sua entrada padrão (o tubo)
e grava-o na saída padrão (o terminal).
- Em seguida,
less
emite o aviso :
, coloca o terminal no modo de caractere,
e começa a ler do terminal ( não da entrada padrão).
- Então, agora temos dois processos (
cat
e less
)
lendo do terminal simultaneamente,
e o fenômeno pinball entra em ação - os personagens (e / ou linhas)
que você digita ir para cat
ou less
, semi-aleatoriamente.
Se for para cat
, ele será gravado no pipe e less
tratará como dados.
Se for para less
, ele será interpretado como um comando less
.
Isso não tem nada a ver com o armazenamento em buffer.