![为了这个目的,可以用另一个函数(即嵌套的)声明/导出 Bash 函数吗?](https://linux22.com/image/212588/%E4%B8%BA%E4%BA%86%E8%BF%99%E4%B8%AA%E7%9B%AE%E7%9A%84%EF%BC%8C%E5%8F%AF%E4%BB%A5%E7%94%A8%E5%8F%A6%E4%B8%80%E4%B8%AA%E5%87%BD%E6%95%B0%EF%BC%88%E5%8D%B3%E5%B5%8C%E5%A5%97%E7%9A%84%EF%BC%89%E5%A3%B0%E6%98%8E%2F%E5%AF%BC%E5%87%BA%20Bash%20%E5%87%BD%E6%95%B0%E5%90%97%EF%BC%9F.png)
为了在已经变得有点笨拙的脚本中利用一些 IDE 非常有用的树/大纲功能;事物需要嵌套才能成为可折叠的树,例如;
据我了解(我还是个初学者),函数是在同一个 shell 中执行的,即不是在子 shell 中执行;因此考虑到这一点,我想到我可以将一大群函数分组,在它们之前并将set -a
它们包装在另一个函数中,例如;
functiongroup() { # ← moved from this level ─╮
set -a # ╭╯
func1() { …;} # ← grouped functions ──┤
func2() { …;} # ← grouped functions ──╯
… #
} #
… #
functiongroup # ← invoke functions function
…或者通过正确地声明它们declare
。
这会导致问题吗?
假设不会,他们会——或者更确切地说新的父函数- 需要被调用以便知道他们会攻击脚本中的给定位置吗?让我重新表述一下:Bash 是否在执行父函数之前处理(知道)嵌套函数?
假设代码是:
1 │ #!/usr/bin/env bash
2 │ # FUNCTIONS & VARS
3 │ functiongroup() { # ← moved from this level ─╮
4 │ set -a # ╭╯
5 │ func1() { …;} # ← grouped functions ──┤
6 │ func2() { …;} # ← grouped functions ──╯
7 │ … #
8 │ } #
9 │ # PROGRAM #
10 │ # ← moved to line 12
11 │ echo -n "something $(func2)" # ← func2 call
12 │ functiongroup # ← accidentally moved a line too late
13 │ if func1; then # ← func1 call
14 │ do #
15 │ … #
16 │ done #
17 │ else #
18 │ echo "MELTDOWN!" #
19 │ exit 1 #
20 │ fi #
21 │ exit 0 #
上面,会func1
运行func2
,还是只是func1
? (如果有的话)
我的参考文献是 GNU 的bash手册有时可能有点太密集所以我与这个进行比较备忘单我发现了很多 StackExchange 的想法,但如果我不能完全理解它,我不会使用*代码,所以我的学习速度没有我想要的那么快。当然不是线性的。 :(
我喜欢这个,因为它很简单,并且您始终可以就最终脚本的功能进行解组,但如果有适当/更好的组织方式,请说出来。
谢谢。
*:尽管我仍然在笔记中保存代码片段以供参考,以便稍后当我达到所需的知识水平时进行回顾……只要我还记得。 Bash、PHP、Python、JavaScript、PowerShell,甚至 HTML……那里积压着未经审查的代码。
答案1
Bash 是否在执行父函数之前处理(知道)嵌套函数?
不。
我们来尝试一下:
$ funcgroup() {
f1() { echo this is f1; }
f2() { echo this is f2; }
}
$ f2
f2: command not found
$ funcgroup
$ f2
this is f2
如果您的脚本变得难以使用,请将函数分解为库:
$ bash
$ cat funcs.bash
f1() { echo this is f1; }
f2() { echo this is f2; }
$ f2
f2: command not found
$ . funcs.bash
$ f2
this is f2
.
(又名)命令source
在当前目录和 PATH 中查找以查找文件。
答案2
正如第一个答案所指出的,将程序分类到单独的模块中通常是一个好主意,尤其是占用太多空间的臃肿软件。
然而,问题是,您需要小心如何调用脚本。它与您调用初始脚本的位置有所不同,初始脚本会获取任何库,因为路径会发生变化,并且初始脚本最终可能找不到任何库。
我通常用以下函数来规避这个问题。
function whereAmI { printf "$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"; }
这告诉您运行此过程的脚本在哪里。
因此,如果库位于相对于初始脚本的某个位置,它总是会找到库,例如lib/
,如果您将结果添加whereAmI
到该相对路径。
不管怎样,由于语言的局限性,很好地组织 Bash 代码非常重要。否则,一年后你再看它,就会发现一切都毫无意义。