在子 shell 中运行函数时不需要导出

在子 shell 中运行函数时不需要导出

我有一个msource.sh脚本,其来源如下:

$ cat msource.sh 
#!/usr/bin/env sh
echo "($BASHPID) - sourced ${BASH_SOURCE[0]}" &>> "$logfile"
  # logfile is defined by the sourcing script
sourced_var="init sourced var with $BASHPID"

我有一个脚本,它将按原样在 a 中获取msource.sh并调用 a 。然后它将调用另一个脚本:functionsubshellmscript2.sh

$ cat mscript.sh 
#!/usr/bin/env sh

logfile=mout.out
rm -f $logfile
source msource.sh

mfun() {
  echo "($BASHPID) in ${FUNCNAME}"  &>> "$logfile"
  echo "  avar: '$avar'" &>> "$logfile"
  echo "  sourced_var: '$sourced_var'" &>> "$logfile"
}

avar="$BASHPID - init"

echo "[mfun] basic call" &>> "$logfile"
mfun

echo -e "\n[mfun &] subshell call" &>> "$logfile"
mfun &
wait $!

## call mscript2.sh
echo -e "\n[mscript2] background call" &>> "$logfile"
bash mscript2.sh &
wait $!

# call mscript2.sh after exporting variables
echo -e "\n[mscript2 &] export and background call" &>> "$logfile"
export logfile
export avar
export sourced_var
bash mscript2.sh &
wait $!

我有另一个脚本,mscript2.sh它将被调用mscript.sh,如上所示:

$ cat mscript2.sh
#!/usr/bin/env sh

[ -z "${logfile:+x}" ] && logfile=mout2.out || true

echo "($BASHPID) - executing ${BASH_SOURCE[0]}" &>> "$logfile"
echo "  avar: '$avar'" &>> "$logfile"
echo "  sourced_var: '$sourced_var'" &>> "$logfile"

我运行一切:

$ bash script.sh

我得到以下输出:

$ cat mout.out 
(13166) - sourced msource.sh
[mfun] basic call
(13166) in mfun
  avar: '13166 - init'
  sourced_var: 'init sourced var with 13166'

[mfun &] subshell call
(13174) in mfun
  avar: '13166 - init'
  sourced_var: 'init sourced var with 13166'

[mscript2 &] background call

[mscript2 &] export and background call
(13184) - executing mscript2.sh
  avar: '13166 - init'
  sourced_var: 'init sourced var with 13166'

$ cat mout2.out 
(13179) - executing mscript2.sh
  avar: ''
  sourced_var: ''

因此,如果我按原样调用该函数,则是pid一样的,我不需要获取变量,msource.sh也不需要导出变量。如果我在中调用该函数subshellmsource.sh仍然不需要获取或导出变量。

但是,调用另一个脚本会subshell丢失所有变量,需要导出这些变量,甚至日志文件也需要重新定义。

subshell有人能解释一下发生了什么吗?在 中执行一个函数和在另一个 中执行另一个脚本有什么区别subshell?为什么父进程的变量不必导出才能传递给subshelled 函数?

答案1

这是设计使然。这个答案Unix & Linux SE 上的 解释了这个问题。主要观点是:

子 shell […] 与执行脚本不同。

相关内容