Jak uzyskać cały wiersz poleceń z procesu?


43

Jak uzyskać argumenty polecenia lub cały wiersz polecenia z uruchomionego procesu, używając jego nazwy?

Na przykład ten proces:

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

I chcę /sbin/udhcpc -b -T 1 -A 12 -i eth0 -p /var/run/udhcpc.eth0.pidtylko argumentów. Znam nazwę procesu i chcę jego argumentów. Używam Busybox na SliTaz.


Czy chcesz przetworzyć dane wyjściowe z ps(niezalecane), czy szukasz alternatywnego polecenia ps, które da ci wynik? Co należy zrobić, gdy pspodaje się wiele wierszy wyników? wydrukować wszystko / pierwszy / ostatni?
Anthon

1
Z jakiego systemu operacyjnego korzystasz?
Cyrus,

Zredagowałem moje pytanie. Znam nazwę procesu i chcę jego argumentów. Używam SliTaz (minimalistyczny linux) z Busybox.
Michael,

@Michael Czy próbowałeś argjak commandna odpowiedź @John ?
Pandya,

Tak, ale jak zapisać to do zmiennej? Myślę o dwóch poleceniach: PID = pidof <process name>ps -o pid, args | grep $ PID | tr -s "" | cut -d "" -f 2 Ale w ten sposób nie otrzymuję argumentów w jednej zmiennej
Michael

Odpowiedzi:


54

Możesz użyć -oprzełącznika, aby określić format wyjściowy:

$ ps -eo args

Ze strony podręcznika :

Polecenie ze wszystkimi argumentami w postaci łańcucha. Modyfikacje argumentów mogą być pokazane. [...]

Możesz także użyć -pprzełącznika, aby wybrać określony PID:

$ ps -p [PID] -o args

pidofmoże również służyć do zmiany nazwy procesu na PID, co pozwala na użycie -pz nazwą:

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

Oczywiście możesz również użyć grepdo tego (w takim przypadku musisz dodać -eprzełącznik):

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

GNU ps pozwala również na usuwanie nagłówków (oczywiście nie jest to konieczne przy użyciu grep):

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

W innych systemach możesz przesyłać do AWK lub sed:

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

Edycja: jeśli chcesz złapać tę linię do zmiennej, po prostu użyj $(...)jak zwykle:

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

lub z grep:

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

@Michael wymienić argsz command(a cmd).
Pandya,

@ Pandya Zarówno cmdi commandsą pseudonimami args, prawdopodobnie nie jest to konieczne.
John WH Smith,

Nie mam opcji -p przy użyciu Busybox: Zastosowanie: ps [-o COL1, COL2 = HEADER] [-T]
Michael

Można używać grepdo połowu linię jesteś rzeczywiście zainteresowany: ps -eo args | grep dhcpcd | head -n -1. Zredagowałem swoją odpowiedź.
John WH Smith,

Och, to wygląda dobrze: ps -o argumenty | grep <nazwa procesu> | głowa -n 1
Michael

12

Wypróbuj coś takiego:

(przykładowe wyjście z busybox na OpenWrt na jednym z moich routerów)

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/cmdlinezawiera argumenty procesu, $PIDtakie jak łańcuchy C po kolei. Każdy ciąg znaków kończy się na zero.

Cytaty wokół niektórych argumentów lub opcji są materiałami powłoki. Musisz przyjrzeć się bliżej wyświetlanym wierszom i miejscu, w którym używane są spacje lub inne znaki o specjalnym znaczeniu dla powłoki. Będziesz musiał jakoś zacytować ten znak (znaki) lub pełny argument przy ponownym łączeniu tych linii z linią poleceń.


1
tr "\0" " " </proc/991/cmdline
Cyrus

@ Cyrus: Nie można wtedy odróżnić argumentów zawierających spacje od sąsiadujących oddzielnych argumentów. Zastępując bajt zerowy spacją, niszczysz informacje.
yeti

1
Zgadzam się, zastępując \0go słowem `` być zły, ale myślę, że tr '\0' '\n' < /proc/$foo/cmdlinejest nieco prostszy niż xargs.
Patrick,

printfułatwia dodawanie cudzysłowów do danych wyjściowych, wstawianie spacji zamiast nowej linii i tak dalej. Myślenie o dodaniu większej ilości przetwarzania printfjest dobrym początkiem.
yeti

12

Metoda nr 1 - Korzystanie z ps

Możesz użyć ps -eaf | grep 1234.

Przykład

$ 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

UWAGA: Busybox psnie zawiera -eafprzełączników, jak pokazano powyżej, z typowego, psktóry jest zawarty w większości Linuksów, jednak Busybox pspokazuje, co wygląda bardzo podobnie do wyjścia podanego przeze mnie. Możesz zainstalować Busybox na większości Linuksów i uruchomić go w następujący sposób:

$ 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

Metoda nr 2 - Korzystanie z / proc

Możesz także spojrzeć na cmdlineplik, pod którym znajduje się każdy PID /proc/<pid>.

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

Ale zauważ, że brakuje odstępów. Wynika to z użycia znaku NUL w tym pliku do oddzielenia argumentów wiersza poleceń. Nie martw się, można je rozebrać.

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

Bibliografia


2

Znając PID, po prostu exec

cat / proc / pid / cmdline

Na przykład dla 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
#
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.