我对于bash
变量是否会被导出到子shell中并且何时能够被脚本访问感到困惑。到目前为止,我的经验使我相信bash
变量会自动传递给子shell。例如:
> FOO=bar
> echo $FOO
bar
> (echo $FOO)
bar
以上内容似乎表明bash
变量可以在子Shell中访问。
给定以下脚本:
#! /usr/bin/bash
# c.sh
func()
{
echo before
echo ${FOO}
echo after
}
func
我理解在当前shell上下文中调用脚本会使其可以访问当前shell的变量:
> . ./c.sh
before
bar
after
如果我不使用“点空格”前缀来调用脚本…
> ./c.sh
before
after
脚本不是在子shell中调用的吗?如果是这样,并且当前shell的变量对子shell可用(正如我从第一个代码块推断出来的那样),那么为什么以这种方式运行时$FOO
不可用于c.sh
?
同样地,为什么在圆括号中运行c.sh
时$FOO
也不可用——我理解圆括号表示在子shell中运行表达式:
> (./c.sh)
before
after
如果这不会在这篇文章中引起太多问题:如果"./c.sh
"和"(./c.sh)
"都在当前shell的子shell中运行脚本,那么两种调用方式之间有什么区别呢?
./foo
并不会在子shell中运行foo
:它是一个完全不相关的子进程,在fork()
和execve()
边界之后。 - Charles Duffy(./c.sh)
会派生一个子shell,然后在其中运行一个子进程,因此该子进程是原始shell的孙子而不是直接子代,并且在子代和孙子之间存在一个execv
的边界(尽管在父代和子代之间不存在)。 - Charles Duffyshell
,所以我想指出并非所有的 shell 都像bash
一样处理子 shell。例如,Korn shell 避免为子 shell 创建一个子进程。 - cdarke