0

Hi Guys I am trying to perform a check in my bash script that needs to meet three conditions, I was able to make the first 2 conditions work in the if statement as I wanted, but when I wanted to implement a third check with some arithmetic using the && operator, the script does not even launch.

DOUBLE_CHECK=0

 if [[ -z "$avail" &&  "$WIFI_ID" == "some_str"  && 'expr $DOUBLE_CHECK % 2' -eq "0"]]; then
        sudo caffeinate xterm -geometry 70x20+0+0 -fa monospace -fs 8 -e './script1.sh'  & disown

fi
(($DOUBLE_CHECK++))

The Idea is I want the third check to have a number that increments over time inside my while loop and then checked, whenever it is divisible by 2 it passes the 3rd condition of the if statement

1
  • if should be ((DOUBLE_CHECK++)) Commented Feb 27, 2020 at 8:59

3 Answers 3

1

As noted in a separate answer, you could use backticks or preferably $() to expand the expression to the output of the inner command, like this :

if [[ -z "$avail" && $WIFI_ID == "some_str" && $(expr $DOUBLE_CHECK % 2) -eq "0" ]]

Please note I have added a (required) space before the final ]].

Another possibility is to use an arithmetic expression :

if [[ -z $avail && $WIFI_ID == "some_str" ]] && ((DOUBLE_CHECK % 2 == 0))

Please note I have removed harmless but unnecessary quotes : the double-bracketed conditional expression is not a normal command, it is special shell syntax, and it does not perform word splitting. I have left quotes around some_str, because equality/inequality comparisons will perform pattern matching on the right-hand expression if it is not quoted. There is also no $ before the variable name in the arithmetic expression : it works, but is not required inside (()) or $(()).

The expression could also be expressed as :

if [[ -z $avail && $WIFI_ID == "some_str" ]] && ! ((DOUBLE_CHECK % 2))

The reason for this is that (( )) has a return code of 0 if its numerical result is non-zero, and a non-zero return code otherwise.

Sign up to request clarification or add additional context in comments.

Comments

0

There are a couple small issues

  1. Your third condition should be evaluated using back-ticks ('`'), instead of quotes. Single-quotes in bash mean string literal. So, 'expr $DOUBLE_CHECK %2' -eq "0" will always be false

  2. The check -eq is used to compare numbers. Your statement is using strings (to compare strings, use the normal == syntax)

Please try,

DOUBLE_CHECK=0

if [[ -z "$avail" ]] &&  [[ "$WIFI_ID" == "some_str" ]] && [[ `expr $DOUBLE_CHECK % 2` -eq 0 ]]; then
        sudo caffeinate xterm -geometry 70x20+0+0 -fa monospace -fs 8 -e './script1.sh'  & disown

fi
(($DOUBLE_CHECK++))

5 Comments

I do not think your #3 recommendation is valid. Bash conditionals support logical operators, and I do not know of a reason to avoid them (contrary to -a and -o in standard [ tests).
[[ "A" == "A" ]] && [[ "B" == "B" ]] && echo 'foo' works for me
Yes, it works. I am not saying the alternative syntax you suggest is wrong, my point was saying that I do not think that recommending to put the logical operators outside the conditionals is good advice. If it is (it could be), it is something new to me.
I am not saying the way you do it is bad at all. It may be more readable to you, and in that case there is nothing to prevent you from doing it. In most cases, I would prefer shorter syntax, but I would not say either way is better in an absolute sense. My intervention was more because you recommended this as being better without giving a clear reason why. It is always helpful telling why one recommends X over Y, especially when both solutions work.
Thanks for feedback. I appreciate it. I have removed the point from my post to avoid future confusion
0

You can use [[ .. ]] for string logic (where = and == are equivalent) and (( ... )) for numeric comparison, and do away with expr:

if [[ -z "$avail" && "$WIFI_ID" = "some_str" ]] && (( DOUBLE_CHECK % 2 == 0 )); then
  # your logic here
fi

Note that prefixing variables with $ is optional inside (( ... )) and quoting variables is optional inside [[ ... ]] since doesn't do word splitting and globbing there.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.