我有几个变量,我想检查以下条件(用文字写出,然后我尝试bash脚本失败):
if varA EQUALS 1 AND ( varB EQUALS "t1" OR varB EQUALS "t2" ) then do something done.
在我失败的尝试中,我提出:
if (($varA == 1)) && ( (($varB == "t1")) || (($varC == "t2")) ); then scale=0.05 fi
以下是if-then-else语句的简短版本的代码:
( [ $a -eq 1 ] || [ $b -eq 2 ] ) && echo "ok" || echo "nok"
请注意以下事项:
如果条件(即圆括号之间)是逻辑操作数(或/和),
|| 和 && 操作数在里面
||
&&
|| 和 && 操作数如果条件意味着那么/ else
实际上声明说:
if(a = 1或b = 2)然后“ok”否则“nok”
if ([ $NUM1 == 1 ] || [ $NUM2 == 1 ]) && [ -z "$STR" ] then echo STR is empty but should have a value. fi
你写的东西实际上几乎可以工作(如果所有变量都是数字,它会起作用),但它根本不是惯用的方式 .
(…) 括号表示subshell . 's inside them isn' t表达式与许多其他语言类似 . 这是一个命令列表(就像外面的括号一样) . 这些命令在单独的子进程中执行,因此在括号内执行的任何重定向,赋值等都不会在括号外执行 .
(…)
带有一个领先的美元符号, $(…) 是command substitution:括号内有一个命令,命令的输出用作命令行的一部分(在额外的扩展之后,除非替换在双引号之间,但那是another story) .
$(…)
{ … } 大括号就像是括号,因为它们对命令进行分组,但它们只会影响分析,而不会影响分组 . 程序 x=2; { x=4; }; echo $x 打印4,而 x=2; (x=4); echo $x 打印2.(大括号也需要它们周围的空格和一个分号才能关闭,而括号只需要一个语法怪癖 . )
{ … }
x=2; { x=4; }; echo $x
x=2; (x=4); echo $x
带有一个领先的美元符号, ${VAR} 是parameter expansion,扩展到变量的值,可能有额外的转换 .
${VAR}
((…)) 双括号围绕arithmetic instruction,即整数计算,其语法类似于其他编程语言 . 此语法主要用于赋值和条件 .
((…))
在算术表达式 $((…)) 中使用相同的语法,它扩展为表达式的整数值 .
$((…))
[[ … ]] 双括号环绕conditional expressions . 条件表达式主要构建在operators上,例如 -n $variable ,用于测试变量是否为空,而 -e $file 用于测试文件是否存在 . 还有字符串相等运算符: "$string1" = "$string2" (请注意右侧是模式,例如 [[ $foo = a* ]] 测试 $foo 是否以 a 开始,而 [[ $foo = "a*" ]] 测试 $foo 是否完全 a* ),以及熟悉的 ! , && 和 || 运算符用于否定,连接和分离以及用于分组的括号 . 请注意,每个运算符周围都需要一个空格(例如 [[ "$x" = "$y" ]] ,而不是[[“$ x”=“$ y”]]),括号内外的空格或字符如 ; (例如 [[ -n $foo ]] ,不是[[ -n $ foo]]) .
[[ … ]]
-n $variable
-e $file
"$string1" = "$string2"
[[ $foo = a* ]]
$foo
a
[[ $foo = "a*" ]]
a*
!
[[ "$x" = "$y" ]]
;
[[ -n $foo ]]
[ … ] 单括号是具有更多怪癖的条件表达式的替代形式(但更旧且更便携) . 不要写任何东西;当你找到包含它们的脚本时,开始担心它们 .
[ … ]
这是用bash编写测试的惯用方法:
if [[ $varA = 1 && ($varB = "t1" || $varC = "t2") ]]; then
如果你需要可移植到其他shell,这将是方式(注意额外的引用和每个单独测试周围的单独括号集):
if [ "$varA" = 1 ] && { [ "$varB" = "t1" ] || [ "$varC" = "t2" ]; }; then
很接近
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"
一个非常便携的版本(甚至是传统的bourne shell):
if [ "$varA" = 1 -a \( "$varB" = "t1" -o "$varB" = "t2" \) ] then do-something fi
这具有最多只运行一个子进程的额外质量(即进程'['),无论shell风格如何 .
如果变量包含数值,则将“=”替换为“-eq”,例如
3 -eq 03是真的,但是
3 = 03是假的 . (字符串比较)
5 回答
以下是if-then-else语句的简短版本的代码:
请注意以下事项:
如果条件(即圆括号之间)是逻辑操作数(或/和),
||
和&&
操作数在里面||
和&&
操作数如果条件意味着那么/ else实际上声明说:
if(a = 1或b = 2)然后“ok”否则“nok”
你写的东西实际上几乎可以工作(如果所有变量都是数字,它会起作用),但它根本不是惯用的方式 .
(…)
括号表示subshell . 's inside them isn' t表达式与许多其他语言类似 . 这是一个命令列表(就像外面的括号一样) . 这些命令在单独的子进程中执行,因此在括号内执行的任何重定向,赋值等都不会在括号外执行 .带有一个领先的美元符号,
$(…)
是command substitution:括号内有一个命令,命令的输出用作命令行的一部分(在额外的扩展之后,除非替换在双引号之间,但那是another story) .{ … }
大括号就像是括号,因为它们对命令进行分组,但它们只会影响分析,而不会影响分组 . 程序x=2; { x=4; }; echo $x
打印4,而x=2; (x=4); echo $x
打印2.(大括号也需要它们周围的空格和一个分号才能关闭,而括号只需要一个语法怪癖 . )带有一个领先的美元符号,
${VAR}
是parameter expansion,扩展到变量的值,可能有额外的转换 .((…))
双括号围绕arithmetic instruction,即整数计算,其语法类似于其他编程语言 . 此语法主要用于赋值和条件 .在算术表达式
$((…))
中使用相同的语法,它扩展为表达式的整数值 .[[ … ]]
双括号环绕conditional expressions . 条件表达式主要构建在operators上,例如-n $variable
,用于测试变量是否为空,而-e $file
用于测试文件是否存在 . 还有字符串相等运算符:"$string1" = "$string2"
(请注意右侧是模式,例如[[ $foo = a* ]]
测试$foo
是否以a
开始,而[[ $foo = "a*" ]]
测试$foo
是否完全a*
),以及熟悉的!
,&&
和||
运算符用于否定,连接和分离以及用于分组的括号 . 请注意,每个运算符周围都需要一个空格(例如[[ "$x" = "$y" ]]
,而不是[[“$ x”=“$ y”]]),括号内外的空格或字符如;
(例如[[ -n $foo ]]
,不是[[ -n $ foo]]) .[ … ]
单括号是具有更多怪癖的条件表达式的替代形式(但更旧且更便携) . 不要写任何东西;当你找到包含它们的脚本时,开始担心它们 .这是用bash编写测试的惯用方法:
如果你需要可移植到其他shell,这将是方式(注意额外的引用和每个单独测试周围的单独括号集):
很接近
应该管用 .
打破它
是一个整数比较,其中as
是一个字符串比较 . 否则,我只是正确地对比分组 .
双方括号分隔条件表达式 . 并且,我发现以下内容是关于这个主题的一个很好的阅读:["(IBM) Demystify test, [, [, ((, and if-then-else"
一个非常便携的版本(甚至是传统的bourne shell):
这具有最多只运行一个子进程的额外质量(即进程'['),无论shell风格如何 .
如果变量包含数值,则将“=”替换为“-eq”,例如
3 -eq 03是真的,但是
3 = 03是假的 . (字符串比较)