以下 bash-fu 代码在 Linux 上运行良好,但在 MacOS 上中断:
files="foo bar"
echo PROG 1
for file in $files
do
echo $file | tee -a tempfile.txt
done
sort -u tempfile.txt
echo PROG 2
function trick {
for file in $files
do
echo $file | tee -a $1
done
}
trick >(sort -u)
错误是:
PROG 1
foo
bar
bar
foo
PROG 2
tee: /dev/fd/63: Bad file descriptor
foo
tee: /dev/fd/63: Bad file descriptor
bar
在 Linux 上写入与没有错误PROG 2
相同的行。PROG 1
在 MacOS 上,管道句柄似乎已关闭或未继承。
以上是重现问题的最小化样本。实际上,我会大量处理绑定输出和重定向句柄。精神上的东西
function trick {
for file in $files
do
echo $file | tee -a $1 | grep -Eo "^.."
done
}
trick >(sort -u | sed 's|o|x|g')
该代码在 Bash 4.1 中不起作用,但在多个发行版(Arch、Ubuntu 和 Debian)中的 Bash 4.4 中起作用
macOS 带有一个非常旧版本的
bash
. 该错误(该进程替换的文件描述符tee
在该上下文中调用之前已关闭)¹已在较新版本中修复。您会在 Linux 上遇到/dev/fd/x
与 bash 3.2 相同的问题(在不同的地方实现不同的错误消息)。在这里,您可以使用
zsh
orksh93
代替。bash
无论如何避免在这里是个好主意,因为它不会等待进程替换中的进程(zsh 等待它们,可以告诉 ksh93wait
为它们)。请注意,即使使用最新版本(撰写时为 4.4.12),
bash
这里仍然存在一些错误,例如:有些仍然由管道触发,例如:
¹ 一旦有管道,bash 就会关闭该文件描述符。更短的复制器: