shell if语句总是返回true

时间:2016-07-16 13:58:35

标签: shell if-statement

我想检查我的VPN是否已连接到特定国家/地区。 VPN客户端有一个状态选项,但有时它不会返回正确的国家/地区,所以我写了一个脚本来检查我是否连接到瑞典。我的脚本看起来像这样:

#!/bin/bash
 country=Sweden
 service=expressvpn

while true; do
   if ((curl -s https://www.iplocation.net/find-ip-address  | grep $country | grep -v "grep" | wc -l) > 0 )
   then
      echo "$service connected!!!"
  else
      echo "$service not connected!"
      $service connect $country
 fi;
 sleep 5;
 done

问题是,它总是说“服务连接”,即使它不是。当我手动输入curl命令时,如果没有找到瑞典,则wc -l返回0,如果没有,则返回1。 if语句有什么问题? 谢谢 彼得

3 个答案:

答案 0 :(得分:3)

(( ))进入数学上下文 - 其中的任何内容都被解释为数学表达式。 (您希望将您的代码解释为数学表达式 - 否则,> 0将创建一个名为0的文件并存储wc -l'在该文件中输出,而不是将wc -l的输出与0进行比较。

由于您未在结束方使用)),这可能正是发生的事情:您将wc -l的输出存储在名为的文件中0,然后使用其退出状态(成功,因为它没有失败)决定遵循if语句的真实分支。 [在关闭方面添加更多parens也不会解决这个问题,因为curl -s ...不是有效的数学语法]。

现在,如果您希望采用数学方法,那么可以做的是运行命令替换,它将命令替换为其输出; 是一个数学表达式:

# smallest possible change that works -- but don't do this; see other sections
if (( $(curl -s https://www.iplocation.net/find-ip-address | grep $country | grep -v "grep" | wc -l) > 0 )); then

...如果您的curl | grep | grep | wc变为5,则在命令替换后,这看起来像:

if (( 5 > 0 )); then

......那就是你所期待的。

那就是说,这太傻了。您想知道您的目标国家/地区是否处于卷曲状态?只需单独使用shell内置函数检查它:

if [[ $(curl -s https://www.iplocation.net/find-ip-address) = *"$country"* ]]; then
  echo "Found $country in output of curl" >&2
fi

...或者,如果确实想要使用grep,请使用grep -q(禁止输出),并检查其退出状态(为零,并且因此,当且仅当它成功找到匹配时):

if curl -s https://www.iplocation.net/find-ip-address | grep -q -e "$country"; then
  echo "Found $country in output of curl with grep" >&2
fi

这更有效,部分原因是grep -q可以在找到匹配后立即停止 - 它不需要继续阅读更多内容 - 所以如果你的文件长度为16KB,国家名称在输出的前1KB中,然后grep可以在第一次匹配1KB时停止从curl读取(curl可以停止下载)看到了。

答案 1 :(得分:1)

curl -s https://www.iplocation.net/find-ip-address | grep $country | grep -v "grep" | wc -l语句的结果是文本。您比较文本和数字,这就是您的if语句不起作用的原因。

这可能会解决您的问题;

if [ $(curl -s https://www.iplocation.net/find-ip-address  | grep $country | grep -v "grep" | wc -l) == "0" ] then ...

答案 2 :(得分:0)

这很有效,谢谢你的帮助,这就是我的剧本现在看来的:

#!/bin/bash
country=Switzerland
service=expressvpn

while true; do
if curl -s https://www.iplocation.net/find-ip-address | grep -q -e "$country"; then
  echo "Found $country in output of curl with grep" >&2
  echo "$service not connected!!!"
  $service connect Russia
else
  echo "$service connected!"
fi;
sleep 5;
done