执行shell脚本时条件表达式中的语法错误?

ars*_*nal 3 linux bash ubuntu awk wget

我正在开发一个项目,在该项目中我需要从 bash shell 脚本对我的一台服务器进行 url 调用。

http://hostname.domain.com:8080/beat
Run Code Online (Sandbox Code Playgroud)

点击上面的网址后,我将得到以下响应,我需要解析它并提取syncssyncs_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
Run Code Online (Sandbox Code Playgroud)

现在,我需要打上面的网址每10秒一个10分钟的时间和提取物的价值syncs,并syncs_behind从它和使用下面的条件来验证它-

syncs > 8
syncs_behind = 0
Run Code Online (Sandbox Code Playgroud)

如果同步大于 8 且 syncs_behind = 0,那么我将用一些消息结束我的 shell 脚本 - “数据已被验证”,否则我会继续尝试 10 分钟窗口。如果在那个 10 分钟窗口中,这不会发生,无论如何我都会结束 shell 脚本,这意味着我不会再试一次。

所以我从下面的代码开始,并将文件保存为beat.sh以下内容 -

#!/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
Run Code Online (Sandbox Code Playgroud)

当我运行它时./beat.sh,出现以下错误 -

./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'
Run Code Online (Sandbox Code Playgroud)

任何想法我在这里做错了什么?

Joh*_*024 5

Bash[[不支持-a. 一种方法是使用[并以其他方式保持不变:

[ $SYNCS -gt "8" -a $SYNCS_BEHIND -eq "0" ]
Run Code Online (Sandbox Code Playgroud)

[但是,为了获得最佳结果,应该双引号变量:

[ "$SYNCS" -gt 8 -a "$SYNCS_BEHIND" -eq 0 ]
Run Code Online (Sandbox Code Playgroud)

但在一般情况下-a-o应该避免,因为当[命令接收到超过 4 个([])时,它无法可靠地解析其参数。所以

[ "$SYNCS" -gt 8 ] && [ "$SYNCS_BEHIND" -eq 0 ]
Run Code Online (Sandbox Code Playgroud)

或者,保留[[&&用于-a

[[ $SYNCS -gt "8" && $SYNCS_BEHIND -eq "0" ]]
Run Code Online (Sandbox Code Playgroud)

许多人更喜欢[[[因为变量周围的双引号是不必要的。

但在这里,如果你打算使用 ksh/bash/zsh 特定的语法,进行算术比较,你不妨这样写:

(( SYNCS > 8 && SYNCS_BEHIND == 0 ))
Run Code Online (Sandbox Code Playgroud)

更多:grep行有两个问题。正如 Hauke 指出的那样,其中有一个多余的冒号。其次,要使用[0-9]+语法,两行都需要-E扩展正则表达式的选项:

SYNCS=$(echo "$DATA" | grep -oE 'syncs: [0-9]+' | awk '{print $2}')
SYNCS_BEHIND=$(echo "$DATA" | grep -oE 'syncs_behind: [0-9]+' | awk '{print $2}')
Run Code Online (Sandbox Code Playgroud)