如何在bash的另一个函数里面定义一个函数

我有以下代码

func1(){ #some function thing function2(){ #second function thing } } 

我想调用function2但我得到一个错误function2 : not found

有解决scheme吗?

bash中的函数定义不能以函数定义在许多其他语言中的工作方式工作。 在bash中,一个函数定义是一个可执行的命令,它定义了一个函数的作用(取代以前的任何定义),就像variables赋值命令定义一个variables的值(replace以前的定义)一样。 也许这个例子将澄清我的意思:

  $ outerfunc1() { > innerfunc() { echo "Running inner function #1"; } > echo "Running outer function #1" > } $ outerfunc2() { > innerfunc() { echo "Running inner function #2"; } > echo "Running outer function #2" > } $ # At this point, both outerfunc1 and outerfunc2 contain definitions of $ # innerfunc, but since neither has been executed yet, the definitions $ # haven't "happened". $ innerfunc -bash: innerfunc: command not found $ outerfunc1 Running outer function #1 $ # Now that outerfunc1 has executed, it has defined innerfunc: $ innerfunc Running inner function #1 $ outerfunc2 Running outer function #2 $ # Running outerfunc2 has redefined innerfunc: $ innerfunc Running inner function #2 

现在,如果你不知道这一点,我敢肯定这不是你嵌套函数定义的原因。 这引出了一个问题:你为什么要嵌套函数定义呢? 无论你期望嵌套定义有什么效果,这不是他们在bash中做的事情; 所以1)不要他们和2)find其他的方法来完成你想让你的巢穴为你做的任何事情。

为了限制内部函数的范围 ,可以使用用括号{}代替大括号{}定义的函数:

 f() ( g() { echo G } g ) # Ouputs `G` f # Command not found. g 

括号函数在子shell中运行,它们具有相同的() vs {}语义,另请参阅: 使用圆括号而不是大括号定义bash函数体

如果您想要:

  • 设置variables
  • exit
  • cd

因为那些在创build的子shell中丢失了。

另请参阅: bash函数:将括号内的括号括起来

不要嵌套函数定义。 用。。。来代替:

 $ cat try.bash function one { echo "One" } function two { echo "Two" } function three { one two } three $ bash try.bash One Two $ 

在问题的情况下,我想你在定义函数之前先调用函数2,函数2的定义应该是“某些函数的东西”。

为了讨论的缘故,我有一个使用这种定义的例子可能会有用处。

假设你想提供一个function可能是复杂的,它的可读性可以通过在较小的function分割代码,但你不希望这样的function是可访问的帮助。

运行以下脚本(inner_vs_outer.sh)

 #!/bin/bash function outer1 { function inner1 { echo '*** Into inner function of outer1' } inner1; unset -f inner1 } function outer2 { function inner2 { echo '*** Into inner function of outer2' } inner2; unset -f inner2 } export PS1=':inner_vs_outer\$ ' export -f outer1 outer2 exec bash -i 

当执行一个新的shell被创build。 在这里,outer1和outer2是有效的命令,但是inner不是,因为它已经从你有outer1和outer2定义的地方取消设置,但inner不是,因为你在函数结尾取消设置。

 $ ./inner_vs_outer.sh :inner_vs_outer$ outer1 *** Into inner function of outer1 :inner_vs_outer$ outer2 *** Into inner function of outer2 :inner_vs_outer$ inner1 bash: inner1: command not found :inner_vs_outer$ inner2 bash: inner2: command not found 

请注意,如果在外层定义内部函数,而不导出它们,则不能从新shell访问它们,但运行外部函数将导致错误,因为它们将尝试执行不再可访问的函数; 相反,每次调用外部函数时都会定义嵌套函数。

如果嵌套一个函数,那么在function1中说function2,直到function1被调用才会变得可用。 有些人可能会认为这是一个function,因为你可以在function1的末尾做一些类似“unset function2”的操作,而且它的作用域完全是本地的(不能从其他地方调用)。 如果你想在其他地方调用函数,那么可能不需要嵌套它。