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.
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)
Vous pouvez utiliser ps -eaf | grep 1234
.
$ 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
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
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.
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
#
Si vous aimez les commandes courtes et que pgrep est disponible, je suggère pgrep -fl <process_name>
.
ps -o args
est tronqué
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