Це 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
(якщо echostdout є терміналом), це не те саме, що якби ви ввели test.
Існує ioctl( TIOCSTI) повернення символів як вхідних даних, але навіть це не справді спрацювало, тому що ви можете повернути його після програми, як уже прочитали, і це змінило б порядок, коли програма читає введення, і будь-яким способом, це означатиме, що ви будете читати це знову і знову.
ttysnoopабо , можливоpeekfd.