将 set -e / set +e in bash 与函数一起使用
Using set -e / set +e in bash with functions
我一直在我的脚本中使用这样一个简单的 bash 序言:
#!/bin/bash
set -e
结合模块化/使用功能,这让我今天很头疼。
所以,假设我在某个地方有一个函数,比如
foo() {
#edit: some error happens that make me want to exit the function and signal that to the caller
return 2
}
理想情况下,我希望能够使用多个小文件,将它们的函数包含在其他文件中,然后像这样调用这些函数
set +e
foo
rc=$?
set -e
。这恰好适用于两层例程。但是如果 foo 也像那样调用子程序,return 之前的最后设置将是 set -e
,这将使脚本在 return 退出 - 我不能在调用函数中覆盖它.所以,我要做的是
foo() {
#calling bar() in a shielded way like above
#..
set +e
return 2
}
我觉得这非常违反直觉(而且也不是我想要的 - 如果在某些情况下我想使用该函数而不屏蔽故障,而在其他情况下我想处理清理怎么办?)处理这个的最佳方法?顺便提一句。我在 OSX 上这样做,我还没有测试这种行为在 Linux.
上是否不同
Shell 函数实际上没有 "return values",只有退出代码。
您可以将 && :
添加到调用者,这会使命令 "tested" 并且不会退出它:
foo() {
echo 'x'
return 42
}
out=$(foo && :)
echo $out
:
是 "null command"(即它什么都不做)。在这种情况下,它甚至不会被执行,因为如果 foo
return 0(它不会),它只会得到 运行。
这输出:
x
可以说它有点难看,但是话又说回来,所有 shell 脚本都可以说有点难看 ;-)
从 FreeBSD 引用 sh(1)
,这比 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.
我一直在我的脚本中使用这样一个简单的 bash 序言:
#!/bin/bash
set -e
结合模块化/使用功能,这让我今天很头疼。
所以,假设我在某个地方有一个函数,比如
foo() {
#edit: some error happens that make me want to exit the function and signal that to the caller
return 2
}
理想情况下,我希望能够使用多个小文件,将它们的函数包含在其他文件中,然后像这样调用这些函数
set +e
foo
rc=$?
set -e
。这恰好适用于两层例程。但是如果 foo 也像那样调用子程序,return 之前的最后设置将是 set -e
,这将使脚本在 return 退出 - 我不能在调用函数中覆盖它.所以,我要做的是
foo() {
#calling bar() in a shielded way like above
#..
set +e
return 2
}
我觉得这非常违反直觉(而且也不是我想要的 - 如果在某些情况下我想使用该函数而不屏蔽故障,而在其他情况下我想处理清理怎么办?)处理这个的最佳方法?顺便提一句。我在 OSX 上这样做,我还没有测试这种行为在 Linux.
上是否不同Shell 函数实际上没有 "return values",只有退出代码。
您可以将 && :
添加到调用者,这会使命令 "tested" 并且不会退出它:
foo() {
echo 'x'
return 42
}
out=$(foo && :)
echo $out
:
是 "null command"(即它什么都不做)。在这种情况下,它甚至不会被执行,因为如果 foo
return 0(它不会),它只会得到 运行。
这输出:
x
可以说它有点难看,但是话又说回来,所有 shell 脚本都可以说有点难看 ;-)
从 FreeBSD 引用 sh(1)
,这比 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.