Solaris 10 /bin/sh 间接分叉

发布于 2024-09-10 15:13:41 字数 853 浏览 5 评论 0原文

我注意到 Solaris 10 的 Bourne shell,/bin/sh(以及 /sbin/sh)在使用间接时会分叉一个子 shell(<) >)。我尝试了一堆其他 Bourne-ish shell,包括:

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

,这些都没有表现出此行为。

我很惊讶我以前没有被这个咬过。例如,在 saner shell(即上面列出的所有 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 退出时,分配会丢失。 (如果我删除 并从 stdin 读取,则按预期输出“1”)。

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

I have noticed that Solaris 10's Bourne shell, /bin/sh (and also /sbin/sh) forks a subshell when using indirection (<). I have tried a pile of other Bourne-ish shells, including:

  • The POSIX /usr/xpg4/bin/sh shell on Solaris 10
  • /bin/bash, /bin/ksh on Solaris 10
  • /bin/sh on AIX 5
  • /bin/sh on Debian Linux 5

and none of these exhibit this behavior.

I'm amazed I haven't been bitten by this before. For example, in the saner shells (ie all those listed above) the following script outputs "1":

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

Solaris 10's /bin/sh returns 0 because the assignment x=1 occurs in the subshell caused by the indirection: when the subshell exits that assignment is lost. (If I remove </etc/passwd and read from stdin instead then "1" is output, as expected).

Is there some age-old reason that the "traditional" Solaris sh has this property? Or is this a bug?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

梦明 2024-09-17 15:13:41

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

除了 Solaris 中的系统(例如:启动/关闭)脚本之外,请勿在 Bourne 中进行开发。请改用 POSIX shell:ksh、bash。 root 的默认 shell 必须是 Bourne shell,否则系统将无法启动。这是旧 System V 的产物。

在 csh 中编码也存在同样的警告。它也还没有准备好迎接黄金时段。

Bourne shell does this - create a child process - for loops and other constructs. It is expected behavior. It is not a bug in the sense that anybody using it 'knows' this problem exists. Which is a bad assumpotion sometimes.

DO NOT develop in Bourne except for system (example: startup/shutdown) scripts in Solaris. Use a POSIX shell: ksh, bash, instead. The default shell for root must be the Bourne shell, if it is not the system will cannot boot. This is an artifact of old System V.

The same kind of caveat exists for coding in csh. It is not ready for prime-time either.

春花秋月 2024-09-17 15:13:41

我想说这违反了 POSIX 标准。

命令替换、用括号分组的命令以及异步列表应在子 shell 环境中执行。此外,多命令管道中的每个命令都位于子shell环境中;然而,作为扩展,管道中的任何或所有命令都可以在当前环境中执行。 所有其他命令应在当前 shell 环境中执行。

来源:Shell 命令语言,第 2.12 节。

I would say this is a violation of the POSIX standard.

Command substitution, commands that are grouped with parentheses, and asynchronous lists shall be executed in a subshell environment. 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. All other commands shall be executed in the current shell environment.

Source: Shell Command Language, section 2.12.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文