パイプとリダイレクト入門 - データの流れを理解する
この記事でできるようになること
- `>` と `>>` で出力をファイルに保存・追記できる
- `|` でコマンドをつないで結果を加工できる
- `2>` と `2>&1` でエラー出力を分けたりまとめたりできる
前提知識(先に読むと理解しやすい記事)
この記事で学べること
- 「データの流れ」 という考え方が分かります。
|(パイプ)と>>>(リダイレクト)の違いが分かります。- 「標準出力」「標準エラー出力」を使い分けられます。
grepやsortを組み合わせて 小さなコマンドを連結 できるようになります。
結論(先に覚えるべき型)
- 画面に出る結果を ファイルに保存 したいときは
>か>>を使います。 - 結果を 次のコマンドに渡す ときは
|を使います。 - エラーだけ を別扱いにしたいときは
2>を使います。
先に知っておくこと:この記事で唯一注意が必要なのは > です。> は保存先のファイルを先に空にします。中身のあるファイルに > を使うと、その内容は消えます。
失敗するとどうなるか:消えた内容はゴミ箱に行きません。元には戻せません。
安全に試す方法:練習では ~/practice のような新しいディレクトリファイルをまとめて整理する入れ物。Windows や macOS の「フォルダ」と同じもの。を作り、そこで新しい名前のファイルに書き出してください。追記したいだけなら、最初から >> を使えば中身は消えません。本サイトの仮想ターミナル入力したコマンドを解釈してコンピュータに実行させる対話プログラム。は学習用なので、あなたのパソコンは壊れません。安心して試してください。
1. まずはここから:データはどこから来てどこへ行く?
結論: Linux コマンドは標準入力・標準出力・標準エラーの 3 つの口を持ち、行き先を付け替えられる。
ls を実行すると画面にファイル名が出ますよね。あれってどこから出てるんですか?言葉の整理:標準入力・標準出力・標準エラー出力は、英語では stdin・stdout・stderr と書きます。読み方は「エスティーディーイン」などですが、記事や本では英語表記のまま出てくることが多いです。どちらも同じものを指します。
3 つの口の名前
| 名前 | 略称 | 番号 | デフォルトの行き先 |
|---|---|---|---|
| 標準入力 | stdin | 0 |
キーボード |
| 標準出力 | stdout | 1 |
画面 |
| 標準エラー | stderr | 2 |
画面 |
2. リダイレクト:出力をファイルに保存する
結論:
>は出力をファイルに上書き保存し、>>は追記する。大事なファイルには>>を使う。
2-1. > で上書き保存
$ ls > files.txt
> で 画面ではなくファイルに行き先を切り替えた から、画面には出ないんだ。中身を見てごらん。cat コマンド。ファイルの中身を画面に出すコマンドだよ。$ cat files.txt
Documents Downloads files.txt Pictures
2-2. >> で追記
$ echo "1行目" > log.txt $ echo "2行目" >> log.txt $ cat log.txt
1行目 2行目
> は 既存の中身を消して上書き する。大事なファイルに > を使うと内容が消える。追記したいときは必ず >> を使うこと。
図1: 左が書き込む前のファイル、右が書き込んだ後の同じファイル。上下は別々のケースだ。> は元の A が消えて B だけになり、>> は A の後ろに B が並ぶ。
2-3. < で入力をファイルから取る(応用)
wc は数を数えるコマンドです。-l を付けると行数を数えます。
$ wc -l < log.txt
2
wc -l log.txt と何が違うんですか?< は「キーボードの代わりにファイルを差し込む」イメージ。最初は > と >> だけ覚えればOK。3. パイプ:コマンドをつなぐ
結論:
|は左のコマンドの出力を右の入力に渡す。小さなコマンドを連結して目的を達成する。
3-1. 基本形
|(縦棒、パイプ)は 「左のコマンドの出力を、右のコマンドの入力にする」 記号。
$ ls | wc -l
12
ls の結果を wc -l に渡してファイル数を数えてるんですね!図2: | は左のコマンドの出力(stdout)を、右のコマンドの入力(stdin)に差し込む。画面には出ず、そのまま次のコマンドへ渡る。エラー(stderr)はこの管を通らず、画面にそのまま出る。
3-2. よく使う組み合わせ
# ファイル一覧から「.txt」を含むものだけ抽出 $ ls | grep .txt # プロセス一覧から nginx を含む行を抽出 $ ps aux | grep nginx # ログを新しい順に表示 $ cat access.log | sort -r | head -n 10
パイプは何個でもつなげる
$ コマンド1 | コマンド2 | コマンド3 | ...
各段で「絞り込む」「並び替える」「整形する」と役割を分担させるのがコツ。
4. リダイレクトとパイプの違い
結論:
>は出力先がファイル、|は出力先が次のコマンドの入力。保存なら>、加工なら|。
> と | って何が違うんですか?> と | の違い
cmd > file → 出力先が【ファイル】 cmd | cmd2 → 出力先が【次のコマンドの入力】
>は保存したいときに使います。|はもう一段加工したいときに使います。
# パターンA: ls の結果をファイルに保存 $ ls > list.txt # パターンB: ls の結果を grep で絞り込む $ ls | grep ".log" # パターンC: 組み合わせ。grep で絞った結果をファイルに保存 $ ls | grep ".log" > log-files.txt
| でつないでから最後に > でファイル化、というのが実務で一番多いパターン。
5. 標準エラー出力(stderr)の扱い
結論: エラーは stderr(番号 2)から出る。
2>で別ファイルに分け、2>&1で標準出力にまとめる。
5-1. エラーは別の口から出ている
$ ls /not-exist > out.txt
ls: '/not-exist' にアクセスできません: そのようなファイルやディレクトリはありません
> out.txt でファイルに出したつもりなのに、エラーが画面に出てます...> は標準出力(stdout)しか拾わない から。エラーを拾うには番号 2 を指定するんだ。> は片方しか拾わないんですね。エラーを取りたいときは 2> を使えばいいんですね。5-2. エラーを別ファイルに分ける
$ ls /not-exist 2> error.log
(画面には何も出ない)
$ cat error.log
ls: '/not-exist' にアクセスできません: そのようなファイルやディレクトリはありません
5-3. 通常出力とエラーをまとめて1ファイルに
$ コマンド > all.log 2>&1
2>&1 の意味
「標準エラー(2)を、標準出力(1)と同じ場所に流す」という指示。 ログ収集で頻出する書き方なので、形で覚えてしまうのがおすすめ。
書く順番に注意。2>&1 > all.log ではなく > all.log 2>&1 の順序が正しい。逆にすると stderr がリダイレクト前の場所(画面)に流れてしまう。
6. よくある初心者のつまずき
結論: 自分自身へのリダイレクトはファイルを空にする。
teeを使えばパイプ途中の内容も保存できる。
6-1. > を使ったらファイルが空になった
$ cat important.txt > important.txt # NG: ファイルが空になる
> は コマンド実行前にファイルを空にする 動きをする。cat important.txt が読む前に中身が消えている。
自分自身に向けてリダイレクトしない のが鉄則。
6-2. | の前後にスペースが要る? 要らない?
どちらでも動く。ただし 読みやすさのため前後にスペースを入れる のが慣習。
$ ls|grep txt # OK だが見づらい $ ls | grep txt # 推奨
6-3. パイプの途中の結果が見たい
$ ls | tee list.txt | wc -l
tee は 流れている内容をファイルに記録しつつ、そのまま次に渡す コマンド。デバッグや「途中経過も保存しておきたい」ときに便利。
7. ミニ課題:実際にやってみよう
結論: 保存・件数カウント・絞り込み保存の 3 問で、リダイレクトとパイプの基本を手で確かめる。
課題1: 自分のホームディレクトリのファイル一覧を home-files.txt に保存しよう。
ヒント1(方向づけ)を見る
一覧を出すコマンドは知っていますね。その結果の行き先を、画面からファイルに付け替えます。
ヒント2(コマンド名)を見る
使うのは ls です。行き先を変える記号は > です。ホームディレクトリは ~ で表します。
答えを見る
$ ls ~ > home-files.txt $ cat home-files.txt
Documents Downloads Pictures home-files.txt
> はコマンドを動かす前にファイルを作ります。そのため home-files.txt 自身も一覧に入ります。中身はお使いの環境で変わります。
課題2: /etc 以下のファイル数を数えて画面に表示しよう(パイプを使う)。
ヒント1(方向づけ)を見る
一覧を出すコマンドの結果を、行数を数えるコマンドに渡します。ファイルには保存しません。
ヒント2(コマンド名)を見る
使うのは ls と wc です。行数を数えるオプションは -l、2つをつなぐ記号は | です。
答えを見る
$ ls /etc | wc -l
220
表示される数はお使いの環境で変わります。数字が1つだけ出れば成功です。
課題3: /etc の中で .conf で終わるファイルだけ取り出して、conf-list.txt に保存しよう。
ヒント1(方向づけ)を見る
一覧を出し、そこから条件に合う行だけを残し、最後にファイルへ保存します。3段構えです。
ヒント2(コマンド名)を見る
使うのは ls と grep です。つなぐのは |、保存するのは > です。「.conf で終わる」は "\.conf$" と書きます。
答えを見る
$ ls /etc | grep "\.conf$" > conf-list.txt $ cat conf-list.txt
adduser.conf ca-certificates.conf debconf.conf nsswitch.conf resolv.conf
grep "\.conf$" の $ は「行末」を意味する正規表現です。そのため「.conf で終わる行」だけが残ります。並ぶファイル名はお使いの環境で変わります。
8. 振り返り
結論: 行き先がファイルなら
>、次のコマンドなら|。エラーは別の口から出る。この3点を言葉にして確認する。
>、次のコマンドに渡したいときは | なんですね。> は行き先がファイル、| は行き先が次のコマンド。ここさえ押さえれば迷わないよ。> ファイル名 2>&1 と書けばいいよ。9. 今日の3行まとめ
結論: リダイレクト・パイプ・エラー出力の3点を3行で整理して定着させる。
>は上書き保存、>>は追記。中身を消したくないときは>>を使う|は左のコマンドの結果を右のコマンドに渡す- エラーは別の口(2番)から出る。
2>で分け、2>&1でまとめる
10. コピペ用テンプレート
結論: 保存・追記・絞り込み・ログ収集・途中保存のよく使う型をまとめて手元に置いておく。
よく使う型をまとめておく
# 結果をファイルに保存(上書き) コマンド > out.txt # 結果をファイルに追記 コマンド >> out.txt # 結果を絞り込む コマンド | grep キーワード # 結果を並び替えて先頭10件 コマンド | sort | head -n 10 # 通常出力とエラーをまとめて記録 コマンド > all.log 2>&1 # エラーだけ別ファイルに コマンド 2> error.log # 途中経過もファイルに残しつつ次へ コマンド | tee progress.txt | 次のコマンド