標準入出力とは - stdin / stdout / stderr の仕組み
標準入出力って何だろう?
> file でログを保存したり、|(パイプ)でコマンドをつないだり——コマンドを学んでいくと、こういう記号に必ず出会う。その裏側にあるのが「標準入出力(stdin / stdout / stderr)」という仕組みだ。
この記事では、3つの標準入出力がそれぞれ何なのか、なぜ出力が2種類に分かれているのか、そしてリダイレクトやパイプで入出力先をどう切り替えるのかを、ライナとライニー先輩の会話でやさしく整理していく。
この記事でわかること
- stdin / stdout / stderr の3つがそれぞれ何を担当しているか
- なぜ出力が stdout と stderr の2種類に分かれているのか
- 番号 0 / 1 / 2(ファイルディスクリプタ)の意味
>2>&>で出力先を切り替える方法- パイプ
|と入力リダイレクト<の使い方
1. 標準入出力とは何か?
結論: 標準入出力は、コマンドが「入力を受け取る口」と「結果を出す口」「エラーを出す口」の3つの標準的な通り道。それぞれ stdin / stdout / stderr と呼ぶ。
- stdin(標準入力): コマンドにデータを渡す入り口
- stdout(標準出力): 通常の結果を出す出口
- stderr(標準エラー出力): エラーや警告を出す出口
「標準」の意味
「標準」とは「特に指定しなければ使われる、決められた通り道」という意味。たとえば ls の結果が画面に出るのは、stdout の標準の行き先が画面(ターミナル)になっているから。この行き先を後から変えられるのが、リダイレクトやパイプの正体だ。
2. なぜ出力が stdout と stderr に分かれているの?
結論: 「次の処理に渡したい結果」と「人間に読ませたいエラー」を混ぜないため。分けておくと、結果だけを保存したりエラーだけを取り出したりできる。
- stdout = 正常な結果(次の処理やファイルに渡したいデータ)
- stderr = エラーや警告(人間に知らせたいメッセージ)
を別々の出口にしている。こうしておけば、結果だけをファイルに保存しても、エラーはちゃんと画面に出て見落とさずに済むんだ。
身近なたとえ
工場のラインで言えば、stdout は「完成品を流すベルトコンベア」、stderr は「不良品を知らせるアラーム」。完成品の箱(ファイル)にアラームの音は入れたくない。だから別々にしてある、というイメージ。
3. 番号 0 / 1 / 2 って何?
結論: stdin / stdout / stderr には 0 / 1 / 2 という番号(ファイルディスクリプタ)が割り当てられている。
2>の2はこの番号のこと。
2> っていう書き方を見たんですけど、この 2 って何ですか?| 番号 | 名前 | 役割 |
|---|---|---|
| 0 | stdin | 標準入力(入り口) |
| 1 | stdout | 標準出力(通常の出口) |
| 2 | stderr | 標準エラー出力(出口) |
番号と記号の対応
リダイレクトの記号はこの番号と直結している。
>は1>の省略形(stdout を送る)2>は stderr を送る<は0<の省略形(stdin から読む)
「2> の 2 は stderr の背番号」と覚えれば、記号の意味が一気に腑に落ちる。
4. リダイレクトで出力先を変えるには?
結論:
>で stdout を、2>で stderr をファイルへ送れる。両方まとめるなら> file 2>&1または&> file。
ls /etc > filelist.txt
> を使うと、画面に出るはずだった stdout の内容が filelist.txt に書き込まれる(画面には何も出ない)。なお > は上書き、>> は追記になる。
エラーだけを保存したいときは 2> を使う。
ls /not-exist 2> errors.txt
(画面には何も出ず、errors.txt に次が記録される) ls: cannot access '/not-exist': No such file or directory
>、stderr は 2> ですね。じゃあ、両方まとめて1つのファイルに入れたいときは?2>&1 を付け足す。「stderr(2)を stdout(1)と同じ行き先に流す」という意味だよ。command > output.txt 2>&1
2>&1 は順番が大事
2>&1 は「stderr を、その時点での stdout の行き先に合わせる」という意味。そのため > output.txt を先に書く必要がある。command 2>&1 > output.txt のように順番を逆にすると、stderr が古い行き先(画面)のまま残ってしまう。新しい &> file 記法(bash)なら順番を気にせず両方まとめられる。
command &> output.txt
5. パイプと標準入力はどう使う?
結論: パイプ
|は左コマンドの stdout を右コマンドの stdin につなぐ。<はファイルの中身を stdin として渡す。
| は、左のコマンドの stdout を、右のコマンドの stdin に直接つなぐ仕組みなんだよ。ls /etc | grep conf
この例では、ls /etc の出力(stdout)が、そのまま grep conf の入力(stdin)に流れ込む。grep はその入力の中から conf を含む行だけを拾い出す。
流れのイメージ
ls /etc ──stdout──▶ | ──stdin──▶ grep conf ──stdout──▶ 画面
パイプは「前のコマンドの出口」と「次のコマンドの入り口」を直結するホースのようなもの。
ファイルの中身を stdin として渡したいときは < を使う。
sort < names.txt
これは names.txt の中身を sort の標準入力に流し込み、並べ替えて表示する。sort names.txt と結果は同じだが、「ファイルを stdin につなぐ」という標準入力の動きが分かりやすい例だ。
パイプやリダイレクトをもっと実践的に練習したいなら、パイプとリダイレクトの基本 で手を動かしながら学べる。出力を画面とファイルの両方に出したいときは tee コマンドの使い方 も便利だ。
まとめ
- 標準入出力は stdin(入力)/ stdout(通常の出力)/ stderr(エラー出力)の3つの通り道
- 出力が2種類あるのは「結果」と「エラー」を混ぜないため
- 3つには番号 0 / 1 / 2(ファイルディスクリプタ)が割り当てられている
>で stdout、2>で stderr をファイルへ送れる(両方なら> file 2>&1または&> file)- パイプ
|は stdout を次の stdin につなぎ、<はファイルを stdin として渡す