以下片段是否有效 Bourne shell 代码?

Is the following snippet valid Bourne shell code?

以下片段在 bash 4.3.39(1) 而不是 zsh 解释时触发语法错误5.0.5.

eprintf()
{
    1>&2 {
        printf "$@"
        printf '\n'
    }
}

我刚刚在 bash 解析器中发现了错误吗?

根据Single Unix Specification,Shell和Utilities Volume,函数定义命令语法为:

fname() compound-command[io-redirect ...]

在你的情况下会得到:

eprintf() { printf "$@" ; printf '\n' } >&2

函数定义命令语法只允许一个复合命令,而且复合命令({ ... })在语法中没有提到任何io重定向,函数有。

所以根据我对标准的阅读,这看起来不像是一个错误。

这不是错误;来自手册页:

The following redirection operators may precede or appear anywhere within a simple command or may follow a command.

所以

>/dev/null echo foo
echo >/dev/null foo
echo foo >/dev/null

都是合法等价的,但是重定向必须跟在复合命令{...}.

后面

因为 {bash 没有真正的特殊含义(alias {=foo 使 { 成为 foo 的别名),行 1>&2 { 被解析为一个简单的命令,假设 { 的查找将在最终调用 eprintf 时成功。结果,第一个}关闭了作为函数体的复合语句,第二个不匹配并触发语法错误。

我不能说没有进一步的研究 为什么 bashzsh 在这里不同,只是它是 bash 的记录行为.