试图在一行代码中检查 3 个条件,但我被卡住了。
本质上,我需要编写以下代码:
如果
字符串 1 不等于字符串 2
和
字符串 3 不等于字符串 4
或者
布尔1=真
然后
显示“条件满足 - 运行代码......”。
根据评论中的要求,我更新了我的示例以尝试使问题更清晰。
#!/bin/sh
string1="a"
string2="b"
string3="c"
string4="d"
bool1=true
# the easy-to-read way ....
if [ "$string1" != "$string2" ] && [ "$string3" != "$string4" ] ; then
echo "conditions met - running code ..."
fi
if $bool1 ; then
echo "conditions met - running code ..."
fi
# or the shorter way ...
[ "$string1" != "$string2" ] && [ "$string3" != "$string4" ] && echo "conditions met - running code ..."
$bool1 && echo "conditions met - running code ..."
上面的代码可能会运行两次:如果满足前两个条件,然后如果满足第三个条件,则再次运行。这不是我需要的。
这个例子的问题是它涉及到两次不同的“echo”调用 - (注意:在真实的代码中,它不是一个 echo,但你明白了)。我试图通过将 3 个条件检查合并到一个命令中来减少代码重复。
我确信现在有一些人摇着头对着屏幕大喊“那是不是你怎么做到的!”
可能还有其他人正在等待将其标记为重复项......好吧,我看了但如果我能从我读过的答案中找出如何做到这一点,我就该死了。
有人可以启发我吗? :)
答案1
这将起作用:
if [ "$string1" != "$string2" ] \
&& [ "$string3" != "$string4" ] \
|| [ "$bool1" = true ]; then
echo "conditions met - running code ...";
fi;
或者用 包围{ ;}
以提高可读性并易于将来维护。
if { [ "$string1" != "$string2" ] && [ "$string3" != "$string4" ] ;} \
|| [ "$bool1" = true ] ; then
echo "conditions met - running code ...";
fi;
注意事项:
- 不存在布尔变量这样的东西。。
- 大括号最后需要分号 (
{ somecmd;}
)。 &&
并||
评估左到右在上面 -&&
优先级高于||
仅在(( ))
和 之内[[..]]
&&
更高的优先级仅发生在[[ ]]
如下证明中。认为bool1=true
。
和[[ ]]
:
bool1=true
if [[ "$bool1" == true || "$bool1" == true && "$bool1" != true ]]; then echo 7; fi #1 # Print 7, due to && higher precedence than ||
if [[ "$bool1" == true ]] || { [[ "$bool1" == true && "$bool1" != true ]] ;}; then echo 7; fi # Same as #1
if { [[ "$bool1" == true || "$bool1" == true ]] ;} && [[ "$bool1" != true ]] ; then echo 7; fi # NOT same as #1
if [[ "$bool1" != true && "$bool1" == true || "$bool1" == true ]]; then echo 7; fi # Same result as #1, proved that #1 not caused by right-to-left factor, or else will not print 7 here
和[ ]
:
bool1=true
if [ "$bool1" == true ] || [ "$bool1" == true ] && [ "$bool1" != true ]; then echo 7; fi #1, no output, due to && IS NOT higher precedence than ||
if [ "$bool1" == true ] || { [ "$bool1" == true ] && [ "$bool1" != true ] ;}; then echo 7; fi # NOT same as #1
if { [ "$bool1" == true ] || [ "$bool1" == true ] ;} && [ "$bool1" != true ]; then echo 7; fi # Same as #1
if [ "$bool1" != true ] && [ "$bool1" == true ] || [ "$bool1" == true ]; then echo 7; fi # Proved that #1 not caused by || higher precedence than &&, or else will not print 7 here, instead #1 is only left-to-right evaluation
答案2
&&
您在条件表达式末尾使用的 意味着如果前面的命令(其第一个参数)返回状态零(传统上被认为是程序的成功代码),则运行后续命令(其第二个参数)。此外,$bool1
您放在那里的 是独立的,这使得 Bash 将其值解释为要运行的命令或程序的名称。您想要实现的似乎是条件表达式评估,这是使用[
以下命令完成的:
if [ "$string1" != "$string2" ] && [ "$string3" != "$string4" ] || [ $bool1 -ne 0 ]; then echo "conditions met - running code ..."; fi
您可能会看到旧代码使用内置的“and”、、-a
和“or”、、、-o
运算符,但这已被POSIX规范并且没有明确定义。
if [ "$string1" != "$string2" -a "$string3" != "$string4" -o $bool1 -ne 0 ]; then echo "conditions met - running code ..."; fi
ksh
如果您使用的是派生自(例如)的 shell bash
,则可以使用内置测试运算符[[
:
[[ "$string1" != "$string2" && "$string3" != "$string4" || $bool1 -ne 0 ]] && echo "conditions met - running code ..."
请注意,布尔值表示为整数,因此-ne
此处可以使用“不等于”的整数表达式测试 , 。以下是演示工作原理的脚本:
#!/bin/bash
string1="Hello"
string2="Hello"
string3="Hello"
string4="Hello"
bool1=1
if [ "$string1" != "$string2" ] && [ "$string3" != "$string4" ] || [ $bool1 -ne 0 ]; then echo "conditions met - running code ..."; fi
exit 0