Я запускаю сценарий уже несколько дней. Я перенаправил stdout на $HOME/mylog
, но не перенаправил stderr, так как думал, что на нем ничего не будет. Внезапно на stderr стали выходить тысячи строк, поэтому я приостановил работу. Есть ли способ, с помощью которого я теперь могу перенаправлять stderr $HOME/myerr
, без необходимости перезапускать скрипт?
У меня есть доступ sudo на коробке, и это OS X.
Возможно, что-то с использованием dtools trapping?
Я не могу потерять работу, которую до сих пор выполнял скрипт, и перезапустить его с нуля. Есть ли способ «сбросить объекты в памяти» на диск, заморозить программу, отредактировать переменные (например, дескрипторы файлов) и продолжить работу с новым контекстом?
bash
io-redirection
stdout
Robottinosino
источник
источник
Ответы:
Я думаю, что это возможно, если вы присоедините процесс соответствующего интерпретатора к GDB. Я пробовал с этим perl one-liner
и это работает, но, к сожалению, не с похожим сценарием Bash.
Прежде всего вы должны выяснить PID того процесса, чей вывод вы хотите записать. Затем запустите
gdb
в другом терминале и выполните следующие команды gdbпосле этого все данные, которые записываются,
stderr
перенаправляются/abs/olu/te/path/filename
, так какattach PID
присоединяет процесс к GDB и останавливает егоcall close(2)
закрываетstderr
файловый дескриптор процесса (дляstdout
файлового дескриптора 1)call open(...)
открывает новый файл и берет самое низкое неиспользуемое целое число для вновь созданного дескриптора файла иdetach PID
продолжает процессПо крайней мере, на моей машине. Первые две строки совместимы с POSIX, но не третья.
Второй и третий аргумент
open
в третьей строке описаны вman 2 open
. В моем случае 65 означает, чтоopen
следует создать файл и открыть файл только для записи, т. Е.O_WRONLY | O_CREAT
(Определено вfcntl.h
). Третий аргумент говорит open, чтобы создать файл с разрешением на чтение и запись для пользователя, т.е.S_IWUSR | S_IRUSR
(определено вsys/stat.h
). Поэтому, возможно, вам придется самостоятельно найти подходящие значения на вашей машине.источник
Это грубый ответ, и я надеюсь, что кто-то еще добьется большего успеха, но если не появятся другие идеи, присоедините gdb и заставьте процесс сделать несколько системных вызовов:
источник
open()
захватывает FD 1? Или вам просто нужно позвонитьdup()
несколько раз?p open("errfile", O_WRONLY)
действительно работает на вашей машине?p dup2(xxx, 2)
а затем,p close(xxx)
гдеxxx
это возвращаемое значениеopen
. Это сложная штука, лучше не использовать эти команды в длительном процессе, пока вы не уверены, что другого выбора нет./dev/null
как свой,errfile
так что мне не нужноO_CREAT
. ИO_WRONLY
то, является ли макрос макросом, расширяется он или нет, зависит от того, остановил ли GDB процесс в строке, где доступны символы отладки и макрос определен. Внедрение кода в процесс с помощью gdb опасно, и никто не должен просто копировать эти команды, не понимая их.