在bash中使用set -e / set + e和函数

时间:2015-01-06 06:28:08

标签: bash shell

我在我的脚本中一直使用这样的简单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也调用这样的子例程,返回前的最后一个设置将是set -e,这将使脚本在返回时退出 - 我无法在调用函数中覆盖它。所以,我必须做的是

foo() {
  #calling bar() in a shielded way like above
  #..      

  set +e
  return 2
}

我发现它非常违反直觉(也不是我想要的 - 如果在某些情况下我想使用该函数而不屏蔽失败,而在其他情况下我想要处理清理?)什么&# 39;这是处理这个问题的最佳方法吗?顺便说一句。我在OSX上这样做了,我还没有测试过Linux上的这种行为是否有所不同。

1 个答案:

答案 0 :(得分:14)

Shell函数确实没有"返回值",只是退出代码。

您可以将&& :添加到来电者,这会使命令"经过测试",并且不会退出:

foo() {
    echo 'x'
    return 42
}

out=$(foo && :)
echo $out

:是" null命令" (即它没有做任何事情)。在这种情况下,它甚至不会被执行,因为它只会在foo返回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.
相关问题