標準入出力とは - stdin / stdout / stderr の仕組み
この記事でできるようになること
- 標準入力・標準出力・標準エラー出力の役割を区別できる
- コマンドの入出力がどこへ流れるかをイメージできる
前提知識(先に読むと理解しやすい記事)
標準入出力って何だろう?
コマンドを学んでいくと、> file や |(パイプ)という記号によく出会う。この記号の裏側にあるのが「標準入出力(stdin / stdout / stderr)」という仕組みだ。
この記事では、3つの標準入出力の役割、出力が2種類に分かれる理由、リダイレクトとパイプの使い方を、リナとライニー先輩の会話で整理する。
この記事でわかること
- stdin / stdout / stderr の3つがそれぞれ何を担当しているか
- なぜ出力が stdout と stderr の2種類に分かれているのか
- 番号 0 / 1 / 2(ファイルディスクリプタ)の意味
>2>&>で出力先を切り替える方法- パイプ
|と入力リダイレクト<の使い方
1. 標準入出力とは何か?
結論: 標準入出力は、コマンドが持つ3つの通り道。データを受け取る口が1つ、結果を出す口とエラーを出す口が2つある。それぞれ stdin・stdout・stderr と呼ぶ。
- 標準入力(stdin。データの入り口): 材料が運び込まれる入り口にあたる
- 標準出力(stdout。結果を出す出口): 完成品が流れる出口にあたる
- 標準エラー出力(stderr。エラー専用の出口): 不良品を知らせるアラームにあたる
図1: 入り口は stdin の1つ、出口は stdout と stderr の2つ。かっこ内の数字は「番号 0 / 1 / 2 って何?」で説明する。
「標準」の意味
「標準」とは「特に指定しなければ使う、決まった通り道」という意味。例えば 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 に書き込まれる。画面には何も表示されない。> は上書き、>> は追記になる。
> は便利ですね。さっそく使ってみます。ls /etc > notes.txt を実行して、そのあとに ls /home > notes.txt も実行しました。notes.txt の中身は消えてしまったよ。> は上書き専用なんだ。同じファイル名にもう一度 > を使うと、前の中身は消えてしまう。残しておきたいときは >>(追記)を使おう。> は「保存」じゃなくて「置き換え」なんですね...! 次からは >> を使います。> による上書き事故に注意
GUI でファイルを保存するときは「同じ名前のファイルがあります。上書きしますか?」という確認が出ます。> には、この確認がありません。Enter を押した瞬間に、元の中身は消えます。ゴミ箱にも残りません。
安全に使うために、次の2つを習慣にしましょう。
- 前の内容を残したいときは
>>(追記)を使う - 保存する前に
ls ファイル名で、同じ名前のファイルがないか確かめる
なお、本サイトの仮想ターミナルは学習用です。ここで > を試しても、あなたのパソコンのファイルは壊れません。安心して練習してください。
エラーだけを保存したいときは 2> を使う。
ls /not-exist 2> errors.txt
このとき画面には何も表示されない。errors.txt の中に、次の1行が記録される。
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(Ubuntu などで標準的に使われるシェル。打ったコマンドを受け取って実行するプログラム)専用の書き方だ。
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 コマンドの使い方 も便利だ。
ミニ課題
結論: stdout・stderr のリダイレクトとパイプを、実際に手を動かして確認する。
課題1: ls /etc の結果だけを etc-list.txt に保存しよう(画面には何も表示しない)
ヒント1(方向づけ)を見る
出力の行き先を、画面からファイルに変える記号がある。上書きでよい。
ヒント2(コマンド名)を見る
> を使う。
答えを見る
ls /etc > etc-list.txt
画面には何も出ず、etc-list.txt に /etc の一覧が保存される。
課題2: 存在しないディレクトリファイルをまとめて整理する入れ物。Windows や macOS の「フォルダ」と同じもの。を ls で指定し、そのエラーメッセージだけを err.txt に保存しよう(画面にはエラーを出さない)
ヒント1(方向づけ)を見る
出力ではなく、エラー専用の出口だけをファイルに向ける記号がある。
ヒント2(コマンド名)を見る
2> を使う。
答えを見る
ls /no-such-dir 2> err.txt
画面には何も出ず、err.txt に ls: cannot access '/no-such-dir': No such file or directory が記録される。
課題3: ls /etc の結果から、conf を含む行だけを画面に表示しよう(ファイルには保存しない)
ヒント1(方向づけ)を見る
前のコマンドの出力を、そのまま次のコマンドの入力として渡すしくみを使う。
ヒント2(コマンド名)を見る
パイプ | と grep を使う。
答えを見る
ls /etc | grep conf
ls /etc の出力から conf を含む行だけが画面に表示される。
まとめ
- 標準入出力は stdin(入力)/ stdout(通常の出力)/ stderr(エラー出力)の3つの通り道
- 出力が2種類あるのは「結果」と「エラー」を混ぜないため
- 3つには番号 0 / 1 / 2(ファイルディスクリプタ)が割り当てられている
>で stdout、2>で stderr をファイルへ送れる(両方なら> file 2>&1または&> file)- パイプ
|は stdout を次の stdin につなぎ、<はファイルを stdin として渡す