Jest to fd po stronie master pseudo-terminala w emulatorze terminali, który chcesz monitorować, jeśli chcesz zobaczyć, co się na nim wyświetla. Ten master fd jest tym, co symuluje drut prowadzący do prawdziwego terminala. Co xterm
pisze na nim jest postacie wygenerowane z klucza naciśnięcia. Odczytuje z niego to, co wyświetla.
Na przykład w systemie 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
A następnie uruchom na przykład:
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'
Oczywiście działa lepiej, jeśli uruchamiasz go w terminalu tego samego typu i wielkości, co ten, który próbujesz monitorować. Rozmiar można uzyskać za pomocą:
stty size < /dev/pts/that-terminal
Że wysypisk co jest czytane przez xterm
od strony głównego terminala, więc to, co jest wyświetlane tam, w tym lokalnej echo
, co jest wpisane.
-e read=4
Powyżej jest strace
do wyjścia hexdump co xterm
czyta na jego fd 4. spoczynku polecenia jest konwersja że do rzeczywistych postaci. Próbowałem, peekfd -n -8 15173 4
ale z jakiegoś powodu podałem tylko to, co zostało napisane.
Używamy -opost
do wyłączania przetwarzania końcowego w naszym terminalu monitorującym, aby wszystko xxd
zapisywało po stronie podrzędnej, co czyni go niezmienionym po stronie nadrzędnej, dzięki czemu nasze monitorowanie xterm
jest takie samo jak monitorowane. -echo
jest tak, że jeśli aplikacja w monitorowanym terminalu wysyła sekwencję ucieczki, która żąda odpowiedzi z terminala (na przykład tych, które żądają pozycji kursora lub typu terminala lub tytułu okna), to przejdzie do naszego monitorowania xterm
i naszej xterm
woli odpowiedz również. Nie chcemy lokalnego echa tego.
Można także monitorować to, co jest wpisane przez śledzenie write
wywołań systemowych do tego samego fd (zamiast read
z write
wyżej). Zauważ, że po naciśnięciu Enteremulator terminala wysyła znak CR, a nie LF. Ponadto, ponieważ śledzimy po stronie wzorcowej, jeśli użytkownik wpisze a<Backspace>b
, zobaczymy wszystkie 3 naciśnięcia klawiszy, nawet jeśli urządzenie końcowe jest w trybie kanonicznym.
Dlaczego twój nie działa:
tee /dev/pts/user_pts </dev/pts/user_pts
Odczytywanie z urządzenia końcowego odczytuje dane wejściowe użytkownika, a zapisywanie na nim ma na celu wyświetlenie go użytkownikowi.
Mówisz tee
czytać z urządzenia końcowego. Więc to, co odczytuje (dane wejściowe użytkownika), nie będzie read
przez aplikacje działające w terminalu (i odwrotnie, tee
i to application
będzie walczyć o dane wejściowe na terminalu). Zapis do urządzenia końcowego służy do wyświetlania, nie służy do umieszczania go z powrotem jako danych wejściowych. Kiedy to zrobisz
echo test
(ze echo
stdout jest terminalem), to nie to samo, co gdybyś pisał test
.
Istnieje funkcja ioctl
( TIOCSTI
), aby wstawić znaki z powrotem jako dane wejściowe, ale nawet to nie zadziałałoby, ponieważ można je było umieścić z powrotem po aplikacji, ponieważ już przeczytało trochę więcej, więc zmieniłoby kolejność, w której aplikacja odczytuje dane wejściowe, i w dowolny sposób, oznaczałoby to, że czytałbyś go w kółko.
ttysnoop
lub prawdopodobniepeekfd
.