2017-01-22 39 views
0

虽然Bash man page指出:如果失败的命令是......在& &或执行命令的一部分可以找到一种方法来设置-e/ERR子shell捕获对&&和||的免疫性限制吗?

不执行ERR陷阱||列表...

我希望在一个子shell中的代码将在不同的上下文,不会受到上述限制。下面的代码表明,即使子shell都没有不受此限制免疫:

#!/bin/bash 

main() 
{ 
    local Arg="$1" 
    (
     set -e 
     echo "In main: $Arg" 
     trap MyTrap ERR 
     $(exit 1) 
     echo "Should not get here" 
    ) 

    return 1 
} 

MyTrap() 
{ 
    echo "In MyTrap" 
} 

main 1 
[[ $? -eq 0 ]] || echo "failed" 
echo 
main 2 || echo "failed" 

上面的代码具有以下的输出:

In main: 1 
In MyTrap 
failed 

In main: 2 
Should not get here 
failed 

我目前的解决办法是使用文件持久保存错误状态在MyTrap然后检查返回代码返回在调用者。例如:

MyTrap() 
{ 
    echo "_ERROR_=$?" > $HOME/.persist 
    echo "In MyTrap" 
} 

main 1 
[[ -f $HOME/.persist ]] && . $HOME/.persist || _ERROR_=0 
[[ $_ERROR_ -eq 0 ]] || echo "failed" 

上述输出现在是:

In main: 1 
In MyTrap 
failed 

所以,问题是:能的方法来发现这样做设置-e/ERR壳层陷阱,不受&&||限制比上述解决方法简单吗?

注:这个问题适用于:

  • 击4.2和更高
  • 红帽7,CentOS的7,以及相关的发行版(即,不Debian的等)
  • 不应该使用第三方软件。软件包必须可用,例如,通过[CentOS-7-x86_64-DVD-1611.iso] [2]存储库ISO中的OS提供程序包(对于RHEL 7,Fedora 7等也是如此)。
+3

如何...不要使用set -e? –

+0

你可能想看看这篇文章:http://stackoverflow.com/questions/41774696/bash-scripting-graceful-function-death-on-error/41774978?noredirect=1#comment70744209_41774978 – codeforester

+0

@gniourf_gniourf请让我知道你的想法会起作用吗? –

回答

0

此代码不是解决方案。这是一个修改后的版本,你可以测试给你一些想法。

#!/bin/bash 

main() 
{ 
    local Arg="$1" 
    (
     echo "In main: $Arg" 
     $(exit 1) 
     echo "Should not get here" 
    ) 

    return 1 
} 

MyTrap() 
{ 
    echo "In MyTrap" 
    exit 1 
} 

set -o errtrace 
set -o functrace 
trap MyTrap ERR 

main 1 
[[ $? -eq 0 ]] || echo "failed" 
echo 
main 2 || echo "failed" 

它不会做你希望它做的(我认为),因为缺少过参与后解释一些重要的东西,但也有一些关键的东西。

如果您想要在所有脚本中统一处理错误,则必须执行以下操作。

  • 设置在顶层的陷阱,并且不使用set -e
  • 使用会使子shell和功能的壳选择继承陷阱(本例中所示)
  • 创建,你区分框架“预期”错误(明确地作为某种异常处理,而不是作为返回代码)以及将被困的“意外”异常(错误)。
  • 不要直接使用逻辑运算符(测试结构或其他您认为足够安全的简单语句除外)
  • 在收集异常之后执行逻辑测试,而不是作为对返回代码的测试。

构建框架是非常棘手的,但可行(我已经在几十个非常复杂的脚本上完美地工作)。一旦你完成了它,如果你选择盲目测试一个命令(没有明确处理异常),如果它失败了,你可以选择将脚本崩溃到陷阱中(exit),而不是继续执行脚本处于不稳定状态。

这可能会导致轻微的性能损失(至少在我使用特殊的try函数之前,使用了异常处理的每个语句之前的函数),并且确实需要在编码方面有很多规范,但在我的情况下它让我更有效率地构建复杂的脚本,并具有合理的信心,任何错误的位置(不是我有任何这些错误......)将更容易查明。

+1

是的,你是对的,有一个帖子涉及太多。实际上,我已经在一个Bash脚本框架的背景下实现了这个框架,该框架考虑了你所提到的所有事情。特别是,我已经完全在Bash中实现了try/catch机制,甚至允许使用持久变量嵌套try/catch。但是,这一切都太多了,我同意!在试图提出一个最小的测试用例时,很多都会丢失......而且很容易忽略我已经处理的事情。如果你愿意,我们可以把它带入聊天会议。 –

+0

好的聊天..但我太新了,我甚至不知道如何聊天,所以我需要一点帮助。 – Fred

+0

在每个页面的底部是聊天链接(在深灰色区域)。你可以点击那里,然后使用'bash'过滤,我们可以在特定的聊天室达成一致。如果您有兴趣让其他人轻松地谈谈对话,这是一个很好的方法。或者,您可以点击原始文章底部的我的个人资料链接,然后修改网址以'chat.'开始,然后点击'用这个用户开始一个新房间'按钮。讨论仍然是公开的,但与使用普通聊天室相比,会减少流量。 –

相关问题