问题描述:

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

$

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?

网友答案:

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.

网友答案:

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.

相关阅读:
Top