shell 小括号的有关问题

shell 小括号的问题
http://www.linuxsir.org/bbs/thread345055.html


shell中的小括号()可以把命令放在子shell中执行,如下:

$var=hello
$(var=hellotest; echo $var)
$hellotest
$echo $var
$hello

说明在子shell中的局部环境变量对父shell不影响

现在运行
$var=hello
$(echo $var) // 子shell只能继承export导出的变量,var=hello是局部变量不会被子shell继承!这里是在子shell中执行的吧?!,下面就不应该显示hello
$hello
$
怎么没有在shell中给var赋值就引用了父shell中的变量了呢?
按照前面的说法:()小括号中的命令在子shell中执行,那么应该是下面才对啊
$var=hello
$(echo $var)
$
$echo $var
$hello

谁解释下,谢谢了


shell确实有很多看似不符合常理的情况,但是manpage里全部交代清楚了!

代码:
       Command  substitution, commands grouped with parentheses, and asynchro-
       nous commands are invoked in a subshell environment that is a duplicate
       of  the  shell  environment,  except that traps caught by the shell are
       reset to the values that the shell inherited from its parent at invoca-
       tion.  Builtin commands that are invoked as part of a pipeline are also
       executed in a subshell environment.  Changes made to the subshell envi-
       ronment cannot affect the shell's execution environment.shell environment 里到底包括了些什么?往上翻阅manpage!

代码:
       The shell has an execution environment, which consists of  the  follow-
       ing:

       o      open  files inherited by the shell at invocation, as modified by
              redirections supplied to the exec builtin

       o      the current working directory as set by cd, pushd, or  popd,  or
              inherited by the shell at invocation

       o      the  file  creation  mode mask as set by umask or inherited from
              the shell's parent

       o      current traps set by trap

       o      shell parameters that are set by variable assignment or with set
              or inherited from the shell's parent in the environment

       o      shell  functions  defined during execution or inherited from the
              shell's parent in the environment

       o      options enabled at invocation (either by default  or  with  com-
              mand-line arguments) or by set

       o      options enabled by shopt

       o      shell aliases defined with alias

       o      various  process  IDs,  including  those of background jobs, the
              value of $$, and the value of $PPID


通过变量赋值的shell参数会成为shell环境的一部分,而通过圆括号创建的子shell所处的环境是父shell环境的一个副本。

也就是说,圆括号创建的子shell,与你直接 bash -c 'do some thing' 创建的子shell环境确实是有些不同的!



(do something) 创建的是子shell;
bash -c 'do something' 创建的也是子shell;
./script.sh 创建的也是子shell;etc。
但是完全复制了父shell环境的就三种情况:
command substitution,命令替换,也就是$(do something);
commands grouped with parentheses,圆括号中的命令组,也就是(do something);
asynchronous commands,异步命令,这个我貌似还没遭遇过... XD




知道$$这个shell参数么?扩展为当前shell的进程号。它是shell环境的一部分,但是不会被子进程继承(怎么可能继承?子进程也是进程,也有自己的进程号!)不过如果子shell中该值没有改变,只有一种解释:子shell复制了父shell的环境。

代码:
$ echo $$
2500
$ (echo $$)
2500
$ echo $(echo $$)
2500
$为什么都是2500?

接着再来:

代码:
$ bash -c 'echo $$'
2530
$ bash
$ echo $$
2531
$ exit
$ echo 'echo $$' | bash
2541
$ cat > script.sh
echo $$
$ bash script.sh
2545
$