これがわかりにくくなってるのは、2に該当する標準エラー出力とは?というのを説明している人があまりいないことなんじゃないかと思ってるので
$ cd /tmp/ $ ls cmclist-20260225 $
例えばこの時に、
"hoge"って単語がcmclist-20260225 内に入ってないとエラーになります。これが標準出力1に該当しています。
grepの場合は、対象ワードが見つけられれば標準出力0、見つけられないと標準出力1となるようになってます。
$ grep "hoge" cmclist-20260225 $ echo $? 1 $
次に、cmclist-20260225じゃなくてcmclist-20260226にgrepしたらどうでしょう?
$ grep "hoge" cmclist-20260226 grep: cmclist-20260226: No such file or directory $ echo $? 2 $
これが標準エラー出力2に該当しています。"grep: cmclist-20260226: No such file or directory"っていうメッセージは必ず出力されてしまいますが、
これを出力させたくないケースのときに>/dev/null 2>&1を使います。
$ grep "hoge" cmclist-20260226 > /dev/null 2>&1 $ echo $? 2 $
こういうことです。
$ grep "y-super-1" cmclist-20260225 y-super-1.cmc $ echo $? 0 $
grepでその行を見つけてこれれば見つけた行が返ってきます。これが標準出力0に相当しています。
$ grep "y-super-1" cmclist-20260225 > /dev/null $ echo $? 0 $
grepの場合は見つけた行は出力されますが、それを出力させたくないときに>/dev/nullに結果を投げます。
これでも0が返ってきますので、cmclist-20260225の中に"y-super-1"が存在していることが分かります。
ちなみに、grepの場合は見つけた場合に出力させないオプションも存在しています。
$ grep -q "y-super-1" cmclist-20260225 $ echo $? 0 $
これでもいいんですけど。さて/dev/nullに投げるのとどっちのほうが挙動が早いんでしょうね???