パイプとリダイレクト入門 - データの流れを理解する
この記事で学べること
- 「データの流れ」 という考え方が分かる
|(パイプ)と>>>(リダイレクト)の違いが分かる- 「標準出力」「標準エラー出力」の使い分けができる
grepやsortを組み合わせて 小さなコマンドを連結 できるようになる
結論(先に覚えるべき型)
- 画面に出る結果を ファイルに保存 したい →
>>> - 結果を 次のコマンドに渡す →
| - エラーだけ 別扱い →
2>
1. まずはここから:データはどこから来てどこへ行く?
ls を実行すると画面にファイル名が出ますよね。あれってどこから出てるんですか?3 つの口の名前
| 名前 | 略称 | 番号 | デフォルトの行き先 |
|---|---|---|---|
| 標準入力 | stdin | 0 |
キーボード |
| 標準出力 | stdout | 1 |
画面 |
| 標準エラー | stderr | 2 |
画面 |
2. リダイレクト:出力をファイルに保存する
2-1. > で上書き保存
$ ls > files.txt
> で 画面ではなくファイルに行き先を切り替えた から、画面には出ないんだ。中身を見てごらん。$ cat files.txt
Documents Downloads files.txt Pictures
2-2. >> で追記
$ echo "1行目" > log.txt $ echo "2行目" >> log.txt $ cat log.txt
1行目 2行目
> は 既存の中身を消して上書き する。大事なファイルに > を使うと内容が消える。追記したいときは必ず >> を使うこと。
2-3. < で入力をファイルから取る(応用)
$ wc -l < log.txt
2
wc -l log.txt と何が違うんですか?< は「キーボードの代わりにファイルを差し込む」イメージ。最初は > と >> だけ覚えればOK。3. パイプ:コマンドをつなぐ
3-1. 基本形
|(縦棒、パイプ)は 「左のコマンドの出力を、右のコマンドの入力にする」 記号。
$ ls | wc -l
12
ls の結果を wc -l に渡してファイル数を数えてるんですね!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)の扱い
5-1. エラーは別の口から出ている
$ ls /not-exist > out.txt
ls: '/not-exist' にアクセスできません: そのようなファイルやディレクトリはありません
> out.txt でファイルに出したつもりなのに、エラーが画面に出てます...> は標準出力(stdout)しか拾わない から。エラーを拾うには番号 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. よくある初心者のつまずき
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. ミニ課題:実際にやってみよう
課題1: 自分のホームディレクトリのファイル一覧を home-files.txt に保存しよう。
ヒントを見る
> でファイルに書き出す。
解答例
$ ls ~ > home-files.txt
課題2: /etc 以下のファイル数を数えて画面に表示しよう(パイプを使う)。
ヒントを見る
ls の結果を wc -l に渡す。
解答例
$ ls /etc | wc -l
課題3: /etc の中で .conf で終わるファイルだけ取り出して、conf-list.txt に保存しよう。
ヒントを見る
ls → grep → > の3段構え。
解答例
$ ls /etc | grep "\.conf$" > conf-list.txt
grep "\.conf$" の $ は「行末」を意味する正規表現。「.conf で終わる行」だけが残る。
8. コピペ用テンプレート
よく使う型をまとめておく
# 結果をファイルに保存(上書き) コマンド > out.txt # 結果をファイルに追記 コマンド >> out.txt # 結果を絞り込む コマンド | grep キーワード # 結果を並び替えて先頭10件 コマンド | sort | head -n 10 # 通常出力とエラーをまとめて記録 コマンド > all.log 2>&1 # エラーだけ別ファイルに コマンド 2> error.log # 途中経過もファイルに残しつつ次へ コマンド | tee progress.txt | 次のコマンド