Проблема довольно проста: я считаю полезным иметь возможностьвключить (и выключить)вывод какой-то работающей программы в каждый момент, который мне нужен. Если быть точнее, я хочу иметь возможность свободно перенаправлять их стандартный вывод (и ошибку) из текущей оболочки в другую, в , /dev/null
в файл или обратно в исходную оболочку.
Я ищу что-то прямое (и безопасное), что использует тот факт, что я знаюзаранеечто я буду включать и выключать выходы. Я также публикую ответ.
Ниже моя первая попытка. Предположим, я работаю в корпусе номер 35.
$ who am I # the command line to ask where am I
myuser pts/35 ... # The answer
Моя попытка начинается с символической ссылки на этот терминал
ln -s /dev/pts/35 MyOutput # The command to link
Идея состоит в том, чтобы запустить программу с установленным перенаправлением на эту ссылку.
./Execute_program > MyOutput
Это работает, перенаправляет вывод на мой терминал, но когда я даю команду изменить ссылку,
ln -sf /dev/null MyOutput
ссылка меняется,но перенаправление не меняетсякак я и надеялся. Это не меняется для запущенного процесса. Если я запускаю новую программу таким же образом, перенаправление следует новому предписанию ссылки. Если я
запускаю снова и устанавливаю ссылку на /dev/null
вывод, он подавляется, как и ожидалось, но снова, когда я меняю ссылку, перенаправление не меняется.
Если я делаю ссылку на ссылку, я получаю тот же результат. Использование hard link
не меняет ситуацию.
Грустнооболочка расширяет командную строку во время запуска.
Есть ли возможность сделать эту работу аналогичным образом или мне нужно найти способ сообщить процессу (или PPID) об изменении ссылки?
Примечания:
Это вопрос из серии «Как перенаправить вывод запущенного процесса?», но он начинается не с того места«Опс, я запустил программу и забыл перенаправить вывод. Теперь я хочу это сделать», а с другой стороны: «Как я могу запустить программу с явной целью перенаправить вывод в другое место на более позднем этапе?».
Я намерен использовать такую процедуру, когда невозможно (или неудобно) модифицировать исходный код программы.
Ячитатьчто можно disown
обрабатывать, использовать screen
и переносить с одного экрана на другой... или использовать отладчик, чтобы перехватить процесс... Все эти решения могли бы работать при наличии достаточного опыта и усилий, но некоторые из них также представляют определенный процент риска.
решение1
Я нахожу решение через mkfifo
, которое создает именованный канал, илиFIFO.
Просто создайте символическую ссылку и сможете использовать все перенаправления, разрешенные в оболочке.
mkfifo MyOutput
ls -l
дает
0 prw-r--r-- 1 My_username My_username 0 May 11 17:45 MyOut|
Я могу запустить программу с перенаправлением на эту ссылку
./Execute_program > MyOutput & cat MyOutput
и вывод начинает поступать на терминал.
Если я нажимаю ctrl+, cя прерываю поток, но не запущенный процесс (мне нужно использовать что-то вроде kill pid
или , kill %1
чтобы сделать это).
Когда во второй раз я спрошуFIFOдля сброса на терминал (снова с помощью cat MyOutput
) он начнет выводить вывод с этого момента.
Примечания и предупреждения:
- Пока я не попрошу дамп из
FIFOs
него будет держать весь вывод.
Как я попрошу в первый раз, он будетвымыватьвсе. - Я могу перенаправить (или добавить) в другой файл
cat MyOutput >> NewRealFile
- Я могу использовать
cat MyOutput
и с другого терминала! - Предупреждение: Если я попрошу две разные программы (или экземпляры) перенаправить вывод в одну и ту же программу,
FIFOs
поток будет объединен (нетаприориспособ отличить, из каких программ взята эта строка). - Предупреждение: Если я спрошу 2 или более раз (возможно, с разных терминалов), он выдаст одну строку для каждого запроса, разделив вывод для запрашивающего. Может быть, есть безопасный обходной путь...
решение2
Если я правильно понял ваш вопрос:
script 1>>~/out.fifo 2>>~/error.fifo
то для мониторинга вы можете сделать что-то вроде:
watch cat ~/out.fifo
Вместо FIFO можно использовать настоящие файлы.
script 1>/tmp/$0-out 2>/tmp/$0-error
затем выполните команду tail -f, и они будут заменены при повторном запуске скриптов.
Я предпочитаю второй метод, или просто использование мультиплексора (т.е. экрана или какой-либо другой популярной реинкарнации на этой неделе)
screen -t "name" bash -c 'script'
затем
screen -r
для «мониторинга» и ctrl+ad для отключения.
Обязательно сделайте паузу в конце скрипта, если вы хотите увидеть результат его выполнения.
решение3
Если бы я был вами, я бы просто перенаправил вывод в файл, а затем выполнил команду tailf для этого файла, когда захотел бы увидеть вывод... также вы можете ограничить размер этого файла, если считаете, что вывод будет довольно длинным, или записать файл в оперативную память, а не на диск, если считаете, что вывод будет довольно быстрым, но как это сделать — другой вопрос, я не знаю.