Este método não é aconselhável. Não use. Se quebrar o seu sistema, você consegue manter todas as peças.
Tudo bem! Ainda comigo? Para um caso descomplicado com inclusões apropriadas ( fcntl
, para open
), redirecionar o padrão para outro local é (em teoria) possível:
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int main(void)
{
while (1) {
printf("blat\n");
sleep(1);
}
exit(EXIT_SUCCESS);
}
Compilado e executado:
$ cc -g blat.c -o blat
$ ./blat &
Agora, em algum outro terminal (isso pode atrapalhar as políticas de segurança por vários motivos óbvios, dado o que um depurador pode fazer em um processo ativo) usando o PID emitido para o job em background:
$ gdb -q -p 3727
...
(gdb) call close(1)
$1 = 0
Depois de ler close(2)
, determinamos que isso é um sucesso, a entrada padrão foi encerrada. Vamos abrir um novo arquivo ...
(gdb) call open("/home/userrunningblat/blat.out", O_CREAT|O_WRONLY, 0666)
No symbol "O_CREAT" in current context.
Bem atirar. Qual é o número mágico sem esses símbolos? Em um terceiro terminal, usando nosso prático compilar-e-executar-algum-programa-C :
$ cfu 'printf("%d\n", O_CREAT|O_WRONLY)'
65
Ou você pode pesquisar o diretório /usr/include
e descobrir os formatos de entrada e bitwise OR, mas isso é super irritante. (Observe também que esses números podem variar por OS.) Voltar para gdb
!
(gdb) call open("/home/userrunningblat/blat.out", 65, 0666)
$2 = 1
(gdb) quit
$ tail -f blat.out
O que significa que, como encerramos anteriormente a norma ( 1
), esta open(2)
chamada reutilizou essa número do descritor de arquivo, então depois que sairmos de gdb
, a saída padrão deve estar indo para aquele arquivo.
Este método pode não ser possível para programas mais complicados, pode não ser possível devido a restrições de segurança, falta de informações sobre o depurador, pode causar uma quebra horrível, etc.