Linuxのリダイレクトとパイプ|>・>>・|・2>&1 の意味を図で理解【初心者向け】

前の記事では、grep でログから1行を探しました。その中で、history | grep apt のように、縦棒(|)でコマンドをつなぐ書き方が少しだけ出てきましたね。

ネットで Linux のコマンドを調べていると、>、>>、|、2>&1 のような記号がたくさん出てきます。私も最初は「呪文みたいで読めない…」と感じて、意味がわからないままコピーしていました。でも、しくみは意外とシンプルです。「コマンドの結果が、どこに流れていくか」を変えているだけなんです。

この記事では、練習用のファイルを使いながら、リダイレクトとパイプを図でイメージできるように整理していきます。

💡
この記事でわかること
  • コマンドの結果がどこに流れているのか(標準出力・標準エラー出力)
  • > と >> の違い(上書きと追記)
  • エラーだけを分けたり、まとめて保存したりする方法(2>・2>&1)
  • |(パイプ)でコマンドをつなぐ方法と、tee・sort・uniq・wc の組み合わせ
🔰
この記事の前提
  • echo・cat・ls を使える
  • grep の基本がわかる

まだの方は、前の記事「Linuxのgrep入門|ログや設定ファイルから1行を探し出す【初心者向け】」から読むのがおすすめです。

💡
用語メモ
  • 標準出力:コマンドのふつうの結果が出る出口(番号は 1)。ふだんは画面に出ます
  • ログ:プログラムが残す「いつ、何が起きたか」の記録
  • コマンド:パソコンへの指示の言葉。ターミナルに打って Enter で実行します

用語で迷ったら、連載のまとめ記事の「よく出てくる用語ミニ辞典」でも確かめられます。


結論:記号は「結果の行き先」を変えるだけ

記号 意味 例
> 結果をファイルに書く(上書き) echo "こんにちは" > note.txt
>> 結果をファイルの最後に足す(追記) echo "追加" >> note.txt
< ファイルの中身をコマンドに渡す wc -l < note.txt
2> エラーだけをファイルに書く ls /no-such-dir 2> err.txt
2>&1 エラーも、ふつうの結果と同じ行き先へ ls ~ /no-such-dir > all.txt 2>&1
&> 結果とエラーをまとめてファイルへ(bash の短い書き方) ls ~ /no-such-dir &> all.txt
/dev/null 捨てる場所(何も残らない) ls /no-such-dir 2>/dev/null

そして、縦棒の パイプ は「前のコマンドの結果を、次のコマンドに渡す」記号です。たとえば次のように使います。

  • 1
ls /etc | wc -l

しくみ:コマンドの結果には「2つの出口」がある

コマンドを実行すると、結果は画面に表示されます。実はこのとき、出口が2つあります。

  • 標準出力(番号は 1):ふつうの結果が出てくる出口
  • 標準エラー出力(番号は 2):エラーのメッセージが出てくる出口

どちらも、何もしなければ同じ画面に流れてくるので、見た目では区別がつきません。リダイレクトは、この出口ごとに「画面ではなくファイルへ流してね」と行き先を変えるしくみです。ちなみに、キーボードからの入力は 標準入力(番号は 0)と呼ばれます。

コマンドの3つの流れ

準備:練習用のディレクトリを作る

練習は ~/linux-practice/redirect-test の中で行います。

  • 1
  • 2
  • 3
mkdir -p ~/linux-practice/redirect-test
cd ~/linux-practice/redirect-test
pwd

🖥️
この記事の出力例について

ここから先の出力例は、Debian 13での実行例です(ユーザー名 kaito・パソコン名 demo のダミー環境)。UbuntuやWSL(=Windows の中で Linux を動かせる、Microsoft のしくみ)では、表示が少し違うことがあります。

(例)

  • 1
/home/kaito/linux-practice/redirect-test

> と >>:上書きと追記

まずは > で、結果をファイルに書いてみます。

  • 1
  • 2
  • 3
  • 4
echo "1行目" > note.txt
cat note.txt
echo "2行目" > note.txt
cat note.txt

(例)

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
kaito@demo:~/linux-practice/redirect-test$ echo "1行目" > note.txt
kaito@demo:~/linux-practice/redirect-test$ cat note.txt
1行目
kaito@demo:~/linux-practice/redirect-test$ echo "2行目" > note.txt
kaito@demo:~/linux-practice/redirect-test$ cat note.txt
2行目

2回目の > で、1行目が消えてしまいました。> は中身をまるごと置きかえる(上書きする)記号です。ファイルがなければ新しく作り、あれば中身を消してから書き込みます。

残したまま後ろに足したいときは、>> を使います。

  • 1
  • 2
  • 3
echo "3行目" >> note.txt
echo "4行目" >> note.txt
cat note.txt

(例)

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
kaito@demo:~/linux-practice/redirect-test$ echo "3行目" >> note.txt
kaito@demo:~/linux-practice/redirect-test$ echo "4行目" >> note.txt
kaito@demo:~/linux-practice/redirect-test$ cat note.txt
2行目
3行目
4行目

ログに1行ずつ足していくような使い方は、>> の出番です。

🚫
大事なファイルに > を向けない(文章だけで説明します)

> は、確認なしで中身を消してから書き込みます。たとえば、>> のつもりで > と打ってしまい、~/.bashrc のような設定ファイルに向けると、それまでの設定が一瞬で消えてしまいます。元に戻すボタンはありません。設定ファイルに書き足すときは、先に cp でコピーを取り、>> になっているか打つ前に見直しましょう。この記事では、練習用のディレクトリの外のファイルには書き込みません。


<:ファイルの中身をコマンドに渡す

< は向きが逆で、ファイルの中身をコマンドの入力として渡します。wc -l は「行の数を数える」コマンドです。

  • 1
  • 2
wc -l note.txt
wc -l < note.txt

(例)

  • 1
  • 2
  • 3
  • 4
kaito@demo:~/linux-practice/redirect-test$ wc -l note.txt
3 note.txt
kaito@demo:~/linux-practice/redirect-test$ wc -l < note.txt
3

ファイル名を直接渡すと名前つきで、< で渡すと数だけが表示されます。ふだんはあまり使いませんが、「矢印の向きで、流れる方向が決まる」と覚えておくと、ほかの記号も読みやすくなります。


2>:エラーだけを分ける

次は、わざとエラーを出してみます。存在しないディレクトリを ls して、結果を > でファイルに送ってみましょう。

  • 1
  • 2
ls /no-such-dir > out.txt
cat out.txt

(例)

  • 1
  • 2
  • 3
kaito@demo:~/linux-practice/redirect-test$ ls /no-such-dir > out.txt
ls: cannot access '/no-such-dir': No such file or directory
kaito@demo:~/linux-practice/redirect-test$ cat out.txt

cannot access '/no-such-dir': No such file or directory は「/no-such-dir にアクセスできません。そのようなファイルやディレクトリはありません」という意味です。cat out.txt は何も表示しませんでした(out.txt は作られましたが、中身は空です)。

ファイルに送ったはずなのに、エラーは画面に出てしまいました。> が行き先を変えるのは、出口 1(ふつうの結果)だけだからです。エラーは出口 2 から出ているので、そのまま画面に流れてきます。

エラーをファイルに送るには、出口の番号をつけて 2> と書きます。

  • 1
  • 2
ls /no-such-dir 2> err.txt
cat err.txt

(例)

  • 1
  • 2
  • 3
kaito@demo:~/linux-practice/redirect-test$ ls /no-such-dir 2> err.txt
kaito@demo:~/linux-practice/redirect-test$ cat err.txt
ls: cannot access '/no-such-dir': No such file or directory

メッセージが日本語で出る環境では

日本語の設定(ロケール)になっている環境では、同じエラーが日本語で表示されます。今回の Debian 13 で日本語の設定にして試すと、次のようになりました。

(例)

  • 1
ls: '/no-such-dir' にアクセスできません: そのようなファイルやディレクトリはありません

Debian 13での実行画面

今度は画面に何も出ず、エラーが err.txt に入りました。自動化のスクリプトで「エラーだけ別のファイルに残しておく」ときに使えます。


2>&1:ふつうの結果とエラーをまとめる

今度は、ある場所(~)とない場所(/no-such-dir)を一度に ls してみます。ふつうの結果とエラーの両方が出るはずです。

  • 1
  • 2
ls ~ /no-such-dir > all.txt 2>&1
cat all.txt

(例)

  • 1
  • 2
  • 3
  • 4
  • 5
kaito@demo:~/linux-practice/redirect-test$ ls ~ /no-such-dir > all.txt 2>&1
kaito@demo:~/linux-practice/redirect-test$ cat all.txt
ls: cannot access '/no-such-dir': No such file or directory
/home/kaito:
linux-practice

all.txt には、エラーの行が先頭に入り、そのあとに /home/kaito: とホームディレクトリの中身(今回は linux-practice だけ)が続きました。ls は、見つからない場所のエラーを先に出してから、見つかった場所の一覧を出すためです。

Debian 13での実行画面

2>&1 は「出口 2(エラー)を、出口 1 と同じ行き先にしてね」という意味です。&1 の & は、「1 という名前のファイル」ではなく「出口 1」を指すための印です。

💡
2>&1 は、うしろに書く

ls ~ /no-such-dir 2>&1 > all.txt のように順番を逆にすると、エラーは画面に出たままになります。シェル(=打ったコマンドを読み取って、プログラムを動かし、結果を返してくれるプログラム)は左から順番に行き先を決めていくので、「先に出口 1 をファイルに向けてから、出口 2 をそれに合わせる」という順番にする必要があるんです。迷ったら「> ファイル 2>&1 の順」と覚えておけば大丈夫です。

bash では、同じことを &> で短く書くこともできます。

  • 1
  • 2
ls ~ /no-such-dir &> all2.txt
cat all2.txt

(例)

  • 1
  • 2
  • 3
  • 4
  • 5
kaito@demo:~/linux-practice/redirect-test$ ls ~ /no-such-dir &> all2.txt
kaito@demo:~/linux-practice/redirect-test$ cat all2.txt
ls: cannot access '/no-such-dir': No such file or directory
/home/kaito:
linux-practice

/dev/null:いらない結果を捨てる

/dev/null は、送ったものが何も残らない特別な場所です。エラーを見なくていいときに使います。前々回の find /etc -name "*.conf" 2>/dev/null でも使いましたね。

  • 1
  • 2
ls /no-such-dir 2>/dev/null
echo "終わりました"

(例)

  • 1
  • 2
  • 3
kaito@demo:~/linux-practice/redirect-test$ ls /no-such-dir 2>/dev/null
kaito@demo:~/linux-practice/redirect-test$ echo "終わりました"
終わりました

ただし、エラーを捨てると、本当に困っているときの手がかりも消えてしまいます。うまく動かないときは、まず /dev/null を外して、エラーを見てみてください。


パイプ:コマンドの結果を次のコマンドに渡す

パイプ(縦棒)は、前のコマンドの出口 1 を、次のコマンドの入力につなぎます。ファイルを間にはさまずに、コマンドをバケツリレーのようにつなげられます。

パイプのしくみ

  • 1
  • 2
ls /etc | wc -l
ls /etc | head -5

(例)

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
kaito@demo:~/linux-practice/redirect-test$ ls /etc | wc -l
137
kaito@demo:~/linux-practice/redirect-test$ ls /etc | head -5
X11
adduser.conf
aliases
alternatives
apache2

数や名前は、入っているソフトによって変わります(今回の検証環境では 137 でした)。

head -5 は「最初の5行だけ表示する」コマンドです。一覧が長いときに、先頭だけを見るのに便利です。

sort と uniq -c:同じものを数える

自動化でよく使う組み合わせが、sort(並べかえる)と uniq -c(同じ行をまとめて数える)です。練習用のデータを作って試してみましょう。

  • 1
  • 2
  • 3
printf '%s\n' りんご みかん りんご ぶどう みかん りんご > fruits.txt
sort fruits.txt | uniq -c
sort fruits.txt | uniq -c | sort -nr

(例)

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
kaito@demo:~/linux-practice/redirect-test$ printf '%s\n' りんご みかん りんご ぶどう みかん りんご > fruits.txt
kaito@demo:~/linux-practice/redirect-test$ sort fruits.txt | uniq -c
      1 ぶどう
      2 みかん
      3 りんご
kaito@demo:~/linux-practice/redirect-test$ sort fruits.txt | uniq -c | sort -nr
      3 りんご
      2 みかん
      1 ぶどう

uniq -c の結果は、数字の前に空白がいくつか入ります(今回は6個)。数字の桁をそろえるための空白なので、気にしなくて大丈夫です。

uniq は「となり合った同じ行」しかまとめられないので、先に sort で並べておくのがコツです。最後の sort -nr は「数として、大きい順に並べる」という意味です。ログの中で「どのエラーが一番多いか」を調べるときにも、この形がそのまま使えます。

grep と組み合わせる

前の記事の grep とつなぐこともできます。

  • 1
  • 2
ls /etc | grep conf
ls /etc | grep conf | wc -l

(例)

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
kaito@demo:~/linux-practice/redirect-test$ ls /etc | grep conf
adduser.conf
ca-certificates.conf
ca-certificates.conf.dpkg-old
debconf.conf
deluser.conf
dhcpcd.conf
e2scrub.conf
gai.conf
host.conf
ld.so.conf
ld.so.conf.d
libaudit.conf
locale.conf
logrotate.conf
manpath.config
mke2fs.conf
netconfig
nftables.conf
nsswitch.conf
pam.conf
resolv.conf
sudo.conf
sudo_logsrvd.conf
vconsole.conf
xattr.conf
kaito@demo:~/linux-practice/redirect-test$ ls /etc | grep conf | wc -l
25

ld.so.conf.d や manpath.config、netconfig のように、名前の途中に「conf」が入っているものも見つかっています。grep は、その文字をどこかに含む行を全部表示するからです。


tee:画面に出しながら、ファイルにも残す

> でファイルに送ると、画面には何も出なくなります。「画面でも見たいし、ファイルにも残したい」ときは、tee をパイプのうしろにつなぎます。

  • 1
  • 2
ls -l | tee list.txt
cat list.txt

(例)

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
kaito@demo:~/linux-practice/redirect-test$ ls -l | tee list.txt
total 20
-rw-rw-r-- 1 kaito kaito 88 Nov  1 05:33 all.txt
-rw-rw-r-- 1 kaito kaito 88 Nov  1 05:33 all2.txt
-rw-rw-r-- 1 kaito kaito 60 Nov  1 05:33 err.txt
-rw-rw-r-- 1 kaito kaito 60 Nov  1 05:33 fruits.txt
-rw-rw-r-- 1 kaito kaito 24 Nov  1 05:33 note.txt
-rw-rw-r-- 1 kaito kaito  0 Nov  1 05:33 out.txt
kaito@demo:~/linux-practice/redirect-test$ cat list.txt
total 20
-rw-rw-r-- 1 kaito kaito 88 Nov  1 05:33 all.txt
-rw-rw-r-- 1 kaito kaito 88 Nov  1 05:33 all2.txt
-rw-rw-r-- 1 kaito kaito 60 Nov  1 05:33 err.txt
-rw-rw-r-- 1 kaito kaito 60 Nov  1 05:33 fruits.txt
-rw-rw-r-- 1 kaito kaito 24 Nov  1 05:33 note.txt
-rw-rw-r-- 1 kaito kaito  0 Nov  1 05:33 out.txt

今回の環境では、ファイルの権限が -rw-rw-r-- と表示されています(権限の記事で見た umask の設定によるものです)。

今回の一覧には list.txt 自身は出ていませんが、list.txt が入ることもあります(そのときはサイズ 0 で表示されます)。パイプの左右の ls と tee は同時に動き始めるので、tee が list.txt を作るのが先か、ls がフォルダの中を読むのが先か、というタイミングで変わるためです。私が同じ手順を少し前に試したときは、list.txt が入っていました。

追記したいときは tee -a を使います。

  • 1
  • 2
echo "5行目" | tee -a note.txt
cat note.txt

(例)

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
kaito@demo:~/linux-practice/redirect-test$ echo "5行目" | tee -a note.txt
5行目
kaito@demo:~/linux-practice/redirect-test$ cat note.txt
2行目
3行目
4行目
5行目

tee は、受け取った 5行目 を画面に出しながら、note.txt の最後にも足しました。


よくあるつまずき:同じファイルに読み書きすると空になる

最後に、ハマりやすい落とし穴を練習用のファイルで確かめておきます。fruits.txt を並べかえて、同じファイルに保存しようとすると…

  • 1
  • 2
  • 3
  • 4
cp fruits.txt fruits-backup.txt
sort fruits.txt > fruits.txt
cat fruits.txt
wc -l fruits.txt

(例)

  • 1
  • 2
  • 3
  • 4
  • 5
kaito@demo:~/linux-practice/redirect-test$ cp fruits.txt fruits-backup.txt
kaito@demo:~/linux-practice/redirect-test$ sort fruits.txt > fruits.txt
kaito@demo:~/linux-practice/redirect-test$ cat fruits.txt
kaito@demo:~/linux-practice/redirect-test$ wc -l fruits.txt
0 fruits.txt

cat fruits.txt は何も表示せず、wc -l も 0 fruits.txt(0行)になりました。エラーも何も出ないので、気づきにくいのがこわいところです。

中身が空になってしまいました。シェルは、sort を動かす前に > の準備をして、fruits.txt を空にしてしまいます。そのあとで sort が fruits.txt を読むので、読むものが何もなく、空の結果が書き込まれるわけです。最初に cp でコピー(fruits-backup.txt)を取っておいたので、元のデータは残っています。並べかえた結果は、別の名前のファイルに保存しましょう。

  • 1
  • 2
sort fruits-backup.txt > fruits-sorted.txt
cat fruits-sorted.txt

(例)

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
kaito@demo:~/linux-practice/redirect-test$ sort fruits-backup.txt > fruits-sorted.txt
kaito@demo:~/linux-practice/redirect-test$ cat fruits-sorted.txt
ぶどう
みかん
みかん
りんご
りんご
りんご

🚫
sudo と > でシステムのファイルに書き込まない(文章だけで説明します)

ネットの記事で、/etc の中の設定ファイルに sudo echo … > ファイル や … | sudo tee ファイル で書き込む例を見かけることがあります。> は sudo(=許可されたユーザーが、コマンドの前につけて、そのコマンドだけを管理者の権限で実行するしくみ)の外でシェルが処理するので前者は「Permission denied」になり、後者は本当に書き込めてしまいます。システムの設定ファイルを > や tee(-a なし)で上書きすると、ネットにつながらない、ログインできないといった状態になりかねません。この記事では試しません。システムのファイルを変えるときは、まずコピーを取り、手順を AI や公式の説明で確かめてからにしましょう。

🤖 詰まったらAIに聞こう:記号だらけのコマンドを読み解きたい

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
Linuxの初心者です。ネットで見つけた次のコマンドの意味を知りたいです。
> や >> 、| 、2>&1 などの記号が、それぞれ何をしているのか、
左から順番に、やさしく説明してください。
実行すると、ファイルが上書きされたり消えたりするおそれがあるかどうかも教えてください。

【使っている環境】WSLのUbuntu など
【読み解きたいコマンド】ここに貼る
【やりたいこと】例:エラーもまとめてファイルに残したい

🔒
AIに貼る前に:秘密情報やパスワードは貼らない

2>&1 でまとめたログや、tee で残したファイルには、APIキー、トークン、パスワード、メールアドレスなどがまざっていることがあります。APIキーやトークンは、Web のサービスを使うときに本人の代わりになる、合言葉のような文字列です。AI に貼る前に中身を見直して、「***」に置き換えてください。コマンドの中にパスワードを直接書いている場合も同じです。


読み解き練習:自動化でよく見る1行

最後に、ここまでの記号を使って、自動化の手順書でよく見る形を読んでみましょう(実行はしなくて大丈夫です)。

問題1:python3 report.py >> run.log 2>&1

答え:python3 report.py の結果を、run.log の最後に追記します(>>)。2>&1 で、エラーも同じ run.log に入ります。毎回の実行の記録が、エラーも含めて1つのファイルにたまっていく形です。> ではなく >> なので、前の記録は消えません。

問題2:grep -i error run.log | wc -l

答え:run.log から、大文字・小文字を区別せずに error を含む行を探し(前の記事の grep -i)、その結果を | で wc -l に渡して行数を数えます。「エラーが何回出たか」がわかります。

問題3:ls /etc 2>/dev/null | sort | tee etc-list.txt

答え:/etc の一覧を出し、エラーは捨てて(2>/dev/null)、sort で並べかえ、tee で画面に出しながら etc-list.txt にも保存します。記号を左から1つずつ区切れば、長い1行も読めます。


よくある質問

Q. 並べかえた結果を、どうしても同じファイルに保存したいです。

sort には、結果の保存先を決める -o という書き方があります。sort -o fruits.txt fruits.txt のように書くと、sort が中身を全部読んでから書き込むので、> のように空になりません。それでも、最初は cp でコピーを取ってから試すと安心です。

Q. 2>&1 と &> は、どちらを使えばいいですか?

どちらも同じ意味ですが、&> は bash などの一部のシェルだけの書き方です。手順書やスクリプトでよく見るのは > ファイル 2>&1 のほうなので、まずはこちらを読めるようにしておくのがおすすめです。

Q. | と > は、どう使い分けますか?

行き先が違います。> は結果をファイルに入れ、| は結果を次のコマンドに渡します。「このあと、さらに絞り込んだり数えたりしたい」なら |、「結果を残しておきたい」なら > です。両方したいときは、この記事の tee が使えます。


まとめ

  • コマンドの結果には、出口 1(ふつうの結果)と出口 2(エラー)がある
  • > は上書き、>> は追記。大事なファイルに > を向けない
  • 2> はエラーだけ、> ファイル 2>&1 はまとめて(順番に注意)
  • /dev/null は捨てる場所。うまくいかないときは外してエラーを見る
  • パイプでコマンドをつなぐ。sort → uniq -c → sort -nr で数えられる
  • tee で画面とファイルの両方に出せる
  • 同じファイルに読み書きすると空になる

次の記事では、たまったファイルをまとめて小さくする tar・gzip・zip の使い分けを見ていきます。


次に読む記事


関連する記事