Utilisation de grep dans une instruction conditionnelle dans bash

22

Je suis encore très nouveau dans les scripts en bash, et j'essaye juste quelques-uns de ce que je pensais être des choses de base. Je veux exécuter DDNS qui se met à jour depuis mon serveur exécutant Ubuntu 14.04.

En empruntant du code à dnsimple, voici ce que j'ai jusqu'à présent:

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

L'idée est qu'il s'exécute toutes les 5 minutes, ce que je travaille en utilisant un cronjob. Je veux ensuite vérifier la sortie de la boucle pour voir si l'état est "200" ou autre. Si c'est autre chose, je veux enregistrer la sortie dans un fichier.

Ce que je ne peux pas faire, c'est la ifdéclaration. Si je comprends bien, la -qsur la grepcommande fournira un code de sortie pour la ifdéclaration. Cependant, je n'arrive pas à le faire fonctionner. Où ai-je mal tourné?

CircularRecursion
la source
Votre script fonctionne-t-il si vous supprimez la ifcoche et faites toujours écho au fichier journal? dnssimple montre un $LOGINavant $TOKEN, mais ça vous manque. Peut-être que cela fait échouer les choses?
Mikel
1
Je l'ai légèrement modifié. J'utilise un DNSimple-Domain-Tokenqui n'a pas besoin de la LOGINvariable.
CircularRecursion
si j'étais vous, je ne l'exécuterais que lorsque l'interface réseau Internet augmente plutôt que toutes les 5 minutes de cron. ou, au moins, cachez "$ IP" dans un fichier quelque part (peut-être /var/tmp/icanhazip) et s'il n'a pas changé depuis la dernière exécution, exit 0avant de faire autre chose. vous n'avez pas besoin de mettre à jour votre entrée DDNS toutes les 5 minutes, uniquement lorsque votre adresse IP change.
cas
Bonne idée - je vais travailler sur l'ajout de cela.
CircularRecursion

Réponses:

28

Tu y es presque. Oubliez simplement le point d'exclamation:

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

Résultat:

MATCH

La ifcondition est remplie si grep retourne avec le code de sortie 0 (ce qui signifie une correspondance). Le !point d'exclamation annulera cela.

Guido
la source
5

Puisque vous utilisez déjà bash, vous pouvez le garder interne à bash:

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

Exemples de cycles:

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


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

Ce n'est pas une réponse à votre question, mais quelques suggestions d'un collègue scripteur:

  • Utilisez $()au lieu de backticks, ne les utilisez pas les deux
  • Retrait des ifinstructions conditionnelles
  • Supprimer l'utilisation inutile de $()

La cohérence et des règles simples vous aideront à déboguer et à maintenir des scripts à long terme ...

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