Bash。 Return 两个函数级别(两个嵌套调用)
Bash. Return two function levels (two nested calls)
我想知道 Bash 是否有适合我的情况的解决方案。我需要在某些条件下执行 "double return"。我的意思是,执行函数的 return 以及父函数的 return 以跳过该父函数的其余代码。
我知道我可以使用函数 return 值做一个条件来实现这个。但我想知道 Bash 中是否存在类似 "break 2" 的函数。如果可能,我不想修改父函数的代码,因为你可以想象,在我的真实脚本中有几十个函数,我不想修改所有的。
示例:
#!/bin/bash
function sublevelone() {
echo "sublevelone"
# Return 2, or break 2 or something :D
}
function main() {
sublevelone
echo "This is the part of the code to being avoid executed"
}
main
我不知道 bash 专家会怎么想,但这至少适用于简单的情况:
multireturn(){
[ -n "" ] && poplevel=""
if [ "$poplevel" -ge 0 ]; then
trap multireturn DEBUG
shopt -s extdebug
(( poplevel-- ))
return 2
else
shopt -u extdebug
trap - DEBUG
return 0
fi
}
这利用了 DEBUG 陷阱和 extdebug
标志:
extdebug
If set at shell invocation, arrange to execute the
debugger profile before the shell starts, identical to
the --debugger option. If set after invocation, behav-
ior intended for use by debuggers is enabled:
1. The -F option to the declare builtin displays the
source file name and line number corresponding to
each function name supplied as an argument.
2. If the command run by the DEBUG trap returns a
non-zero value, the next command is skipped and
not executed.
3. If the command run by the DEBUG trap returns a
value of 2, and the shell is executing in a sub-
routine (a shell function or a shell script exe-
cuted by the . or source builtins), the shell
simulates a call to return.
4. BASH_ARGC and BASH_ARGV are updated as described
in their descriptions above.
5. Function tracing is enabled: command substitu-
tion, shell functions, and subshells invoked with
( command ) inherit the DEBUG and RETURN traps.
6. Error tracing is enabled: command substitution,
shell functions, and subshells invoked with (
command ) inherit the ERR trap.
用法示例:
#!/bin/bash
multireturn(){
[ -n "" ] && poplevel=""
if [ "$poplevel" -ge 0 ]; then
trap multireturn DEBUG
shopt -s extdebug
(( poplevel-- ))
return 2
else
shopt -u extdebug
trap - DEBUG
return 0
fi
}
# define 8 levels of function calls
# (level N prints output, calls level N+1, then prints more output)
for i in $(seq 1 8); do
eval \
'level'$i'(){
echo -n " '$i'"
level'$((i+1))'
echo -n "('$i')"
}'
done
# final level calls multireturn
level9(){
echo -n " 9"
multireturn $n
echo -n "(9)"
}
# test various skip amounts
for i in $(seq 0 10); do
echo -n "$i:"
n=$i
level1
echo .
done
echo
echo done
结果:
0: 1 2 3 4 5 6 7 8 9(9)(8)(7)(6)(5)(4)(3)(2)(1).
1: 1 2 3 4 5 6 7 8 9(8)(7)(6)(5)(4)(3)(2)(1).
2: 1 2 3 4 5 6 7 8 9(7)(6)(5)(4)(3)(2)(1).
3: 1 2 3 4 5 6 7 8 9(6)(5)(4)(3)(2)(1).
4: 1 2 3 4 5 6 7 8 9(5)(4)(3)(2)(1).
5: 1 2 3 4 5 6 7 8 9(4)(3)(2)(1).
6: 1 2 3 4 5 6 7 8 9(3)(2)(1).
7: 1 2 3 4 5 6 7 8 9(2)(1).
8: 1 2 3 4 5 6 7 8 9(1).
9: 1 2 3 4 5 6 7 8 9.
10: 1 2 3 4 5 6 7 8 9
done
你为什么不像在任何其他 programming/scripting 语言中那样 return 函数的退出状态并向 main
添加 if 语句?
#!/bin/bash
function sublevelone() {
echo "sublevelone"
[ 0 -eq 1 ]
return $? # Returns 1 in this case because 0 != 1
}
function main() {
sublevelone
[ $? -eq 0 ] || return 1 # Return in case of error
echo "This is the part of the code to being avoid executed"
}
main
exit 0
这有点古怪,但是如果你使用括号来定义levelone
,它将执行subshell中的函数,然后你可以退出其中 shell 来自内部函数。也就是说,我认为使用 return
发送回您在父函数中检查的 value 更合适。
#!/bin/bash
function leveltwo() {
echo "two"
exit
}
function levelone() (
echo "one"
leveltwo
echo "three"
)
levelone
echo "four"
将打印:
one
two
four
只是@jhnc 的一个简短版本,正好从一个函数中回答了 2 级 return:
trap 'trap "shopt -u extdebug; trap - DEBUG; return 0" DEBUG; return 2' DEBUG
shopt -s extdebug
return
我想知道 Bash 是否有适合我的情况的解决方案。我需要在某些条件下执行 "double return"。我的意思是,执行函数的 return 以及父函数的 return 以跳过该父函数的其余代码。
我知道我可以使用函数 return 值做一个条件来实现这个。但我想知道 Bash 中是否存在类似 "break 2" 的函数。如果可能,我不想修改父函数的代码,因为你可以想象,在我的真实脚本中有几十个函数,我不想修改所有的。
示例:
#!/bin/bash
function sublevelone() {
echo "sublevelone"
# Return 2, or break 2 or something :D
}
function main() {
sublevelone
echo "This is the part of the code to being avoid executed"
}
main
我不知道 bash 专家会怎么想,但这至少适用于简单的情况:
multireturn(){
[ -n "" ] && poplevel=""
if [ "$poplevel" -ge 0 ]; then
trap multireturn DEBUG
shopt -s extdebug
(( poplevel-- ))
return 2
else
shopt -u extdebug
trap - DEBUG
return 0
fi
}
这利用了 DEBUG 陷阱和 extdebug
标志:
extdebug If set at shell invocation, arrange to execute the debugger profile before the shell starts, identical to the --debugger option. If set after invocation, behav- ior intended for use by debuggers is enabled: 1. The -F option to the declare builtin displays the source file name and line number corresponding to each function name supplied as an argument. 2. If the command run by the DEBUG trap returns a non-zero value, the next command is skipped and not executed. 3. If the command run by the DEBUG trap returns a value of 2, and the shell is executing in a sub- routine (a shell function or a shell script exe- cuted by the . or source builtins), the shell simulates a call to return. 4. BASH_ARGC and BASH_ARGV are updated as described in their descriptions above. 5. Function tracing is enabled: command substitu- tion, shell functions, and subshells invoked with ( command ) inherit the DEBUG and RETURN traps. 6. Error tracing is enabled: command substitution, shell functions, and subshells invoked with ( command ) inherit the ERR trap.
用法示例:
#!/bin/bash
multireturn(){
[ -n "" ] && poplevel=""
if [ "$poplevel" -ge 0 ]; then
trap multireturn DEBUG
shopt -s extdebug
(( poplevel-- ))
return 2
else
shopt -u extdebug
trap - DEBUG
return 0
fi
}
# define 8 levels of function calls
# (level N prints output, calls level N+1, then prints more output)
for i in $(seq 1 8); do
eval \
'level'$i'(){
echo -n " '$i'"
level'$((i+1))'
echo -n "('$i')"
}'
done
# final level calls multireturn
level9(){
echo -n " 9"
multireturn $n
echo -n "(9)"
}
# test various skip amounts
for i in $(seq 0 10); do
echo -n "$i:"
n=$i
level1
echo .
done
echo
echo done
结果:
0: 1 2 3 4 5 6 7 8 9(9)(8)(7)(6)(5)(4)(3)(2)(1).
1: 1 2 3 4 5 6 7 8 9(8)(7)(6)(5)(4)(3)(2)(1).
2: 1 2 3 4 5 6 7 8 9(7)(6)(5)(4)(3)(2)(1).
3: 1 2 3 4 5 6 7 8 9(6)(5)(4)(3)(2)(1).
4: 1 2 3 4 5 6 7 8 9(5)(4)(3)(2)(1).
5: 1 2 3 4 5 6 7 8 9(4)(3)(2)(1).
6: 1 2 3 4 5 6 7 8 9(3)(2)(1).
7: 1 2 3 4 5 6 7 8 9(2)(1).
8: 1 2 3 4 5 6 7 8 9(1).
9: 1 2 3 4 5 6 7 8 9.
10: 1 2 3 4 5 6 7 8 9
done
你为什么不像在任何其他 programming/scripting 语言中那样 return 函数的退出状态并向 main
添加 if 语句?
#!/bin/bash
function sublevelone() {
echo "sublevelone"
[ 0 -eq 1 ]
return $? # Returns 1 in this case because 0 != 1
}
function main() {
sublevelone
[ $? -eq 0 ] || return 1 # Return in case of error
echo "This is the part of the code to being avoid executed"
}
main
exit 0
这有点古怪,但是如果你使用括号来定义levelone
,它将执行subshell中的函数,然后你可以退出其中 shell 来自内部函数。也就是说,我认为使用 return
发送回您在父函数中检查的 value 更合适。
#!/bin/bash
function leveltwo() {
echo "two"
exit
}
function levelone() (
echo "one"
leveltwo
echo "three"
)
levelone
echo "four"
将打印:
one
two
four
只是@jhnc 的一个简短版本,正好从一个函数中回答了 2 级 return:
trap 'trap "shopt -u extdebug; trap - DEBUG; return 0" DEBUG; return 2' DEBUG
shopt -s extdebug
return