Siehe Ausgabe von einem laufenden Prozess umleiten .
Zuerst führe ich den Befehl cat > foo1
aus in einer Sitzung und testen Sie, ob Daten von stdin in die Datei kopiert werden. Dann leite ich in einer anderen Sitzung die Ausgabe um.
Finden Sie zuerst die PID des Prozesses:
$ ps aux | grep cat
rjc 6760 0.0 0.0 1580 376 pts/5 S+ 15:31 0:00 cat
Überprüfen Sie nun die geöffneten Datei-Handles:
$ 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
Führen Sie nun GDB:
aus$ 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
Die p
Der Befehl in GDB gibt den Wert eines Ausdrucks aus, ein Ausdruck kann eine aufzurufende Funktion sein, es kann ein Systemaufruf sein … Also führe ich einen close()
aus Systemaufruf und Dateihandle 1 übergeben, dann führe ich einen creat()
aus Systemaufruf zum Öffnen einer neuen Datei. Das Ergebnis von creat()
war 1, was bedeutet, dass es das vorherige Dateihandle ersetzt hat. Wenn ich dieselbe Datei für stdout und stderr verwenden oder ein Dateihandle durch eine andere Nummer ersetzen wollte, müsste ich dup2()
aufrufen Systemaufruf, um dieses Ergebnis zu erzielen.
Für dieses Beispiel habe ich mich für creat()
entschieden statt open()
weil es weniger Parameter gibt. Die C-Makros für die Flags können nicht von GDB verwendet werden (es verwendet keine C-Header), also müsste ich Header-Dateien lesen, um dies zu entdecken – das ist nicht so schwer, würde aber mehr Zeit in Anspruch nehmen. Beachten Sie, dass 0600 die oktale Berechtigung für den Eigentümer mit Lese-/Schreibzugriff und die Gruppe und andere ohne Zugriff ist. Es würde auch funktionieren, 0 für diesen Parameter zu verwenden und später chmod auf der Datei auszuführen.
Danach verifiziere ich das Ergebnis:
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
Geben Sie mehr Daten in cat
ein ergibt die Datei /tmp/foo3
angehängt wird.
Wenn Sie die ursprüngliche Sitzung schließen möchten, müssen Sie alle Dateihandles dafür schließen, ein neues Gerät öffnen, das das steuernde tty sein kann, und dann setsid()
aufrufen .
Sie können dies auch mit reredirect
tun (https://github.com/jerome-pouiller/reredirect/).
Der folgende Befehl leitet die Ausgaben (Standard und Fehler) des Prozesses PID
um bis FILE
:
reredirect -m FILE PID
Die README
von reredirect
erklärt auch andere interessante Funktionen:wie man den ursprünglichen Zustand des Prozesses wiederherstellt, wie man auf einen anderen Befehl umleitet oder nur stdout oder stderr umleitet.
Das Tool bietet auch relink
, ein Skript, mit dem die Ausgaben auf das aktuelle Terminal umgeleitet werden können:
relink PID
relink PID | grep usefull_content
(reredirect
scheint dieselben Funktionen zu haben wie Dupx, die in einer anderen Antwort beschrieben wurden, hängt jedoch nicht von Gdb ab).