É o fd para o lado mestre do pseudo-terminal no emulador de terminal que você deseja monitorar se quiser ver o que é exibido nele. Aquele mestre fd é o que simula o fio que vai para um terminal real. O que xterm
escreve nele são os caracteres gerados a partir da tecla que você pressiona. O que ele lê é o que é exibido.
Por exemplo, no Linux:
$ lsof -ac xterm /dev/ptmx
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
xterm 15173 chazelas 4u CHR 5,2 0t0 2131 /dev/ptmx
E, em seguida, execute por exemplo:
stty -echo -opost
strace -e read -e read=4 -p15173 2>&1 | stdbuf -o0 sh -c '
grep "^ |" | cut -b11-60 | tr -d " " | xxd -r -p'
Claro, funciona melhor se você executar isso em um terminal do mesmo tipo e tamanho que você está tentando monitorar. Você pode obter o tamanho com:
stty size < /dev/pts/that-terminal
Isso despeja o que é lido por xterm
do lado mestre do terminal, então o que é exibido lá, incluindo o local echo
do que está sendo digitado.
O -e read=4
acima é para strace
para gerar um hexdump do que xterm
lê em seu fd 4. O restante do comando é convertê-lo nos caracteres reais. Eu tentei peekfd -n -8 15173 4
, mas por algum motivo que apenas deu o que estava sendo escrito.
Estamos usando -opost
para desabilitar qualquer pós-processamento em nosso terminal de monitoramento, para que tudo que xxd
grava no lado escravo torne-o inalterado para o nosso mestre, para que nosso monitoramento xterm
obtenha o mesmo coisa como o monitorado. -echo
é para que, se a aplicação no terminal monitorado enviar uma sequência de escape que solicite uma resposta do terminal (como aquelas que solicitam a posição do cursor ou o tipo de terminal ou título da janela), ele será encaminhado para o nosso monitoramento xterm
e nosso xterm
também responderão. Nós não queremos um eco local disso.
Você também pode monitorar o que está sendo digitado, rastreando as chamadas do sistema write
para o mesmo fd (substitua read
por write
acima). Note que ao pressionar Enter , o emulador de terminal envia um caractere CR, não LF. Além disso, como estamos rastreando no lado mestre, se o usuário digitar a<Backspace>b
, veremos todos os três pressionamentos de tecla mesmo se o dispositivo terminal estiver no modo canônico.
Por que o seu não funciona:
tee /dev/pts/user_pts </dev/pts/user_pts
A leitura do dispositivo terminal está lendo a entrada do usuário e a gravação é para exibi-lo ao usuário.
Você está dizendo tee
para ler o dispositivo terminal. Então, o que ele lê (a entrada do usuário) não será read
pelo (s) aplicativo (s) em execução no terminal (e vice-versa, tee
e que application
lutará pela entrada do terminal). Escrevendo para o dispositivo terminal, é para exibição lá, não é para colocá-lo de volta lá como entrada. Quando você faz
echo test
(com o stdout de echo
sendo o terminal), não é a mesma coisa que se você tivesse digitado test
.
Existe um ioctl
( TIOCSTI
) para colocar os caracteres de volta como entrada, mas mesmo isso não funcionaria realmente porque você poderia colocá-lo de volta após o aplicativo, como já leu um pouco mais então isso mudaria a ordem em que o aplicativo está lendo entrada, e de qualquer forma, isso significaria que você o leria repetidas vezes.