Bash – syntax error in conditional expression while executing the shell script

awkbashlinuxUbuntuwget

I am working on a project in which I need to make a url call to one of my server from the bash shell script..

http://hostname.domain.com:8080/beat

After hitting the above url, I will be getting the below response which I need to parse it and extract value of syncs and syncs_behind

state: READY num_retries_allowed: 3 syncs: 30 syncs_behind: 100 num_rounds: 60 hour_col: 2 day_col: 0 oldest_day_col: 0

Now I need to hit the above url every 10 seconds for a period of 10 minutes and extract the value of syncs and syncs_behind from it and use to validate it with below condition –

syncs > 8
syncs_behind = 0

if the syncs is greater than 8 and syncs_behind = 0, then I will end my shell script with some message saying – "Data has been validated", otherwise I would keep on trying for 10 minute window.. If in that 10 minute window, this doesn't happen I will end the shell script anyway meaning I won't retry again.

So I started with the below code and I saved the file as beat.sh with the below contents –

#!/bin/bash

COUNT=60   #number of 10 second timeouts in 10 minutes
SUM_SYNCS=0
SUM_SYNCS_BEHIND=0

while [[ $COUNT -ge "0" ]]; do

#send the request, put response in variable
DATA=$(wget -O - -q -t 1 http://hostname.domain.com:8080/beat)

#grep $DATA for syncs and syncs_behind
SYNCS=$(echo $DATA | grep -o 'syncs: [0-9]+' | awk '{print $2}')
SYNCS_BEHIND=$(echo $DATA | grep -o 'syncs_behind: [0-9]+' | awk '{print $2}')
echo $SYNCS
echo $SYNCS_BEHIND

#add new values to the sum totals
let SUM_SYNCS+=SYNCS
let SUM_SYNCS_BEHIND+=SYNCS_BEHIND

#verify conditionals
if [[ $SYNCS -gt "8" -a $SYNCS_BEHIND -eq "0" ]]; then exit -1; fi

#decrement the counter
let COUNT-=1

#wait another 10 seconds
sleep 10

done

And when I am running it as ./beat.sh, I got below error –

./beat.sh: line 23: syntax error in conditional expression
./beat.sh: line 23: syntax error near `-a'
./beat.sh: line 23: `if [[ $SYNCS -gt "8" -a $SYNCS_BEHIND -eq "0" ]]; then exit -1; fi'

Any thoughts what wrong I am doing here?

Best Answer

Bash's [[ does not support -a. One approach is to use [ and otherwise keep things the same:

[ $SYNCS -gt "8" -a $SYNCS_BEHIND -eq "0" ]

For best results with [, though, one should double-quote variables:

[ "$SYNCS" -gt 8 -a "$SYNCS_BEHIND" -eq 0 ]

In the general case though -a and -o should be avoided as the [ command cannot parse its arguments reliably when it receives more than 4 (beside [ and ]). So

[ "$SYNCS" -gt 8 ] && [ "$SYNCS_BEHIND" -eq 0 ]

Alternatively, keep the [[ but use && for -a:

[[ $SYNCS -gt "8" && $SYNCS_BEHIND -eq "0" ]]

Many people prefer [[ over [ because the double-quotes around variables are unnecessary.

But here, if you're going to use ksh/bash/zsh specific syntax, for arithmetic comparison, you might as well write it:

(( SYNCS > 8 && SYNCS_BEHIND == 0 ))

MORE: The grep lines have two issues. As Hauke pointed out, there is a superfluous colon in one. Second, to use the [0-9]+ syntax, both lines need the -E option for extended regex:

SYNCS=$(echo "$DATA" | grep -oE 'syncs: [0-9]+' | awk '{print $2}')
SYNCS_BEHIND=$(echo "$DATA" | grep -oE 'syncs_behind: [0-9]+' | awk '{print $2}')
Related Question