Bashには、ファイル記述子番号を選択して変数に割り当てる機能があります。
$ exec {fd}>foo.txt
$ echo "$fd"
11
$ echo "bar" >&$fd
$ cat foo.txt
bar
この機能はbash 4.4ではうまく機能しますが、bash 4.2では関数で使用すると問題が発生しました。以下は最小限のデモです。
$ bash --version | head -1
GNU bash, version 4.2.46(1)-release (x86_64-redhat-linux-gnu)
$ (func() { echo 1>&$fd; }; type func)
func is a function
func ()
{
echo &>$fd
}
$ (func() { echo 2>&$fd; }; type func)
func is a function
func ()
{
echo 2>&$fd
}
最初のテストではに1>&$fd
なります&>$fd
。$fd
11の場合、fd 11にリダイレクトされず、代わりに次にリダイレクトされます。文書ただし、名前11
は標準出力でのみ機能します。 2番目のテストでわかるように、stderrにはこのエラーはありません。
bash 4.4も同様です。
$ bash --version | head -1
GNU bash, version 4.4.19(1)-release (x86_64-pc-linux-gnu)
$ (func() { echo 1>&$fd; }; type func)
func is a function
func ()
{
echo 1>&$fd
}
これは修正されたバグのようです。本当に?さらに重要なのは、回避策を提案できますか?
答え1
回避策は、目的の動作を維持しながらエラーを防ぐことです>&
。1<&
fdをコピーするときにfdが読み取り用または書き込み用に開くかどうかは重要ではありません。dup2()
気にしないでください。
$ bash --version | head -1
GNU bash, version 4.2.46(1)-release (x86_64-redhat-linux-gnu)
$ (func() { echo 1<&$fd; }; type func)
func is a function
func ()
{
echo 1<&$fd
}