【问题标题】:Multiple AND conditions in bash that work independently based on an OR condition separator?bash中的多个AND条件基于OR条件分隔符独立工作?
【发布时间】:2016-06-28 18:04:36
【问题描述】:

这个问题与许多潜在的重复问题不同,我无法找到这个特定问题的答案甚至被问到......

也许我在这里忽略了一些简单的逻辑,但我遇到了以下问题:

我正在尝试创建一个if 语句,其中必须满足$V1$V2 等条件为真||或$V3$V4 为真。这是一个简单的测试:

#!/bin/bash

V1="File Placeholder"
#echo $V1
V2="May contain some text"
#echo $V2

V3="Some command output"
#echo $V3
V4="Command output contains this text"
#echo $V4

if [[ "$V1" ]] && [[ "$V2" == *"contain some"* ]] || [[ "$V3" ]] && [[ "$V4" == *"output contains"* ]]
then
echo "Hello $V1"
echo "World full of: $V2"
fi 

意思是,如果:

$V1 为真(文件存在) 和 $V2 为真(找到了一些字符串)

$V3 为真(即不为空) 和 $V4 为真(命令输出包含文本)

它似乎有点工作,但我意识到它不能正常工作:如果第二个&& 条件都是 FALSE 即:|| [[ "$V6" ]] && [[ "$V4" == *"output contains"* ]],它不会返回 TRUE(为什么我认为我可能忽略了一些逻辑,也许会以某种方式被取消?)。

为什么这不起作用,因为我认为它会 if a AND b are TRUE ... OR ... if x AND z are TRUE

【问题讨论】:

  • 谢谢!第三个示例“评估顺序”看起来可能是我需要的。我会试一试并报告。
  • shell 运算符&&|| 具有相同的优先级,这与大多数语言中常用的布尔运算符不同。也就是说,a || b && c(a || b) && c 相同,而不是 a || (b && c)

标签: bash if-statement operators


【解决方案1】:

您应该使用此 sn-p 将 && 条件组合到一个 [[ ... ]] 中。

if [[ -n $V1 && $V2 == *"contain some"* ]] || [[ -n $V3 && $V4 == *"output contains"* ]]
then
   echo "Hello $V1"
   echo "World full of: $V2"
fi

【讨论】:

  • 我非常喜欢这个解决方案,结合两个 AND 语句的非常简洁的技巧!
【解决方案2】:

布尔条件一旦有足够的信息来满足测试就会停止处理。所以,如果你有类似true && false && true 的东西,最后一个 true 将永远无法实现。一个假就足以知道整个测试将是假的,因为你必须拥有所有的真。

您可以尝试添加 (),它会为每个创建一个子 shell。这应该有效地将测试组合在一起,并允许将较大的测试分开:

if ( [[ "$V1" ]] && [[ "$V2" == *"contain some"* ]] ) || ( [[ "$V3" ]] && [[ "$V4" == *"output contains"* ]] )
then
    echo "Hello $V1"
    echo "World full of: $V2"
fi

重要的是要记住将您的条件分开。

【讨论】:

  • 最好使用{ ... } 而不是(...) 以避免分叉不必要的子shell。
  • 这也很有效,很高兴知道如何创建这样的子shell。另外,感谢@chepner 添加您的意见,这也是有价值的信息!
【解决方案3】:

我最终选择使用“评估顺序”方法,正如@Lino 引用此答案groups of compound conditions in Bash test 中的第三个示例首先评论的那样

if [[ "$V6" && "$V2" == *"contain some"* || ( "$V3" && "$V4" == *"output contains"* ) ]]
then
echo "Hello $V1"
echo "World full of: $V2"
fi

如果由于某种原因这是一种不好的方法,我将不胜感激。

我喜欢它全部包含在单个 [[ ]] 双括号中的方式,并且仍然可读。

所有答案和 cmets 都非常有帮助和启发! @DKing's answer 建议使用subshells@anubhava's answer 干净地结合语句,以及所有@chepner 的cmets!

【讨论】:

    猜你喜欢
    • 2021-03-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-31
    • 2018-11-25
    • 2014-08-13
    相关资源
    最近更新 更多