Использование grep в условном выражении в bash

22

Я все еще очень плохо разбираюсь в скриптах на bash, и просто пробую несколько вещей, которые, как я думал, будут простыми. Я хочу запустить DDNS, который обновляется с моего сервера под управлением Ubuntu 14.04.

Заимствование некоторого кода из 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оператора. Однако я не могу заставить его работать. Где я ошибся?

CircularRecursion
источник
Работает ли ваш скрипт, если вы удалите ifпроверку и всегда откликаетесь на файл журнала? dnssimple показывает $LOGINраньше $TOKEN, но вы упускаете это. Может быть, это заставляет вещи терпеть неудачу?
Микель
1
Я немного изменил это. Я использую, DNSimple-Domain-Tokenкоторый не нуждается в LOGINпеременной.
CircularRecursion
Если бы я был вами, я бы запустил это только тогда, когда интернет-интерфейс запускается, а не каждые 5 минут из cron. или, по крайней мере, кешировать "$ IP" в файл где-нибудь (возможно /var/tmp/icanhazip), и если он не изменился с момента последнего запуска, exit 0прежде чем делать что-либо еще. Вам не нужно обновлять свою запись DDNS каждые 5 минут, только при изменении вашего IP-адреса.
cas
Хорошая идея - я буду работать над добавлением этого.
CircularRecursion

Ответы:

28

Ты почти там. Просто опустите восклицательный знак:

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

Результат:

MATCH

ifУсловие выполняется , если Grep возвращается с кодом выхода 0 (что означает совпадение). !Восклицательный знак будет отрицать это.

Guido
источник
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
Vikyboss
источник