我注意到Solaris 10的Bourne shell /bin/sh
(以及/sbin/sh
)在使用间接(<
)时会分支子shell。我尝试了一堆其他Bourne-ish炮弹,包括:
/usr/xpg4/bin/sh
shell /bin/bash
,/bin/ksh
/bin/sh
/bin/sh
并且这些都没有表现出这种行为。
我很惊讶我以前没有被这个咬过。例如,在saner shell(即上面列出的所有内容)中,以下脚本输出“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,因为赋值x=1
出现在子shell中由间接引起:当子shell退出时,该赋值将丢失。 (如果我删除</etc/passwd
并从stdin
读取,则按预期输出“1”。
“传统的”Solaris sh
是否有这个属性,有一些古老的原因吗?或者这是一个错误吗?
答案 0 :(得分:1)
Bourne shell执行此操作 - 创建子进程 - 用于循环和其他构造。这是预期的行为。从某种意义上讲,任何使用它的人都“知道”这个问题就不存在了。这有时是一个不好的假设。
除了Solaris中的系统(例如:启动/关闭)脚本之外,不要在Bourne中开发。使用POSIX shell:ksh,bash,而不是。 root的默认shell必须是Bourne shell,如果不是系统将无法启动。这是旧系统V的工件。
在csh中编码存在同样的警告。它尚未准备好迎接黄金时段。
答案 1 :(得分:1)
我认为这违反了POSIX标准。
命令替换,用括号分组的命令和异步列表应在子shell环境中执行。另外,多命令管道的每个命令都在子shell环境中;但是,作为扩展,管道中的任何或所有命令都可以在当前环境中执行。 所有其他命令都应在当前的shell环境中执行。
资料来源:Shell Command Language,第2.12节。