2012-03-27 44 views
0

我开始在我的bash脚本中使用set -e, ,并发现短格式的条件表达式会中断脚本执行。当使用set时,bash单行条件失败-e

例如,下面的线应该检查是$ var不为空:

[ -z "$var" ] && die "result is empty" 

但导致从脚本无声退出时是$ var具有非零长度。

我曾经在许多地方,这种形式的条件表达式...

我应该怎么做,使之正常运行?用“if”构造重写所有内容(这会很丑陋)?或放弃“set -e”?

编辑:大家都在问代码。这里充满[无]工作示例:

#!/bin/bash 
set -e 

function check_me() 
{ 
    ws="smth" 
    [ -z "$ws" ] && echo " fail" && exit 1 
} 

echo "checking wrong thing" 
check_me 
echo "check finished" 

我希望它之前和之后的函数调用打印两相呼应。 但它在check_me函数中静静失败。输出是:

checking wrong thing 
+0

你在哪里使用'set -e'?显示完整的代码。 – 2012-03-27 08:46:53

+0

你所描述的不应该发生(我不能再现)。这是专门列出的情况下shell不会退出手册页。 – Mat 2012-03-27 08:49:46

+0

这可能是在这里有意义的用法。我已经添加了一个示例脚本(完整)。 – LiMar 2012-03-27 09:09:09

回答

5

使用

[ -n "$var" ] || die "result is empty" 

这样一来,整个语句的返回值是true,如果$var非空,所以ERR陷阱不会被触发。

+0

@LiMar:你期望一个叫做'die'的函数能够返回吗? – ams 2012-03-27 09:26:46

+0

@ams:不,我不知道。这只是一个“回声”,接着是“退出1”的包装。 – LiMar 2012-03-27 09:30:57

+1

@LiMar:因此,如果测试返回false,它将调用死亡,并且一切都将按预期工作。如果测试返回true,那么脚本将继续。我在这里看不到你的问题? – ams 2012-03-27 09:33:34

2

您应该编写脚本,以避免命令以非零状态退出。

在你的命令[ -z "$var" ]可以是真的,在这种情况下,你可以拨打die,或者在这种情况下-e是真的。

要么与if写,就像你说的,还是用这样的:

[ -z "$var" ] && die "result is empty" || true 

我建议if虽然。

+0

As @ I0b0表示,这个具体示例有一个更漂亮的方法,但上面的方法适用于任何事情。 – ams 2012-03-27 09:16:23

+0

[对此非常谨慎](http://mywiki.wooledge.org/BashPitfalls#cmd1_.26.26_cmd2_.7C.7C_cmd3)。在这种情况下,它可能会起作用,但要知道如果这些命令不重要,效果将会变得非常棘手。 – l0b0 2012-03-27 09:21:26

+0

这就是为什么我建议'如果'。 – ams 2012-03-27 09:25:39

2

恐怕你不得不重写所有内容,以免发生虚假陈述。

set -e定义很明确:如果

-e立即退出一个简单的命令(见以上SHELL文法)具有非零状态退出。如果失败的命令是命令列表的一部分,紧接着一段时间或直到关键字,if语句中的测试的一部分,或者是一个&或更高版本的一部分,则shell不会退出。列表,或者命令的返回值是否通过!来反转。如果设置了ERR,则会在shell退出之前执行陷阱。

你正在使用bash的“优化”系统:因虚假陈述将导致AND(&&)语句永远是真实的,庆典知道它没有执行该行的第二部分。但是,这是对系统的一种巧妙的“滥用”,并非意欲的行为,因此与set -e不兼容。您将不得不重写所有内容,以便使用正确的if s。