ps aux | grepは何を行っているコマンドなのか？

OS上で動いているプロセスの確認をする際に使用する`ps aux|grep <process_name>`
このコマンドは<process_name>に、検索したいプロセスの名前を入れると、該当のプロセスが稼働しているかどうかを確認することができる便利なコマンドです。

ですが、実際、なんで`ps aux|grep <process_name>`と叩くと、このような出力結果を得ることができるのでしょうか？
今回は`ps aux|grep <process_name>`にあるパイプライン`|`に焦点をあてて解説したいと思います。

# コマンドの解説
まずは前提となる`ps aux`と`grep`について簡単に解説します。
## ps auxについて
`ps aux`のみを走らせてみましょう

```
~ ❯❯❯ ps aux
USER               PID  %CPU %MEM      VSZ    RSS   TT  STAT STARTED      TIME COMMAND
toshiokun  1465  18.4  2.7  6631496 448688   ??  S     6:19AM   1:15.15 com.docker.hyper
_windowserver      129   6.5  0.7  7502272 122076   ??  Ss    6:18AM   1:02.39 /System/Library/
toshiokun   511   5.7  0.4  5227076  64424   ??  S     6:19AM   0:03.67 /Applications/iT
toshiokun   682   2.7  1.4 23820844 243012   ??  S     6:19AM   0:16.65 /Applications/Vi
root               304   2.0  1.0  7502908 162908   ??  Ss    6:19AM   0:54.12 /System/Library/
toshiokun   625   1.9  0.4  4822416  74404   ??  S     6:19AM   0:13.14 /Applications/Vi
root                65   1.5  0.1  4418140  10388   ??  Ss    6:18AM   0:04.61 /Library/Applica
root                85   1.4  0.2  4566788  38356   ??  Ss    6:18AM   0:14.30 /System/Library/
_driverkit         288   1.2  0.0  4806844   2308   ??  Ss    6:19AM   0:03.48 /System/Library/
toshiokun   493   0.7  1.3  5568640 217188   ??  S     6:19AM   0:29.34 /Applications/Go
```
こんな感じで表示されると思います。

`ps`単体がそもそもLinux上で動いているプロセスを確認するコマンドなのですが、`ps aux`とオプションも指定してあげることで、「端末操作の」「ＣＰＵやメモリの使用率を付与した」「現在実行中の」プロセスを確認することができます。
基本的には`ps aux`とセットで覚えている方が多いでしょう。

## grepについて
grepはある特定の単語を含む行を返すためのメソッドです。
例えば下記のようなファイルがあったとします。

```hoge.txt
hoge
fuga
piyo
hogehoge
fugafuga
piyopiyo
```

この中から、`hoge`の文字を含む行を検索したいときには下記のコマンドを叩きます。

```
~ ❯❯❯ grep hoge hoge.txt
hoge #検索結果1
hogehoge #検索結果2
```

この場合、

- 第１引数の`hoge`が検索単語
- 第2引数の`hoge.txt`が後述する標準入力
- 出力結果が後述する標準出力

となっています。

# パイプライン(|)の意味
さて、今回のテーマである`ps aux | grep`の中にあるパイプライン(|)は何を意味しているのでしょうか。これを説明するにあたって、「標準入力」と「標準出力」について説明したいと思います。

## 標準入力とは？
標準入力とは、コマンドに対して**入力**する情報のことを指します。
それはコマンドラインで入力することもあるし、ファイルのこともあります。

先ほどのgrepの例で言えば、`hoge.txt`というファイルが標準入力になっているわけですが、コマンドラインの入力を標準入力にすることもできます。

```
~ ❯❯❯ grep hoge                                                        ✘ 130
hogehoge #コマンドラインから入力した標準入力
hogehoge #検索結果

~ ❯❯❯ grep hoge                                                        ✘ 130
fugafuga #コマンドラインから入力した標準入力
#標準入力の内容にhogeが含まれている行が存在しないため、検索結果が出力されない
```

## 標準出力とは？
対して標準出力というのは、コマンドの出力結果のことを指します。
これも出力先がコマンドラインのこともあるし、ファイルのこともあります。

少し余談ですが、もし標準出力をファイルにしたいときには下記のように`>`をつけてあげます。

```
grep hoge hoge.txt > result.txt
```

```result.txt
hoge
hogehoge
```

## パイプラインは標準出力を次のコマンドの標準入力に渡す仕組み
さてここでようやく本題に入れます。
パイプラインというのは、**前のコマンドの標準出力をそのまま次のコマンドの標準入力として渡す仕組み**のことを言います。

`ps aux|grep node`
というコマンドを叩くとすると、

1. `ps aux`でOS上で実行中のプロセスが一覧として表示され、標準出力される
2. `grep node`の標準入力として、1.で標準出力されたプロセスの一覧が渡される
3. 結果として、OS上で実行中のプロセスの中で、nodeという文字列を含んだプロセスが標準出力としてコマンドライン上に表示される

というフローになるわけです。
なので、`node index.js`というコマンドを実行中に`ps aux|grep node`というコマンドを叩くと以下のような標準出力を得ることができます。

```
~ ❯❯❯ ps aux|grep node
toshiokun  3094   0.0  0.0  4268424    684 s002  R+   11:04AM   0:00.00 grep --color=auto node
toshiokun  3003   0.0  0.3  4602960  46216 s000  S+   11:03AM   0:00.94 node index.js
```

明示的に標準入力を受け付ける部分を指定する際には-(ハイフン)を使用することもできます。

```
~ ❯❯❯ ps aux|grep node -
toshiokun  3094   0.0  0.0  4268424    684 s002  R+   11:04AM   0:00.00 grep --color=auto node -
toshiokun  3003   0.0  0.3  4602960  46216 s000  S+   11:03AM   0:00.94 node index.js
```


# まとめ
いかがだったでしょうか。
普段`ps aux|grep <process_name>`のコマンドを叩いている方の中にも、パイプラインの正確な定義を知らなかった方もいたのではないでしょうか。

パイプラインが「標準出力を次のコマンドの標準入力として渡す」ということを明確に理解していると、複雑なコマンドも比較的簡単に書くことができるようになるかと思います。

是非参考になれば幸いです。