我使用source
( .
)$HOME/.bash_profile
从本地文件执行命令$HOME/.dotfiles/.bash_profile
:
[[ -r "$HOME/.dotfiles/.bash_profile" ]] && . "$HOME/.dotfiles/.bash_profile"
现在, in$HOME/.dotfiles/.bash_profile
的$0
值为"-bash"
,这意味着它不能用于dirname
检索正在执行的脚本的当前目录。
我读过BASH_SOURCE
应该用执行脚本的名称填充(并且它有效!)。
但为什么当执行脚本被定义为与 shell 函数对应的源文件名数组时,是否BASH_SOURCE
保存执行脚本的名称?man bash
此外,由于BASH_SOURCE
被定义为一个数组,因此按如下方式使用它来检索执行脚本的当前目录是不安全的,因为它可以保存多个值dirname $BASH_SOURCE
:
man bash
:
BASH_SOURCE
An array variable whose members are the source filenames
where the corresponding shell function names in the FUNCNAME array
variable are defined. The shell function ${FUNCNAME[$i]} is defined
in the file ${BASH_SOURCE[$i]} and called from ${BASH_SOURCE[$i+1]}.
答案1
但是
BASH_SOURCE
,当执行脚本在 man bash 中定义为与 shell 函数对应的源文件名数组时,为什么要保存执行脚本的名称呢?
为什么?可能是因为拥有可用的主脚本的文件名也很有用。
我们看一下手册中的描述:
BASH_SOURCE
FUNCNAME
一个数组变量,其成员是源文件名,其中定义了数组变量 中相应的 shell 函数名称。 shell函数${FUNCNAME[$i]}
在文件中定义${BASH_SOURCE[$i]}
并从${BASH_SOURCE[$i+1]}
FUNCNAME
一个数组变量,包含当前执行调用堆栈中的所有 shell 函数的名称。索引为 0 的元素是任何当前正在执行的 shell 函数的名称。最底部的元素(索引最高的元素)是“main”。
foo
在从主脚本调用的函数中,${FUNCNAME[0]}
包含foo
和${BASH_SOURCE[0]}
包含定义的文件的名称foo
。${FUNCNAME[1]}
包含main
并${BASH_SOURCE[1]}
包含主脚本文件的名称。
对于FUNCNAME
,明确指出在函数之外它是空的。因为BASH_SOURCE
它不同。始终在末尾添加主脚本文件的名称的扩展BASH_SOURCE
有点合乎逻辑:函数调用和返回只需要在前面添加/删除元素。
它没有这么说,但BASH_SOURCE
也跟踪源脚本(. foo.sh
或类似的脚本)。FUNCNAME
只要没有调用任何函数,它们也不会显示,但当source
前面有实际函数时,它们就会显示。
此外,由于
BASH_SOURCE
被定义为一个数组,因此按如下方式使用它来检索执行脚本的当前目录是不安全的,因为它可以保存多个值dirname $BASH_SOURCE
:
我不确定这是一个问题还是一个陈述。但请记住,引用没有索引的数组与使用索引相同0
。$BASH_SOURCE
也是如此${BASH_SOURCE[0]}
,并且包含定义当前函数的文件的名称。 (不是主脚本的那个,因为你需要类似的东西${BASH_SOURCE[ ${#BASH_SOURCE[@]} - 1 ]}
。)
请注意,文件名可能仍然类似于./foo.sh
或foo.sh
,因此dirname
可能无法告诉任何有用的信息。