Làm thế nào để có được toàn bộ dòng lệnh từ một quá trình?


43

Làm cách nào tôi có thể nhận được các đối số lệnh hoặc toàn bộ dòng lệnh từ một quy trình đang chạy bằng tên quy trình của nó?

Ví dụ quy trình này:

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

Và những gì tôi muốn là /sbin/udhcpc -b -T 1 -A 12 -i eth0 -p /var/run/udhcpc.eth0.pidhoặc các đối số. Tôi biết tên quy trình và muốn các đối số của nó. Tôi đang sử dụng Busybox trên SliTaz.


Bạn có muốn xử lý đầu ra từ ps(không được khuyến nghị) hoặc bạn đang tìm kiếm một số lệnh thay thế để pscung cấp cho bạn đầu ra? Những gì cần phải được thực hiện khi pscung cấp nhiều dòng đầu ra? in tất cả / đầu tiên / cuối cùng?
Anthon

1
Bạn sử dụng hệ điều hành nào?
Cyrus

Tôi đã chỉnh sửa câu hỏi của tôi. Tôi biết tên quy trình và muốn các đối số của nó. Tôi đang sử dụng SliTaz (linux tối giản) với Busybox.
Michael

@Michael Bạn đã thử argnhư câu trả lờicommand @John chưa?
Pandya

Có nhưng làm thế nào để viết nó vào một biến? Tôi nghĩ về hai lệnh: PID = pidof <process name>ps -o pid, args | grep $ PID | tr -s "" | cut -d "" -f 2 Nhưng theo cách này tôi không nhận được các đối số trong một biến
Michael

Câu trả lời:


54

Bạn có thể sử dụng công -otắc để chỉ định định dạng đầu ra của mình:

$ ps -eo args

Từ trang người đàn ông :

Lệnh với tất cả các đối số của nó như là một chuỗi. Sửa đổi các đối số có thể được hiển thị. [...]

Bạn cũng có thể sử dụng công -ptắc để chọn một PID cụ thể:

$ ps -p [PID] -o args

pidofcũng có thể được sử dụng để chuyển từ tên tiến trình sang PID, do đó cho phép sử dụng -pvới tên:

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

Tất nhiên, bạn cũng có thể sử dụng grepcho việc này (trong trường hợp đó, bạn phải thêm công -etắc):

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

GNU ps cũng sẽ cho phép bạn loại bỏ các tiêu đề (tất nhiên, điều này là không cần thiết khi sử dụng grep):

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

Trên các hệ thống khác, bạn có thể chuyển sang AWK hoặc sed:

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

Chỉnh sửa: nếu bạn muốn bắt dòng này thành một biến, chỉ cần sử dụng $(...)như bình thường:

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

hoặc, với grep:

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

@Michael thay thế argsbằng command(hoặc cmd).
Pandya

@Pandya Cả cmdcommandđều là bí danh args, điều này có lẽ không cần thiết.
John WH Smith

Tôi không có tùy chọn -p khi sử dụng Busybox: Cách sử dụng: ps [-o COL1, COL2 = Header] [-T]
Michael

Bạn có thể sử dụng grepđể bắt dòng mà bạn thực sự quan tâm : ps -eo args | grep dhcpcd | head -n -1. Tôi chỉnh sửa câu trả lời của tôi.
John WH Smith

Ồ, điều này có vẻ tốt: ps -o args | grep <tên quy trình> | đầu -n 1
Michael

12

Hãy thử một cái gì đó như thế này:

(ví dụ đầu ra từ busybox trên OpenWrt trên một trong các bộ định tuyến của tôi)

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/cmdlinechứa các đối số của quá trình $PIDnhư chuỗi C-ish lần lượt. Mỗi chuỗi không được kết thúc.

Trích dẫn arround một số đối số hoặc tùy chọn là công cụ shell. Bạn phải nhìn gần hơn vào các dòng được hiển thị và nơi sử dụng khoảng trắng hoặc các ký tự khác có ý nghĩa đặc biệt cho vỏ. Bạn sẽ cần trích dẫn (các) ký tự đó bằng cách nào đó hoặc đối số hoàn chỉnh khi nối các dòng này lại với một dòng lệnh.


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

@Cyrus: Bạn không thể phân biệt các đối số không gian đối lập với các đối số riêng biệt liền kề sau đó. Bằng cách thay thế byte bằng một khoảng trắng bạn hủy thông tin.
yeti

1
Tôi đồng ý thay thế \0bằng `` là xấu, nhưng tôi nghĩ tr '\0' '\n' < /proc/$foo/cmdlineđơn giản hơn một chút xargs.
Patrick

printflàm cho việc thêm dấu ngoặc kép vào đầu ra dễ dàng hơn, chèn một khoảng trắng thay vì dòng mới, v.v. Khi nghĩ đến việc thêm nhiều xử lý, cách trên printflà một khởi đầu tốt.
yeti

12

Phương pháp # 1 - Sử dụng ps

Bạn có thể sử dụng ps -eaf | grep 1234.

Thí dụ

$ 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

LƯU Ý: Busybox pskhông bao gồm các -eafcông tắc như được hiển thị ở trên từ một điển hình pscó trong hầu hết các Linux, tuy nhiên Busybox pscho thấy đầu ra trông rất giống với ví dụ tôi cung cấp. Bạn có thể cài đặt Busybox trên hầu hết các Linux và chạy nó như vậy:

$ 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

Phương pháp # 2 - Sử dụng / Proc

Bạn cũng có thể xem cmdlinetập tin mà mỗi PID có /proc/<pid>.

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

Nhưng lưu ý rằng nó thiếu khoảng cách. Điều này là do một ký tự NUL được sử dụng trong tệp này để phân tách các đối số dòng lệnh của bạn. Không phải lo lắng mặc dù, những điều này có thể được tước bỏ.

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

Người giới thiệu


2

Biết về PID, chỉ cần thực hiện

mèo / Proc / pid / cmdline

Chẳng hạn, với 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
#
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.