sh AND 和 OR 在一个命令中

sh AND 和 OR 在一个命令中

试图在一行代码中检查 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;

注意事项:

  1. 不存在布尔变量这样的东西。
  2. 大括号最后需要分号 ( { somecmd;})
  3. &&||评估左到右在上面 -&&优先级高于|| 仅在(( ))和 之内[[..]]

&&更高的优先级仅发生在[[ ]]如下证明中。认为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

相关内容