强制 POSIX 模式

强制 POSIX 模式

大括号扩展,例如 {a,b,c} 是POSIX 未定义。我想在 POSIX 模式下运行我的 shell。对于 Debian,这很简单:

$ bash -c 'echo {a,b,c}'
a b c

$ sh -c 'echo {a,b,c}'
{a,b,c}

然而 Fedora 的行为有所不同:

$ bash -c 'echo {a,b,c}'
a b c

$ sh -c 'echo {a,b,c}'
a b c

我尝试使用--posix选项,但没有效果:

$ sh --posix -c 'echo {a,b,c}'
a b c

Bash 可以强制在 POSIX 模式下运行吗?

答案1

Bash 可以被告知禁用大括号扩展set +B,它是 的倒数set -B

-Bshell 将执行大括号扩展(参见支撑扩张)。该选项默认处于启用状态。

您还可以在启动 shell 时在命令行上提供此信息:

$ bash +B -c 'echo {a,b,c}'
{a,b,c}

您可以将其与--posixset -o posix选项更接近完全 POSIX 行为。您还需要shopt -s xpg_echo至少启用。

还会有其他的角落——许多扩展是相当根深蒂固的——而且我认为不可能让 Bash 只支持实际的行为强制的通过 POSIX。甚至连dash这个都做不到。

然而,你可能会发现dash(Debian 上的默认设置/bin/sh)如果您的目标是避免扩展行为,那么它会更有帮助,尽管它也支持一些扩展。还有BusyBox 的ash小程序,它也有一些扩展,但许多可以静态禁用。

答案2

根据 Bash 参考手册(http://www.gnu.org/software/bash/manual/html_node/Bash-POSIX-Mode.html),该--posix标志“将使 Bash 更加符合 POSIX 标准”。似乎完全符合 POSIX 要求并不是一个选择。

至于行为上的差异,我相信您会发现Fedora 上/bin/sh有一个符号链接。 /bin/bashDebian 可能有一个非 bash 的/bin/sh.

答案3

在默认的 Debian 中,是(不是)sh的链接。 Dash 更符合 POSIX 的“大括号扩展”行为。dashbash

shBash 与历史(来自 man bash)有记录的差异:

括号扩展与 sh 的历史版本略有不兼容。当左括号或右括号作为单词的一部分出现时,sh 不会对它们进行特殊处理,并将它们保留在输出中。Bash 会从单词中删除括号,这是括号扩展的结果。例如,在 sh 中输入的单词 file{1,2} 在输出中完全相同。经过 bash 扩展后,同一个单词将输出为 file1 file2。如果希望与 sh 严格兼容,请使用 +B 选项启动 bash 或使用 set 命令的 +B 选项禁用括号扩展。

这项工作之一:

bash +B -c 'echo {a,b,c}'
bash -c 'set +B; echo {a,b,c}'

而且,如果您仍然需要更 POSIXly bash:

bash --posix +B -c 'echo {a,b,c}'
bash --posix -c 'set +B; echo {a,b,c}'

由于更改默认 shell 会对/bin/sh系统范围产生许多影响,因此我不建议您更改/bin/shdash.

但是,通常$HOME/bin/(或又名)在 PATH 中~/bin/设置在前面。/bin/因此,您可以将 dash 可执行文件复制到您的用户~/bin/sh(甚至是符号或实际链接),并且 dash 将作为该用户的默认 sh。

有时,包含~/bin/作为用户可执行程序是在以下位置完成的.profile

[ -d "${HOME}/bin" ] && export PATH="${HOME}/bin:$PATH"

它在第一次登录时(在用户的服务器 X 启动时间)由(几乎任何 shell)bash 获取,从那时起它作为环境值存在。

如果存在,您所要做的就是创建该/home/$USER/bin目录。
当然,您需要重新登录或源~/.profile一次。

相关内容