Використання grep в умовному вираженні в bash


22

Я все ще дуже новачок в сценаріях на баш, і я просто пробую декілька, що я вважав, що це будуть основні речі. Я хочу запустити 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 хвилин, що я працюю за допомогою кронштейна. Потім я хочу перевірити вихід завитка, щоб побачити, чи статус "200" чи інший. Якщо це щось інше, то я хочу зберегти вихідний файл.

Що я не можу працювати - це ifтвердження. Як я розумію, команда -qon grepнадасть вихідний код для ifоператора. Однак я не можу зробити так, щоб це спрацювало. Де я помилився?


Чи працює ваш сценарій, якщо ви видалите ifчек і завжди лунає у файлі журналу? dnssimple показує $LOGINраніше $TOKEN, але ви цього не вистачаєте. Може, це спричиняє невдачі?
Мікель

1
Я її трохи змінив. Я використовую змінну, DNSimple-Domain-Tokenякій не потрібна LOGIN.
Кругова

якби я був ти, я би запускав це лише тоді, коли інтерфейс мережі Інтернет піднімається, а не кожні 5 хвилин від cron. або, принаймні, кешуйте "$ IP" у файлі десь (можливо /var/tmp/icanhazip), і якщо він не змінився з останнього запуску, exit 0перш ніж робити щось інше. вам не потрібно оновлювати запис DDNS кожні 5 хвилин, лише коли ваша IP-адреса змінюється.
cas

Гарна ідея - я працюю над тим, щоб додати це.
Кругова

Відповіді:


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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.