Sub-shell process not be able to access variables

2019-07-21 17:49发布

问题:

I have 3 scripts in the same directory, please find below contents of x.sh, y.sh and z.sh :-

x.sh :-

xData="DataOfX"

function xInit(){
    echo "xInit : data of a >$xData<"
}

y.sh :-

. x.sh

xInit

sh z.sh zInit

z.sh :-

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

$@

Executing

. y.sh

in the same directory gives below output :-

xInit : data of a >DataOfX<
zInit of z
z.sh: line 3: xInit: command not found

How can a sub-shell process can access the variables and functions initialised in the parent shell?

回答1:

Adding export should do the work:

export xData="DataOfX"

https://www.tutorialspoint.com/unix_commands/export.htm

export- command is one of the bash shell BUILTINS commands, which means it is part of your shell. The export command is fairly simple to use as it has straightforward syntax with only three available command options. In general, the export command marks an environment variable to be exported with any newly forked child processes and thus it allows a child process to inherit all marked variables.



回答2:

The term "sub-shell" is problematic, and even man bash is inconsistent in the way it is used. Strictly speaking a sub-shell is another shell environment which inherits all features, including all variables, of the parent.

Parentheses gives a subshell. The variable BASH_SUBSHELL gives the level of subshell, and $$ gives the PID of the shell (in subshells it is faked to be the PID of the parent).

$ x=42

$ echo $BASH_SUBSHELL, $x, $$
0, 42, 1130
$ (echo $BASH_SUBSHELL, $x, $$)
1, 42, 1130
$ ( (echo $BASH_SUBSHELL, $x, $$) )
2, 42, 1130

When you execute a script, that is not a subshell. Take a script gash.sh with:

echo $BASH_SUBSHELL, $x, $$

Running it as:

$ ./gash.sh
0, , 8419

Notice the blank because x is not copied. It is not a subshell, and the PID is different. Even

$ (./gash.sh)
1, , 8421

that is a subshell running a child process, so that doesn't work either.

You need to move the variable to the environment block, which is copied to child processes, using export:

$ export x
$ ./gash.sh
0, 42, 8423

Variables that are not exported are only available in subshells using ( ), not other child processes. For functions use export -f.