Comment obtenir une ligne de commande complète à partir d'un processus?

44

Comment puis-je obtenir les arguments de commande ou la ligne de commande complète d'un processus en cours à l'aide de son nom de processus?

Par exemple ce processus:

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

Et ce que je veux c'est /sbin/udhcpc -b -T 1 -A 12 -i eth0 -p /var/run/udhcpc.eth0.pidou les arguments. Je connais le nom du processus et je veux ses arguments. J'utilise Busybox sur SliTaz.

Michael
la source
Voulez-vous traiter la sortie de ps(non recommandé) ou cherchez-vous une commande alternative à pscelle qui vous donnera la sortie? Que faut-il faire quand on psdonne plusieurs lignes de sortie? imprimer tout / premier / dernier?
Anthon
1
Quel système d'exploitation utilisez-vous?
Cyrus
J'ai édité ma question. Je connais le nom du processus et je veux ses arguments. J'utilise SliTaz (linux minimaliste) avec Busybox.
Michael
@Michael Avez-vous essayé argcomme commanddans la réponse @John ?
Pandya
Oui mais comment l'écrire dans une variable? Je pense à deux commandes: PID = pidof <process name>ps -o pid, args | grep $ PID | tr -s "" | cut -d "" -f 2 Mais de cette façon, je ne reçois pas les arguments dans une variable
Michael

Réponses:

55

Vous pouvez utiliser le -ocommutateur pour spécifier votre format de sortie:

$ ps -eo args

De la page de manuel :

Commande avec tous ses arguments sous forme de chaîne. Des modifications aux arguments peuvent être montrées. [...]

Vous pouvez également utiliser le -pcommutateur pour sélectionner un PID spécifique:

$ ps -p [PID] -o args

pidofpeut également être utilisé pour passer d'un nom de processus à un PID, permettant ainsi l'utilisation d' -pun nom:

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

Bien sûr, vous pouvez aussi utiliser greppour cela (dans ce cas, vous devez ajouter le -ecommutateur):

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

GNU ps vous permettra également de supprimer les en-têtes (bien sûr, cela n’est pas nécessaire lors de l’utilisation grep):

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

Sur d’autres systèmes, vous pouvez diriger vers AWK ou sed:

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

Edit: si vous voulez attraper cette ligne dans une variable, utilisez $(...)comme d'habitude:

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

ou avec grep:

$ CMDLINE=$(ps -eo args | grep dhcpcd | head -n -1)
John WH Smith
la source
@Michael remplacer argspar command(ou cmd).
Pandya
@Pandya Les deux cmdet commandsont des alias args, c'est probablement inutile.
John WH Smith
Je n'ai pas d'option -p utilisant Busybox: Utilisation: ps [-o COL1, COL2 = EN-TÊTE] [-T]
Michael
Vous pouvez utiliser greppour attraper la ligne que vous êtes réellement intéressé par: ps -eo args | grep dhcpcd | head -n -1. J'ai édité ma réponse.
John WH Smith
Oh, ça a l'air bien: ps -o args | grep <nom du processus> | tête-n 1
Michael
12

Essayez quelque chose comme ça:

(exemple de sortie de busybox sur OpenWrt sur l'un de mes routeurs)

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/cmdlinecontient les arguments de processus $PIDcomme des chaînes C-ish les unes après les autres. Chaque chaîne est terminée par zéro.

Les citations autour de certains arguments ou options font partie du shell. Vous devez examiner de plus près les lignes affichées et l'emplacement des espaces ou autres caractères ayant une signification particulière pour le shell. Vous aurez besoin de citer ce caractère (s) ou l'argument complet lorsque vous joignez à nouveau ces lignes à une ligne de commande.


la source
1
tr "\0" " " </proc/991/cmdline
Cyrus
@Cyrus: Vous ne pouvez pas distinguer les arguments contenant des espaces d'arguments séparés adjacents. En remplaçant l'octet zéro par un espace, vous détruisez des informations.
1
Je suis d’accord pour remplacer \0«être mauvais», mais je pense tr '\0' '\n' < /proc/$foo/cmdlineêtre un peu plus simple que xargs.
Patrick
printffacilite l'ajout de guillemets à la sortie, l'insertion d'un espace au lieu de la nouvelle ligne, etc. Lorsque vous songez à ajouter davantage de traitement, cette solution printfest un bon début.
12

Méthode n ° 1 - Utiliser ps

Vous pourriez utiliser ps -eaf | grep 1234.

Exemple

$ 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

REMARQUE: Busybox psn'inclut pas les -eafcommutateurs illustrés ci-dessus par rapport psà la plupart des systèmes Linux. Cependant, Busybox psindique une sortie qui ressemble beaucoup à l'exemple que j'ai fourni. Vous pouvez installer Busybox sur la plupart des Linux et l’exécuter comme suit:

$ 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

Méthode n ° 2 - Utiliser / proc

Vous pouvez également consulter le cmdlinefichier sous lequel se trouve chaque PID /proc/<pid>.

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

Mais remarquez qu'il manque l'espacement. Cela est dû au fait qu'un caractère NUL est utilisé dans ce fichier pour séparer vos arguments de ligne de commande. Ne vous inquiétez pas cependant, ceux-ci peuvent être supprimés.

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

Les références

slm
la source
2

Connaître le PID, juste exec

cat / proc / pid / cmdline

Par exemple, pour 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
la source