Могу ли я сделать что-то похожее на перенаправление процесса stdout в файл?
rustyx
@rustyx: непроверенная, но это должно работать: создать файл , а не трубу, touch /tmp/thefile. Stdout равен 1, поэтому call close (1); Кроме того , использовать правильные разрешения для записи: call open ("/tmp/thefile", 0400). Это echo…, конечно, не нужно.
Ансгар Эстерманн
Это здорово! Я использую это, чтобы отправить "y" или "n" ответы на определенные процессы, которые были полностью отключены. Отдельный процесс имеет свой стандартный вывод в отдельном окне. Однако, когда я делаю этот трюк, я вижу, что он не "получает" 'y' или 'n', как только я повторяю его, я должен выйти из gdb и отсоединить его, а затем он получает все эхо соответственно, поэтому Есть ли способ сделать это, не выходя из GDB, прежде чем процесс получит входные данные из fifo?
krb686
к сожалению , это только кажется , висит на call open("/tmp/fifo", 0600). любая помощь будет принята с благодарностью
Лучник
27
Когда оригинальный терминал больше не доступен ...
Посмотрите на reptyr , который делает именно это. Страница github содержит всю информацию.
reptyr - инструмент для "перепечатывания" программ.
reptyr - это утилита, которая берет существующую работающую программу и присоединяет ее к новому терминалу. Запустил длительный процесс через ssh, но должен уйти и не хочет его прерывать? Просто запустите экран, используйте reptyr, чтобы захватить его, а затем завершите сеанс ssh и идите домой.
ИСПОЛЬЗОВАНИЕ
PID рептира
«reptyr PID» захватит процесс с идентификатором PID и подключит его к вашему текущему терминалу.
После подключения процесс примет входные данные и запишет выходные данные на новый терминал, включая ^ C и ^ Z. (К сожалению, если вы справитесь с этим, вам все равно придется запускать «bg» или «fg» в старом терминале. Вероятно, это невозможно исправить разумным способом без исправления вашей оболочки.)
Там нет никакого способа в стандартах (POSIX, SUS), но и на многих (большинство?) Систем это является возможным с помощью механизмов, отладчики использования. Смотрите ответ Ансгара . С помощью rootвы можете даже сделать это с процессами других пользователей.
dmckee
3
Выполнение echo "test" > /dev/pts/1не отправит входные данные процессу 9947- оно выведет слово «тест» на терминал этого процесса.
psmears
6
РЕДАКТИРОВАТЬ : Как сказал Стефан Гименес, это не так просто. Это позволяет вам печатать только на другом терминале.
Вы можете попытаться написать в этот процесс, используя / proc . Он должен находиться в / proc / pid / fd / 0 , поэтому просто:
echo "hello">/proc/PID/fd/0
должен сделать это. Я не пробовал, но это должно работать, пока этот процесс все еще имеет действительный дескриптор файла stdin . Вы можете проверить его ls -lна / Proc / PID / FD / .
если это ссылка на / dev / null => она закрыта
если это ссылка на / dev / pts / X или сокет => она открыта
Смотрите nohup для более подробной информации о том, как сохранить процессы запущенными.
Это не так просто. Например, если stdin связан с терминалом, если echoчто-то на терминальное устройство просто напечатает то, что вы написали на терминале, оно не будет передано процессу.
Стефан Гименес
5
Простое завершение командной строки &не полностью отсоединит процесс, а просто запустит его в фоновом режиме. (С помощью zshвы можете использовать, &!чтобы фактически отсоединить его, в противном случае вы должны сделать disownэто позже).
Когда процесс выполняется в фоновом режиме, он больше не будет получать входные данные от своего управляющего терминала. Но вы можете отправить его обратно на передний план, fgи тогда он снова будет читать ввод.
В противном случае, невозможно внешне изменить его файловые дескрипторы (включая stdin) или подключить потерянный управляющий терминал ... если вы не используете инструменты отладки (см . Ответ Ансгара или посмотрите на rettyкоманду).
@andcoz: Да, но ему повезло, что программа не была взломана. Я предлагал более безопасный метод.
Стефан Гименес
здесь, disown действительно работает, только если я сначала перенаправляю стандартный вывод, как с помощью >>/dev/stderr, в противном случае, когда я закрываю терминал, процесс «отречения» тоже закончится .. Я никогда не понимал этого, хотя…
retty
,neercs
и т.д. , а также увидеть serverfault.com/questions/24425 , serverfault.com/questions/115998Ответы:
Да, это. Во- первых, создать канал:
mkfifo /tmp/fifo
. Используйте gdb для присоединения к процессу:gdb -p PID
Затем закройте STDIN:
call close (0)
; и откройте его снова:call open ("/tmp/fifo", 0600)
Наконец, запишите (с другого терминала, поскольку gdb, вероятно, зависнет):
echo blah > /tmp/fifo
источник
touch /tmp/thefile
. Stdout равен 1, поэтомуcall close (1)
; Кроме того , использовать правильные разрешения для записи:call open ("/tmp/thefile", 0400)
. Этоecho…
, конечно, не нужно.call open("/tmp/fifo", 0600)
. любая помощь будет принята с благодарностьюКогда оригинальный терминал больше не доступен ...
reptyr
может быть, что вы хотите, см. https://serverfault.com/a/284795/187998Цитата оттуда:
источник
Я совершенно уверен, что вы не можете.
Проверьте с помощью
ps x
. Если процесс имеет в?
качестве управляющего терминала , вы не можете отправить свой вклад в него больше.В этом примере вы можете отправить ввод, чтобы
9947
сделать что-то вродеecho "test" > /dev/pts/1
. Другой процесс (9942
) недоступен.В следующий раз вы можете использовать screen или tmux, чтобы избежать этой ситуации.
источник
dtach
если вам не нужно целоеscreen
.root
вы можете даже сделать это с процессами других пользователей.echo "test" > /dev/pts/1
не отправит входные данные процессу9947
- оно выведет слово «тест» на терминал этого процесса.РЕДАКТИРОВАТЬ : Как сказал Стефан Гименес, это не так просто. Это позволяет вам печатать только на другом терминале.
Вы можете попытаться написать в этот процесс, используя / proc . Он должен находиться в / proc / pid / fd / 0 , поэтому просто:
должен сделать это. Я не пробовал, но это должно работать, пока этот процесс все еще имеет действительный дескриптор файла stdin . Вы можете проверить его
ls -l
на / Proc / PID / FD / .Смотрите nohup для более подробной информации о том, как сохранить процессы запущенными.
источник
echo
что-то на терминальное устройство просто напечатает то, что вы написали на терминале, оно не будет передано процессу.Простое завершение командной строки
&
не полностью отсоединит процесс, а просто запустит его в фоновом режиме. (С помощьюzsh
вы можете использовать,&!
чтобы фактически отсоединить его, в противном случае вы должны сделатьdisown
это позже).Когда процесс выполняется в фоновом режиме, он больше не будет получать входные данные от своего управляющего терминала. Но вы можете отправить его обратно на передний план,
fg
и тогда он снова будет читать ввод.В противном случае, невозможно внешне изменить его файловые дескрипторы (включая stdin) или подключить потерянный управляющий терминал ... если вы не используете инструменты отладки (см . Ответ Ансгара или посмотрите на
retty
команду).источник
>>/dev/stderr
, в противном случае, когда я закрываю терминал, процесс «отречения» тоже закончится .. Я никогда не понимал этого, хотя…