一个Bash脚本可以判断它是否被引用吗?

5
在Python中,常见的写法是像这样编写代码:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

def main():
    pass

if __name__ == "__main__":
    main()

这样做是为了避免在导入Python脚本时自动运行其主方法。在Bash中是否有类似的习语?
2个回答

7
您可以在脚本顶部使用此代码片段来确定脚本是否被引用:
#!/bin/bash

if [[ ${BASH_SOURCE[0]} != $0 ]]; then
   printf "script '%s' is sourced in\n" "${BASH_SOURCE[0]}"
fi

当脚本被引用时,$0 变成 -bash,否则它会保存脚本本身的名称。

2
++ 用于演示如何在脚本中使用,我自己还没有机会使用它,只是知道它的存在。 - Inian

4

有一个特殊的 bash 变量可以用于此目的,

BASH_SOURCE

一个数组变量,其成员是相应 shell 函数名在 FUNCNAME 数组变量中定义的源文件名。shell 函数 ${FUNCNAME[$i]} 在文件 ${BASH_SOURCE[$i]} 中定义,并从 ${BASH_SOURCE[$i+1]} 调用。

它实际上是一个数组变量,保存了源代码的堆栈跟踪,其中 ${BASH_SOURCE[0]} 是最新的。

以下是一个示例,无耻地这个网站偷来,仅供演示目的,

脚本 aaa.sh

#!/bin/bash
echo "from ${BASH_SOURCE[0]} : BASH_SOURCE = ${BASH_SOURCE[*]}"
source bbb.sh

脚本 bbb.sh

#!/bin/bash
echo "from ${BASH_SOURCE[0]} : BASH_SOURCE = ${BASH_SOURCE[*]}"
source ccc.sh

脚本 ccc.sh

#!/bin/bash
echo "from ${BASH_SOURCE[0]} : BASH_SOURCE = ${BASH_SOURCE[*]}"
for i in ${BASH_SOURCE[@]}; do
    readlink -f $i
done

运行 aaa.sh 会产生以下结果:
from aaa.sh : BASH_SOURCE = aaa.sh                
from bbb.sh : BASH_SOURCE = bbb.sh aaa.sh
from ccc.sh : BASH_SOURCE = ccc.sh bbb.sh aaa.sh
/tmp/ccc.sh                                       # -> first element showing the latest script sourced 
/tmp/bbb.sh
/tmp/aaa.sh

所以如果我确定我的文件是该数组中的第一个条目,那么我的文件已经被引用了吗?如果它不是其中的第一个条目,那么它就没有被引用只是在执行吗? - Naftuli Kay
是的,它包含最近的脚本源。这是一个原子操作,一旦文件被引用,它就占据了索引0 - Inian
请参考我的更新来查看用法示例。 - Inian

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接