子shell进程无法访问父shell中定义的变量和函数

mog*_*gli 2 variables bash shell function subshell

我在同一个目录中有 3 个脚本,请在下面找到 x.sh、y.sh 和 z.sh 的内容:-

x.sh :-

xData="DataOfX"

function xInit(){
    echo "xInit : data of a >$xData<"
}
Run Code Online (Sandbox Code Playgroud)

y.sh :-

. x.sh

xInit

sh z.sh zInit
Run Code Online (Sandbox Code Playgroud)

z.sh :-

function zInit(){
    echo "zInit of z"
    xInit
}

$@
Run Code Online (Sandbox Code Playgroud)

执行

. y.sh

在同一目录中给出以下输出:-

xInit : data of a >DataOfX<
zInit of z
z.sh: line 3: xInit: command not found
Run Code Online (Sandbox Code Playgroud)

子 shell 进程如何访问在父 shell 中初始化的变量和函数?

cda*_*rke 5

术语“子壳”是有问题的,甚至man bash在使用方式上也不一致。严格来说,子 shell 是另一个 shell 环境,它继承了父级的所有特征,包括所有变量。

括号给出了一个子shell。该变量BASH_SUBSHELL给出了子外壳的级别,并$$给出了PID外壳的级别(在子外壳中,它被伪装成父级的 PID)。

$ x=42

$ echo $BASH_SUBSHELL, $x, $$
0, 42, 1130
$ (echo $BASH_SUBSHELL, $x, $$)
1, 42, 1130
$ ( (echo $BASH_SUBSHELL, $x, $$) )
2, 42, 1130
Run Code Online (Sandbox Code Playgroud)

当您执行脚本时,它不是 subshel​​l。拿一个脚本gash.sh

echo $BASH_SUBSHELL, $x, $$
Run Code Online (Sandbox Code Playgroud)

运行它:

$ ./gash.sh
0, , 8419
Run Code Online (Sandbox Code Playgroud)

请注意空白,因为x未复制。它不是子shell,PID不同。甚至

$ (./gash.sh)
1, , 8421
Run Code Online (Sandbox Code Playgroud)

这是一个运行子进程的子shell,所以它也不起作用。

您需要使用以下命令将变量移动到环境块,然后将其复制到子进程export

$ export x
$ ./gash.sh
0, 42, 8423
Run Code Online (Sandbox Code Playgroud)

未导出的变量仅在使用 的子shell 中可用( ),而不能在其他子进程中使用。对于函数使用export -f.