Це FD до основного боку псевдо-терміналу в емуляторі термінала, який ви хочете контролювати, якщо ви хочете бачити, що на ньому відображається. Цей головний fd - це те, що імітує провід, який йде до реального терміналу. На ньому xterm
написано символи, згенеровані натисканням клавіші. Що з нього читається - це те, що відображається.
Наприклад, в 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
А потім запустіть, наприклад:
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'
Звичайно, це працює краще, якщо ви запускаєте це в терміналі того ж типу і розміру, як той, який ви намагаєтеся контролювати. Розмір можна отримати за допомогою:
stty size < /dev/pts/that-terminal
Те , що відвали , що читають на xterm
з головної частини терміналу, так що відображаються там, в тому числі місцевого , echo
що в даний час набрано.
-e read=4
Вище для strace
виводити шістнадцятирічного того , що xterm
читає на його дескриптором 4. Решта команди полягає в перетворенні , що в реальних персонажів. Я намагався, peekfd -n -8 15173 4
але чомусь дав лише те, що написано.
Ми використовуємо -opost
для відключення будь-якої післяобробки в нашому терміналі моніторингу, так що все, що xxd
записується на підлеглий, робить його незмінним для нашої основної сторони, так що наш моніторинг xterm
отримує те саме, що і моніторинг. -echo
це так, що якщо програма в моніторинговому терміналі надсилає послідовність відхилення, яка вимагає відповіді від терміналу (наприклад, ті, що запитують позицію курсора або тип термінала або назву вікна), це зробить шлях до нашого моніторингу xterm
та нашої xterm
волі відповідь також. Ми не хочемо локального відгомону цього.
Крім того, можна контролювати , що набираючись відстеженням write
системних викликів в тому ж дескриптор (замінити read
з write
вище). Зауважте, що після натискання Enterемулятор терміналу надсилає символ CR, а не LF. Крім того, оскільки ми відстежуємо на головній стороні, якщо користувач вводить a<Backspace>b
, ми побачимо всі 3 натискання клавіш, навіть якщо термінальний пристрій знаходиться в канонічному режимі.
Щодо того, чому ваша не працює:
tee /dev/pts/user_pts </dev/pts/user_pts
Читання з термінального пристрою - це читання вводу користувача, а запис до нього - для відображення його користувачеві.
Ви говорите tee
читати з термінального пристрою. Отже, те, що він читає (введення користувача), не відбуватиметься read
за допомогою додатків, що працюють у терміналі (і навпаки, tee
і це application
буде боротися за термінальний вхід). Запис на термінальний пристрій призначений для відображення там, це не для того, щоб повернути його туди як вхід. Коли ви робите
echo test
(якщо echo
stdout є терміналом), це не те саме, що якби ви ввели test
.
Існує ioctl
( TIOCSTI
) повернення символів як вхідних даних, але навіть це не справді спрацювало, тому що ви можете повернути його після програми, як уже прочитали, і це змінило б порядок, коли програма читає введення, і будь-яким способом, це означатиме, що ви будете читати це знову і знову.
ttysnoop
або , можливоpeekfd
.