我有两个脚本foo.sh和bla.sh
foo.sh
#bin/bash
test(){
"hello world"
}
test
exit 1
bla.sh
#bin/bash
source ./a.sh
echo a.test
问题是源似乎运行a.sh脚本,当然然后在退出1 b之后永远不会执行。
有没有办法只使用bla的函数测试而不运行整个脚本?
答案 0 :(得分:7)
如果您希望您的脚本能够在不运行其内容的情况下获取源代码,您应该以这种方式进行设计。
#!/bin/bash
# put your function definitions here
mytest() { echo "hello world"; }
# ...and choose one of the following, depending on your requirements:
# more reliable approach, *except* doesn't detect being sourced from an interactive or
# piped-in shell.
(( ${#BASH_SOURCE[@]} > 1 )) && return
# less reliable approach in general, but *does* detect being sourced from an interactive
# shell.
[[ "$BASH_SOURCE" != "$0" ]] && return
# put your actions to take when executed here
mytest
exit 1
(( ${#BASH_SOURCE[@]} > 1 ))
如果源文件数组(每个堆栈帧)在脚本的 root 中的长度不止一个,那么拥有任何额外堆栈帧的唯一方法就是脚本已经存在来自其他地方。
这里需要注意的是,交互式shell(或者来自管道或其他非文件源的非交互式shell的输入)在BASH_SOURCE
数组中没有条目,所以如果我们来自人类驱动的shell - 或者从管道或其他非文件源读取其输入的shell - 仍然只有一个条目。
[[ $BASH_SOURCE != "$0" ]]
BASH_SOURCE
是一个源文件数组,每个堆栈帧一个元素;与所有bash数组一样,当展开而不显式索引到特定元素时,它默认为第一个(即当前正在执行的文件或sourced )。 $0
是正在执行的命令的名称,source
命令未更新。
因此,如果这些不匹配,我们就知道我们来自。
重要提示:
请注意,在某些情况下,必须依赖于$0
:cat input-script | bash
无法准确了解input-script
来自的磁盘上的位置,因此它始终会将其检测为来源。请参阅{em>为什么$ 0不是BashFAQ #28的选项部分,以详细了解这些限制。