Ich habe eine lange andauernde bash
Instanz (innerhalb eines screen
session), die einen komplexen Satz von Befehlen innerhalb einer Schleife ausführt (wobei jede Schleife Pipes, Redirects usw. ausführt).
Die lange Befehlszeile wurde in das Terminal geschrieben – sie befindet sich nicht in einem Skript. Jetzt kenne ich die Bash-Prozess-ID und habe Root-Zugriff – wie kann ich die genaue Befehlszeile sehen, die in dieser bash
ausgeführt wird ?
Beispiel
bash$ echo $$
1234
bash$ while true ; do
someThing | somethingElse 2>/foo/bar |
yetAnother ; sleep 600 ; done
Und in einer anderen Shell-Instanz möchte ich die in PID 1234 ausgeführte Befehlszeile sehen:
bash$ echo $$
5678
bash$ su -
sh# cd /proc/1234
sh# # Do something here that will display the string
'while true ; do someThing | somethingElse 2>/foo/bar |
yetAnother ; sleep 600 ; done'
Ist das möglich?
EDIT #1
Hinzufügen von Gegenbeispielen für einige Antworten, die ich habe.
-
Über die Verwendung der
cmdline
unter/proc/PID
:Das funktioniert nicht, zumindest nicht in meinem Szenario. Hier ist ein einfaches Beispiel:$ echo $$ 8909 $ while true ; do echo 1 ; echo 2>/dev/null ; sleep 30 ; done
In einer anderen Shell:
$ cat /proc/8909/cmdline bash
-
Verwenden von
ps -p PID --noheaders -o cmd
ist genauso nutzlos:$ ps -p 8909 --no-headers -o cmd bash
-
ps -eaf
ist auch nicht hilfreich:$ ps -eaf | grep 8909 ttsiod 8909 8905 0 10:09 pts/0 00:00:00 bash ttsiod 30697 8909 0 10:22 pts/0 00:00:00 sleep 30 ttsiod 31292 13928 0 10:23 pts/12 00:00:00 grep --color=auto 8909
Das heißt, es gibt keine Ausgabe der ORIGINAL-Befehlszeile, wonach ich suche – dh der
while true ; do echo 1 ; echo 2>/dev/null ; sleep 30 ; done
.
Akzeptierte Antwort:
Ich wusste, dass ich nach Strohhalmen greife, aber UNIX versagt nie!
So habe ich es geschafft:
bash$ gdb --pid 8909
...
Loaded symbols for /lib/i386-linux-gnu/i686/cmov/libnss_files.so.2
0xb76e7424 in __kernel_vsyscall ()
Dann am (gdb)
prompt Ich habe den Befehl ausgeführt, call write_history("/tmp/foo")
was diesen Verlauf in die Datei /tmp/foo
schreiben wird .
(gdb) call write_history("/tmp/foo")
$1 = 0
Ich löse mich dann aus dem Prozess.
(gdb) detach
Detaching from program: /bin/bash, process 8909
Und beenden Sie gdb
.
(gdb) q
Und tatsächlich…
bash$ tail -1 /tmp/foo
while true ; do echo 1 ; echo 2>/dev/null ; sleep 30 ; done
Für eine einfache zukünftige Wiederverwendung habe ich ein Bash-Skript geschrieben, das den Prozess automatisiert.