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?


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.


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

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
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.