Wie bekomme ich die gesamte Befehlszeile von einem Prozess?

43

Wie kann ich die Befehlsargumente oder die gesamte Befehlszeile von einem laufenden Prozess unter Verwendung seines Prozessnamens abrufen?

Zum Beispiel dieser Prozess:

# ps
PID   USER     TIME   COMMAND
 1452 root       0:00 /sbin/udhcpc -b -T 1 -A 12 -i eth0 -p /var/run/udhcpc.eth0.pid

Und was ich will, ist /sbin/udhcpc -b -T 1 -A 12 -i eth0 -p /var/run/udhcpc.eth0.pidoder die Argumente. Ich kenne den Prozessnamen und möchte dessen Argumente. Ich benutze Busybox auf SliTaz.

Michael
quelle
Möchten Sie die Ausgabe von verarbeiten ps(nicht empfohlen) oder suchen Sie nach einem alternativen Befehl ps, mit dem Sie die Ausgabe erhalten? Was ist zu tun, wenn psmehrere Zeilen ausgegeben werden? Alles / Erstes / Letztes drucken?
Anthon
1
Welches Betriebssystem verwenden Sie?
Cyrus
Ich habe meine Frage bearbeitet. Ich kenne den Prozessnamen und möchte dessen Argumente. Ich verwende SliTaz (minimalistisches Linux) mit Busybox.
Michael
Haben Sie versucht , @ Michael argwie commandlaut @John Antwort ?
Pandya
Ja, aber wie schreibt man es in eine Variable? Ich denke an zwei Befehle: PID = pidof <process name>ps -o pid, args | grep $ PID | tr -s "" | cut -d "" -f 2 Aber auf diese Weise bekomme ich die Args nicht in einer Variablen
Michael,

Antworten:

54

Sie können den -oSchalter verwenden, um Ihr Ausgabeformat anzugeben:

$ ps -eo args

Von der Manpage :

Befehl mit allen Argumenten als Zeichenfolge. Änderungen an den Argumenten können angezeigt werden. [...]

Sie können den -pSchalter auch verwenden , um eine bestimmte PID auszuwählen:

$ ps -p [PID] -o args

pidofkann auch verwendet werden, um von Prozessname zu PID zu wechseln, wodurch die Verwendung -pmit einem Namen ermöglicht wird:

$ ps -p $(pidof dhcpcd) -o args

Natürlich können Sie auch dafür verwenden grep(in diesem Fall müssen Sie den -eSchalter hinzufügen ):

$ ps -eo args | grep dhcpcd | head -n -1

Mit GNU ps können Sie auch die Header entfernen (dies ist natürlich nicht erforderlich, wenn Sie verwenden grep):

$ ps -p $(pidof dhcpcd) -o args --no-headers

Auf anderen Systemen können Sie an AWK oder sed weiterleiten:

$ ps -p $(pidof dhcpcd) -o args | awk 'NR > 1'
$ ps -p $(pidof dhcpcd) -o args | sed 1d

Bearbeiten: Wenn Sie diese Zeile in eine Variable fangen möchten, verwenden Sie einfach $(...)wie gewohnt:

$ CMDLINE=$(ps -p $(pidof dhcpcd) -o args --no-headers)

oder mit grep:

$ CMDLINE=$(ps -eo args | grep dhcpcd | head -n -1)
John WH Smith
quelle
@ Michael ersetzt argsmit command(oder cmd).
Pandya
@Pandya Beides cmdund commandsind Aliase dafür args, das ist wohl unnötig.
John WH Smith
Ich habe keine Option -p mit Busybox: Verwendung: ps [-o COL1, COL2 = HEADER] [-T]
Michael
Sie können verwendet werden um grepdie Linie zu fangen Sie wirklich interessiert sind: ps -eo args | grep dhcpcd | head -n -1. Ich habe meine Antwort bearbeitet.
John WH Smith
Oh, das sieht gut aus: ps -o args | grep <Prozessname> | head -n 1
Michael
12

Versuchen Sie so etwas:

(Beispielausgabe von busybox unter OpenWrt auf einem meiner Router)

root@ap8:~# xargs -0 printf '%s\n' </proc/991/cmdline
/usr/sbin/uhttpd
-f
-h
/www
-r
ap8
-x
/cgi-bin
-u
/ubus
-t
60
-T
30
-k
20
-A
1
-n
3
-N
100
-R
-p
0.0.0.0:80
-p
[::]:80

/proc/$PID/cmdlineenthält die Argumente des Prozesses $PIDwie ein C-String nach dem anderen. Jede Zeichenfolge ist mit Null abgeschlossen.

Anführungszeichen um einige Argumente oder Optionen sind Shell-Sachen. Sie müssen sich die angezeigten Zeilen genauer ansehen und herausfinden, wo Leerzeichen oder andere Zeichen mit besonderer Bedeutung für die Shell verwendet werden. Sie müssen diese Zeichen oder das gesamte Argument in Anführungszeichen setzen, wenn Sie diese Zeilen wieder mit einer Befehlszeile verbinden.

Yeti
quelle
1
tr "\0" " " </proc/991/cmdline
Cyrus
@ Cyrus: Sie können dann keine Argumente, die Leerzeichen enthalten, von benachbarten, separaten Argumenten unterscheiden. Indem Sie das Null-Byte durch ein Leerzeichen ersetzen, zerstören Sie Informationen.
Yeti
1
Ich bin damit einverstanden, \0durch `` zu ersetzen , um schlecht zu sein, aber ich denke tr '\0' '\n' < /proc/$foo/cmdline, ein bisschen einfacher zu sein als xargs.
Patrick
printfErleichtert das Hinzufügen von Anführungszeichen zur Ausgabe, das Einfügen eines Leerzeichens anstelle der neuen Zeile usw. Wenn Sie daran denken, mehr Verarbeitung hinzuzufügen, ist der Weg darüber printfein guter Anfang.
Yeti
12

Methode 1 - Verwenden von ps

Du könntest es gebrauchen ps -eaf | grep 1234.

Beispiel

$ ps -eaf | grep 28865
saml     28865  9661  0 03:06 pts/2    00:00:00 bash -c sleep 10000; while [ 1 ];do echo hi;sleep 10;done
saml     28866 28865  0 03:06 pts/2    00:00:00 sleep 10000

ANMERKUNG: Busybox psenthält nicht die -eafSwitches, wie oben gezeigt ps, die in den meisten Linux-Versionen enthalten sind. Busybox pszeigt jedoch, welche Ausgabe dem von mir bereitgestellten Beispiel sehr ähnlich zu sein scheint . Sie können Busybox unter den meisten Linux-Betriebssystemen installieren und folgendermaßen ausführen:

$ busybox ps
  852 root       0:00 /sbin/auditd -n
  855 root       0:01 /sbin/audispd
  857 root       0:00 /usr/sbin/sedispatch
  866 root       0:00 /usr/sbin/alsactl -s -n 19 -c -E ALSA_CONFIG_PATH=/etc/alsa/alsactl.conf --initfile=/lib/alsa/init/00main rdaemon
  867 root       0:00 /usr/libexec/bluetooth/bluetoothd
  869 root       0:01 {firewalld} /usr/bin/python -Es /usr/sbin/firewalld --nofork --nopid
  871 root       0:32 /usr/libexec/accounts-daemon
  873 rtkit      0:05 /usr/libexec/rtkit-daemon
  875 root       0:00 /usr/sbin/ModemManager
  876 avahi      0:03 avahi-daemon: running [dufresne.local]
  878 root       0:54 /usr/sbin/irqbalance --foreground
  884 root       0:00 /usr/sbin/smartd -n -q never
  886 avahi      0:00 avahi-daemon: chroot helper
  891 chrony     0:01 /usr/sbin/chronyd
  892 root       0:01 /usr/lib/systemd/systemd-logind
  893 dbus       1:28 /bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation

Methode 2 - Verwenden von / proc

Sie können sich auch die cmdlineDatei ansehen, unter der sich jede PID befindet /proc/<pid>.

$ cat /proc/28865/cmdline 
bash-csleep 10000; while [ 1 ];do echo hi;sleep 10;done

Beachten Sie jedoch, dass der Abstand fehlt. Dies liegt daran, dass in dieser Datei ein NUL-Zeichen verwendet wird, um die Befehlszeilenargumente zu trennen. Keine Sorge, diese können herausgenommen werden.

$ tr '\0' ' ' </proc/28865/cmdline
bash -c sleep 10000; while [ 1 ];do echo hi;sleep 10;done

Verweise

slm
quelle
2

Wenn Sie die PID kennen, führen Sie einfach aus

cat / proc / pid / cmdline

Zum Beispiel für PID = 127

# cat /proc/127/cmdline ; echo ""
/usr/lib/jvm/jdk-8-oracle-x64//bin/java-Djava.util.logging.config.file=/opt/tomcat/conf/logging.properties-Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager-Djava.library.path=/usr/lib/jni-javaagent:/jmxtrans-agent-1.2.2.jar=/opt/tomcat/conf/jmxtrans-agent.xml-Dcom.sun.management.jmxremote.port=5000-Dcom.sun.management.jmxremote-Dcom.sun.management.jmxremote.ssl=false-Dcom.sun.management.jmxremote.authenticate=false-Djava.endorsed.dirs=/opt/tomcat/endorsed-classpath/opt/tomcat/bin/bootstrap.jar:/opt/tomcat/bin/tomcat-juli.jar-Dcatalina.base=/opt/tomcat-Dcatalina.home=/opt/tomcat-Djava.io.tmpdir=/opt/tomcat/temporg.apache.catalina.startup.Bootstrapstart
#
jmlotero
quelle