Uma pergunta relacionada aos pty-s (pseudo-terminais) e à maneira como (cat) golang os lê.
Primeiro, fiz o seguinte.
- abra dois terminais (
dev/pts/0
- 0 edev/pts/1
- 1) - então eu digito no segundo terminal "cat dev/pts/0" (então o que estiver escrito no primeiro terminal será exibido no segundo)
- comece a escrever no primeiro terminal (TUI)
Geralmente funciona na maior parte do tempo, mas alguns caracteres são pulados de vez em quando.
Mais precisamente, para aqueles caracteres que não são exibidos no segundo terminal, eu tenho echo, enquanto para aqueles que são exibidos, eu não tenho. É como se echo e cat estivessem competindo por caracteres.
Entretanto, quando trabalho com as funções de varredura golang e fmt, sempre que escrevo algo no terminal (e, portanto, no /dev/pts/0
terminal), a função de varredura lê tudo (nenhum byte faltando) + o conteúdo inserido é exibido na TUI ("echo" funciona neste caso).
package main
import "fmt"
func main() {
var input string
fmt.Println("Enter text:")
for {
fmt.Scanln(&input)
fmt.Println("You wrote:", input)
}
}
Portanto, neste caso, parece que não existe "competição" entre echo e golang...
Espero o mesmo comportamento em ambos os casos. Em particular, ler todos os bytes em ambos os casos e ter (ou não ter) um eco em ambos os casos.
Qual é a diferença? Por que "cat" às vezes pula bytes ao ler de outro terminal, mas a função de varredura golang não? Eu pensei que o golang apenas lê de "dev/pts/0" da mesma forma que "cat" faz e apenas dá o resultado.
Eu posso reproduzir a "competição" com o
go
código também. Você não nos mostrou exatamente o que você faz lá, eu fiz umgo run test.go < /dev/pts/0
no terminal 1 e então digitei no terminal 0. Eu acho que você simplesmente não teve "sorte" o suficiente com o tempo aleatório.Existem dois leitores de
/dev/pts/0
. Um é seu shell rodando no terminal 0, esperando você digitar o próximo comando, como se ele fizesse isso se você não tentasse sequestrar sua entrada. O outro écat
ougo
no terminal 1. É absolutamente indeterminístico qual deles será o mais rápido a notar um novo caractere disponível. Este é inerentemente o caso sempre que dois leitores tentam simultaneamente ler de um fluxo de bytes (pipe, socket, terminal).Você pode tentar executar um
sleep inf
no terminal 0, dessa forma haverá apenas um leitor: seucat
orgo
(porquesleep
não está lendo sua entrada). No entanto, suas configurações de terminal (modo raw vs. cooked) serão diferentes (seu shell alterna antes/depois de executar cada comando), portanto, você notará um comportamento de buffer de linha em vez de um baseado em caracteres, a edição de linha acontecerá no terminal 0 (isso é feito pelo kernel antes que qualquer um desses dados seja disponibilizado para o aplicativo leitor) e então a linha completa será lida pelo aplicativo em execução no terminal 1.Não sei o motivo de você estar fazendo esse experimento, mas se precisar separar a entrada e a saída em dois terminais diferentes, recomendo redirecionar a saída para um terminal externo, em vez da entrada.