Verwendung von grep in der bedingten Anweisung in der Bash

17

Ich bin noch sehr neu im Schreiben von Skripten in Bash und probiere nur ein paar Dinge aus, von denen ich dachte, dass sie grundlegende Dinge sind. Ich möchte DDNS ausführen, das von meinem Server mit Ubuntu 14.04 aktualisiert wird.

Ich habe mir bisher Code von dnsimple ausgeliehen:

#!/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

Die Idee ist, dass es alle 5 Minuten läuft, wobei ich mit einem Cronjob arbeite. Ich möchte dann die Ausgabe der Wellung überprüfen, um festzustellen, ob der Status "200" oder ein anderer ist. Wenn es etwas anderes ist, dann möchte ich die Ausgabe in eine Datei speichern.

Was ich nicht zum Arbeiten bringen kann, ist die ifAussage. Soweit ich weiß, liefert -qder grepBefehl on einen Exit-Code für die ifAnweisung. Allerdings kann ich nicht scheinen, es zum Laufen zu bringen. Wo habe ich mich geirrt?

CircularRecursion
quelle
Funktioniert Ihr Skript, wenn Sie die ifPrüfung entfernen und immer in die Protokolldatei zurückkehren? dnssimple zeigt ein $LOGINvorher $TOKEN, aber das fehlt dir. Vielleicht scheitert das daran?
Mikel
1
Ich habe es leicht modifiziert. Ich benutze eine, DNSimple-Domain-Tokendie die LOGINVariable nicht benötigt .
CircularRecursion
Wenn ich Sie wäre, würde ich dies nur ausführen, wenn die Internet-Netzwerkschnittstelle nicht alle 5 Minuten von cron aus hochgefahren wird. oder zumindest "$ IP" irgendwo in einer Datei zwischenspeichern (vielleicht /var/tmp/icanhazip), und wenn es sich seit dem letzten Durchlauf nicht geändert hat, exit 0bevor Sie etwas anderes tun. Sie müssen Ihren DDNS-Eintrag nicht alle 5 Minuten aktualisieren, nur wenn sich Ihre IP-Adresse ändert.
cas
Gute Idee - ich werde daran arbeiten, das hinzuzufügen.
CircularRecursion

Antworten:

22

Du bist fast da. Lass einfach das Ausrufezeichen weg:

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

Ergebnis:

MATCH

Die ifBedingung ist erfüllt, wenn grep mit dem Exit-Code 0 (was eine Übereinstimmung bedeutet) zurückgibt. Das !Ausrufezeichen negiert dies.

Guido
quelle
5

Da Sie bash bereits verwenden, können Sie es intern für bash belassen:

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

Probeläufe:

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


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

Dies ist keine Antwort auf Ihre Frage, sondern nur ein paar Vorschläge eines Kollegen:

  • Verwenden Sie $()anstelle von Backticks nicht beide
  • Bedingte ifAnweisungen einrücken
  • Entfernen Sie unnötigen Gebrauch von $()

Konsistenz und einfache Regeln helfen Ihnen, Skripte auf lange Sicht zu debuggen und zu warten ...

#!/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
quelle