7

Теоретически, если я знаю pid запущенной оболочки bash, я могу запустить кошку, чей стандартный вывод перенаправляется на стандартный ввод этой оболочки. Кажется, будто я что-то набираю на этой оболочке. К сожалению, поток будет исходить от cat, НО НЕ заставит оболочку работать должным образом (введенная команда cat не будет выполнена bash).

Откройте терминал:

ps -ef | grep bash
ymf       4906  4887  0 16:19 pts/0    00:00:00 /bin/bash

На другом терминале:

cat 1> /proc/4906/fd/0
echo 'hello!'

Зачем?

3 ответа3

7

Я устал от ограничения "только один абзац" в комментариях =)

Если вы запустите shell sh и получите pid $pid вы сможете найти файловые дескрипторы, которые вы описываете. Пример:

$ ls -l /proc/29201/fd
total 0
lrwx------ 1 eroen users 64 Mar 22 15:52 0 -> /dev/pts/2
lrwx------ 1 eroen users 64 Mar 22 15:52 1 -> /dev/pts/2
lrwx------ 1 eroen users 64 Mar 22 15:52 2 -> /dev/pts/2
lrwx------ 1 eroen users 64 Mar 22 15:52 255 -> /dev/pts/2

Вы заметите, что 1 , 2 и 3 - все символические ссылки на один и тот же tty (chardev). Другими словами, входные данные процесса считываются с того же узла устройства, на который записываются выходные данные.

Когда вы пытаетесь записать (в другом процессе) в тот же tty (как /proc/$pid/fd/0 или /dev/pts/? вы делаете то же самое, что и сам процесс, когда он записывает данные в свой вывод; данные отображаются в окне терминала.

На самом деле изменить точку fd [0-2] после запуска процесса довольно сложно, но не невозможно. Reptyr - это бесплатное приложение с открытым исходным кодом, которое модифицирует существующий процесс, так что fd [0-2] указывает на другой tty (а также некоторые другие вещи). Это достигается через структуру ptrace. В посте также упоминаются другие программы, которые делают то же самое, и что это можно сделать через gdb.

В зависимости от того, чего вы на самом деле хотели достичь, вы можете обнаружить, что Reptyr или другое программное обеспечение делает то, что вам нужно. В противном случае вы можете посмотреть / скопировать / изменить исходный код и узнать, как они справляются с задачей.

Приложение:
Это содержит несколько иллюстрирующих диаграмм, в частности третью схему сверху.

5

Перейти к терминалу А любого типа tty

вы получите что-то вроде "/dev/pts/0"

Теперь перейдите к терминалу B и введите exec 0</dev/pts/0 (или что-то, что дала вам команда tty)

Вернитесь к терминалу A, и введенные вами команды будут выполняться на терминале B.

1

Как перенаправить на стандартный ввод работающей оболочки Bash?

используя C (https://stackoverflow.com/a/7370822. Я не проверял это):

char* cmd="ls\n";
int fd = open (ptsname, O_RDWR);

while (*cmd)
{
    ioctl(fd, TIOCSTI, cmd++);
}

использование Perl (https://unix.stackexchange.com/a/48221. работает отлично, но только для текущей оболочки):

require "sys/ioctl.ph";
ioctl(STDIN, &TIOCSTI, $_) for split "", join " ", @ARGV;

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .