我有以下代码
func1(){
#some function thing
function2(){
#second function thing
}
}
我想致电function2
,但收到错误function2 : not found
有解决方案吗?
答案 0 :(得分:56)
限制内部功能的范围
使用用括号()
定义的函数代替大括号{}
:
f() (
g() {
echo G
}
g
)
# Ouputs `G`
f
# Command not found.
g
括号函数在子shell中运行,子shell具有与()
vs {}
相同的语义,另请参阅:Defining bash function body using parenthesis instead of braces
如果您想要:
,则无法使用exit
cd
因为那些在创建的子shell中丢失了。
另请参阅:bash functions: enclosing the body in braces vs. parentheses
答案 1 :(得分:43)
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
现在,如果您还不知道这一点,我很确定这不是您嵌套函数定义的原因。这提出了一个问题:为什么 你完全嵌套函数定义?无论你期望嵌套定义有什么影响,这都不是他们在bash中所做的;所以1)不要他们和2)找到其他方法来完成你想要为你做的任何事情。
答案 2 :(得分:12)
不嵌套函数定义。替换为:
$ cat try.bash
function one {
echo "One"
}
function two {
echo "Two"
}
function three {
one
two
}
three
$ bash try.bash
One
Two
$
答案 3 :(得分:12)
在问题情况下,我认为你在定义之前试图调用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
执行时会创建一个新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
请注意,如果在外层定义内部函数并且不导出它们,则无法从新shell中访问它们,但运行外部函数将导致错误,因为它们将尝试执行函数no更容易接近;相反,每次调用外部函数时都会定义嵌套函数。
答案 4 :(得分:2)
如果您正在嵌套一个函数,比如function1中的function2,那么在调用function1之前它不可用。有些人可能会认为这是一个功能,因为你可以做一些像" unset function2"在function1的末尾,它的范围对于该函数是完全本地的(不能从其他地方调用)。如果你想在其他地方调用该函数,那么无论如何都可能不需要嵌套它。
答案 5 :(得分:0)
您的代码应该以书面的方式工作,前提是您只能在定义之后调用嵌套函数。
As said in another answer, func2
语句是一个可执行语句,用于定义与该函数关联的名称(在全局范围内)。就像定义了一个变量一样。
因此,您可以在func2(){<...>}
语句运行后在代码中的任何位置使用#func2 not defined
func1(){
#not defined
func2(){<...>}
#defined
}
#not defined
func1
#defined
func3(){
#only defined if func3 is called after `func2(){<...>}' has run
}
:
{{1}}