跟着a question I asked yesterday,我有一个脚本,它运行三个测试并报告每个测试。
Tom Fenech为我提供了一些简单的代码,可以解决我的问题。但是,它似乎没有按预期工作。
pass=1
[[ test1 ]] || { echo 'test1 failed'; pass=0 }
[[ test2 ]] || { echo 'test2 failed'; pass=0 }
[[ test3 ]] || { echo 'test3 failed'; pass=0 }
[[ $pass -eq 0 ]] && echo 'one of the tests failed'
让我们只使用其中一项测试。假设我有一个变量,我需要将其值与数字进行比较:
[[ ${VAR} == '128' ]] || { echo "test failed"; pass=0 }
这总是会导致错误:
./magic_sysrq.sh: line 64: syntax error near unexpected token `else'
./magic_sysrq.sh: line 64: `else'
对于上下文,脚本包含一个if...elif...else...fi
块,运行这些测试。第一个(if
)块根据RedHat的版本以一种方式运行代码,第二个(elif
)以另一种方式运行代码,具体取决于RedHat版本。 else
块仅表示由于意外版本而未执行任何操作。
我总是使用提供的代码格式来解决上述错误。如果我删除括号,我可以通过错误。但是,无论成功更改,这都会导致测试失败。
我已尝试将格式设置为
[[ ${VAR} == '128' ]] || echo "test failed" || pass=0
这也不对。即使出现故障,它也会产生成功消息。我已尝试将第二个逻辑运算符设置为&&
,但即使成功更改,也会导致测试失败消息。
有人可以说明我可能做错了吗?我想我可以写出每个测试的所有if...fi
块作为另一个建议,但这最多是乏味的。
答案 0 :(得分:6)
语法。
[[ ${VAR} == '128' ]] || { echo "test failed"; pass=0 }
...缺少分号;它需要是:
[[ ${VAR} == '128' ]] || { echo "test failed"; pass=0; }
...否则,}
被解释为一个参数(或者,紧跟在此处的变量赋值之后,作为应用于环境的分配运行的命令),留下{{1} } unclosed,导致语法错误。
相比之下:
{
....出于不同的原因是错误的:如果[[ ${VAR} == '128' ]] || echo "test failed" || pass=0
命令成功(并且echo
命令失败并出现错误是一种非常罕见的情况),它将永远不会继续运行echo
。 (对于任何实现短路布尔逻辑的语言都是如此,而不仅仅是bash)。
答案 1 :(得分:4)
与括号不同,花括号对贝壳本身并不特殊;他们只在某些职位上被认可。最重要的是,如果在shell发现新语句开始的地方找到它,则只能将close-brace识别为终止代码块。这意味着您必须在每个}
之前插入换行符或分号:
pass=1
[[ test1 ]] || { echo 'test1 failed'; pass=0; }
[[ test2 ]] || { echo 'test2 failed'; pass=0; }
[[ test3 ]] || { echo 'test3 failed'; pass=0; }
[[ $pass -eq 0 ]] && echo 'one of the tests failed'
请注意,由于上次测试是算术运算,因此您可以使用((
... ))
。例如:
(( pass )) || echo 'one of the tests failed'