从bash脚本导入函数定义,无需运行它

时间:2016-05-20 15:27:04

标签: bash shell

我有两个脚本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的函数测试而不运行整个脚本?

1 个答案:

答案 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命令更新。

因此,如果这些不匹配,我们就知道我们来自。

重要提示: 请注意,在某些情况下,必须依赖于$0cat input-script | bash无法准确了解input-script来自的磁盘上的位置,因此它始终会将其检测为来源。请参阅{em>为什么$ 0不是BashFAQ #28的选项部分,以详细了解这些限制。