2010-07-15 28 views
4

我注意到当使用间接寻址(<)时,Solaris 10的Bourne shell,/bin/sh(还有/sbin/sh)会生成一个子shell。我已经尝试了一堆其他的Bourne十岁上下壳,其中包括:Solaris 10/bin/sh间接寻址

  • 在Solaris 10上的POSIX /usr/xpg4/bin/sh外壳
  • /bin/bash/bin/ksh在Solaris 10
  • /bin/sh在AIX 5
  • /bin/sh在Debian Linux上5

并且这些都没有表现出这种行为。

我很惊讶我以前没有被咬过。例如,在更稳健的壳(即,所有上面列出的那些)在以下脚本输出“1”:因为赋值x=1所造成的间接子外壳发生

$ cat foo 
#!/bin/sh 
x=0 
while read y ; do 
    x=1 
done </etc/passwd 
echo $x 
$ ./foo 
0 
$ 

的Solaris 10的/bin/sh返回0:当子外壳退出分配失败。 (如果我删除</etc/passwd并从stdin中读取,则按预期输出“1”)。

是否有一些古老的原因,“传统”Solaris sh有这个属性?或者这是一个错误?

回答

1

我会说这是违反POSIX标准的。

命令替换,括号括起来的命令和异步列表应在子shell环境中执行。另外,多命令管道的每个命令都在一个子shell环境中;作为扩展,然而,流水线中的任何或所有命令可以在当前环境中执行。 所有其他命令应在当前shell环境中执行。

来源:Shell Command Language,第2.12节。

+0

同时被视为命令? – Anders 2010-07-15 11:48:49

+0

是的,下面是使用shell语法(可以在上面的链接文档中找到)的推导:'command - > compound_command - > while_clause' – 2010-07-15 13:12:03

+4

Solaris 10和更早发行版中的'/ bin/sh'命令记录为不符合POSIX标准 - 对于符合POSIX标准,您需要使用'/ usr/xpg4/bin/sh'(实际上它基于ksh88而不是Bourne shell)。 – alanc 2010-07-15 14:50:04

1

Bourne shell执行此操作 - 创建子进程 - for循环和其他构造。这是预期的行为。这不是一个错误,任何使用它的人都知道这个问题存在。有时候这是一个糟糕的假设。

除了Solaris系统(例如:启动/关闭)脚本之外,不要在Bourne中开发。改用POSIX shell:ksh,bash。 root的默认shell必须是Bourne shell,否则系统将无法启动。这是旧系统V的伪像。

在csh中存在相同类型的警告。它还没有准备好黄金时段。

+0

我相信bash是POSIX兼容的--posix选项。 – Anders 2010-07-15 12:21:08

+0

我相信即使使用--posix选项,bash也不符合POSIX标准,但这是另一回事:)尝试一下,例如'echo {a,b}'。在POSIX shell中它应该打印'{a,b}'。 – 2010-07-15 13:14:24

+0

你是正确的先生,http://www.gnu.org/software/bash/manual/html_node/Bash-POSIX-Mode.html也明确指出“将导致Bash更符合posix标准” – Anders 2010-07-15 13:20:29