Вопрос: Как я могу перенаправить stdout / stderr уже запущенного процесса?


(Работает на 64-битном сервере Ubuntu 10.04)

Вчера я допустил ошибку при запуске процесса (который я не понимал, что потребуется несколько дней для запуска) через SSH без использования экрана. Сегодня я провел весь день, пытаясь понять, каким образом я могу вырвать вывод процесса из железа, чтобы я мог перезагрузить мою клиентскую машину, но я никуда не денусь.

Я попытался использовать gdb и следуя инструкциям внизу эта страница, но когда я запускаю первую команду gdb для создания файла, я получаю сообщение об ошибке No symbol table is loaded. Use the "file" command.  Из того, что я собрал, это означает, что мне нужно перекомпилировать программу, выход которой я пытаюсь перенаправить, что, конечно, абсолютно не помогает мне сейчас, когда она уже запущена.

Я также подумал, что могу использовать retty для перенаправления вывода на другой терминал, но, по-видимому, он не компилируется на 64-битных платформах.

Как я могу перенаправить вывод этого процесса на другой терминал или в файл?


7
2017-12-16 01:48


Источник




Ответы:


Похоже, что эти инструкции приведены для gdb являются неправильными и неполными несколькими способами.

Во-первых, вам нужно использовать

gdb [executablefile] [pid]

так что GDB знает, что программа, с которой она подключается на самом деле является, Я просто проверил это, и он может использовать лишенный исполняемый файл. Обратите внимание, что пока gdb подключен к процессу, процесс будет приостановлен. Если этот процесс взаимодействует через сеть, введите быстро или сетевое соединение, вероятно, будет тайм-аутом.

Во-вторых, приведенные команды не объясняют какие они делают, и инструкция, которую вы должны записать в каталог, в котором вы хотите, чтобы ваша программа записывала файлы, неверна, поскольку gdb просит исходную программу выполнить creat() функция. В приведенном примере будут созданы файлы myprog.stderr и myprog.stdout в текущем рабочем каталоге запущенной программы, а не в каталоге, в котором вы запускали gdb. Используйте абсолютные пути, если вы не знаете, что такое CWD этой программы (или посмотрите на ls -l /proc/[pid]/cwd).

В-третьих, работая с отсутствием объяснений, важно знать, что первый параметр dup2() это номер дескриптора файла, возвращенный предыдущим creat() поэтому, если в этой запущенной программе было открыто несколько файлов, вы могли бы получить обмен, например

(gdb) call creat("/home/me/myprog.stdout",0600)
$1 = 7
(gdb) call dup2(7,1)
$2 = 1
(gdb) call creat("/home/me/myprog.stderr",0600)
$3 = 8
(gdb) call dup2(8,2)
$4 = 2

Когда вы выйдете из gdb, он спросит вас, хотите ли вы «все равно выйти (и отделить его)», ответ «да».

В заключение, bg а также disown являются bash builtins. Если вы не использовали bash, то вы сами отсюда. bg перемещает приостановленное задание на задний план, как если бы оно было запущено там, используя somecommand &, а также disown удаляет программу из списка активных программ bash в SIGHUP при выходе bash.


5
2017-12-16 05:21



Я выполнил ваши инструкции, изменив команды соответственно, и команды на этот раз были выполнены! Однако ничто не записывается в файлы, которые были созданы. В настоящее время ls -l / proc / [pid] / fd читается следующим образом (за вычетом нерелевантных бит): 0 -> / dev / pts / 0 (удалено); 1 -> / dev / pts / 0 (удалено); 2 -> / dev / pts / 0 (удалено); 3 -> / dev / sdb; 4 -> /root/myprog.stdout; 5 -> /root/myprog.stdout; 6 -> /root/myprog.stderr; 7 -> /root/myprog.stderr (И в случае, если вам интересно, рассматриваемый процесс является работающий от имени root, поэтому он должен иметь возможность записывать эти файлы.) - nonoitall
Что-то пошло не так с call dup2() то он должен был дублировать fd для «myprog.stdout» поверх fd 1, а не создавать новый fd 5. Вы все равно сможете исправить это, если будете переделывать gdb и call dup2(4,1) а также call dup2(6,2), Надеемся, что дополнительная копия открытого файла не будет мешать, но не пытайтесь call close(5) на запасной копии, я только что проверил это, и программа сразу же прервалась. - DerfK
Ах, я вижу, что пошло не так. Я спешил войти в команды gdb, и я оставил «2» в «dup2». Все, кажется, сейчас, но поскольку вывод записывается в файл stderr, который я создал. Есть еще несколько дополнительных дескрипторов, открытых, но похоже, что они не навредят. Благодаря! - nonoitall


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


0
2017-12-16 02:21



Это то, что я делал. Мне все еще нужно знать, что будет работать на стороне сервера. - nonoitall


Вы можете использовать reredirect (https://github.com/jerome-pouiller/reredirect/).

Тип

reredirect -m FILE PID

и выходы (стандарт и ошибка) будут записаны в FILE.

reredirect README также объясняет, как восстановить исходное состояние процесса, как перенаправить на другую команду или перенаправить только stdout или stderr.


0
2017-10-14 14:33