わかりづらいLinux psオプションシリーズまとめ

# はじめに
LinuC 101/102の資格を取得しようと学習していますが、psオプションのややこしさに毎回つまづいているため、psオプションについてまとめました。
psオプションのわかりづらいところはなんといっても<strong>ハイフン</strong>が付くか付かないかによっても若干違いがあるところです。

一目で見やすくなるように表にしてみたいと思います。

# そもそもなんでハイフン付きとそうでないものがあるのか
Linuxのオプションには大きく分けて3の形式が存在する。
|形式|内容|
|----|----|
|Unix98形式|先頭にハイフンを付けて複数まとめて表示する|
|BSD形式|先頭に何も付けずに複数をまとめて表示する|
|GNU形式|先頭にハイフン2つ（--）を付けて長い名前のオプションを指定|

ちなみにこの3つの違いは流派の違いらしい。

# オプション
|オプション|意味|
|---------|---|
|a|端末操作の他のユーザー(制御端末[^1]のあるすべてのユーザー)のプロセスも表示<br>(xオプションと組み合わせることで全てのプロセスを表示)|
|-a|端末を持たないプロセスを除いてすべてのプロセスを表示する|
|-A, -e(every)|すべてのプロセスを表示する|
|e|コマンドの後に環境変数などを表示する|
|u, -u|プロセスの実行ユーザ名も表示する|
|x|制御端末の無い[^2]デーモン等のプロセスを表示する|
|r|実行中のプロセスのみ表示する|
|f, --forest[^3]|階層表示する|
|-f|情報を省略しない完全なフォーマットで表示する|

# 実際にコマンドを打った例
ハイフンのありなし等で実行結果に違いがあることに注目してみてください。

:::note warn
また、以下はwslや仮想サーバ(Ubuntu)等で実行した結果となるため、必ずしも皆さんが実行した結果と同じにならないことや、コマンドの実行結果をすべて記載してないことは前提としておいてください。
:::

端末制御のあるすべてのユーザーのプロセスを表示
端末(tty)を持つすべてのプロセスをリストする。
```bash
$ ps a
```
実行結果
```bash
  PID TTY      STAT   TIME COMMAND
   75 pts/1    Ss+    0:00 -bash
 1674 pts/1    Tl     0:00 docker exec -i competent_darwin /bin/bash
 2994 pts/2    Ss     0:00 -bash
 3700 pts/2    R+     0:00 ps a
```
端末を持たないプロセスを除いて、すべてのプロセスを表示

```bash
$ ps -a
```
実行結果
```bash
  PID TTY          TIME CMD
 1674 pts/1    00:00:00 docker
 3701 pts/2    00:00:00 ps
```

すべてのプロセスを表示する
```bash
$ ps -A
$ ps -e
```
実行結果
```bash
  PID TTY          TIME CMD
    1 ?        00:00:00 init
    4 ?        00:00:00 init
   10 ?        00:00:00 init
   73 ?        00:00:00 init
   75 pts/1    00:00:00 bash
  672 ?        00:00:35 dockerd
  680 ?        00:03:16 containerd
 1674 pts/1    00:00:00 docker
以下省略
```
コマンドの後に環境変数などを表示
```bash
$ ps e
```
実行結果
```bash
  PID TTY      STAT   TIME COMMAND
   75 pts/1    Ss+    0:00 -bash HOSTTYPE=x86_64 LANG=ja_JP.UTF8 PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/
 1674 pts/1    Tl     0:00 docker exec -i competent_darwin /bin/bash SHELL=/bin/bash WSL2_GUI_APPS_ENABLED=1 WSL_DIS
 2994 pts/2    Ss     0:00 -bash HOSTTYPE=x86_64 LANG=ja_JP.UTF8 PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/
 3715 pts/2    R+     0:00 ps e SHELL=/bin/bash WSL2_GUI_APPS_ENABLED=1 WSL_DISTRO_NAME=Ubuntu NAME=DESKTOP-1N30IA1 
```
プロセスの実行ユーザ名も表示
```bash
$ ps u
$ ps -u 
```
実行結果
```bash
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
hoge       75  0.0  0.3  11160  7092 pts/1    Ss+   1月09   0:00 -bash
hoge     1674  0.0  3.0 1126232 60020 pts/1   Tl    1月09   0:00 docker exec -i competent_darwin /bin/bash
hoge     2994  0.0  0.2   9832  5472 pts/2    Ss    1月10   0:00 -bash
hoge     3716  0.0  0.1   9924  3364 pts/2    R+   16:42   0:00 ps u 

```
制御端末の無いデーモン等のプロセスも表示する
```bash
$ ps x
```
実行結果
```bash
    PID TTY      STAT   TIME COMMAND
   1674 ?        Ss     0:00 /lib/systemd/systemd --user
   1675 ?        S      0:00 (sd-pam)
   1680 ?        S<sl   0:00 /usr/bin/pulseaudio --daemonize=no --log-target=journal
以下省略
```
実行中のプロセスのみ表示

:::note warn
なかなか自身の端末でこのコマンドを打っても参考になりませんが一応
:::
```bash
$ ps r
```
実行結果
```bash
  PID TTY      STAT   TIME COMMAND
 3721 pts/2    R+     0:00 ps r
```
階層表示
```bash
$ ps f
```
実行結果
```bash
   PID TTY      STAT   TIME COMMAND
  4875 pts/0    Ss     0:00 bash
  7093 pts/0    R+     0:00  \_ ps f
  2490 pts/1    Ss+    0:00 -bash
  1724 tty2     Ssl+   0:00 /usr/lib/gdm3/gdm-x-session --run-script env GNOME_SHELL_SESSION_MODE=ubuntu 
  1731 tty2     Sl+    0:12  \_ /usr/lib/xorg/Xorg vt2 -displayfd 3 -auth /run/user/1000/gdm/Xauthority -
  1779 tty2     Sl+    0:00  \_ /usr/libexec/gnome-session-binary --systemd --systemd --session=ubuntu
```

```bash
$ ps --forest
```
実行結果
```bash
   PID TTY          TIME CMD
  4875 pts/0    00:00:00 bash
 　7094 pts/0    00:00:00  \_ ps
```
情報を省略しない完全なフォーマットで表示
```bash
$ ps -f
```
実行結果
```bash
UID          PID    PPID  C STIME TTY          TIME CMD
izumi       4875    4864  0 06:54 pts/0    00:00:00 bash
izumi       7281    4875  0 17:56 pts/0    00:00:00 ps -f
```

# 応用
|オプション|意味|
|----------|---|
|aux[^5]|aで端末を使っているすべてのプロセス、uでプロセスを実行しているユーザ、xで端末を使っていないすべてのプロセスを表示する。<br>システムが起動しているすべてのプロセスを表示と置き換えてもよい|

:::note warn
auxコマンドを実行すると大量の情報が表示されるため、以下のように組み合わせることもできます。
```bash
情報の下から10レコード分の情報を表示
$ ps aux | tail

情報の上から10レコード分の情報を表示
$ ps aux | head

必要な情報のみ取得したい場合
以下の場合、実行したユーザ名を指定してプロセス検索を実施している
$ ps aux | grep <ユーザ名>
```
:::
ps auxコマンドを実行した際の以下の意味
```bash
USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
```
わかりづらいもののみ記載
|項目|意味|
|----|---|
|%CPU|プロセスのCPU使用率|
|%MEM|プロセスが確保している物理メモリ|
|VSZ,RSS|仮想メモリ領域のサイズ、物理メモリ領域のサイズ|
|TTY|端末名|
|STAT|プロセスの状態|
|START|プロセスの開始時刻|
|TIME|プロセスの総実行時間|

# STATのプロセスの状態の意味って？
|項目|意味|
|----|----|
|R|実行可能状態なプロセス|
|S|割り込み可能な待ち状態|
|D|ディスクのIO待ち状態|
|Z|ゾンビプロセス状態|

|項目|意味|
|----|----|
|+|フォアグランドのプロセス状態|
|s|セッションリーダー|
|<|優先度の高いプロセス|
|N|優先度が低いプロセス|
|l|マルチスレッドのプロセス|

# Linuxの学習において気になっている本
[エンジニア1年生のための世界一わかりやすいLinuxコマンドの教科書](https://amzn.to/3vWlUJO)
上記の本が気になっています。
まだまだ、LinuCの資格を取得する上でLinuxの事が分かっていないため、購入して勉強してみたいと思います。

# 最後に
[ITサービス指向エンジニアブログ](https://kyrieee.com/)というブログにて個人ブログで様々なことをアウトプットしています。
今回のQiitaを読んでちょっとでも興味あるな、と思った方はぜひのぞいてみてください。
ここまで読んでいただきありがとうございます。

[^1]:SSHなどでログインし、ターミナルで制御している端末 tty
[^2]:制御端末の無いとは、通常ユーザーによって操作されたプロセスが生成されますが、ユーザー操作以外のプロセスのことを指します。デーモンから起動された端末は制御端末を持たないため、非表示になっています。
[^3]:fと--forestで階層表示はするが、fは制御端末のあるすべてのユーザーのプロセスも表示する
[^4]:コンピュータに対するコマンド(命令文)の一つ。接続端末(ターミナルで接続している端末)のデバイス名->もう少しわかりやすく言うと同じLinuxに複数でSSH接続した後にターミナルでttyとコマンドを実行するとわかりやすいですが、接続しているターミナルごとの名札やタグのようなもの
[^5]:よくある組み合わせのオプション。一つ一つのオプションの意味を組み合わせて読み解いていけばなんのオプションかがわかります。