我一直在我的脚本中使用这样的简单bash前导码:
#!/bin/bash
set -e
Run Code Online (Sandbox Code Playgroud)
与模块化/使用功能相结合,这使我今天感到困惑.
所以,说我有一个像某个地方的功能
foo() {
#edit: some error happens that make me want to exit the function and signal that to the caller
return 2
}
Run Code Online (Sandbox Code Playgroud)
理想情况下,我希望能够使用多个小文件,将其功能包含在其他文件中,然后调用这些函数
set +e
foo
rc=$?
set -e
Run Code Online (Sandbox Code Playgroud)
.这适用于两层例程.但是如果foo也调用这样的子程序,返回前的最后一个设置将是set -e
,这将使脚本在返回时退出 - 我无法在调用函数中覆盖它.所以,我必须做的是
foo() {
#calling bar() in a shielded way like above
#..
set +e
return 2
}
Run Code Online (Sandbox Code Playgroud)
我发现它非常违反直觉(也不是我想要的 - 如果在某些情况下我想使用该函数而不屏蔽失败,而在其他情况下我想要处理清理?)什么是处理这个问题的最佳方法?顺便说一句.我在OSX上这样做,我还没有测试过Linux上的这种行为是否有所不同.
Mar*_*oij 14
Shell函数实际上没有"返回值",只是退出代码.
您可以添加&& :
到调用者,这使命令"已测试",并且不会退出它:
foo() {
echo 'x'
return 42
}
out=$(foo && :)
echo $out
Run Code Online (Sandbox Code Playgroud)
这:
是"空命令"(即它没有做任何事情).在这种情况下,它甚至不会被执行,因为它只在foo
返回0 时运行(它没有).
这输出:
x
Run Code Online (Sandbox Code Playgroud)
它可以说有点难看,但是再一次,所有的shell脚本都可以说有点难看;-)
引sh(1)
自FreeBSD,这比bash的手册页更好地解释了这一点:
-e errexit
Exit immediately if any untested command fails in non-interactive
mode. The exit status of a command is considered to be explicitly
tested if the command is part of the list used to control an if,
elif, while, or until; if the command is the left hand operand of
an “&&” or “||” operator; or if the command is a pipeline preceded
by the ! operator. If a shell function is executed and its exit
status is explicitly tested, all commands of the function are con?
sidered to be tested as well.
Run Code Online (Sandbox Code Playgroud)