Linuxシステムにおける入出力リダイレクトとファイルディスクリプタの操作

基本的なリダイレクト演算子

Linux環境では、>< を使用してデータの流れを制御します。これらはコマンドの入出力をファイルに関連付けるために使用されます。

# source_fileの内容をcommandの標準入力(STDIN)として渡す
command < source_file

# commandの実行結果(標準出力)をoutput.logに保存する
# ファイルが存在しない場合は新規作成され、存在する場合は上書きされる
command > output.log

# 標準出力を既存ファイルの末尾に追加する
command >> output.log

ヒアドキュメント (<<)

インライン入力リダイレクトとも呼ばれ、任意の識別子(EOFなど)が現れるまでのテキストを標準入力としてコマンドに流し込みます。

cat << END_TEXT
これは複数行の
テキスト入力の例です。
END_TEXT

パイプライン (|)

あるコマンドの標準出力を、別のコマンドの標準入力として直接接続します。複数のコマンドを繋いで複雑な処理を行う際に不可欠です。

# プロセス一覧から特定の名前を検索し、その行数をカウントする
ps aux | grep "nginx" | wc -l

ファイルディスクリプタの管理

Linuxではすべての入出力チャンネルがファイルとして扱われ、非負の整数である「ファイルディスクリプタ (FD)」で識別されます。デフォルトでは以下の3つが定義されています。

  • 0 (STDIN): 標準入力
  • 1 (STDOUT): 標準出力
  • 2 (STDERR): 標準エラー出力

これらを明示的に指定することで、エラーメッセージのみを分離して保存するといった操作が可能になります。

# 標準エラー出力のみをerror.logに記録する(2と>の間にスペースを入れない)
ls /non_existent_dir 2> error.log

# 標準出力と標準エラー出力の両方をひとつのファイルにまとめる
command &> combined.log

# スクリプト内でメッセージを明示的に標準エラー出力へ送る
echo "エラーが発生しました" >&2

execコマンドによるディスクリプタの制御

exec を使用すると、現在のシェルプロセスにおける入出力を恒久的にリダイレクトしたり、独自のディスクリプタ(3〜9番)を利用してパスを一時的に保存したりできます。

# ファイルディスクリプタ3を作成し、現在の標準出力(1)をコピーする
exec 3>&1

# 標準出力をファイルに変更する
exec 1> output_report.txt

echo "この行はファイルに書き込まれます。"

# 標準出力を元の状態(ディスクリプタ3に保存していたもの)に戻す
exec 1>&3
echo "この行は再びターミナルに表示されます。"

同様の手法で、標準入力をファイルに切り替えた後、再びキーボード入力に戻す処理も記述できます。

# 現在の標準入力(0)をディスクリプタ6に退避
exec 6<&0

# 入力元をファイルに変更
exec 0< user_list.csv

idx=1
while read -r row
do
    echo "処理中 [${idx}行目]: ${row}"
    ((idx++))
done

# 標準入力を元のキーボード入力(6番)に戻す
exec 0<&6

read -p "全データの処理が完了しました。終了しますか? (y/n): " final_check
echo "入力された回答: ${final_check}"

タグ: linux bash ShellScript Redirect pipe

8月23日 18:26 投稿