考虑到 POSIX 是所有 unice 中最接近通用标准的东西,我有兴趣知道是否有一个专门支持它的 shell。虽然大多数现代 shell 都提供对 POSIX 的支持(并且可以毫无问题地运行 POSIX 兼容的脚本),但它们在指出不兼容的功能方面表现不佳。
是否有任何 shell 只实现 POSIX 和 POSIX,这样它就会针对任何不兼容的功能抛出错误?
编辑我想澄清的是,我并不是要求提供编写可移植 shell 脚本的一般技巧。评论中提到的相关问题已经涵盖了这一点。当我发现bash
有一个--posix
选项但只是发现它只影响一些初始化行为时,我想到了这个问题,这并不完全是我想要的。
答案1
您可以使用ShellCheck (GitHub)作为 shell 脚本的 linter。还有一个网络版。
检测 POSIX 兼容性问题(例如SC2039), 这舍邦线你的 shell 脚本应该是#!/bin/sh
.您也可以传递--shell=sh
到shellcheck
.
例子 (test.sh
):
#!/bin/sh
if [[ $HOSTNAME == test ]]; then
echo fail &> foo
fi
结果 (shellcheck test.sh
):
In test.sh line 2:
if [[ $HOSTNAME == test ]]; then
^-- SC2039: In POSIX sh, [[ ]] is undefined.
^-- SC2039: In POSIX sh, HOSTNAME is undefined.
In test.sh line 3:
echo fail &> foo
^-- SC2039: In POSIX sh, &> is undefined.
答案2
不幸的是,对于 shell 脚本来说,“可移植”通常是比“POSIX 兼容”更严格的要求。也就是说,编写在任何 POSIX shell 上运行的东西并不太难,但让它在任何现实世界的 shell 上运行就更难了。
您可以从在包管理器中安装每个 shell 开始,特别是 debian 的posh
听起来像您想要的(符合策略的普通 SHell)。 Debian 的政策是 POSIX,但有一些例外(echo -n
指定的,local
...)。
除此之外,测试还必须涵盖一系列平台上的一些 shell(尤其是 /bin/sh)。我在 Solaris(/bin/sh 和 xpg4/sh)和 BSD 上进行测试。 AIX 和 HP-UX 非常合规,不会造成问题。 bash 有它自己的一个小世界。
我会推荐Autoconf 便携式 shell 指南,这绝对很棒并且节省了大量时间。其中很大一部分已经过时了,但这没关系;如果您不在乎,请跳过 TruUnix 和 Ultrix 等!
答案3
POSIXLY_CORRECT
如果设置了环境变量,Bash 将以 POSIX 兼容模式运行。从联机帮助页:
POSIXLY_CORRECT
If this variable is in the environment when bash starts, the
shell enters posix mode before reading the startup files, as if
the --posix invocation option had been supplied. If it is set
while the shell is running, bash enables posix mode, as if the
command set -o posix had been executed.
许多其他 GNU 实用程序也将尊重POSIXLY_CORRECT
,因此,如果您使用的系统主要是 GNU 工具(例如大多数 Linux 系统),并且您的目标是符合 POSIX,那么这是一个良好的开始。
答案4
是否有任何 shell 只实现 POSIX 和 POSIX,这样它就会针对任何不兼容的功能抛出错误?
短跑符合这里的要求。
DASH 是符合 POSIX 标准的实现,
/bin/sh
其目标是尽可能小。它在尽可能不牺牲速度的情况下做到这一点。事实上,对于大多数任务来说,它比 bash(GNU Bourne-Again SHell)要快得多。
编写 shell 脚本时应符合POSIX Shell 命令语言,我在测试脚本时使用 Dash 作为解释器,因为它仅实现 POSIX shell 功能,并且如果遇到任何 Bashism(例如数组变量或进程替换),则会抛出错误。
Dash 是 Almquist shell 的一个端口(因此得名 Debian Almquist shell),在基于 Debian 的系统上,/bin/sh
它是/bin/dash
.有关更多信息,请参阅阿尔姆奎斯特外壳 - 维基百科。