我们看一下下面的例子:
# testing(){ echo hello;}
# testing
hello
# echo $(testing)
hello
# echo testing >script
# ./script
./script: line 1: testing: command not found
# source ./script
hello
# export -f testing
# ./script
hello
事实证明,bash
只有当您想要在非源脚本中使用函数时,才需要导出该函数。我尝试了几层子 shell,行为是一样的。有人可以证实这一点吗,因为我发现这与子 shell 中不存在局部变量的说法相矛盾。
答案1
source ./script
不创建子 shell。脚本在当前 shell 中执行。这里没有什么意外。
但是,像下面这样的命令替换echo $(testing)
做创建一个子 shell。如果我理解正确,你会惊讶于它能正常工作。
这在Bash 参考手册,命令执行环境部分[强调我的]:
命令替换、用括号分组的命令以及异步命令在与 shell 环境重复的子 shell 环境中调用,不同之处在于 shell 捕获的陷阱会被重置为 shell 在调用时从其父级继承的值。
因此,这是对局部变量不存在于子 shell 中的说法的一个有据可查的例外。
答案2
函数通过导出成为进程环境的一部分,就像变量一样。因此,要让子进程(如被调用的脚本)继承它们,必须导出它们。在不导出之前,它只是 shell 变量的一部分。
注意:您可以使用内置命令列出当前环境env
,并使用列出变量set
。
注意 2:该source
命令不会创建子 shell(子进程),其他人也指出了这一点,因此其source script
工作方式与示例中所示一致。但是该./script
命令会创建子 shell,因此您需要导出该函数。