我在脚本中使用动态分配的文件描述符,如本文所述:
zsh 和 POSIX 相当于 bash 的 `{var}>&1`
该脚本本身可以在 bash 和 zsh 之间移植,因此emulate -LR bash
如果脚本检测到它正在 zsh 中运行,则会尽早执行。
不幸的是,这打破了exec {fd}>&...
zsh 和 bash 已经支持相当长一段时间的功能。
为了说明这一点,该脚本成功了(在 bash 中也有效):
#!/usr/bin/env zsh
set -euo pipefail
for i in {1..10}; do
exec {fd}> >( tee /dev/stderr | logger )
echo "FD: ${fd}" >&"${fd}"
done
但这并不:
#!/usr/bin/env zsh
set -euo pipefail
emulate -LR bash
for i in {1..10}; do
exec {fd}> >( tee /dev/stderr | logger )
echo "FD: ${fd}" >&"${fd}"
done
command not found: {fd}
任何人都可以向我指出其幕后功能的完整列表emulate -R bash
(也许我忽略了它,但我无法找到真正的手册页emulate
)。或者更好的是,如果有人知道哪个特定选项导致此问题,那就太好了。
预先感谢您的任何帮助。
答案1
zsh
没有bash
仿真模式。如果您通过了bash
(或以s
or开头的任何内容b
(对于伯恩)) 到emulate
,它将使用sh
仿真模式:
$ emulate bash -c emulate
sh
zsh
的仿真模式有zsh
(默认)、sh
(最初主要是 SysV/Bourne sh
,现在更多的是 POSIX sh
)csh
和ksh
.
bash
是一个主要兼容 POSIX 的 shell sh
,但其扩展大部分来自 Korn shell,因此要zsh
解释bash
使用非 POSIX 扩展的代码,最好的选择是 ksh 模拟(您可能还想启用BASH_REMATCH
预期的选项)为了bash
兼容性)。
该{fd}<
功能实际上来自zsh
.它是在 中同时实现的zsh
,ksh93
并且bash
是根据一位 zsh 开发人员在所有 3 个 shell 的维护者之间的讨论中的建议而实现的。
echo {fd}< /dev/null
POSIX 需要输出{fd}
(尽管这将在标准的未来版本中发生变化),因此在仿真zsh
中禁用它sh
。它不在ksh
仿真中,因此您需要在这里使用它。
至于在哪个仿真(zsh、sh、ksh、csh)中启用哪个选项,请参阅手册中每个选项描述旁边的, <C>
, <K>
, ( )。<S>
<Z>
info zsh 'Description of Options'
哪些选项影响该{fd}>...
功能在手册 ( ) 中对该功能的描述中指定info zsh 'file descriptors, use with parameters'
:IGNORE_BRACES
其描述 ( info zsh IGNORE_BRACES
) 旁边有一个,表示它仅<S>
在仿真中默认启用。sh
虽然zsh
附带了手册页(其中一些),但手册页对于这么大的手册来说是相当不够的。我建议使用info
超文本并具有可搜索索引和目录。要了解zsh
的emulate
内置内容,您可以运行info zsh emulate
,或者从内部info zsh
按I指数,然后输入emulate
(可以使用制表符补全)。在某些系统上,您可能需要安装zsh-doc
软件包或等效程序,因为默认情况下并不总是安装信息文档。