Consulta Reindirizzamento dell'output da un processo in esecuzione .
Per prima cosa eseguo il comando
cat > foo1
in una sessione e verificare che i dati da stdin vengano copiati nel file. Poi in un'altra sessione reindirizzo l'output.Per prima cosa trova il PID del processo:
$ ps aux | grep cat rjc 6760 0.0 0.0 1580 376 pts/5 S+ 15:31 0:00 cat
Ora controlla gli handle di file che ha aperto:
$ ls -l /proc/6760/fd total 3 lrwx—— 1 rjc rjc 64 Feb 27 15:32 0 -> /dev/pts/5 l-wx—— 1 rjc rjc 64 Feb 27 15:32 1 -> /tmp/foo1 lrwx—— 1 rjc rjc 64 Feb 27 15:32 2 -> /dev/pts/5
Ora esegui GDB:
$ gdb -p 6760 /bin/cat GNU gdb 6.4.90-debian [license stuff snipped] Attaching to program: /bin/cat, process 6760 [snip other stuff that's not interesting now] (gdb) p close(1) $1 = 0 (gdb) p creat("/tmp/foo3", 0600) $2 = 1 (gdb) q The program is running. Quit anyway (and detach it)? (y or n) y Detaching from program: /bin/cat, process 6760
L'
p
comando in GDB stamperà il valore di un'espressione, un'espressione può essere una funzione da chiamare, può essere una chiamata di sistema... Quindi eseguo unclose()
chiamata di sistema e passo l'handle di file 1, quindi eseguo uncreat()
chiamata di sistema per aprire un nuovo file. Il risultato delcreat()
era 1, il che significa che ha sostituito l'handle di file precedente. Se volessi usare lo stesso file per stdout e stderr o se volessi sostituire un handle di file con un altro numero allora avrei bisogno di chiamare ildup2()
chiamata di sistema per ottenere quel risultato.Per questo esempio ho scelto di utilizzare
creat()
invece diopen()
perché ci sono meno parametri. Le macro C per i flag non sono utilizzabili da GDB (non usa le intestazioni C) quindi dovrei leggere i file di intestazione per scoprirlo - non è così difficile farlo ma richiederebbe più tempo. Si noti che 0600 è l'autorizzazione ottale per il proprietario che ha accesso in lettura/scrittura e il gruppo e altri non hanno accesso. Funzionerebbe anche usare 0 per quel parametro ed eseguire chmod sul file in un secondo momento.Successivamente, verifico il risultato:
ls -l /proc/6760/fd/ total 3 lrwx—— 1 rjc rjc 64 2008-02-27 15:32 0 -> /dev/pts/5 l-wx—— 1 rjc rjc 64 2008-02-27 15:32 1 -> /tmp/foo3 <==== lrwx—— 1 rjc rjc 64 2008-02-27 15:32 2 -> /dev/pts/5
Digitando più dati in
cat
risulta nel file/tmp/foo3
essere aggiunto a.Se vuoi chiudere la sessione originale devi chiudere tutti gli handle di file per essa, aprire un nuovo dispositivo che può essere il tty di controllo, quindi chiamare
setsid()
.
Puoi anche farlo usando reredirect
(https://github.com/jerome-pouiller/reredirect/).
Il comando seguente reindirizza gli output (standard ed errore) del processo PID
a FILE
:
reredirect -m FILE PID
Il README
di reredirect
spiega anche altre caratteristiche interessanti:come ripristinare lo stato originale del processo, come reindirizzare a un altro comando o reindirizzare solo stdout o stderr.
Lo strumento fornisce anche relink
, uno script che consente di reindirizzare gli output al terminale corrente:
relink PID
relink PID | grep usefull_content
(reredirect
sembra avere le stesse caratteristiche di Dupx descritto in un'altra risposta ma non dipende da Gdb).