あなたはps -ef派なのか、auxf派なのかをちょっとだけまとめてみた

何気なく、ツイートしたところ、たくさんリアクションもらえて嬉しかったのと、僕も普段手癖で打ってて、オプションの記憶怪しかったり、知らないオプションがあった。正確で、詳細なオプションはmanを参照してください。

ps -ef 派は比較的少数で、多数派のauxf 派はいくつかの派生があるみたいです。

ps -eLw

@joker1007 さんが教えてくれたオプションです。

-e はすべてのプロセスを表示、-L はLWP(Light weight process)の表示で実体はスレッドID、-w は出力幅の追加。雑なマルチスレッドなコードで確認しましょう。

threads = []
10.times { threads << Thread.new { sleep 10 } }
threads.each { |thr| thr.join }

この状態でコマンドを実行すると

vagrant@localhost:~$ ps -eLw  |grep -e rb  -e LWP
  PID   LWP TTY          TIME CMD
 1713  1715 pts/1    00:00:00 test.rb:2
 1713  1716 pts/1    00:00:00 test.rb:2
 1713  1717 pts/1    00:00:00 test.rb:2
 1713  1718 pts/1    00:00:00 test.rb:2
 1713  1719 pts/1    00:00:00 test.rb:2
 1713  1720 pts/1    00:00:00 test.rb:2
 1713  1721 pts/1    00:00:00 test.rb:2
 1713  1722 pts/1    00:00:00 test.rb:2
 1713  1723 pts/1    00:00:00 test.rb:2
 1713  1724 pts/1    00:00:00 test.rb:2

こんな感じでスレッドのIDが見えますね。また -o でカラムを追加することもできます。CPU使用率を表示してみましょう。

vagrant@localhost:~$ ps -eLw  -o pid,lwp,%cpu,command |grep -e test -e LWP
  PID   LWP %CPU COMMAND
 1595  1595  0.0 vi test.rb
 1856  1856  0.4 ruby test.rb
 1856  1857  0.0 ruby test.rb
 1856  1858  0.0 ruby test.rb
 1856  1859  0.0 ruby test.rb
 1856  1860  0.0 ruby test.rb
 1856  1861  0.0 ruby test.rb
 1856  1862  0.0 ruby test.rb
 1856  1863  0.0 ruby test.rb
 1856  1864  0.0 ruby test.rb
 1856  1865  0.0 ruby test.rb
 1856  1866  0.0 ruby test.rb
 1856  1867  0.0 ruby test.rb
 1879  1879  0.0 grep --color=auto -e test -e LWP

そして、さらにテストコードをちょっとだけ変えてみます。10個のスレッドのうち、半分のスレッドでCPU負荷を与えてみます。

require 'prime'
threads = []
10.times do |i|
  threads << Thread.new do
        if i % 2 == 0
                loop do (Random.rand(100000)+1).prime_division end
        else
                sleep 10
        end
  end
end
threads.each { |thr| thr.join }
~                                
vagrant@localhost:~$ ps -eLw  -o pid,lwp,%cpu,command |grep -e test -e LWP
  PID   LWP %CPU COMMAND
 1595  1595  0.0 vi test.rb
 1919  1919  0.7 ruby test.rb
 1919  1920  0.0 ruby test.rb
 1919  1921 20.5 ruby test.rb
 1919  1922  0.0 ruby test.rb
 1919  1923 20.2 ruby test.rb
 1919  1924  0.0 ruby test.rb
 1919  1925 20.0 ruby test.rb
 1919  1926  0.0 ruby test.rb
 1919  1927 18.5 ruby test.rb
 1919  1928  0.0 ruby test.rb
 1919  1929 19.7 ruby test.rb
 1919  1930  0.0 ruby test.rb
 1934  1934  0.0 grep --color=auto -e test -e LWP

面白いですね!もし、マルチスレッドなプログラムを調査する場合に、特定のスレッドでなにかあるとかが、見つけられるきっかけになるかもしれません。

ps fax

次は、@kazeburo さんが紹介してくれたオプション。

f はプロセスの階層表示で後でまた出てくるので、後述します。 a は端末を持つプロセスの全て、xは端末を持たないプロセスのすべてを表示するというオプションです。ちなみに -aa は違う意味になるのでご注意ください。

vagrant@localhost:~$ ps fax|more
  PID TTY      STAT   TIME COMMAND
    2 ?        S      0:00 [kthreadd]
    3 ?        S      0:00  \_ [ksoftirqd/0]
    4 ?        S      0:00  \_ [kworker/0:0]
    5 ?        S<     0:00  \_ [kworker/0:0H]
    7 ?        S      0:00  \_ [rcu_sched]
    8 ?        S      0:00  \_ [rcu_bh]
    9 ?        S      0:00  \_ [migration/0]

出力はこんな感じですね。このとき出力される STAT カラムは実は大事で、プロセスの状態を表しています。個人的には D が多いときはなにかに待たされていることが多いので、最初に見るカラムです。

ちなみに、u をつけると下記の表示になり、後述します。

vagrant@localhost:~$ ps faxu |head
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         2  0.0  0.0      0     0 ?        S    May21   0:00 [kthreadd]
root         3  0.0  0.0      0     0 ?        S    May21   0:00  \_ [ksoftirqd/0]
root         4  0.0  0.0      0     0 ?        S    May21   0:00  \_ [kworker/0:0]
root         5  0.0  0.0      0     0 ?        S<   May21   0:00  \_ [kworker/0:0H]
root         7  0.0  0.0      0     0 ?        S    May21   0:00  \_ [rcu_sched]
root         8  0.0  0.0      0     0 ?        S    May21   0:00  \_ [rcu_bh]
root         9  0.0  0.0      0     0 ?        S    May21   0:00  \_ [migration/0]
root        10  0.0  0.0      0     0 ?        S    May21   0:00  \_ [watchdog/0]
root        11  0.0  0.0      0     0 ?        S    May21   0:00  \_ [kdevtmpfs]

auxfww

@hokkai7go さんとかyokuさんが使っているオプション。結構多数派な印象です。

新しいオプションとしては、 u ですね。これは表示項目を増やしたり見やすくするってオプションで、リソースの情報も追加されます。f はツリー構造でプロセスの親子関係を見やすくするためのオプションです。このf-f とは違うものなので注意してください。 -f はfull formatなので、異なる解釈になります。

vagrant@localhost:~$ ps -ef f |tail # プロセスがツリーで見える
root      1633   741  0 May21 ?        Ss     0:00  \_ sshd: vagrant [priv]
vagrant   1653  1633  0 May21 ?        S      0:00      \_ sshd: vagrant@pts/2
vagrant   1654  1653  0 May21 pts/2    Ss     0:00          \_ -bash
vagrant   2135  1654  0 00:30 pts/2    R+     0:00              \_ ps -ef f
vagrant   2136  1654  0 00:30 pts/2    S+     0:00              \_ tail
ntp        761     1  0 May21 ?        Ss     0:00 /usr/sbin/ntpd -p /var/run/ntpd.pid -g -u 108:114
root       768     1  0 May21 tty1     Ss+    0:00 /sbin/agetty --noclear tty1 linux
root       836     1  0 May21 ?        Sl     0:00 /usr/sbin/VBoxService --pidfile /var/run/vboxadd-service.pid
vagrant   1351     1  0 May21 ?        Ss     0:00 /lib/systemd/systemd --user
vagrant   1352  1351  0 May21 ?        S      0:00  \_ (sd-pam)
vagrant@localhost:~$ ps -ef |tail # プロセスツリーは見えない
vagrant   1412  1392  0 May21 ?        00:00:00 sshd: vagrant@pts/1
vagrant   1413  1412  0 May21 pts/1    00:00:00 -bash
vagrant   1595  1376  0 May21 pts/0    00:00:00 vi test.rb
root      1633   741  0 May21 ?        00:00:00 sshd: vagrant [priv]
vagrant   1653  1633  0 May21 ?        00:00:00 sshd: vagrant@pts/2
vagrant   1654  1653  0 May21 pts/2    00:00:00 -bash
root      1908     2  0 00:06 ?        00:00:00 [kworker/0:1]
root      1960     2  0 00:12 ?        00:00:00 [kworker/u2:0]
vagrant   2137  1654  0 00:30 pts/2    00:00:00 ps -ef
vagrant   2138  1654  0 00:30 pts/2    00:00:00 tail

ww は表示領域の制限を解除するオプションですね。長い引数を付けて確認してみましょう。

vagrant@localhost:~$ ruby test.rb "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "bbbbbbbbbbbbbbbbbbbbb" "ccccccccccccccccccc"
vagrant@localhost:~$ ps ax # 表示が途切れる
 2245 pts/1    Sl+    0:00 ruby test.rb aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
 2277 pts/2    R+     0:00 ps ax
vagrant@localhost:~$ ps axww # wwをつけると全部の引数が表示される
 2245 pts/1    Sl+    0:00 ruby test.rb aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbb ccccccccccccccccccc

ちなみにかしこくて、grepとかをかけると、ww なしでも全部表示されます。

vagrant@localhost:~$ ps ax|grep test
 1595 pts/0    S+     0:00 vi test.rb
 2285 pts/1    Sl+    0:00 ruby test.rb aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbb ccccccccccccccccccc

やー、よくできてますね!

agx

力武先生が教えてくれたオプション。特に g は見慣れないですね。

本当に全てのプロセスを選択する。セッションリーダも含む。 このフラグは旧式で、 将来のリリースでは廃止されるかもしれない。 この振る舞いは通常 a フラグで暗黙に有効になり、 sunos4 の流儀で操作するときにのみ役立つ。

https://linuxjm.osdn.jp/html/procps/man1/ps.1.html

本当に #とは という感じですが、現在のサーバで利用する分には a だけで多くの場合事足りそうですね。sunos4・・・って僕はSolarisを前職で触ってたことはありますが、そのリプレース前がsunosだったような違うような・・・。

最後に

改めてmanを眺めると、全然知らないオプションも多くて面白いですね!日常で使うコマンドって ps もそうですし、 top とか sed とか awk とかそれぞれ皆さん一芸持たれているのではないでしょうか?そういうテクニック結構知らない人多そうだから、身近な社内だけでもLTとかすると同僚の生産性が上がって良いのかもしれません。それでは、良い週末を。