Answers:
您编写的内容实际上几乎可以运行(如果所有变量均为数字,则可以运行),但这根本不是惯用的方式。
(…)
括号表示子壳。它们里面的东西并不像许多其他语言那样表达。这是命令列表(就像外括号一样)。这些命令在单独的子过程中执行,因此在括号内执行的任何重定向,赋值等在括号外均无效。
{ … }
花括号类似于括号,因为它们将命令分组,但是它们仅影响语法分析,而不影响分组。该程序将x=2; { x=4; }; echo $x
打印4,而将x=2; (x=4); echo $x
打印2。(大括号在闭合之前也需要在其周围留一个空格和一个分号,而括号则不需要。这只是一个语法怪异。)
${VAR}
是参数扩展,扩展为变量的值,并可能进行额外的转换。((…))
双括号包围着算术指令,即对整数的计算,其语法类似于其他编程语言。此语法主要用于赋值和条件句中。
$((…))
,该语法扩展为表达式的整数值。[[ … ]]
双括号包围条件表达式。条件表达式主要建立在运算符上,例如-n $variable
测试变量是否为空以及-e $file
测试文件是否存在。还有字符串相等运算符:"$string1" == "$string2"
(提防右手边是一个模式,如[[ $foo == a* ]]
检测是否$foo
开始与a
同时[[ $foo == "a*" ]]
测试,如果$foo
是完全a*
),和熟悉!
,&&
以及||
对否定,合和脱节,以及对分组圆括号运营商。请注意,您需要在每个运算符周围加一个空格(例如[[ "$x" == "$y" ]]
,not [[ "$x"=="$y" ]]
;
在方括号内和外都需要一个空格或字符(例如[[ -n $foo ]]
,[[-n $foo]]
[ … ]
单括号是条件表达式的另一种形式,具有更多怪癖(但较旧且更易于移植)。现在不要写任何东西;当您发现包含它们的脚本时,就开始担心它们。这是在bash中编写测试的惯用方式:
if [[ $varA == 1 && ($varB == "t1" || $varC == "t2") ]]; then
如果您需要移植到其他外壳,可以采用这种方式(请注意每个单独测试的附加引号和单独的括号,并使用传统的=
运算符,而不是ksh / bash / zsh ==
变体):
if [ "$varA" = 1 ] && { [ "$varB" = "t1" ] || [ "$varC" = "t2" ]; }; then
==
区分变量和比较的方法(也是=
)
[[ $varA = 1 && ($varB = "t1" || $varC = "t2") ]]
尽管第一个要点明确指出:“ [括号]内的内容不像许多其他语言一样,但表达式 ”中的那些并没有启动子过程-但肯定在这里!对于经验丰富的bash向导来说,这可能是显而易见的,但对我而言,甚至不是立即。之所以会引起混淆,是因为在语句中可以使用单括号if
,而不能在双括号内的表达式中使用。
==
并不是真的比“更惯用” =
。它们具有相同的含义,但是==
是ksh的变体,也可以在bash和zsh中使用,而它们=
是可移植的。使用确实没有任何优势==
,并且在普通模式下也不起作用。
==
在内部编写文字[[ … ]]
,但=
同时也可以使用[ … ]
,因此,我建议完全不要养成使用的习惯==
。
很接近
if [[ $varA -eq 1 ]] && [[ $varB == 't1' || $varC == 't2' ]];
then
scale=0.05
fi
应该管用。
分解
[[ $varA -eq 1 ]]
是整数比较,其中as
$varB == 't1'
是字符串比较。否则,我只是将比较正确地分组。
双方括号定界了条件表达式。而且,我发现以下内容是该主题的不错的读物:“(IBM)Demystify test,[,[[,((,and if-then-else“
't1'
是不必要的,对吧?因为相对于在双括号算术指令,其中t1
将是可变的,t1
在双条件表达式括号仅仅是一个文字串。即[[ $varB == 't1' ]]
与完全相同[[ $varB == t1 ]]
,对吧?
if ([ $NUM1 == 1 ] || [ $NUM2 == 1 ]) && [ -z "$STR" ]
then
echo STR is empty but should have a value.
fi