プロセスからコマンドライン全体を取得する方法は?


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複数行の出力を行う場合、何をする必要がありますか?すべて/最初/最後を印刷しますか?
アントン14年

1
どのオペレーティングシステムを使用していますか?
サイラス14年

質問を編集しました。プロセス名を知っており、その引数が必要です。BusyboxでSliTaz(minimalistic linux)を使用しています。
マイケル14年

あなたは試したことがあり@Michael argのようなcommand@ジョンのあたりなどの答え
パンディア14年

はい、しかしそれを変数に書き込む方法は?私は2つのコマンドを考えます:PID = pidof <process name>ps -o pid、args | grep $ PID | tr -s "" | cut -d "" -f 2しかし、この方法では1つの変数に引数を取得しません
Michael

回答:


54

-oスイッチを使用して出力形式を指定できます。

$ ps -eo args

manページから:

すべての引数を文字列として持つコマンド。引数の変更が表示される場合があります。[...]

-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)に置き換えられます。
パンディア14年

@Pandya cmdcommandは、のエイリアスでありargs、おそらく不要です。
ジョンWHスミス14年

Busyboxを使用する-pオプションがありません:使用法:ps [-o COL1、COL2 = HEADER] [-T]
Michael 14年

grep実際に興味のある行をキャッチするために使用できますps -eo args | grep dhcpcd | head -n -1。回答を編集しました。
ジョンWHスミス14年

ああ、これは良さそうです:ps -o args | grep <プロセス名> | ヘッド-n 1-
マイケル

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$PIDCのような文字列のようなプロセスの引数が次々に含まれています。各文字列はゼロで終了します。

一部の引数またはオプションを囲む引用符はシェルのものです。表示されている行と、シェルにとって特別な意味を持つスペースまたは他の文字が使用されている場所を詳しく調べる必要があります。これらの行をコマンドラインに再度結合するときは、何らかの方法でその文字または完全な引数を引用符で囲む必要があります。


1
tr "\0" " " </proc/991/cmdline
サイラス14年

@Cyrus:スペースを含む引数と隣接する個別の引数を区別することはできません。ゼロバイトをスペースに置き換えると、情報が破壊されます。
イエティ14年

1
私は\0``に置き換えることは悪いことであることに同意tr '\0' '\n' < /proc/$foo/cmdlineしますが、に比べて少しシンプルだと思いますxargs
パトリック

printf出力に引用符を追加したり、改行の代わりにスペースを挿入したりすることが簡単になります。より多くの処理を追加することを考えている場合、この方法printfは良いスタートです。
イエティ

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いる典型的な上記のスイッチは含まれていませんが、psBusyboxには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を知っている、ただexec

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
#
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.