如何在Bash中的另一个函数内定义一个函数?

tir*_*dev 53 bash

我有以下代码

func1(){
    #some function thing
    function2(){
        #second function thing
    }
}
Run Code Online (Sandbox Code Playgroud)

我想打电话function2但是我收到了一个错误function2 : not found

有解决方案吗?

Cir*_*四事件 64

限制内部函数的范围

使用用括号()而不是大括号定义的函数{}:

f() (
  g() {
    echo G
  }
  g
)

# Ouputs `G`
f
# Command not found.
g
Run Code Online (Sandbox Code Playgroud)

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

如果您想要:

  • 设置变量
  • exit
  • cd

因为那些在创建的子shell中丢失了.

另请参阅:bash函数:将主体括在括号和括号中

  • 尼斯.您甚至可以将本地范围变量传递给g.在许多情况下解决了声明全局数组的问题?示例:function f()(local var = $ 1; function g(){echo $ var;}; g;) (2认同)

Gor*_*son 48

bash中的函数定义不适用于函数定义在许多其他语言中的工作方式.在bash中,函数定义是一个可执行命令,它定义函数的效果(替换任何先前的定义),其方式与变量赋值命令定义变量的值(替换任何先前的定义)的方式非常相似.也许这个例子将澄清我的意思:

$ 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
Run Code Online (Sandbox Code Playgroud)

现在,如果您还不知道这一点,我很确定这不是您嵌套函数定义的原因.这带来了一个问题:为什么你嵌套函数的定义呢?无论你期望嵌套定义有什么影响,这都不是他们在bash中所做的; 所以1)不要他们和2)找到一些其他方法来完成你想要为你做的嵌套.


Teu*_*ndo 14

在问题情况下,我认为你在定义之前试图调用function2,"一些函数之物"应该在function2定义之后.

为了便于讨论,我有一个案例,使用这些定义可能有一些用处.

假设您想提供一个可能很复杂的函数,可以通过在较小的函数中拆分代码来帮助它的可读性,但是您不希望这些函数可以访问.

运行以下脚本(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
Run Code Online (Sandbox Code Playgroud)

执行时会创建一个新的shell.这里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
Run Code Online (Sandbox Code Playgroud)

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

  • 尼斯和[POSIX](http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_29).遗憾的是它会破坏名为`inner1`的外部函数,所以应该加上像`__`前缀这样的命名约定. (4认同)

Cha*_*tin 12

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

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

function two {
  echo "Two"
}

function three {
   one
   two
}

three
$ bash try.bash 
One
Two
$ 
Run Code Online (Sandbox Code Playgroud)

  • 当你说''不嵌套函数'*时,是因为bash不支持嵌套函数吗?(我只是很好奇,因为我对bash不是很熟悉) (16认同)
  • 您可以从彼此内部调用这些功能.您不能像在原始帖子中那样在彼此内定义它们并期望它能够工作. (2认同)
  • 我有一个巨大的代码,其中嵌套了很多函数,我想为另一个函数中的某些函数添加命令行参数 (2认同)