大括号扩展,例如 {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}
您可以将其与--posix
或set -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/bash
Debian 可能有一个非 bash 的/bin/sh
.
答案3
在默认的 Debian 中,是(不是)sh
的链接。 Dash 更符合 POSIX 的“大括号扩展”行为。dash
bash
sh
Bash 与历史(来自 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/sh
为dash
.
但是,通常$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
一次。