Estou executando um script há vários dias. Eu redirecionei o stdout para $HOME/mylog
, mas não o redirecionei, pois pensei que não haveria nada nele. De repente, milhares de linhas começaram a sair no stderr, então eu suspendi o trabalho. Existe uma maneira de redirecionar o stderr $HOME/myerr
de agora em diante, sem a necessidade de reiniciar o script?
Eu tenho acesso sudo na caixa e é OS X.
Talvez algo usando dtools trapping?
Não posso perder o trabalho que o script fez até agora e reiniciá-lo do zero. Existe uma maneira de "despejar os objetos na memória" no disco, congelar o programa, editar as variáveis (por exemplo, os descritores de arquivo) e continuar com o novo contexto?
bash
io-redirection
stdout
Robottinosino
fonte
fonte
Respostas:
Eu acho que é possível se você anexar o processo do intérprete relacionado ao gdb. Eu tentei com este one-liner perl
e funciona, mas infelizmente não com um script bash semelhante.
Primeiro, você precisa descobrir o PID desse processo cuja saída você deseja capturar. Então comece
gdb
em outro terminal e execute os seguintes comandos gdbdepois disso, todos os dados que são gravados
stderr
são redirecionados/abs/olu/te/path/filename
, poisattach PID
anexa o processo ao gdb e o interrompecall close(2)
fecha ostderr
editor de arquivos do processo (parastdout
o editor de arquivos é 1)call open(...)
abre um novo arquivo e pega o menor número inteiro não utilizado para o recém-criado editor de arquivos edetach PID
continua o processoPelo menos na minha máquina. As duas primeiras linhas são compatíveis com POSIX, mas não a terceira.
O segundo e o terceiro argumento de
open
na terceira linha estão documentados emman 2 open
. No meu caso, 65 significa queopen
deve criar o arquivo e abrir o arquivo somente para gravação, ou seja,O_WRONLY | O_CREAT
(definido emfcntl.h
). O terceiro argumento diz aberto para criar o arquivo com permissão de leitura e gravação para o usuário, ou sejaS_IWUSR | S_IRUSR
(definido emsys/stat.h
). Então, talvez você precise descobrir os valores apropriados em sua máquina.fonte
Esta é uma resposta grosseira e espero que alguém faça melhor, mas se nenhuma outra idéia surgir, anexe o gdb e force o processo a fazer alguns syscalls:
fonte
open()
FD 1 é garantido? Ou você só precisa ligardup()
algumas vezes?p open("errfile", O_WRONLY)
realmente funciona na sua máquina?p dup2(xxx, 2)
e entãop close(xxx)
ondexxx
está o valor de retorno doopen
. Isso é complicado, é melhor não usar esses comandos em um processo de longa execução até ter certeza de que não há outra opção./dev/null
como meuerrfile
e não preciseiO_CREAT
. EO_WRONLY
sendo uma macro, se ela se expande ou não, depende se o gdb interrompeu o processo em uma linha em que os símbolos de depuração estão disponíveis e a macro está definida. Injetar código em um processo com o gdb é perigoso e ninguém deve copiar esses comandos sem entendê-los.