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

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

プロセス名を使用して実行中のプロセスからコマンド引数またはコマンドライン全体を取得するにはどうすればよいですか?

たとえば、次のプロセスは次のようになります。

# 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を使用しています。

答え1

-oスイッチを使用して出力フォーマットを指定できます。

$ ps -eo args

~からマニュアルページ:

コマンドとそのパラメーターはどちらも文字列です。パラメーターの修正が表示されることがあります。 [...]

-pスイッチを使用して特定のPIDを選択することもできます。

$ ps -p [PID] -o args

pidof-pプロセス名からPIDへの切り替えにも使用できるため、名前は許可されます。

$ 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)

答え2

方法#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(上記を参照)は含まれていませんが、Busyboxに表示される出力は私が提供した例と非常によく似ています。ほとんどのLinuxにBusyboxをインストールし、次のように実行できます。psps

$ 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

引用する

答え3

次のようにしてみてください。

(私のルータの1つにある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$PID1つのC文字列のように、プロセスのパラメータを含みます。すべての文字列はゼロで終了します。

一部のパラメータまたはオプションの引用符はシェルです。表示される行とシェルに特別な意味を持つスペースやその他の文字を使用する場所を注意深く見てください。この行をコマンドラインに再接続するときは、文字または引数全体を何らかの形で引用する必要があります。

答え4

短いコマンドが好きで、pgrepを使用できる場合pgrep -fl <process_name>

ps -o args切り取った

関連情報