Bash 使shell函数仅在导入文件的作用域中找到

Bash 使shell函数仅在导入文件的作用域中找到,bash,shell,scope,Bash,Shell,Scope,我在一个shell文件中声明函数 #a.sh foo(){…} 函数栏(){…} 并通过source导入另一个shell文件: #b.sh 来源./a.sh #调用foo和bar 福 酒吧 现在在shell中,我可以在执行b.sh后使用foo/bar $source b.sh ... #我现在可以在shell中调用foo或bar(不需要) $foo ... 如何使函数成为导入文件范围内的局部变量,并避免它们污染全局/环境变量?shell中没有“文件范围”这样的东西——只有全局范围和函数范围

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

#a.sh
foo(){…}
函数栏(){…}
并通过
source
导入另一个shell文件:

#b.sh
来源./a.sh
#调用foo和bar
福
酒吧
现在在shell中,我可以在执行
b.sh
后使用
foo
/
bar

$source b.sh
...
#我现在可以在shell中调用foo或bar(不需要)
$foo
...
如何使函数成为导入文件范围内的局部变量,并避免它们污染全局/环境变量?

shell中没有“文件范围”这样的东西——只有全局范围和函数范围。最接近的方法是在另一个shell中运行b.sh:

$ b.sh   # run b.sh rather than reading it into the current shell
然后,b.sh中的所有内容都将位于另一个shell中,并在退出时“消失”。但这适用于b.sh中定义的所有内容——所有函数、别名、环境和其他变量。

shell中没有“文件范围”这类内容——只有全局范围和函数范围。最接近的方法是在另一个shell中运行b.sh:

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

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

即使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%可靠,但应涵盖大多数情况。

即使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%可靠的,但应该涵盖大多数情况。

这样可以隔离私有shell函数

#源于a.sh
#a_main暴露在公众面前
我的(公众)(
二等兵(a){
回声“我是私人的,只有我的公众才能看到”
}
二等兵{
echo“我的公众只能看到我的照片”
}
案件“$1”
a) 二等兵;;
b) 私人;;
*)退出;;
以撒
)
#b.sh
来源a.sh
我的公众
我的公众
未找到private_a#命令
未找到private_b#命令

这样可以隔离私有shell函数

#源于a.sh
#a_main暴露在公众面前
我的(公众)(
二等兵(a){
回声“我是私人的,只有我的公众才能看到”
}
二等兵{
echo“我的公众只能看到我的照片”
}
案件“$1”
a) 二等兵;;
b) 私人;;
*)退出;;
以撒
)
#b.sh
来源a.sh
我的公众
我的公众
未找到private_a#命令
未找到private_b#命令

bash
没有模块或名称空间<代码>源代码基本上实现了文件级宏扩展。行
source foo
的行为与使用
foo
的内容替换该行时的行为完全相同
bash
没有模块或名称空间<代码>源代码基本上实现了文件级宏扩展。行
source foo
的行为与将该行替换为
foo
的内容完全相同@李岡諭 注意:容器子外壳在每次调用时都是一个新实例,因此不能在调用之间持久化变量。它还每次重新实例化其内部函数声明。有些人更喜欢模拟库名称空间,将函数声明为
lib\u name::function\u name
将my作为bash库示例@李岡諭 注意:容器子外壳在每次调用时都是一个新实例,因此不能在调用之间持久化变量。它还每次重新实例化其内部函数声明。有些人更喜欢模拟库名称空间,将函数声明为
lib\u name::function\u name
将my作为bash库示例