Как получить целую командную строку из процесса?

Как я могу получить аргументы команды или всю командную строку из запущенного процесса, используя его имя процесса?

Например, этот процесс:

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

И то, что я хочу, это /sbin/udhcpc -b -T 1 -A 12 -i eth0 -p /var/run/udhcpc.eth0.pid или аргументы. Я знаю имя процесса и хочу его аргументы. Я использую Busybox на SliTaz.

Вы можете использовать ключ -o чтобы указать свой выходной формат:

 $ ps -eo args 

На странице руководства :

Команда со всеми ее аргументами в виде строки. Модификации аргументов могут быть показаны. […]

Вы также можете использовать ключ -p для выбора определенного PID:

 $ ps -p [PID] -o args 

pidof также может использоваться для переключения с имени процесса на PID, следовательно, использование -p с именем:

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

Конечно, вы также можете использовать grep для этого (в этом случае вы должны добавить ключ -e ):

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

GNU ps также позволит удалить заголовки (конечно, это не нужно при использовании grep ):

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

В других системах вы можете подключиться к AWK или sed:

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

Изменить: если вы хотите поймать эту строку в переменной, просто используйте $(...) как обычно:

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

или, с grep :

 $ CMDLINE=$(ps -eo args | grep dhcpcd | head -n -1) 

Попробуйте что-то вроде этого:

(пример вывода из busybox на OpenWrt на одном из моих маршрутизаторов)

 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 содержит аргументы процесса $PID как строки C-ish один за другим. Каждая строка заканчивается нулем.

Цитаты arround некоторые аргументы или опции – это материал оболочки. Вы должны смотреть ближе к отображаемым линиям и где используются пробелы или другие символы со специальным значением для оболочки. Вам нужно будет процитировать этот символ (-ы) как-то или полный аргумент при повторном присоединении этих строк к командной строке.

Метод №1 – Использование ps

Вы можете использовать ps -eaf | grep 1234 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 

ПРИМЕЧАНИЕ. ps Busybox не включает в -eaf переключатели -eaf как показано выше, из типичного ps который включен в большинство Linux, однако pss Busybox показывает, что похоже на очень похожий вывод в примере, который я предоставил. Вы можете установить Busybox на большинстве Linux и запустить его так:

 $ 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 

Метод №2 – Использование / proc

Вы также можете посмотреть файл cmdline который имеет каждый PID в /proc/<pid> .

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

Но заметьте, что в нем отсутствует интервал. Это связано с тем, что в этом файле используется символ NUL для разделения аргументов командной строки. Не волнуйтесь, их можно убрать.

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

Рекомендации

  • Как я могу увидеть точную командную строку, выполняемую внутри некоторого экземпляра bash?

Зная PID, просто выполните

cat / proc / pid / cmdline

Например, для 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 #