是否有最低兼容POSIX.2的外壳? [英] Is there a minimally POSIX.2 compliant shell?

查看:86
本文介绍了是否有最低兼容POSIX.2的外壳?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在以下意义上是否存在至少 POSIX .2兼容的外壳(我们将其称为mpcsh):

Is there a minimally POSIX.2 compliant shell (let's call it mpcsh) in the following sense:

如果mpcsh myscript.sh在我的(兼容)系统上正确运行,则xsh myscript.sh对于任何兼容系统上的任何POSIX.2兼容shell xsh都将表现相同. (相同地"最多不相关的事情,例如错误消息的措辞等).

if mpcsh myscript.sh behaves correctly on my (compliant) system then xsh myscript.sh will behave identically for any POSIX.2 compliant shell xsh on any compliant system. ("Identically" up to less relevant things like the wording of error messages etc.)

破折号是否合格?

如果没有,是否有任何方法可以验证myscript.sh的符合性?

If not, is there any way to verify compliance of myscript.sh?

推荐答案

预先悲伤的答案

它不会为您提供帮助(不如您期望的那样可靠得多).

The sad answer in advance

It won't help you (not as much and reliably as you would expect and want it to anyway).

这是为什么.

虚拟的"POSIX shell"无法解决的一个大问题是措辞含糊或仅在标准中未解决,因此shell可以在遵循标准的同时以不同的方式实现事情.

One big problem that cannot be addressed by a virtual "POSIX shell" are things that are ambiguously worded or just not addressed in the standard, so that shells may implement things in different ways while still adhering to the standard.

以关于管道的这两个示例为例,第一个是众所周知的:

Take these two examples regarding pipelines, the first of which is well known:

$ ksh -c 'printf "foo" | read s; echo "[${s}]"'
[foo]

$ bash -c 'printf "foo" | read s; echo "[${s}]"'
[]

ksh在当前shell中执行管道的最后一个命令,而bash在子shell中执行所有-包括最后一个命令. bash 4引入了lastpipe选项,使其行为类似于ksh:

ksh executes the last command of a pipe in the current shell, whereas bash executes all - including the last command - in a subshell. bash 4 introduced the lastpipe option which makes it behave like ksh:

$ bash -c 'shopt -s lastpipe; printf "foo" | read s; echo "[${s}]"'
[foo]

所有这些都是(有争议的)根据标准:

All of this is (debatably) according to the standard:

此外,多命令管道中的每个命令都在子shell环境中.作为扩展,但是,管道中的任何或所有命令都可以在当前环境中执行.

Additionally, each command of a multi-command pipeline is in a subshell environment; as an extension, however, any or all commands in a pipeline may be executed in the current environment.

我不确定他们对扩展的含义是什么,但是根据文档中的其他示例,这并不意味着shell必须提供一种在行为之间进行切换的方法,而仅仅是如果愿意,它可以以扩展方式"实现事物.其他人对此有不同的理解,并争辩说ksh行为是非标准兼容的,我可以理解为什么.措辞不仅很不幸,而且首先允许这样做不是一个好主意.

I am not 100% certain on what they meant with extension, but based on other examples in the document it does not mean that the shell has to provide a way to switch between behavior but simply that it may, if it wishes so, implement things in this "extended way". Other people read this differently and argue about the ksh behavior being non-standards-compliant and I can see why. Not only is the wording unlucky, it is not a good idea to allow this in the first place.

在实践中,哪种行为是正确的并不重要,因为那些是"两个大壳",人们会认为,如果您不使用它们的扩展名,而仅使用符合POSIX的代码,都可以使用,但是事实是,如果您依靠上面提到的一种或另一种行为,您的脚本可能会以可怕的方式破坏.

In practice it doesn't really matter which behavior is correct since those are the """two big shells""" and people would think that if you don't use their extensions and only supposedly POSIX-compliant code that it will work in either, but the truth is that if you rely on one or the other behavior mentioned above your script can break in horrible ways.

我几天前才了解到这一点,请在这里:

This one I learnt about just a couple of days ago, see my answer here:

foo | bar 2>./qux | quux

常识和 POLA 告诉我,当按下下一行代码时,两个quuxbar应该已经完成​​运行,这意味着文件./qux已完全填充.正确的?不.

Common sense and POLA tells me that when the next line of code is hit, both quux and bar should have finished running, meaning that the file ./qux is fully populated. Right? No.

POSIX 指出

如果管道不在后台(请参见异步列表),则外壳程序必须等待管道中指定的最后一条命令完成,并且还可以等待所有命令完成.)

If the pipeline is not in the background (see Asynchronous Lists), the shell shall wait for the last command specified in the pipeline to complete, and may also wait for all commands to complete.)

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

May (!) wait for all commands to complete! WTH!

等待:

shell等待管道中的所有命令终止,然后返回值.

The shell waits for all commands in the pipeline to terminate before returning a value.

但是的问题不会:

除最后一条命令外,每个命令都作为单独的进程运行; Shell等待最后一条命令终止.

Each command, except possibly the last, is run as a separate process; the shell waits for the last command to terminate.

因此,如果您在管道之间使用重定向,请确保您知道自己在做什么,因为对此的处理方式会有所不同,并且可能会严重破坏边缘情况,具体取决于您的代码.

So if you use redirection inbetween a pipe, make sure you know what you are doing since this is treated differently and can horribly break on edge cases, depending on your code.

我可以举一个与管道无关的例子,但我希望这两个条件就足够了.

I could give another example not related to pipelines, but I hope these two suffice.

拥有一个标准是好的,不断修改它甚至会更好,并且遵守它也很棒.但是,如果标准由于歧义性或宽容性而失败,那么事情仍然可能出乎意料地破坏,实际上使该标准的有用性失效.

Having a standard is good, continuously revising it is even better and adhering to it is great. But if the standard fails due to ambiguity or permissiveness things can still unexpectedly break practically rendering the usefulness of the standard void.

在实践中,这意味着在编写"POSIX兼容"代码之外,您仍然需要思考并知道自己在做什么以防止某些事情发生.

What this means in practice is that on top of writing "POSIX-compliant" code you still need to think and know what you are doing to prevent certain things from happening.

话虽如此,但尚未提及的一个外壳是 posh 据认为是POSIX,加上比dash更少的扩展名(主要是echo -nlocal关键字),具体取决于其手册页:

All that being said, one shell which has not yet been mentioned is posh which is supposedly POSIX plus even fewer extensions than dash has, (primarily echo -n and the local keyword) according to its manpage:

BUGS
   Any bugs in posh should be reported via the Debian BTS.
   Legitimate bugs are inconsistencies between manpage and behavior,
   and inconsistencies between behavior and Debian policy
   (currently SUSv3 compliance with the following exceptions:
   echo -n, binary -a and -o to test, local scoping).

YMMV.

这篇关于是否有最低兼容POSIX.2的外壳?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆