使shell函数只能在导入文件的范围内找到



我在一个shell文件中声明函数

# a.sh
foo() { ... }
function bar() { ... }

并通过source:导入到另一个shell文件中

# b.sh
source ./a.sh
# invoke foo and bar
foo
bar

现在在shell中,我可以在执行b.sh后使用foo/bar

$ source b.sh
...
# I can call foo or bar now in the shell (undesirable)
$ foo
...

如何使函数成为导入文件范围内的局部变量,并避免它们污染全局/环境变量?

shell中没有"文件作用域",只有全局作用域和函数作用域。最接近的是在另一个shell中运行b.sh:

$ b.sh   # run b.sh rather than reading it into the current shell

那么b.sh中的所有内容都将只在另一个shell中,并在它退出时"消失"。但这适用于b.sh中定义的所有——所有函数、别名、环境和其他变量。

通过这种方式可以隔离私有shell函数。

# sourced a.sh
# a_main is exposed public
my_public_a() (
private_a() {
echo "I am private_a only visible to my_public_a"
}
private_b() {
echo "I am get_b only visible to my_public_a"
}
case "$1" in
a) private_a;;
b) private_b;;
*) exit;;
esac
)
# b.sh
source a.sh
my_public_a a
my_public_a b
private_a # command not found
private_b # command not found

即使bash不提供直接支持,您所需要的仍然可以实现:

#!/usr/bin/env bash
# b.sh
if  [[ "${BASH_SOURCE[0]}" = "$0" ]] ;then
source ./a.sh
# invoke foo and bar
foo
bar
else
echo "b.sh is being sourced. foo/bar will not be available."
fi

以上内容并非100%可靠,但应涵盖大多数情况。

最新更新