TTY контрольні символи, надіслані до stdin of sh, не працюють


1

Я спробував розробити віддалений додаток, який запускає sh і повторно надсилає вхідні дані там, і виявив, що деякі спеціальні послідовності не працюють.

Отже, для тестування я запустив на своєму робочому столі sh, потім виконав там команду ping localhost, намагаючись порушити перерву пінг, виконавши echo -e "\003" > /proc/$shPID/fd/0з іншого оболонки. Байт 0x3- це той, який виробляється комбінацією Ctrl+ C. Незалежно від того, що я спробував (додавши новий рядок, додавши CSI на початку) , це не вийшло - символи просто відображаються у stdout sh (я маю на увазі, наприклад, новий рядок) , але не перериває виконання ping.

Як я перерваю цей ping через stdin SH?

Відповіді:


3

Це ^ C обробка здійснюється драйвером термінального пристрою, а не оболонкою.

Саме тоді, коли цей символ отримується на дроті, який підключається до пристрою tty (або записується на головній стороні основного боку псевдотермінальної пари (як xtermце робиться при натисканні Ctrl+C)), то дисципліна в рядку tty (драйвер у ядро) посилає сигнал SIGINT до групи переднього плану терміналу.

Тому вам потрібно буде надіслати цього символу на fd, який xterm відкрив на стороні master.

$ eval "$(xprop -notype -id $WINDOWID 32i '=$0\n' _NET_WM_PID)"; lsof -ap "$_NET_WM_PID" /dev/ptmx
COMMAND   PID     USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
xterm   21123 stephane    4u   CHR    5,2      0t0 1460 /dev/ptmx

Написати його /proc/21123/fd/4на Linux не вийшло, оскільки це було б просто відкрито, /dev/ptmxтому не посилайтеся на той самий псевдотермінал. Вам потрібно буде переконати в тому , xterm щоб написати це ^ C до його fd 4.

Тож насправді не варіант.

Ви можете запустити свою власну псевдотермінальну пару і запустити в ній sh і ping. Тоді ви можете написати ^ C на головній стороні для того, щоб SIGINT був надісланий групі процесу переднього плану, але простіше тут було б направити сигнал безпосередньо (перевагу буде SIGTERM).

Також зауважте, що намагатися написати персонаж /proc/$pid/fd/0не має сенсу. Дескриптор файлу зазвичай відкритий для читання. В Linux, відкриття () на цьому /proc/$pid/fd/0фактично відновлює ресурс, на який вказує цей fd.

Так, наприклад , якщо shбув запущений з sh < /some/file, роблячи echo something > "/proc/$shpid/fd/0"б замінити вміст /some/fileз something\n. Якби це було tty, то це просто відображатиметься somethingна цьому терміналі. Єдиний випадок, коли пишуть something, що щось читається - shце, коли б це було, - це труба. Якщо в Linux (і тільки в Linux), якщо ви працюєте open()в режимі запису до /proc/$shpid/fd/0(де це труба), то це відкриває кінець запису цієї труби (хоча цей fd 0 фактично вказує на кінець читання).

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.