Linux における入力と出力のリダイレクト

CompTIABeginner
オンラインで実践に進む

はじめに

この実験では、Linux シェルにおける入力と出力のリダイレクトに関する基本的なテクニックを学びます。標準出力 (stdout)、標準エラー出力 (stderr)、標準入力 (stdin) という 3 つの標準ストリームを操作することで、コマンドからのデータフローを制御する方法を詳しく見ていきます。この実験を通じて、コマンドの実行結果を保存したり、エラーメッセージを管理したり、ファイルからコマンドに入力を与えたりするための、不可欠なリダイレクト演算子の実戦的な使い方を習得できます。

一連の演習では、> 演算子を使用してコマンドの出力をファイルに送り(既存の内容を上書き)、>> 演算子を使用してデータを失うことなく出力を追記する方法を学びます。また、2> を使用してエラーメッセージを特定のリダイレクト先に送る方法や、標準出力と標準エラー出力の両方を 1 つのファイルにまとめる方法も学習します。最後に、tee コマンドを使用して画面に出力を表示しながら同時にファイルに保存する方法や、< 演算子を使用してキーボードの代わりにファイルからコマンドに入力を読み込ませる標準入力のリダイレクトを実践します。

> 演算子による標準出力のリダイレクト

このステップでは、コマンドの標準出力をリダイレクトする方法を学びます。Linux シェルでは、ほとんどのコマンドが何らかの出力を生成します。デフォルトでは、この出力は「標準出力(Standard Output または stdout)」と呼ばれ、ターミナル画面に表示されます。しかし、> 演算子を使用すると、この出力をファイルにリダイレクトできます。これは、コマンドの結果を保存したり、ログファイルを作成したり、レポートを生成したりする際に非常に便利です。

まず、簡単なコマンドを実行して、ターミナルに表示される出力を確認してみましょう。

echo "Hello from LabEx"

ターミナルに直接以下の出力が表示されるはずです。

Hello from LabEx

次に、この出力をファイルにリダイレクトしてみましょう。> 演算子の後にファイル名を指定します。これにより、シェルは echo コマンドの出力を現在のディレクトリ(~/project)にある hello.txt という名前のファイルに送るよう指示されます。

以下のコマンドを実行してください。

echo "Hello from LabEx" > hello.txt

今回はターミナルに何も表示されないことに注目してください。これは、出力が hello.txt ファイルに送られたためです。cat コマンドを使用して、ファイルの内容を確認できます。

cat hello.txt

リダイレクトされたテキストが表示されます。

Hello from LabEx

> 演算子は、ファイルが存在しない場合は新しく作成します。注意点として、ファイルが既に存在する場合、> 演算子は警告なしにその内容をすべて上書きします。実際に確認してみましょう。

まず、現在のディレクトリの内容をリスト表示し、それを file_list.txt という新しいファイルに保存します。

ls -l > file_list.txt

次に、file_list.txt の内容を確認します。

cat file_list.txt

プロジェクトディレクトリ内のファイルリストが表示されます。内容は以下のようになります。

total 4
-rw-rw-r-- 1 labex labex  0 Jun 25 14:56 file_list.txt
-rw-rw-r-- 1 labex labex 17 Jun 25 14:56 hello.txt

ここで、別のコマンドを実行し、その出力を同じ file_list.txt ファイルにリダイレクトしてみます。

echo "This is new content." > file_list.txt

もう一度 file_list.txt の内容を確認すると、元のファイルリストが置き換わっていることがわかります。

cat file_list.txt

出力は以下のようになります。

This is new content.

これが > 演算子の上書き動作です。次のステップでは、既存の内容を上書きせずに出力をファイルに追記する方法を学びます。

>> 演算子による標準出力の追記

このステップでは、既存の内容を削除せずに、ファイルの末尾に出力を追加する方法を学びます。前のステップで見たように、> 演算子は保存先のファイルを上書きします。これを避けるには、追記演算子 >> を使用します。この演算子は、時間の経過とともに新しいエントリを追加していくログファイルの管理などに非常に役立ちます。

まず、初期内容を含むファイルを作成しましょう。名前は greetings.txt とします。

echo "Hello, this is the first line." > greetings.txt

内容を確認します。

cat greetings.txt

出力は以下の通りです。

Hello, this is the first line.

次に、ファイルを上書きする代わりに、>> 演算子を使用して新しい行を追記します。

echo "This is the second line, appended." >> greetings.txt

再度 greetings.txt の内容を確認します。

cat greetings.txt

今回は、元の内容の後に新しい行が追加されているのがわかります。

Hello, this is the first line.
This is the second line, appended.

>> 演算子はログファイルの作成に最適です。activity.log という名前の簡単なログファイルを作成し、date コマンドを使用してタイムスタンプを追加してみましょう。

date > activity.log

次に、同じファイルに別のタイムスタンプを追記します。

date >> activity.log

最終的な activity.log ファイルを表示して、両方のエントリを確認します。

cat activity.log

2 つのタイムスタンプが表示され、2 番目のコマンドがファイルを上書きせずに出力を追記したことがわかります。正確な時刻は実行タイミングによって異なります。

Wed Jun 25 14:56:53 CST 2025
Wed Jun 25 14:56:56 CST 2025

このように、>> は既存のデータを保持したまま新しいデータをファイルの末尾に追加するため、新しい情報でファイルを安全に更新することができます。

2> 演算子による標準エラー出力のリダイレクト

このステップでは、エラーメッセージの管理方法を学びます。コマンドは標準出力 (stdout) のほかに、「標準エラー出力(Standard Error または stderr)」と呼ばれる別の種類の出力を生成します。これは、エラーメッセージや診断情報のために特別に使用されるストリームです。デフォルトでは、stdoutstderr の両方がターミナルに表示されますが、これまでに学んだリダイレクト演算子(> および >>)は stdout にしか影響しません。

stderr をリダイレクトするには、そのファイル記述子(ファイルディスクリプタ)である 2 を指定する必要があります。実は > 演算子は 1> の略記であり、1stdout のファイル記述子です。したがって、stderr をリダイレクトするには 2> を使用します。

実際にエラーを発生させて確認してみましょう。存在しないファイルをリスト表示しようとしてみます。

ls non_existent_file

このコマンドは失敗し、ターミナルにエラーメッセージが表示されます。

ls: cannot access 'non_existent_file': No such file or directory

次に、標準の > 演算子を使ってこれをリダイレクトしてみます。

ls non_existent_file > output.txt

エラーメッセージが依然としてターミナルに表示されることに注目してください。> 演算子ではキャッチできませんでした。output.txt ファイルを確認しても、中身は空です。

cat output.txt

標準出力は生成されず、標準エラー出力のみが生成されたため、ファイルには何も書き込まれません。

では、2> を使用して標準エラー出力を error.log というファイルに正しくリダイレクトしてみましょう。

ls non_existent_file 2> error.log

今回はターミナルにメッセージが表示されません。エラーは正常にリダイレクトされました。error.log の内容を表示して、キャッチされたメッセージを確認できます。

cat error.log

ls コマンドからのエラーメッセージが表示されます。

ls: cannot access 'non_existent_file': No such file or directory

>> が標準出力を追記するのと同様に、2>> を使用して標準エラー出力をファイルに追記することもできます。別の存在しないファイルをリスト表示し、そのエラーを error.log に追記してみましょう。

ls another_fake_file 2>> error.log

再度 error.log の内容を確認します。

cat error.log

新しいエラーメッセージがファイルの末尾に追加されているのがわかります。

ls: cannot access 'non_existent_file': No such file or directory
ls: cannot access 'another_fake_file': No such file or directory

このテクニックは、通常の出力とエラーメッセージを分離するのに非常に役立ちます。メインの出力ファイルを汚すことなく、後で確認するためにエラーだけをログに記録できます。

標準出力と標準エラー出力の両方を 1 つのファイルにリダイレクトする

このステップでは、コマンドからのすべての出力(標準出力と標準エラー出力の両方)を 1 つのファイルにキャプチャする方法を学びます。これは、発生したエラーを含め、スクリプトやコマンドの実行記録を完全に残したい場合に特に便利です。

stdoutstderr の両方を生成するコマンドを使用してみましょう。存在するファイル (/etc/passwd) と存在しないファイル (non_existent_file) を同時にリスト表示します。

ls -l /etc/passwd non_existent_file

ターミナルに 2 種類の出力が表示されます。最初の行は標準エラー出力で、2 行目は標準出力です。

ls: cannot access 'non_existent_file': No such file or directory
-rw-r--r-- 1 root root 1916 Jul 18  2024 /etc/passwd

stdout 用の > だけを使ってリダイレクトしようとすると、エラーメッセージは画面に残ります。

ls -l /etc/passwd non_existent_file > output_only.txt

ターミナルの出力:

ls: cannot access 'non_existent_file': No such file or directory

そして、output_only.txt には標準出力のみが含まれます。

cat output_only.txt
-rw-r--r-- 1 root root 1916 Jul 18  2024 /etc/passwd

両方のストリームを 1 つのファイルにリダイレクトするには、&> 演算子を使用できます。これは、stdout (ファイル記述子 1) と stderr (ファイル記述子 2) の両方を指定したファイルに送る便利な短縮形です。

試してみましょう。すべての出力を combined.log というファイルにリダイレクトします。

ls -l /etc/passwd non_existent_file &> combined.log

今回はターミナルに何も表示されません。すべての出力が combined.log にキャプチャされました。内容を確認してみましょう。

cat combined.log

ファイルに標準出力と標準エラー出力の両方が含まれていることがわかります。

ls: cannot access 'non_existent_file': No such file or directory
-rw-r--r-- 1 root root 1916 Jul 18  2024 /etc/passwd

同じ結果を得るための、より伝統的ですが少し複雑な構文もあります:> file 2>&1。これを分解すると以下のようになります。

  • > file: 標準出力 (ファイル記述子 1) を file にリダイレクトします。
  • 2>&1: 標準エラー出力 (ファイル記述子 2) を標準出力 (ファイル記述子 1) と同じ場所にリダイレクトします。stdout は既に file に送られているため、stderr もそこに送られます。

この方法で、出力を combined_traditional.log に保存してみましょう。

ls -l /etc/passwd non_existent_file > combined_traditional.log 2>&1

やはりターミナルには何も表示されません。ファイルの内容を確認すると、同じ結果が得られます。

cat combined_traditional.log
ls: cannot access 'non_existent_file': No such file or directory
-rw-r--r-- 1 root root 1916 Jul 18  2024 /etc/passwd

&> の方が短く好まれることが多いですが、古いスクリプトでは 2>&1 を頻繁に見かけるため、その仕組みを理解しておくことは重要です。両方のストリームを追記したい場合は、&>> または >> file 2>&1 を使用します。

tee による出力の分岐と < による標準入力のリダイレクト

この最後のステップでは、2 つの補完的なリダイレクトの概念を学びます。tee コマンドによる出力の分岐と、< 演算子を使用したファイルからのコマンドへの入力提供です。

tee による出力の分岐

コマンドの出力をファイルに保存しつつ、同時にターミナルでも確認したい場合があります。>>> 演算子は出力をファイル専用にリダイレクトするため、画面からは消えてしまいます。tee コマンドは、出力を分岐させてファイルと標準出力(画面)の両方に送ることで、この問題を解決します。名前の由来は、配管の T 字分岐(T-splitter)からきており、流れを 2 つの経路に分ける役割を果たします。

実際に見てみましょう。/etc/ ディレクトリの内容をリスト表示し、tee を使って画面に表示しながら etc_listing.txt というファイルにも保存します。

ls /etc/ | tee etc_listing.txt

ターミナルにディレクトリリストがすべて表示されます。同時に、tee コマンドは全く同じ内容を etc_listing.txt に書き込んでいます。これを確認してみましょう。

cat etc_listing.txt

ファイルの内容が画面に表示されたものと一致しているはずです。

デフォルトでは、tee は保存先のファイルを上書きします。代わりに追記したい場合は、-a オプションを使用します。これはログ記録に非常に便利です。ログファイルを作成し、2 つのエントリを追記してみましょう。

date | tee system_log.txt
echo "User labex performed a system check." | tee -a system_log.txt

最初のコマンドは、現在の日付で system_log.txt を作成します。2 番目のコマンドは tee -a を使用して、日付を消さずに新しい行を追記します。最終的なファイルを確認します。

cat system_log.txt

出力には両方の行が表示されます。

Wed Jun 25 14:56:53 CST 2025
User labex performed a system check.

< による標準入力のリダイレクト

次に、出力リダイレクトの逆である「標準入力 (stdin)」のリダイレクトについて見ていきましょう。sortwccat などの多くのコマンドは、stdin(通常はキーボード)からデータを読み取ることができます。< 演算子を使用すると、キーボードの代わりにファイルから入力を取得するようコマンドに指示できます。

まず、項目のリストを含む簡単なファイルを作成します。名前は items.txt とします。

echo "banana" > items.txt
echo "apple" >> items.txt
echo "cherry" >> items.txt

これで、3 つの未ソートの項目が入った items.txt ができました。sort コマンドはテキストの行を並べ替えることができます。< を使って items.txtsort コマンドに流し込んでみましょう。

sort < items.txt

コマンドは items.txt の内容を入力として読み取り、それらをソートして、結果を標準出力(ターミナル)に表示します。

apple
banana
cherry

これは機能的には sort items.txt を実行するのと似ていますが、ファイルをコマンドの標準入力にリダイレクトするという強力な概念を示しています。これは、引数としてファイル名を受け付けず、stdin からしか読み取れないコマンドを扱う際に不可欠になります。

最後の例として、cat < items.txt を考えてみましょう。これは cat に対して items.txt から入力を読み取るよう指示します。cat の役割は入力をそのまま出力することなので、ファイルの内容が画面に表示されます。

cat < items.txt

これで、Linux における基本的な入出力リダイレクトの学習は終了です。これで、コマンドの入力元と出力先を自在に制御するためのツールが手に入りました。

まとめ

この実験では、Linux におけるコマンド出力のリダイレクトの基本を学びました。まず > 演算子を使用してコマンドの標準出力 (stdout) をファイルに送る方法を確認し、この演算子が既存のファイルを上書きすることに注意しました。上書きを避けるために、>> 演算子を使用してファイルの末尾に出力を追記する方法を学びました。また、2> 演算子を使用して標準エラー出力 (stderr) をファイルにリダイレクトする練習も行いました。これは、エラーメッセージを標準出力とは別にキャプチャするのに役立ちます。

さらに、stdoutstderr の両方を 1 つのファイルにリダイレクトして包括的なログを作成する方法も学びました。tee コマンドを探索し、出力を分岐させてファイルに保存しながら同時にターミナルに表示する方法を確認しました。最後に、< 演算子を使用して標準入力 (stdin) をリダイレクトし、キーボードの代わりにファイルからコマンドに入力を読み込ませる方法を習得しました。