Skip to content

Instantly share code, notes, and snippets.

@showa-yojyo
Last active August 3, 2026 13:18
Show Gist options
  • Select an option

  • Save showa-yojyo/e06b2cae967d080783b47614ba9b5cf1 to your computer and use it in GitHub Desktop.

Select an option

Save showa-yojyo/e06b2cae967d080783b47614ba9b5cf1 to your computer and use it in GitHub Desktop.
WIP
author プレハブ小屋 <2386769+showa-yojyo@users.noreply.github.com>
created 2026-08-02
draft true
modified 2026-08-03
tags
bash
redirections
file descriptors
title Bash redirections ノート

Bash redirections ノート

ファイル記述子

ファイルを表すのに、ファイル名ではなく番号を使う場合がある。その番号をファイル記述子と呼ぶ。

Redirection に関して特別なファイル

Redirection において、Bash は下のファイル名を特別に扱う:

ファイル名 ファイル
/dev/fd/fd ファイル記述子 fd に同じ
/dev/stdin ファイル記述子 0 に同じ
/dev/stdout ファイル記述子 1 に同じ
/dev/stderr ファイル記述子 2 に同じ
/dev/tcp/host/port 対応 TCP ソケットを開こうとする †1
/dev/udp/host/port 対応 UDP ソケットを開こうとする †1

†1: host は有効なホスト名か Internet 所在地であり、port はポート番号かサービス名とする。

入力

このすべての構文において n は省いてもよい。そのときは 0, つまり標準入力が指定されたとみなされる。

構文 意味
n<word word を展開して得られる名前のファイルから入力する
n<&word 入力ファイル記述子 word を複製して n で使えるようにする
n<&digit- 入力ファイル記述子 digitn に移転する
n<<word here document の始まり
n<<-word here document の始まり(タブ文字によるインデント可)
n<<<word here string

紙幅の都合上、here document/string は本稿では取り扱わない。

出力

このすべての構文において n は省いてもよい。そのときは 1, つまり標準出力が指定されたとみなされる。

word に対応するファイルが実行直前に存在しない場合、Bash はそのファイルをまず作成する。

構文 意味
n>word 記述子 n への出力をファイル word に向け直す †2
n>|word †2
n>>word 記述子 n への出力をファイル word の末尾に出力する
>&word †3
&>word 1>word 2>&1 と同値 †3
&>>word 1>>word 2>&1 と同値
n>&word 出力ファイル記述子 word を複製して n で使えるようにする
n>&digit- 出力ファイル記述子 digitn に移転する

†2: この二つは実行直前に word が存在する場合の挙動が異なる。縦棒なしの記法では set -o noclobber である場合にエラーとなる。

†3: この二つは基本的に同じ意味だが、構文 >&word では語が番号や - に展開されることは許されない(構文 n>&word と解釈される)。

入力と出力をどちらでも行う

記法 n<>word はファイル word を、入力と出力のどちらもファイル拡張子 n により実現できるようにする。

{varname}redirection 構文

ファイル記述子 0, 1, 2 以外のものを利用する場合、未使用のものを自分で探すのは危険だ。

構文 {var}<fd, {var}>fd, etc. を用いると、Bash が操作者に代わって新しいファイル記述子を見つくろい使用可能にし、変数 var に割り当てる。

また、shopt -s varredir_close である場合、命令の実行完了時に {var}<fd 構文を用いて割り当てられたファイル記述子は Bash が閉じる。

Tip

当然 shopt -s varredir_close しておくべきだろう。

標準出力と標準エラーへの両方の出力を同一のファイルに行う

Bash Reference Manual から例を引く:

ls > dirlist 2>&1
  1. > dirlist1>dirlist の意味だから、標準出力への出力をファイル dirlist に向け直す。
  2. 2>&1 は標準出力を複製して標準エラーで使えるようにする。

実行直後、ファイル dirlist の内容が標準出力と標準エラーへの出力に、発生順に書き出されていることが期待される。

Bash では演算子 &> も使えるということを知らないとマズい:

ls &>dirlist

順序前後によりストリームが消滅?する

次の命令は標準出力しかファイルに書き出さない:

ls 2>&1 > dirlist
  1. 2>&1 は標準エラーを標準出力の複製として扱う。
  2. > dirlist は標準出力をファイル dirlist に向け直す。

ファイルを開いてファイル記述子に割り当てる

$ exec 3<> /tmp/foo
$ echo "test" >&3
$ cat /tmp/foo
test
$ exec 3>&-
$ echo "test" >&3
-bash: 3: Bad file descriptor
  • ファイル記述子を「開いて」「閉じる」には exec を用いる。
  • 同時に複数のファイル記述子を開くことが可能であることに注意。面白い何かが実現するかもしれない。

Bash Reference Manual にわずかに記載があるように、構文 {varname}redirecion を用いてもいい:

$ exec {var}>|/tmp/foo
$ echo test >|{var}
$ cat <{var}
test
$ ls /dev/fd/${var}
/dev/fd/10
$ exec {var}>&-
$ ls /dev/fd/${var}
ls: cannot access '/dev/fd/10': No such file or directory

割り当てた記述子を閉じる

番号 n を(自分で開いた)ファイル記述子とする。手動でこれを閉じるには exec n>&-exec n<&- のどちらでも有効だ。

解説

Redirection の機能はファイルハンドルを操作することで、命令の入出力対象を変更することだと考えられる。

  • 組み込み命令 exec を用いる場合、redirection は現在のシェル実行環境内のファイルハンドルを変更する。
  • Redirection 演算子は単一命令の(先頭、途中、末尾の)どこにでも書ける。
  • Redirection は出現順に、左から右へと処理される。Redirection の順序は重要だ。
  • 上の各表で n が付けられる redirection は、{varname} 形式の語を代わりに先頭に付けることも可能。
  • ファイル記述子は 10 以上の番号になり、それを {varname} に割り当てる。
  • >&- or <&- の先頭にある場合、値 {varname} により閉じられるファイル記述子が定義される。
  • 命令の有効範囲を超えて生き残るファイル記述子を、使用者が手動で(移転構文で)管理しろ。

上の各表における演算子直後の word は、基本的には各種展開(中括弧展開や変数展開など)の対象となる。複数の語に展開される場合、エラーとなる。

  • ファイルを開くか作成できない場合、redirection は失敗する。
  • 少なくとも {varname}redir 構文を用いないと、番号が 9 より大きいファイル記述子はシェルが内部で使用するものと衝突する可能性がある。

以上

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment