Перенаправить stderr из уже запущенного скрипта

Я уже несколько дней запускаю скрипт. Я перенаправил stdout на $HOME/mylog , но не перенаправлял stderr, так как думал, что на нем ничего не будет. Внезапно на stderr вышли тысячи линий, поэтому я приостановил работу. Есть ли способ, с которого я могу перенаправить stderr в $HOME/myerr с этого $HOME/myerr , без перезапуска скрипта?

У меня есть sudo доступ на коробке, и это OS X.

Возможно, что-то, использующее dtools trapping?

Я не могу потерять работу, которую сценарий сделал до сих пор, и перезапустить ее с нуля. Есть ли способ «сбрасывать объекты в памяти» на диск, замораживать программу, редактировать переменные (например, дескрипторы файлов) и возобновлять их с помощью нового контекста?

  • Unix без / dev / stdin, / dev / stdout и / dev / stderr?
  • IO и другие команды оболочки, когда программа не запускается терминалом
  • где находится stdin, stdout, дескриптор файла stderr в AIX (unix)
  • Командная строка 'buffer'
  • Как эти параметры qemu для перенаправления stdout работают?
  • Как узнать, перенаправляется ли выход в файл?
  • Есть ли способ выполнить собственный бинарный файл из канала?
  • Захват stdout из сеанса ssh на локальную машину
  • 2 Solutions collect form web for “Перенаправить stderr из уже запущенного скрипта”

    Я думаю, что это возможно, если вы присоедините процесс связанного интерпретатора к gdb. Я попробовал это с помощью этого perl one-liner

      perl -e 'do { print "x\n"; sleep(1) } while(1)' 

    и он работает, но, к сожалению, не с похожим сценарием bash.


    Прежде всего, вам нужно выяснить PID этого процесса, выход которого вы хотите захватить. Затем запустите gdb в другом терминале и выполните следующие команды gdb

     attach PID call close(2) call open("/abs/olu/te/path/filename", 65, 384) detach PID 

    после этого все данные, которые записываются в stderr , перенаправляются в /abs/olu/te/path/filename , поскольку

    • attach PID присоединяет процесс к gdb и останавливает его
    • call close(2) закрывает stderr filedescriptor процесса (для stdout filedescriptor равен 1)
    • call open(...) открывает новый файл и берет наименьшее неиспользованное целое число для вновь созданного filedescriptor и
    • detach PID продолжает процесс

    По крайней мере, на моей машине. Первые две строки совместимы с POSIX, но не с третьей.

    Второй и третий аргументы open в третьей строке задокументированы в man 2 open . В моем случае 65 означает, что open должен создать файл и открыть файл только для записи, т. O_WRONLY | O_CREAT O_WRONLY | O_CREAT (определяется в fcntl.h ). Третий аргумент говорит open для создания файла с правами чтения и записи для пользователя, то есть S_IWUSR | S_IRUSR S_IWUSR | S_IRUSR (определяется в sys/stat.h ). Так что, может быть, вам нужно самостоятельно найти соответствующие значения на вашей машине.

    Это грубый ответ, и я надеюсь, что кто-то другой сделает лучше, но, если нет других идей, присоедините gdb и заставите процесс сделать несколько системных вызовов:

     (gdb) attach 12345 # target PID (gdb) p close(2) (gdb) p open("errfile", O_WRONLY) (gdb) c 
    Linux и Unix - лучшая ОС в мире.