web-dev-qa-db-fra.com

Comment obtenir toute la ligne de commande d'un processus?

Comment puis-je obtenir les arguments de commande ou la ligne de commande entière à partir d'un processus en cours en utilisant 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.pid ou les arguments. Je connais le nom du processus et je veux ses arguments. J'utilise Busybox sur SliTaz.

58
Michael

Vous pouvez utiliser le commutateur -o 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 peuvent être apportées aux arguments. [...]

Vous pouvez également utiliser le commutateur -p Pour sélectionner un PID spécifique:

$ ps -p [PID] -o args

pidof peut également être utilisé pour passer du nom du processus au PID, permettant ainsi l'utilisation de -p avec un nom:

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

Bien sûr, vous pouvez également utiliser grep pour cela (auquel cas, vous devez ajouter le commutateur -e):

$ 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 lorsque vous utilisez 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 simplement $(...) comme d'habitude:

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

ou, avec grep:

$ CMDLINE=$(ps -eo args | grep dhcpcd | head -n -1)
70
John WH Smith

Méthode n ° 1 - Utilisation de ps

Vous pouvez 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: ps de Busybox n'inclut pas le -eaf commute comme indiqué ci-dessus à partir d'un ps typique inclus avec la plupart des Linux, cependant ps de Busybox montre ce qui semble être une sortie très similaire à l'exemple que j'ai fourni. Vous pouvez installer Busybox sur la plupart des Linux et l'exécuter comme ceci:

$ 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 - Utilisation de/proc

Vous pouvez également consulter le fichier cmdline que chaque PID a sous /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û à l'utilisation d'un caractère NUL 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

Références

15
slm

Essayez quelque chose comme ceci:

(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/cmdline contient les arguments du processus $PID comme une chaîne C-ish l'une après l'autre. Chaque chaîne se termine par zéro.

Les citations entourant certains arguments ou options sont des choses Shell. Vous devez regarder de plus près les lignes affichées et où les espaces ou autres caractères ayant une signification particulière pour le Shell sont utilisés. Vous devrez citer ce ou ces caractères ou l'argument complet lorsque vous joindrez à nouveau ces lignes à une ligne de commande.

13
user62916

Connaître le PID, juste exec

chat/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
#
5
jmlotero

Si vous aimez les commandes courtes et que pgrep est disponible, je suggère pgrep -fl <process_name>.

ps -o args est tronqué

0
Mickael Cagnion

Version allégée de la commande ps (BusyBox):

PROCNAME="udhcpc"   
CMD=$(ps | grep $PROCNAME | grep -v grep | head -n 1 | grep -o '/.*$')

Version complète de la commande ps:

PROCNAME="udhcpc"
CMD=$(ps -f --no-headers -C $PROCNAME | head -n 1 | grep -o '/.*$')

Ou une combinaison des deux. Puisque ps dans BusyBox n'a pas d'argument pour déterminer la version (il passera une erreur de sortie), nous pouvons en profiter:

PROCNAME="udhcpc"
if ps --version; then
    CMD=$(ps -f --no-headers -C $PROCNAME | head -n 1 | grep -o '/.*$')     # full-featured "ps" command
else
    CMD=$(ps | grep $PROCNAME | grep -v grep | head -n 1 | grep -o '/.*$')  # "ps" command from BusyBox
fi

Si vous n'avez besoin que d'arguments après le nom du processus, divisez la chaîne après le premier espace, comme ceci:

echo $CMD | cut -d ' ' -f 2-99
0
s3n0