
2026/02/27 4:58
「`2>&1`」は、bash などのシェルで使われるリダイレクト構文です。 - **`2`** は標準エラー出力(stderr)を指します。 - **`>`** は「ここへ送る」という意味のリダイレクト演算子です。 - **`&1`** はファイルディスクリプタ 1、すなわち標準出力(stdout)を参照することを示しています。 したがって `2>&1` は「stderr を stdout と同じ先へ送る」という指示になります。例えば ```bash command > output.txt 2>&1 ``` とすると、コマンドの標準出力とエラー出力の両方を `output.txt` に書き込むことができます。 - **目的** エラーメッセージも含めて同じファイルや別プロセスに集約したい場合に使用します。 - **注意点** 先に stdout をリダイレクトしてから `2>&1` と書く必要があります(順序を逆にすると正しく動作しません)。
RSS: https://news.ycombinator.com/rss
要約▶
Japanese Translation:
(欠落している要素を組み込む)
Summary
コアのアイデアは、Bash のリダイレクト演算子 (
>, >>, 2>&1 など) がコマンドの出力先を決定し、その順序が重要であるということです。新しい Bash バージョンでは、プロセス置換などの便利なショートカットが追加され、複数のストリームをきれいに扱えるようになっています。
はファイルを書き換え、>
は追記します。>>- 各リダイレクトの位置は結果となるファイルディスクリプタを変化させます(例:
とcmd > out 2>&1
)。cmd 2>&1 > out - パイプとリダイレクトを組み合わせて、標準出力や標準エラーを別々にフィルタリングできます(
,cmd | sed …
)。cmd 2> >(sed …) - Bash 4+ はプロセス置換を導入し、
のように使えます。cmd 2> >(sed 's/^/E:/') > >(sed 's/^/O:/')
演算子は|&
の省略形で、両方のストリームを単一のパイプへ送ります。2>&1 |
や&>
といったショートカット構文は両方のストリームを同時にリダイレクトします(例:>&
)。ls … &>/dev/null- リダイレクト順序を入れ替えることも可能で、場合によって便利です(
,2>/dev/null 1>&2
)。1>&2 2>&1
は誤った上書きを防ぎます。set -o noclobber
で解除したり、set +o noclobber
で状態を確認できます。set -o | grep noclobber
演算子は>|
が設定されていても強制的に上書きします。noclobber
これらのルールを理解することでバグを回避し、データ保護ができ、スクリプトがより明確で保守性の高いものになります。
本文
リダイレクトの裏技 – クイックリファレンス
1 – 上書き vs アペンド
| 記号 | 意味 | ファイルが存在しない場合に作成されるか |
|---|---|---|
| 出力先へリダイレクト。既存なら 上書き( が設定されていない限り)。 | |
| 出力をファイル末尾に追記。必要なら作成。 |
2 – コマンドラインの順序が重要
# stdout と stderr の両方を書き込む基本コマンド $ ls -ld /tmp /tnt ls: cannot access /tnt: No such file or directory drwxrwxrwt 118 root root 196608 Jan 7 11:49 /tmp # stdout のみリダイレクト $ ls -ld /tmp /tnt >/dev/null ls: cannot access /tnt: No such file or directory # stderr のみリダイレクト $ ls -ld /tmp /tnt 2>/dev/null drwxrwxrwt 118 root root 196608 Jan 7 11:49 /tmp # 両方をリダイレクト(stdout →、その後stderr) $ ls -ld /tmp /tnt >/dev/null 2>&1 # OK – 出力なし # 順序を入れ替えると stderr がコンソールへ $ ls -ld /tmp /tnt 2>&1 >/dev/null ls: cannot access /tnt: No such file or directory
各ストリームを個別にフィルタリング
# stdout を `sed` にパイプ $ ls -ld /tmp /tnt | sed 's/^.*$/<-- & --->/' ls: cannot access /tnt: No such file or directory <-- drwxrwxrwt 118 root root 196608 Jan 7 12:02 /tmp ---> # ストリームをまず結合してからフィルタ $ ls -ld /tmp /tnt 2>&1 | sed 's/^.*$/<-- & --->/' <-- ls: cannot access /tnt: No such file or directory ---> <-- drwxrwxrwt 118 root root 196608 Jan 7 12:02 /tmp ---> # 両方を抑制しつつフィルタ(何も表示されない) $ ls -ld /tmp /tnt >/dev/null | sed 's/^.*$/<-- & --->/'
高度なテクニック – stdout と stderr を別々にパイプ
(ls -ld /tmp /tnt | sed 's/^/O: /' >&9) 9>&2 2>&1 | sed 's/^/E: /' O: drwxrwxrwt 118 root root 196608 Jan 7 12:13 /tmp E: ls: cannot access /tnt: No such file or directory
Bash >4.0 なら、より読みやすく書けます:
ls -ld /tmp /tnt 2> >(sed 's/^/E: /') > >(sed 's/^/O: /')
または後で結合する場合:
cat -n <(ls -ld /tmp /tnt 2> >(sed 's/^/E: /') > >(sed 's/^/O: /')) 1 O: drwxrwxrwt 17 root root 28672 Nov 5 23:00 /tmp 2 E: ls: cannot access /tnt: No such file or directory
|&
の使用
|&command |& other は command 2>&1 | other の省略形です。順序ルールは同じく適用されます。
3 – noclobber
と >|
のオーバーライド
noclobber>|$ testfile=$(mktemp /tmp/testNoClobberDate-XXXXXX) $ date > $testfile ; cat $testfile # 毎回上書きされる $ set -o noclobber # 上書きを防止 $ date > $testfile # エラー:既存ファイルを上書きできない # `>|` でオーバーライド $ date >| $testfile ; cat $testfile # 再び成功
オプションの切替:
$ set +o noclobber # 無効にする
4 – 両方のストリームをリダイレクトするショートカット
# 明示的 ls -ld /tmp /tnt >/dev/null 2>&1 # Bash にて利用可能な短縮形 ls -ld /tmp /tnt &>/dev/null ls -ld /tmp /tnt >&/dev/null # 別順序 ls -ld /tmp /tnt 2>/dev/null 1>&2 # 両ストリームを stderr に送る
ディスクリプタの混合と入れ替え
$ ls -ld /tmp /tnt 2>&1 1>&2 | sed 's/^/++/' ++/bin/ls: cannot access /tnt: No such file or directory ++drwxrwxrwt 193 root root 196608 Feb 9 11:08 /tmp/ $ ls -ld /tmp /tnt 1>&2 2>&1 | sed 's/^/++/' /bin/ls: cannot access /tnt: No such file or directory drwxrwxrwt 193 root root 196608 Feb 9 11:08 /tmp/
5 – 更なる読解
完全な構文については Bash のリダイレクトセクションを参照してください:
man bash | less +/^REDIRECTION