É o fd no lado principal do pseudo-terminal no emulador de terminal que você deseja monitorar se deseja ver o que é exibido nele. Esse 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 ele exibe.
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 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'
Obviamente, funciona melhor se você o executar em um terminal do mesmo tipo e tamanho que o que você está tentando monitorar. Você pode obter o tamanho com:
stty size < /dev/pts/that-terminal
Isso despeja o que é lido pelo xterm
lado mestre do terminal, então o que é exibido lá, incluindo o local echo
do que está sendo digitado.
O exemplo -e read=4
acima é para strace
gerar um hexdump do que é xterm
lido em seu fd 4. O restante do comando é converter isso nos caracteres reais. Eu tentei, peekfd -n -8 15173 4
mas por algum motivo, apenas deu o que estava sendo escrito.
Estamos usando -opost
para desativar qualquer pós-processamento em nosso terminal de monitoramento, para que tudo o que é xxd
gravado no lado escravo o mantenha inalterado em nosso lado mestre, para que nosso monitoramento xterm
fique com a mesma coisa que o monitorado. -echo
é para que, se o aplicativo 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 o título da janela), isso vá para o nosso monitoramento xterm
e nossa xterm
vontade responda também. Não queremos um eco local disso.
Você também pode monitorar o que está sendo digitado, rastreando as write
chamadas do sistema para o mesmo fd (substitua read
por write
acima). Observe 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 as três teclas pressionadas, mesmo que o dispositivo terminal esteja no modo canônico.
Por que o seu não funciona:
tee /dev/pts/user_pts </dev/pts/user_pts
A leitura do dispositivo do terminal está lendo a entrada do usuário e a gravação é exibida para o usuário.
Você está dizendo tee
para ler no dispositivo terminal. Portanto, 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 isso application
lutará pela entrada do terminal). Escrever no dispositivo do terminal é para exibição lá, não é para colocá-lo lá de volta como entrada. Quando você faz
echo test
(com echo
stdout sendo o terminal), não é a mesma coisa que se você tivesse digitado test
.
Há um ioctl
( TIOCSTI
) para colocar caracteres de volta como entrada, mas mesmo isso não funcionaria realmente porque você poderia colocá-lo novamente após o aplicativo já ter lido mais um pouco, portanto isso mudaria a ordem em que o aplicativo está lendo a entrada e, de qualquer maneira, isso significaria que você a leria repetidas vezes.
ttysnoop
ou provavelmentepeekfd
.