如何在shell脚本中的函数中获取脚本名称?

3
我有三个脚本:
  • 我的主要脚本:script1.sh
  • 具有函数“logger”的脚本:script2.sh
  • 调用函数“logger”的脚本:script3.sh

我的脚本内容:

script1.sh:

echo"This is script1"
source script2.sh
sh script3.sh
echo "End of script1"

script2.sh:

logger(){
 echo "The calling script name is $BASH_SOURCE"
}

script3.sh:

echo "Script3 start"
logger
echo "End of script3"

当我运行sh script1.sh时,我希望日志记录函数打印出

script3.sh

因为这是调用该函数的脚本。但实际上,它打印出了

script2.sh

有没有什么办法可以解决这个问题?

2
通过参数传递调用“logger”的脚本名称? - Sean Pianka
起初我也是这么想的。但我不想硬编码它。 - Djeah
这很不可能。你没有展示所有的东西。在Bash中,函数是不可导出的,因此在script1中引用script2不会使loggerscript3中可见。你必须在script3中做了一些事情。 - Jason Hu
1
调用“logger”时,只需将$0作为参数传递,这不是硬编码。 - Sean Pianka
运行 sh script1.sh 只会打印 script2.sh 吗?我确定它应该会打印更多内容。请发布完整的内容。 - Inian
@SeanPianka,谢谢。那就可以了。 - Djeah
1个回答

5

正如我所评论的,你的脚本甚至无法实现你声称它可以做的事情:

这是不太可能的。你没有展示所有内容。在Bash中,函数是不能导出的,因此在脚本1中来源于脚本2并不会使logger在脚本3中可见。你一定在脚本3中做了些什么。

事实上,复制你的代码并在本地运行显示出了发生了什么:

$ ./script1.sh 
++ echo 'This is script1'
This is script1
++ source script2.sh
++ sh script3.sh
+ echo Script3 start
Script3 start
+ log
script3.sh: 3: script3.sh: log: not found
+ echo End of script3
End of script3
++ echo 'End of script1'
End of script1

请注意命令未找到的错误,这正是我所想的。
事实上,如果您正确查看bash的手册,就有一种确切的方法可以实现您想要的内容:

BASH_SOURCE

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

请仔细阅读,它说从${BASH_SOURCE[$i]}定义函数并从${BASH_SOURCE[$i+1]}调用。在这种情况下,logger位于${BASH_SOURCE[0]}中,而调用者只需位于${BASH_SOURCE[1]}中。
因此,请将您的script2更改为以下内容即可:
$ cat script2.sh 
log(){
 echo "The calling script name is ${BASH_SOURCE[1]}"
}

(除了我更改了函数名称以避免与我的其他shell工具冲突。)


示例:

$ ./script1.sh 
This is script1
Script3 start
The calling script name is ./script3.sh
End of script3
End of script1

确实完成了工作。

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