Перенаправить STDERR/STDOUT процесса ПОСЛЕ запуска, используя командную строку?
В оболочке вы можете перенаправить, >
<
и т.д., но как насчет ПОСЛЕ запуска программы?
Вот как я пришел, чтобы задать этот вопрос, программа, работающая на моем терминале, выводит раздражающий текст. Это важный процесс, поэтому я должен открыть другую оболочку, чтобы избежать текста. Я хотел бы иметь возможность >/dev/null
или другое перенаправление, чтобы я мог продолжать работать в той же оболочке.
Ответы
Ответ 1
Замыкание и повторное открытие вашего tty (т.е. отключение и повторное включение, что также может прервать некоторые из ваших фоновых процессов в процессе), у вас остается только один выбор:
- присоединяется к рассматриваемому процессу с помощью gdb и запускается:
- p dup2 (open ( "/dev/null", 0), 1)
- p dup2 (open ( "/dev/null", 0), 2)
- открепление
- выйти
например:.
$ tail -f /var/log/lastlog &
[1] 5636
$ ls -l /proc/5636/fd
total 0
lrwx------ 1 myuser myuser 64 Feb 27 07:36 0 -> /dev/pts/0
lrwx------ 1 myuser myuser 64 Feb 27 07:36 1 -> /dev/pts/0
lrwx------ 1 myuser myuser 64 Feb 27 07:36 2 -> /dev/pts/0
lr-x------ 1 myuser myuser 64 Feb 27 07:36 3 -> /var/log/lastlog
$ gdb -p 5636
GNU gdb 6.8-debian
Copyright (C) 2008 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Attaching to process 5636
Reading symbols from /usr/bin/tail...(no debugging symbols found)...done.
Reading symbols from /lib/librt.so.1...(no debugging symbols found)...done.
Loaded symbols for /lib/librt.so.1
Reading symbols from /lib/libc.so.6...(no debugging symbols found)...done.
Loaded symbols for /lib/libc.so.6
Reading symbols from /lib/libpthread.so.0...(no debugging symbols found)...done.
[Thread debugging using libthread_db enabled]
[New Thread 0x7f3c8f5a66e0 (LWP 5636)]
Loaded symbols for /lib/libpthread.so.0
Reading symbols from /lib/ld-linux-x86-64.so.2...(no debugging symbols found)...done.
Loaded symbols for /lib64/ld-linux-x86-64.so.2
(no debugging symbols found)
0x00007f3c8eec7b50 in nanosleep () from /lib/libc.so.6
(gdb) p dup2(open("/dev/null",0),1)
[Switching to Thread 0x7f3c8f5a66e0 (LWP 5636)]
$1 = 1
(gdb) p dup2(open("/dev/null",0),2)
$2 = 2
(gdb) detach
Detaching from program: /usr/bin/tail, process 5636
(gdb) quit
$ ls -l /proc/5636/fd
total 0
lrwx------ 1 myuser myuser 64 Feb 27 07:36 0 -> /dev/pts/0
lrwx------ 1 myuser myuser 64 Feb 27 07:36 1 -> /dev/null
lrwx------ 1 myuser myuser 64 Feb 27 07:36 2 -> /dev/null
lr-x------ 1 myuser myuser 64 Feb 27 07:36 3 -> /var/log/lastlog
lr-x------ 1 myuser myuser 64 Feb 27 07:36 4 -> /dev/null
lr-x------ 1 myuser myuser 64 Feb 27 07:36 5 -> /dev/null
Вы также можете рассмотреть:
- с помощью
screen
; экран предоставляет несколько виртуальных TTY, с которыми вы можете переключаться, не открывая новые SSH/telnet/etc, сеансы
- с помощью
nohup
; это позволяет закрыть и снова открыть сеанс, не теряя фоновых процессов в процессе....
Ответ 2
Это сделает:
strace -ewrite -p $PID
Это не так чисто (показывает строки вроде: write(#,<text you want to see>)
), но работает!
Вам также может не понравиться тот факт, что аргументы сокращены. Чтобы управлять этим, используйте параметр -s
, который устанавливает максимальную длину отображаемых строк.
Он захватывает все потоки, поэтому вы можете каким-то образом отфильтровать его:
strace -ewrite -p $PID 2>&1 | grep "write(1"
показывает только вызовы дескриптора 1. 2>&1
- перенаправить STDERR на STDOUT, поскольку strace
записывает в STDERR по умолчанию.
Ответ 3
riffing off vladr (и другие) отличные исследования:
создайте следующие два файла в одном каталоге, что-то на вашем пути, скажем $HOME/bin:
silence.gdb, содержащий (из ответа vladr):
p dup2(open("/dev/null",0),1)
p dup2(open("/dev/null",0),2)
detach
quit
и тишина, содержащая:
#!/bin/sh
if [ "$0" -a "$1" ]; then
gdb -p $1 -x $0.gdb
else
echo Must specify PID of process to silence >&2
fi
chmod +x ~/bin/silence # make the script executable
Теперь, в следующий раз, когда вы забудете переадресовать firefox, например, и ваш терминал начнет запутываться с неизбежным "(firefox-bin: 5117): сообщения Gdk-WARNING **: XID, возникшие проблемы впереди":
ps # look for process xulrunner-stub (in this case we saw the PID in the error above)
silence 5117 # run the script, using PID we found
Вы также можете перенаправить вывод gdb в /dev/null, если вы не хотите его видеть.
Ответ 4
Перенаправить вывод из работающего процесса на другой терминал, файл или экран:
tty
ls -l /proc/20818/fd
gdb -p 20818
Внутри gdb:
p close(1)
p open("/dev/pts/4", 1)
p close(2)
p open("/tmp/myerrlog", 1)
q
Отсоедините выполняемый процесс от терминала bash и сохраните его:
[Ctrl+z]
bg %1 && disown %1
[Ctrl+d]
Пояснение:
20818 - просто пример запуска процесса pid
p - результат печати команды gdb
закрыть (1) - закрыть стандартный вывод
/dev/pts/ 4 - терминал для записи на
close (2) - закрыть вывод ошибки
/tmp/myerrlog - файл для записи в
q - выйти из gdb
bg% 1 - запустить приостановленное задание 1 на фоне
Отключить% 1 - снять работу 1 с терминала
Ответ 5
Не прямой ответ на ваш вопрос, но это техника, которую я нашел полезной в течение последних нескольких дней: запустите исходную команду, используя "экран", а затем отсоедините.
Ответ 6
это часть сценария bash, основанная на предыдущих ответах, которая перенаправляет файл журнала во время выполнения открытого процесса, используется в качестве postscript в процессе logrotate
#!/bin/bash
pid=$(cat /var/run/app/app.pid)
logFile="/var/log/app.log"
reloadLog()
{
if [ "$pid" = "" ]; then
echo "invalid PID"
else
gdb -p $pid >/dev/null 2>&1 <<LOADLOG
p close(1)
p open("$logFile", 1)
p close(2)
p open("$logFile", 1)
q
LOADLOG
LOG_FILE=$(ls /proc/${pid}/fd -l | fgrep " 1 -> " | awk '{print $11}')
echo "log file set to $LOG_FILE"
fi
}
reloadLog
Ответ 7
Dupx - простая утилита * nix для перенаправления стандартного вывода/ввода/ошибки уже запущенного процесса.
https://www.isi.edu/~yuri/dupx/
Ответ 8
Вы можете использовать переадресацию (https://github.com/jerome-pouiller/reredirect/).
Тип
reredirect -m FILE PID
и выходные данные (стандарт и ошибка) будут записаны в ФАЙЛ.
Переадресация README также объясняет, как восстановить исходное состояние процесса, как перенаправить на другую команду или перенаправить только stdout или stderr.
reredirect
также предоставляет скрипт relink
который позволяет перенаправить на текущий терминал:
relink PID
relink PID | grep usefull_content
(Переадресация, похоже, обладает теми же возможностями, что и Dupx, описанный в другом ответе, но это не зависит от Gdb).