Як отримати цілий командний рядок з процесу?


43

Як я можу отримати аргументи команд або весь командний рядок із запущеного процесу, використовуючи його ім'я процесу?

Наприклад цей процес:

# 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.


Ви хочете обробити результат з ps(не рекомендується) або шукаєте якусь альтернативну команду, psяка дасть вам вихід? Що потрібно зробити, коли psдає кілька рядків виводу? надрукувати все / перше / останнє?
Антон

1
Яку операційну систему ви використовуєте?
Кіра

Я відредагував своє запитання. Я знаю ім'я процесу і хочу його аргументи. Я використовую SliTaz (мінімалістичний Linux) з Busybox.
Майкл

@Michael Ви пробували, argяк commandна відповідь @John ?
Пандія

Так, але як записати його до змінної? Я думаю про дві команди: PID = pidof <process name>ps -o pid, args | grep $ PID | tr -s "" | cut -d "" -f 2 Але таким чином я не отримую аргументи в одній змінній
Michael

Відповіді:


54

Ви можете використовувати -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)

@Michael замінити argsна command(або cmd).
Пандія

@Pandya Обидва cmdі commandє псевдонімами args, це, мабуть, непотрібно.
Джон У. Сміт

У мене немає опції -p за допомогою Busybox: Використання: ps [-o COL1, COL2 = HEADER] [-T]
Майкл

Ви можете використовувати , grepщоб зловити лінію ви на справді цікаво: ps -eo args | grep dhcpcd | head -n -1. Я відредагував свою відповідь.
Джон У. Сміт

О, це добре виглядає: ps -o args | grep <назва процесу> | head -n 1
Michael

12

Спробуйте щось подібне:

(наприклад, вихід із зайнятої скриньки на 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 одна за одною. Кожен рядок закінчується нулем.

Цитати, які містять деякі аргументи або параметри, є оболонками. Ви повинні придивитись уважніше до рядків, що відображаються, та де використовуються пробіли чи інші символи, що мають спеціальне значення для оболонки. Вам потрібно буде якось цитувати цього символу або повний аргумент, коли знову додавати ці рядки до командного рядка.


1
tr "\0" " " </proc/991/cmdline
Кіра

@Cyrus: Ви не можете відрізнити аргументи, що містять пробіли, від сусідніх окремих аргументів. Замінивши нульовий байт пробілом, ви знищуєте інформацію.
yeti

1
Я погоджуюся замінити \0на `` погано, але я думаю, tr '\0' '\n' < /proc/$foo/cmdlineщо це трохи простіше, ніж xargs.
Патрік

printfполегшує додавання лапок до виводу, вставляє пробіл замість нового рядка тощо. Коли думаєте додати ще обробку, шлях printfє гарним початком.
yeti

12

Метод №1 - Використання пс

Ви можете використовувати 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

ПРИМІТКА. Busybox psне включає -eafперемикачі, як показано вище, як psправило, типовий, що входить до більшості Linux, однак Busybox psпоказує, що виглядає дуже схожим на вихідний приклад. Ви можете встановити 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 - Використання / проц

Ви також можете переглянути cmdlineфайл, який має кожен PID /proc/<pid>.

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

Але зауважте, що пропуску немає. Це пов’язано з символом NUL, який використовується в цьому файлі для відокремлення аргументів вашого командного рядка. Не хвилюйтеся, проте їх можна викреслити.

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

Список літератури


2

Знаючи 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
#
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.