如何在没有$0的情况下获取shell脚本文件名?

7

我尝试在shell脚本中使用python中常用的if __name__ == "__main__":写法。

以下是样例脚本:

a.sh:

#!/bin/bash

filename="a.sh"

function main() {
  echo "start from $0"
  echo "a.sh is called"
  source b.sh
  bfunc
}

[[ "$0" == "${filename}" ]] && main

b.sh:

#!/bin/bash

filename="b.sh"

function main() {
  echo "start from $0"
  echo "b.sh is called"
}

function bfunc() {
  echo "hello bfunc"
}

[[ "$0" == "${filename}" ]] && main

你可以使用 bash a.sh 命令来调用它。

如果你使用 bash a.sh 命令,你会得到如下结果:

start from a.sh
a.sh is called
hello bfunc

这里是我的问题。 如何在不使用$0的情况下获取文件名本身? 我不想直接编写文件名,即我想将文件名值传递给${filename}
如果您不知道上述Python练习是什么,请参见链接:if __name__ == "__main__"是做什么的? 如何检查b.sh是从命令行启动还是被包含在a.sh中执行?

4
旁注:在Bash脚本中,“function”关键字是多余的,而且没有理由会让你的脚本与POSIX不兼容。建议删除它。 - hek2mgl
3
我认为$0是最简单的方法。你为什么不喜欢它呢? - Viktor Khilin
2
@ViktorKhilin:$0 指的是执行程序,但他想要指向当前文件。如果当前文件是从另一个脚本中包含的,则 $0 将会给出错误的结果。 - clemens
@ViktorKhilin,最简单但不可靠。请参阅[BashFAQ#28](https://mywiki.wooledge.org/BashFAQ/028)。 - Charles Duffy
1个回答

7
您可以使用变量$BASH_SOURCE获得当前脚本文件的名称。
if [[ "$0" == "$BASH_SOURCE" ]]
then
    : "Execute only if started from current script"
else
    : "Execute when included in another script"
fi

你在这里缺少一些语法;按照给定的方式,这将尝试使用第一个参数==运行 $0(可能会递归!)。需要是[[ "$0" == "$BASH_SOURCE" ]][ "$0" = "$BASH_SOURCE" ] - Charles Duffy
请注意,在 [情况下只有单个= - 这是因为POSIXtest规范仅指定=作为字符串比较运算符; ==是一种不可移植的扩展...虽然如果您使用[[,您的代码已经不可移植,所以这不是很重要。 - Charles Duffy
1
如果一个 ifelse 块只包含注释,则不是有效语法;即使是 true 或其同义词 :,也需要某些命令 - Charles Duffy
@CharlesDuffy:谢谢,你说得对,我脑海中Python的内容太多了。只有在需要时才会编写else块。 - clemens

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