保持设置-e设置在||内或者&&

时间:2017-09-12 15:49:54

标签: error-handling sh posix

我有一个简单的脚本,其功能很简单,可能会导致错误。让我们定义这个功能,并让它破碎:

brokenFunction () {
    ls "non-existing-folder"
}

如果我们在一个块中执行此函数,检测它是否已损坏,则效果很好:

brokenFunction || printf "It is broken\n"

打印"它被打破"

现在,让我们通过在最后添加一个正确的命令来使函数更复杂:

#!/bin/sh

brokenFunction () {
    ls "non-existing-folder"
    printf "End of function\n"
}

brokenFunction || printf "It is broken\n"

此脚本打印:

$ ./script.sh 
ls: cannot access 'non-existing-folder': No such file or directory
End of function

虽然我希望函数在printf语句之前停止,然后显示下一个块"它已被打破"。

事实上,如果我检查brokenFunction的退出状态代码,则为0。

我尝试将set -e添加到脚本的顶部。行为仍然相同,但如果在没有brokenFunction的情况下调用,则||的退出代码现在变为2。如果使用它调用,状态代码仍为0

有没有办法将set -e设置保留在使用||调用的函数中?

编辑:我刚才意识到示例中的函数是无用的。我遇到了一个简单的块和条件相同的问题。

#!/bin/sh
set -e
{
    ls "non-existing-dir"
    printf "End of block\n"
} || {
    printf "It is broken\n"
} 

打印

$ ./script.sh 
ls: cannot access 'non-existing-dir': No such file or directory
End of block

1 个答案:

答案 0 :(得分:0)

man bash所述,set -e在某些情况下会被忽略。 ||&&之前的命令就是这样的背景。

trap看起来像是一个可行的解决方案。使用trap的最后一个脚本的替代工作方式如下:

#!/bin/sh
abort () {
    printf "It is broken\n"
}
trap 'abort' ERR
(
    set -e
    false
    printf "End of block\n"
)
trap - ERR

有些事情需要注意:

  • trap 'abort' ERRabort函数绑定到任何引发的错误;
  • 由于两个原因,在子shell中执行损坏的块。首先是将set -e设置保留在块内并限制边框效果。第二是在错误(set -e效果)上退出此子shell,而不是整个脚本;
  • 最后
  • trap - ERR重置trap绑定,这意味着脚本的以下部分将像以前一样执行。

要测试边框效果,我们可以添加以前的非工作部分:

#!/bin/sh
abort () {
    printf "It is broken\n"
}

trap 'abort' ERR
(
    set -e
    false
    printf "End of block\n"
)
trap - ERR

{   
    false
    printf "End of second block\n"
} || {
    printf "It is broken too\n"
}

打印:

It is broken
End of second block