Adr*_*rth 21
它对你没有帮助(没有你想象的那么多和可靠,无论如何都要它).
这就是原因.
虚拟"POSIX shell"无法解决的一个大问题是标准中含糊不清或者没有解决的问题,因此shell可能会以不同的方式实现,同时仍然遵循标准.
关于管道的这两个例子,其中第一个是众所周知的:
$ ksh -c 'printf "foo" | read s; echo "[${s}]"'
[foo]
$ bash -c 'printf "foo" | read s; echo "[${s}]"'
[]
Run Code Online (Sandbox Code Playgroud)
ksh执行当前shell中管道的最后一个命令,而bash在子shell中执行all - 包括最后一个命令.bash 4介绍了lastpipe使其表现如下的选项ksh:
$ bash -c 'shopt -s lastpipe; printf "foo" | read s; echo "[${s}]"'
[foo]
Run Code Online (Sandbox Code Playgroud)
所有这些都是(根据标准):
另外,多命令管道的每个命令都在子shell环境中; 但是,作为扩展,管道中的任何或所有命令都可以在当前环境中执行.
我不是100%肯定他们对扩展的意思,但基于文档中的其他示例,这并不意味着shell必须提供一种在行为之间切换的方法,而只是如果它愿意的话,它可以实现的东西在这种"扩展的方式".其他人对此的ksh看法不同,并且认为这种行为符合非标准,我可以理解为什么.措辞不仅不吉利,首先允许这样做并不是一个好主意.
在实践中,哪种行为是正确的并不重要,因为那些行为是""两个大壳""并且人们会认为如果你不使用它们的扩展并且只有符合POSIX标准的代码它将起作用要么,但事实是,如果你依赖于上面提到的一种或另一种行为,你的脚本可能会以可怕的方式打破.
这一次我以前了解仅仅几天,看到我的答案在这里:
foo | bar 2>./qux | quux
Run Code Online (Sandbox Code Playgroud)
常识和POLA告诉我,当下一行代码被命中,双方quux并bar应已完成运行,这意味着该文件./qux是完全填充.对?没有.
POSIX说明了这一点
如果管道不在后台(请参阅异步列表),则shell应等待管道中指定的最后一个命令完成,并且还可以等待所有命令完成.)
可以(!)等待所有命令完成!WTH!
bash等待:
shell在返回值之前等待管道中的所有命令终止.
但是ksh没有:
除了最后一个命令之外,每个命令都作为一个单独的进程运行; shell等待最后一个命令终止.
因此,如果您在管道之间使用重定向,请确保您知道自己在做什么,因为这会被区别对待,并且可能会因边缘情况而严重中断,具体取决于您的代码.
我可以给另一个与管道无关的例子,但我希望这两个就足够了.
有一个标准是好的,不断修改它甚至更好,并坚持它是伟大的.但是,如果标准由于模糊或允许而失败,那么事情仍然可能意外地破坏实际上使标准空白的有用性.
这在实践中意味着,除了编写"POSIX兼容"代码之外,您还需要思考并知道自己在做什么来防止某些事情发生.
所有这一切,根据其手册页,一个尚未被提及的shell posh是所谓的POSIX加上甚至更少的扩展dash(主要echo -n是local关键字):
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).
Run Code Online (Sandbox Code Playgroud)
因人而异.