LinuxやUnix系システムのシェルであるBashを利用する際、コマンドの実行結果を画面に表示するだけでなく、後から確認するためにファイルへ保存したい場面は頻繁に発生します。
ログの記録や自動化スクリプトの作成において、この「リダイレクト」という機能は欠かせない基本技術です。
本記事では、初心者の方でも迷わずに使い分けができるよう、リダイレクトの仕組みから標準出力・標準エラー出力の制御、そして実務で役立つ応用テクニックまで詳しく解説します。
Bashにおける入出力とリダイレクトの基本概念
Bashでコマンドを実行すると、通常はその結果がターミナルの画面に出力されます。
しかし、プログラムの内部では、データがどこから入力され、どこへ出力されるかを管理する「標準ストリーム」という仕組みが働いています。
リダイレクトを理解するためには、まずこのストリームと「ファイル記述子 (ファイルディスクリプタ)」の概念を把握することが重要です。
標準ストリームとファイル記述子
Bashには、主に3つの標準ストリームが存在します。
これらはそれぞれに識別番号 (ファイル記述子) が割り当てられています。
| ストリーム名 | ファイル記述子 | 役割 | デフォルトの対象 |
|---|---|---|---|
| 標準入力 (stdin) | 0 | コマンドへのデータ入力 | キーボード |
| 標準出力 (stdout) | 1 | コマンドの正常な実行結果の出力 | 画面 (ターミナル) |
| 標準エラー出力 (stderr) | 2 | エラーメッセージや警告の出力 | 画面 (ターミナル) |
通常、標準出力と標準エラー出力はどちらも画面に表示されるため、一見すると区別がつきません。
しかし、リダイレクトを使用することで、正常な結果だけをファイルに保存し、エラーメッセージは画面に出すといった柔軟な制御が可能になります。
標準出力をファイルに保存する方法
最も基本的な操作は、コマンドの実行結果 (標準出力) をファイルに書き込むことです。
これには > または >> という記号を使用します。
上書き保存と追記保存の使い分け
リダイレクトの記号には、ファイルを上書きするタイプと、既存の内容の後ろに書き足すタイプの2種類があります。
1. 新規作成・上書き保存 (>)
指定したファイルが存在しない場合は新規に作成し、既に存在する場合は中身をすべて消去してから新しい内容を書き込みます。
# 現在のディレクトリのファイル一覧を list.txt に保存する
ls -l > list.txt
# 保存された内容を確認する
cat list.txt
total 4
-rw-r--r-- 1 user group 0 May 1 10:00 file1.txt
-rw-r--r-- 1 user group 0 May 1 10:00 file2.txt
2. 追記保存 (>>)
既存のファイルの内容を保持したまま、その末尾に新しい結果を追加します。
ログファイルのように、過去の履歴を残したい場合に適しています。
# 現在の日時を log.txt に追記する
date >> log.txt
# さらにもう一度実行して追記する
date >> log.txt
# 内容を確認する
cat log.txt
Fri May 1 10:05:00 JST 2026
Fri May 1 10:05:10 JST 2026
標準エラー出力を個別に保存する
コマンドが失敗した際に出力されるエラーメッセージは、通常の標準出力とは異なるルート (ファイル記述子 2) を通ります。
そのため、単純に > を使ってもエラー内容はファイルに保存されません。
エラーメッセージのみをファイルに書き出す
エラーメッセージを保存するには、ファイル記述子の 2 を明示的に指定してリダイレクトを行います。
# 存在しないディレクトリを表示しようとしてエラーを発生させ、error.log に保存する
ls /nonexistent_directory 2> error.log
# 画面には何も表示されず、エラー内容はファイルに記録される
cat error.log
ls: cannot access '/nonexistent_directory': No such file or directory
このように、正常な出力とエラー出力を分離して管理することは、トラブルシューティングを効率化する上で非常に役立ちます。
標準出力と標準エラー出力をまとめて保存する
スクリプトの実行ログを記録する場合など、正常な結果とエラーメッセージの両方を1つのファイルにまとめたいことがあります。
Bashではいくつかの記述方法がありますが、現代的な書き方と伝統的な書き方の両方を知っておくと役立ちます。
推奨される現代的な書き方 (&>)
Bashの比較的新しいバージョン (バージョン4以降) では、&> を使うことで簡潔にすべての出力をリダイレクトできます。
# 全出力を all_output.log に保存する (上書き)
command_name &> all_output.log
# 全出力を all_output.log に追記する
command_name &>> all_output.log
伝統的な書き方 (2>&1)
古いシェル環境や POSIX 準拠を意識する必要がある場合は、2>&1 という記述を使用します。
これは「標準エラー出力 (2) の送り先を、標準出力 (1) と同じ場所にする」という意味です。
# 標準出力を file.log に送り、標準エラー出力も同じ場所 (file.log) に送る
ls -l /bin /nonexistent 1> file.log 2>&1
ここで注意が必要なのは、記述の順番です。
リダイレクトは左から順番に処理されるため、必ず先に 1> file.log (または単に > file.log) を記述し、その後に 2>&1 を繋げる必要があります。
出力を画面に表示しつつファイルにも保存する (teeコマンド)
リダイレクトを使用すると、出力がファイルに流れてしまうため、実行中に現在の状況を画面で確認することができなくなります。
この問題を解決するのが tee コマンドです。
teeコマンドの基本的な使い方
tee は、パイプ (|) を通じて受け取ったデータを「画面」と「ファイル」の両方に分岐させて出力します。
# 実行結果を画面に表示し、同時に output.txt にも保存する
ls -la | tee output.txt
teeで追記やエラー出力を扱う
tee で追記を行いたい場合は、-a (append) オプションを使用します。
また、標準エラー出力も含めたい場合は、前述のリダイレクト技術と組み合わせます。
# 画面で確認しながら、エラーも含めてすべて log.txt に追記する
# まず 2>&1 でエラーを標準出力に合流させ、それを tee に渡す
./myscript.sh 2>&1 | tee -a log.txt
この方法は、長時間かかる処理の進捗を監視しつつ、後で解析するためにログを残したいという場面で非常に重宝します。
不要な出力を捨てる方法 (/dev/null)
時には、コマンドの結果やエラーメッセージを一切表示させたくない、保存もしたくないという場合があります。
そのようなときは、Linuxの「空のデバイス」である /dev/null にリダイレクトします。
実行結果やエラーを完全に消去する
/dev/null に送られたデータは、システムによって即座に破棄されます。
# 標準出力だけを捨てる (エラーは表示される)
command > /dev/null
# エラーメッセージだけを捨てる (正常な結果は表示される)
command 2> /dev/null
# すべての出力を完全に無視する
command &> /dev/null
cronなどの自動実行ジョブにおいて、特定のコマンドから出る不要な通知を抑制したい際によく使われるテクニックです。
リダイレクト利用時の注意点と安全策
リダイレクトは非常に強力ですが、操作ミスによって重要なファイルを上書きしてしまうリスクも孕んでいます。
noclobberオプションで上書きを防ぐ
Bashには、既存のファイルを > で誤って上書きしてしまうのを防ぐ設定があります。
# 上書き禁止設定を有効にする
set -o noclobber
# 既存のファイルに上書きしようとするとエラーになる
echo "test" > existing_file.txt
# Bash: existing_file.txt: cannot overwrite existing file
もし意図的に上書きしたい場合は、>| という記号を使うことで設定を一時的に無視して書き込むことが可能です。
パイプとリダイレクトの混同に注意
初心者によく見られるミスとして、パイプ (|) とリダイレクト (>) の混同があります。
- パイプ (
|): 左側のコマンドの「出力」を、右側のコマンドの「入力」として渡す。 - リダイレクト (
>): 左側のコマンドの「出力」を、「ファイル」に書き込む。
右側にくるのが「コマンド」なのか「ファイル名」なのかを常に意識するようにしましょう。
実践的な活用シーン
ここまでの知識を組み合わせた、実務で使える応用例をいくつか紹介します。
1. 実行ログを日時付きで保存する
スクリプトの実行ごとに新しいログファイルを作成する例です。
# 現在の日時をファイル名に含めて保存する
./batch_process.sh > "log_$(date +%Y%m%d_%H%M%S).txt" 2>&1
2. 特定の文字列を含むエラーだけを抽出して保存する
パイプとリダイレクトを組み合わせることで、高度なフィルタリングが可能になります。
# エラー出力を grep に渡し、"CRITICAL" を含む行だけをファイルに保存する
./server_start.sh 2>&1 | grep "CRITICAL" > critical_errors.log
3. ヒアドキュメントによる複数行のファイル作成
コマンドの結果を保存するのとは少し異なりますが、Bash自体の機能で複数行のテキストをファイルに出力する方法もあります。
# 複数行のテキストを config.conf に一括で書き込む
cat << EOF > config.conf
server_name=localhost
port=8080
timeout=30
EOF
まとめ
Bashのリダイレクトは、コマンドの実行結果をファイルに保存するための基本でありながら、非常に奥が深い機能です。
>は上書き、>>は追記。- 標準出力は
1、標準エラー出力は2というファイル記述子で管理される。 2>&1や&>を使うことで、すべての出力を1つにまとめられる。teeコマンドを使えば、画面確認とファイル保存を両立できる。- 不要な出力は
/dev/nullへ送って破棄する。
これらの仕組みを正しく理解し、使い分けることができるようになると、サーバー管理の効率化や自動化スクリプトの品質向上に直結します。
まずは基本的な上書きと追記の使い分けから練習し、徐々にエラー出力の制御やパイプとの組み合わせに慣れていってください。
Bashの操作に自信を持つための第一歩として、リダイレクトをマスターしましょう。
