是否有最低限度的POSIX.2外壳?

时间:2012-07-07 17:01:37

标签: shell posix

在以下意义上是否存在最低限度POSIX。2的shell(我们称之为mpcsh):

如果mpcsh myscript.sh在我的(兼容)系统上运行正常,那么xsh myscript.sh对任何兼容系统上任何符合POSIX.2的shell xsh的行为都相同。 (“相同”,以及不太相关的事情,如错误信息的措辞等。)

dash符合资格吗?

如果没有,有没有办法验证myscript.sh的合规性?

5 个答案:

答案 0 :(得分:21)

提前的悲伤答案

它对你没有帮助(没有你想象的那么多和可靠,无论如何都希望它。)


这就是原因。

虚拟“POSIX shell”无法解决的一个大问题是标准含糊不清或者没有解决的问题,因此shell可能会以不同的方式实现,同时仍然遵守标准。

关于管道的这两个例子,其中第一个是众所周知的:

示例1 - 范围

$ 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标准的代码那么将会工作,但事实是,如果你依赖上面提到的一个或另一个行为,你的脚本可能会以可怕的方式破解。

示例2 - 重定向

这是我几天前才知道的,请参阅我的回答here

foo | bar 2>./qux | quux

常识和POLA告诉我,当下一行代码被命中时,quuxbar都应该已经完成​​运行,这意味着文件./qux是人口稠密。对?否。

POSIX表示

  

如果管道不在后台(请参阅异步列表),shell应等待管道中指定的最后一个命令完成,并且还可以等待所有命令完成。)

可能(!)等待所有命令完成! WTH!

等待:

  

shell在返回值之前等待管道中的所有命令终止。

没有:

  

除了最后一个命令之外,每个命令都作为一个单独的进程运行; 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 ))

bashksh93支持。

我知道bashset -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的合规性?

这基本上属于质量保证。从:

开始
  • 代码审核
  • 单元测试(是的,我已经完成了这个)
  • 功能测试
  • 使用尽可能多的shell程序执行测试套件。 (ashbashdashksh93mkshzsh

就个人而言,我的目标是bashksh93支持的常用扩展程序集。它们是最古老,最广泛使用的shell语言解释器。

编辑最近我遇到了rylnd/shpec - shell代码的测试框架。您可以在测试用例中描述代码的功能,并指定如何验证它们。 披露:我帮助它在bash,ksh和dash中运行。