Bagaimana cara mendapatkan seluruh baris perintah dari suatu proses?


44

Bagaimana saya bisa mendapatkan argumen perintah atau seluruh baris perintah dari proses yang sedang berjalan menggunakan nama prosesnya?

Misalnya proses ini:

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

Dan yang saya inginkan adalah /sbin/udhcpc -b -T 1 -A 12 -i eth0 -p /var/run/udhcpc.eth0.pidargumen. Saya tahu nama proses dan ingin argumennya. Saya menggunakan Busybox di SliTaz.


Apakah Anda ingin memproses output dari ps(tidak disarankan) atau Anda mencari beberapa perintah alternatif psyang akan memberi Anda output? Apa yang perlu dilakukan ketika psmemberikan beberapa jalur output? cetak semua / pertama / terakhir?
Anthon

1
Sistem operasi apa yang Anda gunakan?
Cyrus

Saya mengedit pertanyaan saya. Saya tahu nama proses dan ingin argumennya. Saya menggunakan SliTaz (linux minimalis) dengan Busybox.
Michael

@ Michael Apakah Anda mencoba argseperti commandper @ John jawabannya ?
Pandya

Ya tapi bagaimana cara menulisnya ke variabel? Saya memikirkan dua perintah: PID = pidof <process name>ps -o pid, args | grep $ PID | tr -s "" | cut -d "" -f 2 Tapi dengan cara ini saya tidak mendapatkan argumen dalam satu variabel
Michael

Jawaban:


55

Anda bisa menggunakan -osakelar untuk menentukan format output Anda:

$ ps -eo args

Dari halaman manual :

Perintah dengan semua argumennya sebagai string. Modifikasi pada argumen dapat ditampilkan. [...]

Anda juga dapat menggunakan -psakelar untuk memilih PID tertentu:

$ ps -p [PID] -o args

pidofjuga dapat digunakan untuk beralih dari nama proses ke PID, karenanya memungkinkan penggunaan -pdengan nama:

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

Tentu saja, Anda juga dapat menggunakan grepini (dalam hal ini, Anda harus menambahkan -esakelar):

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

GNU ps juga akan memungkinkan Anda untuk menghapus header (tentu saja, ini tidak perlu saat menggunakan grep):

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

Pada sistem lain, Anda dapat mengirim ke AWK atau sed:

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

Sunting: jika Anda ingin menangkap baris ini menjadi variabel, cukup gunakan $(...)seperti biasa:

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

atau, dengan grep:

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

@Michael ganti argsdengan command(atau cmd).
Pandya

@ Pandya Keduanya cmddan commandalias args, ini mungkin tidak perlu.
John WH Smith

Saya tidak memiliki opsi -p menggunakan Busybox: Usage: ps [-o COL1, COL2 = HEADER] [-T]
Michael

Anda dapat menggunakan grepuntuk menangkap garis Anda benar-benar tertarik: ps -eo args | grep dhcpcd | head -n -1. Saya mengedit jawaban saya.
John WH Smith

Oh, ini terlihat bagus: ps -o args | grep <nama proses> | head -n 1
Michael

12

Coba sesuatu seperti ini:

(contoh output dari busybox di OpenWrt di salah satu router saya)

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/cmdlineberisi argumen proses $PIDseperti string C-ish satu demi satu. Setiap string diakhiri nol.

Kutipan di sekitar beberapa argumen atau opsi adalah barang shell. Anda harus melihat lebih dekat pada garis yang ditampilkan dan di mana spasi atau karakter lain dengan makna khusus untuk shell digunakan. Anda perlu mengutip karakter itu entah bagaimana atau argumen lengkap ketika bergabung dengan baris ini ke baris perintah lagi.


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

@Cyrus: Anda tidak dapat membedakan args containg spasi dari args terpisah yang berdekatan. Dengan mengganti byte nol dengan ruang Anda menghancurkan informasi.

1
Saya setuju mengganti \0dengan `` menjadi buruk, tapi saya pikir tr '\0' '\n' < /proc/$foo/cmdlinesedikit lebih sederhana daripada xargs.
Patrick

printfmembuatnya lebih mudah untuk menambahkan kutipan ke output, menyisipkan spasi, bukan baris baru dan sebagainya. Ketika berpikir untuk menambahkan lebih banyak pemrosesan, jalan keluar printfadalah awal yang baik.

12

Metode # 1 - Menggunakan ps

Anda bisa menggunakannya ps -eaf | grep 1234.

Contoh

$ 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

CATATAN: Busybox's pstidak menyertakan -eafsakelar seperti yang ditunjukkan di atas dari tipikal psyang disertakan dengan sebagian besar Linux, namun Busybox's psmenunjukkan apa yang tampak seperti output yang sangat mirip dengan contoh yang saya berikan. Anda dapat menginstal Busybox di sebagian besar Linux dan menjalankannya seperti ini:

$ 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

Metode # 2 - Menggunakan / proc

Anda juga dapat melihat cmdlinefile yang dimiliki masing-masing PID /proc/<pid>.

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

Tetapi perhatikan bahwa itu tidak ada spasi. Ini disebabkan oleh karakter NUL yang digunakan dalam file ini untuk memisahkan argumen baris perintah Anda. Tidak perlu khawatir, ini bisa dilucuti.

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

Referensi


2

Mengetahui PID, hanya eksekutif

cat / proc / pid / cmdline

Misalnya, untuk 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
#
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.