在bash中的条件语句中使用grep


22

我对使用bash编写脚本还是很陌生,只是尝试一些我认为是基本的事情。我想运行从运行Ubuntu 14.04的服务器更新的DDNS。

从dnsimple借用一些代码,这是我到目前为止所拥有的:

#!/bin/bash

LOGIN="email"
TOKEN="token"
DOMAIN_ID="domain"
RECORD_ID="record"
IP=`curl -s http://icanhazip.com/`

OUTPUT=`
curl -H "Accept: application/json" \
     -H "Content-Type: application/json" \
     -H "X-DNSimple-Domain-Token: $TOKEN" \
     -X "PUT" \
     -i "https://api.dnsimple.com/v1/domains/$DOMAIN_ID/records/$RECORD_ID" \
     -d "{\"record\":{\"content\":\"$IP\"}}"`

if ! echo "$OUTPUT" | grep -q "(Status:\s200)"; then

echo "match"

$(echo "$OUTPUT" | grep -oP '(?<="message":")(.[^"]*)' >> /home/ddns/ddns.log)
$(echo "$OUTPUT"| grep -P '(Status:\s[0-9]{3}\s)' >> /home/ddns/ddns.log)

fi

想法是它每5分钟运行一次,而我使用cronjob进行工作。然后,我想检查curl的输出以查看状态是否为“ 200”或其他。如果还有其他问题,那么我想将输出保存到文件中。

我不能工作的是if声明。据我了解,-qon grep命令将为该if语句提供退出代码。但是我似乎无法正常工作。我哪里出问题了?


如果删除if检查并始终回显日志文件,您的脚本是否起作用? dnssimple显示一个$LOGINbefore $TOKEN,但是您错过了。也许这会导致事情失败?
Mikel

1
我已经对其稍作修改。我正在使用DNSimple-Domain-Token不需要LOGIN变量的。
CircularRecursion

如果我是您,则仅在Internet网络接口启动时才运行此程序,而不是从cron每5分钟运行一次。或者,至少将“ $ IP”缓存在某个文件中(可能是/var/tmp/icanhazip)中,如果自上次运行以来未更改,则应exit 0进行其他操作。您不需要每5分钟更新一次DDNS条目,仅当您的IP地址更改时。
cas

好主意-我会继续添加。
CircularRecursion

Answers:


28

你快到了。只需省略感叹号即可:

OUTPUT='blah blah (Status: 200)'
if echo "$OUTPUT" | grep -q "(Status:\s200)"; then
    echo "MATCH"
fi

结果:

MATCH

if如果grep返回的退出代码为0(表示匹配),则满足该条件。该!感叹号会否定这一点。


5

由于您已经在使用bash,因此可以将其保留在bash内部:

if [[ $OUTPUT =~ (Status:[[:space:]]200) ]]; then
  echo match
fi

样品运行:

OUTPUT='something bogus'
[[ $OUTPUT =~ (Status:[[:space:]]200) ]] && echo match


OUTPUT='something good (Status: 200)'
[[ $OUTPUT =~ (Status:[[:space:]]200) ]] && echo match
match

3

不是您的问题的答案,而是脚本编写者的一些建议:

  • 采用 $()而不是反引号,不要两者都使用
  • 缩进条件if语句
  • 删除不必要的用法 $()

一致且简单的规则将帮助您长期调试和维护脚本...

#!/bin/bash

LOGIN="email"
TOKEN="token"
DOMAIN_ID="domain"
RECORD_ID="record"
IP=$(curl -s http://icanhazip.com/)

OUTPUT=$(
curl -H "Accept: application/json" \
    -H "Content-Type: application/json" \
    -H "X-DNSimple-Domain-Token: $TOKEN" \
    -X "PUT" \
    -i "https://api.dnsimple.com/v1/domains/$DOMAIN_ID/records/$RECORD_ID" \
    -d "{\"record\":{\"content\":\"$IP\"}}"
)

if ! echo "$OUTPUT" | grep -q "(Status:\s200)"; then
    echo "match"
    echo "$OUTPUT" | grep -oP '(?<="message":")(.[^"]*)' >> /home/ddns/ddns.log
    echo "$OUTPUT"| grep -P '(Status:\s[0-9]{3}\s)' >> /home/ddns/ddns.log
fi
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.