在以下意义上是否存在最低限度POSIX。2的shell(我们称之为mpcsh
):
如果mpcsh myscript.sh
在我的(兼容)系统上运行正常,那么xsh myscript.sh
对任何兼容系统上任何符合POSIX.2的shell xsh
的行为都相同。 (“相同”,以及不太相关的事情,如错误信息的措辞等。)
dash符合资格吗?
如果没有,有没有办法验证myscript.sh
的合规性?
答案 0 :(得分:21)
它对你没有帮助(没有你想象的那么多和可靠,无论如何都希望它。)
这就是原因。
虚拟“POSIX shell”无法解决的一个大问题是标准含糊不清或者没有解决的问题,因此shell可能会以不同的方式实现,同时仍然遵守标准。
关于管道的这两个例子,其中第一个是众所周知的:
$ ksh -c 'printf "foo" | read s; echo "[${s}]"'
[foo]
$ bash -c 'printf "foo" | read s; echo "[${s}]"'
[]
ksh
执行当前shell中管道的最后一个命令,而bash
在子shell中执行all(包括最后一个命令)。 bash 4
引入了lastpipe
选项,使其行为类似于ksh
:
$ bash -c 'shopt -s lastpipe; printf "foo" | read s; echo "[${s}]"'
[foo]
根据the standard:
,所有这些都是(可辩解的)此外,多命令管道的每个命令都在子shell环境中;但是,作为扩展,管道中的任何或所有命令都可以在当前环境中执行。
我不是100%肯定他们对扩展的含义,但基于文档中的其他示例,这并不意味着shell必须提供一种在行为之间切换的方法,而仅仅是它可能,如果它愿意,可以用这种“扩展方式”实施。其他人对此的看法不同,并且认为ksh
行为符合非标准,我明白为什么。措辞不仅不吉利,首先允许这样做并不是一个好主意。
在实践中,哪种行为是正确的并不重要,因为那些行为是“”“两大壳”“”并且人们会认为如果你不使用它们的扩展而且只有符合POSIX标准的代码那么将会工作,但事实是,如果你依赖上面提到的一个或另一个行为,你的脚本可能会以可怕的方式破解。
这是我几天前才知道的,请参阅我的回答here:
foo | bar 2>./qux | quux
常识和POLA告诉我,当下一行代码被命中时,quux
和bar
都应该已经完成运行,这意味着文件./qux
是人口稠密。对?否。
POSIX表示
如果管道不在后台(请参阅异步列表),shell应等待管道中指定的最后一个命令完成,并且还可以等待所有命令完成。)
可能(!)等待所有命令完成! WTH!
bash等待:
shell在返回值之前等待管道中的所有命令终止。
但ksh没有:
除了最后一个命令之外,每个命令都作为一个单独的进程运行; shell等待最后一个命令终止。
因此,如果您在管道之间使用重定向,请确保您知道自己在做什么,因为这会受到不同的处理,并且可能会因边缘情况而严重中断,具体取决于您的代码。
我可以提供另一个与管道无关的例子,但我希望这两个就足够了。
有一个标准是好的,不断修改它甚至更好,并坚持它是伟大的。但是,如果标准由于含糊不清或放纵而失败,那么事情仍然可能意外地破坏了实际上标准空白的有用性。
在实践中,这意味着除了编写“符合POSIX标准”的代码之外,您还需要思考并知道自己在做些什么来防止某些事情发生。
所有这一切,一个尚未被提及的shell是posh
,据推测它是POSIX加上比dash
更少的扩展,(主要是echo -n
和{{1关键字)根据其联机帮助页:
local
因人而异。
答案 1 :(得分:4)
可能是canonical shell is ash
最接近The NetBSD Foundation,由其他组织维护的内容。
这个shell called dash
的下游变体更为人所知。
答案 2 :(得分:3)
目前,POSIX shell
没有单一的角色模型。
自最初的Bourne shell以来,POSIX shell已采用了许多其他功能。
我知道实现这些功能的所有shell都具有超出POSIX shell功能集的扩展。
例如,POSIX允许采用以下格式的算术表达式:
var=$(( expression ))
但它不允许等效:
(( var = expression ))
由bash
和ksh93
支持。
我知道bash
有set -o posix
选项,但不会禁用任何扩展程序。
$ set -o posix
$ (( a = 1 + 1 ))
$ echo $a
2
据我所知,ksh93
尝试开箱即用POSIX,但仍允许扩展。
答案 3 :(得分:2)
POSIX开发人员花费了数年时间(而不是夸大其词)来解决这个问题:"应用程序符合标准意味着什么?"虽然POSIX开发人员能够为标准(POSIX.1和POSIX.2)的实现定义一致性测试套件,并且可以定义严格符合应用程序的概念" 34;作为一个不使用标准强制性要素之外的界面的人,他们无法确定一种测试制度,以确认某一特定的应用程序是否严格遵守"到POSIX.1,或者shell脚本严格遵守"到POSIX.2。
原始问题就是这样;验证脚本的一致性测试仅使用完全指定的标准元素。唉,这个标准充满了" weasel words"放松了对行为的定义,对于任何有用程度的脚本来说,这样的测试实际上是不可能的。 (即使抛开shell脚本可以生成并执行shell脚本这一事实也是如此,因此提出了严格遵守"等同于停止问题的问题。)
(完全披露:我是IEEE-CS TCOS的工作成员和委员会负责人,是1988-1999标准POSIX系列标准的创建者。)
答案 4 :(得分:1)
如果没有,有没有办法验证myscript.sh的合规性?
这基本上属于质量保证。从:
开始ash
,bash
,dash
,ksh93
,mksh
,zsh
)就个人而言,我的目标是bash
和ksh93
支持的常用扩展程序集。它们是最古老,最广泛使用的shell语言解释器。
编辑最近我遇到了rylnd/shpec - shell代码的测试框架。您可以在测试用例中描述代码的功能,并指定如何验证它们。 披露:我帮助它在bash,ksh和dash中运行。