我原以为这会起作用:
source <(sed '1,/# HELPER FUNCTIONS #/d' "$0")
fun abc
# HELPER FUNCTIONS #
fun() {
echo"$@"
}
但现在我想了一下,脚本完成后会将辅助函数引入当前 shell。
有没有办法将我的辅助函数放在脚本的末尾?
答案1
请注意,您的方法实际上有效,但是声明辅助函数的语句将执行两次,一次是在source
running 之前执行,一次是在 running 之后执行fun abc
。因此,我将exit
在分隔线之前插入一个简单的声明。
#!/bin/bash
source <(sed '1,/^# HELPER FUNCTIONS #$/d' "$0")
fun ABC
exit
# HELPER FUNCTIONS #
fun () {
echo "$@"
}
另请注意,您需要锚定正则表达式,至少锚定到行的开头,否则它将匹配包含命令的行source
,这反过来会导致脚本的上半部分(sans sed
)由 执行source
,这是我们想要避免的。
就我个人而言,我认为这使得代码有点难以阅读。它还改变了分隔符之后的一些东西。例如,该BASH_SOURCE
数组将有一个额外的文件名作为其第一个元素,BASH_LINENO
将按脚本初始部分的大小以及脚本下部的错误消息中报告的任何行号(和脚本名称)进行偏移将很难跟进。
执行此操作的另一种方法不需要$0
具有合理的值,也不需要sed
调用动态修改脚本,而是养成将脚本的主体放入其自己的函数(可能称为 )中的习惯main
,然后在脚本的最后调用该函数:
#!/bin/sh
main () {
fun ABC
}
fun () {
echo "$@"
}
# Call "main" with the arguments given to the script
# (even if the function may not use them).
main "$@"
这意味着 shell 将读取脚本到最后,所有函数都将被实例化,并且main
可以调用完成其工作所需的任何函数,无论这些函数位于代码中的何处。
另请参阅 shell 脚本的 Google 风格指南,其中专门介绍了建议这个,尽管它说也将函数的代码放在main
最后,但这并不是绝对必要的。事实上,也许值得一提第一的以便于查找。
有关的: