ChatGPT解决这个技术问题 Extra ChatGPT

Bash if statement with multiple conditions throws an error

I'm trying to write a script that will check two error flags, and in case one flag (or both) are changed it'll echo-- error happened. My script:

my_error_flag=0
my_error_flag_o=0
do something.....
if [[ "$my_error_flag"=="1" || "$my_error_flag_o"=="2" ] || [ "$my_error_flag"="1" &&     "$my_error_flag_o"="2" ]]; then
    echo "$my_error_flag"
else
    echo "no flag"
fi

Basically, it should be, something along:

if ((a=1 or b=2) or (a=1 and b=2))
  then
     display error
else
     no error
fi

The error I get is:

 line 26: conditional binary operator expected
 line 26: syntax error near `]'
 line 26: `if [[ "$my_error_flag"=="1" || "$my_error_flag_o"=="2" ] || [ "$my_error_flag"="1" && "$my_error_flag_o"="2" ]]; then'

Are my brackets messed up?

Use parenthesis - ()
Logically, a==1 or b==2 already covers the case where a==1 and b==2. Testing separately for that is completely superfluous here.

B
BuZZ-dEE

Use -a (for and) and -o (for or) operations.

tldp.org/LDP/Bash-Beginners-Guide/html/sect_07_01.html

Update

Actually you could still use && and || with the -eq operation. So your script would be like this:

my_error_flag=1
my_error_flag_o=1
if [ $my_error_flag -eq 1 ] ||  [ $my_error_flag_o -eq 2 ] || ([ $my_error_flag -eq 1 ] && [ $my_error_flag_o -eq 2 ]); then
      echo "$my_error_flag"
else
    echo "no flag"
fi

Although in your case you can discard the last two expressions and just stick with one or operation like this:

my_error_flag=1
my_error_flag_o=1
if [ $my_error_flag -eq 1 ] ||  [ $my_error_flag_o -eq 2 ]; then
      echo "$my_error_flag"
else
    echo "no flag"
fi

@Simply_Me: No, a logical OR is true if either or both of its operands are true. You're thinking of "exclusive or" (XOR), which is true if exactly one of its operands is true. (Actually, there are versions of XOR that work on more than 2 operands, in which case it's true if an odd number of operands are true.)
BTW, problems in the original code include using [ and ] for grouping (they don't do that), and failing to put spaces around the operator (e.g. "$my_error_flag"="1"), which prevents the shell from recognizing it as an operator at all. Please read BashFAQ #17 (on grouping) and #31 (on the difference between different types of test expression). Actually, in this case it would be even easier to use an arithmetic expression.
-a and -o are considered obsolete by the POSIX specification; use separate tests combined with || as in the update.
No need to group using subshells, normally grouping using {} should also be possible.
to add to phk's comment above, ( ) is launching subshells in bash, which can have all sorts of subtle [probably unwanted] effects.
F
Fizer Khan

You can use either [[ or (( keyword. When you use [[ keyword, you have to use string operators such as -eq, -lt. I think, (( is most preferred for arithmetic, because you can directly use operators such as ==, < and >.

Using [[ operator

a=$1
b=$2
if [[ a -eq 1 || b -eq 2 ]] || [[ a -eq 3 && b -eq 4 ]]
then
     echo "Error"
else
     echo "No Error"
fi

Using (( operator

a=$1
b=$2
if (( a == 1 || b == 2 )) || (( a == 3 && b == 4 ))
then
     echo "Error"
else
     echo "No Error"
fi

Do not use -a or -o operators Since it is not Portable.


p
pacholik

Please try following

if ([ $dateR -ge 234 ] && [ $dateR -lt 238 ]) || ([ $dateR -ge 834 ] && [ $dateR -lt 838 ]) || ([ $dateR -ge 1434 ] && [ $dateR -lt 1438 ]) || ([ $dateR -ge 2034 ] && [ $dateR -lt 2038 ]) ;
then
    echo "WORKING"
else
    echo "Out of range!"

( ... ) creates subshells -- lots of performance impact for no benefit.
Use { ...; } for grouping without subshell creation.
D
Daniel Andrei Mincă

You can get some inspiration by reading an entrypoint.sh script written by the contributors from MySQL that checks whether the specified variables were set.

As the script shows, you can pipe them with -a, e.g.:

if [ -z "$MYSQL_ROOT_PASSWORD" -a -z "$MYSQL_ALLOW_EMPTY_PASSWORD" -a -z "$MYSQL_RANDOM_ROOT_PASSWORD" ]; then
    ...
fi

-a is marked as obsolescent in the current version of the POSIX test standard; see the OB markers at pubs.opengroup.org/onlinepubs/9699919799/utilities/test.html. Use [ -z "$FOO" ] && [ -z "$BAR" ] to have more reliable code.