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
.但是,它仅适用于标准输出。正如第二个测试所示,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
}