如何从进程中获取整个命令行?


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还是论点。我知道进程名称,并需要它的参数。我在SliTaz上使用Busybox。


您是要处理来自ps(不推荐)的输出,还是在寻找替代ps输出的命令?ps提供多行输出时需要做什么?全部打印/第一个/最后一个?
Anthon 2014年

1
您使用哪个操作系统?
赛勒斯2014年

我编辑了问题。我知道进程名称,并需要它的参数。我在Busybox中使用SliTaz(minimalistic linux)。
2014年

@迈克尔您是否尝试过argcommand按@约翰的答案
2014年

是的,但是如何将其写入变量?我想到了两个命令:PID = pidof <process name>ps -o pid,args | grep $ PID | tr -s“” | cut -d“” -f 2但是这样一来,我就无法在一个变量中获得args
Michael

Answers:


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 argscommand(或cmd)替换。
潘迪2014年

@Pandya cmd和和command都是的别名args,这可能是不必要的。
约翰·史密斯

我没有使用Busybox的-p选项:用法:ps [-o COL1,COL2 = HEADER] [-T]
Michael

您可能会使用grep实际感兴趣的线:ps -eo args | grep dhcpcd | head -n -1。我编辑了答案。
约翰·史密斯

哦,看起来不错:ps -o args | grep <进程名称> | 头-n 1
Michael

12

尝试这样的事情:

(示例来自我的一台路由器上OpenWrt上busybox的输出)

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形字符串。每个字符串都以零结尾。

引号周围的一些参数或选项是外壳程序。您必须仔细查看所显示的行以及在shell中使用空格或其他具有特殊含义的字符。将这些行再次连接到命令行时,您将需要以某种方式引用该字符或完整参数。


1
tr "\0" " " </proc/991/cmdline
赛勒斯2014年

@Cyrus:您无法将args包含空格与相邻的单独args区分开。通过用空格替换零字节,您会破坏信息。
yeti 2014年

1
我确实同意用\0`` 替换是不好的,但我认为tr '\0' '\n' < /proc/$foo/cmdline比#要简单一些xargs
Patrick

printf使您更容易在输出中添加引号,插入空格而不是换行等。考虑添加更多处理时,过渡printf是一个好的开始。
yeti 2014年

12

方法1-使用ps

您可以使用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不包括大多数Linux随附-eaf的典型开关,如上所示ps,但是Busybox的ps输出看起来与我提供的示例非常相似。您可以在大多数Linux上安装Busybox并按以下方式运行它:

$ 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' ' ' </proc/28865/cmdline
bash -c sleep 10000; while [ 1 ];do echo hi;sleep 10;done

参考文献


2

了解PID,只需执行

猫/ 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
#
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.