web-dev-qa-db-fra.com

Utilisation de grep dans une instruction conditionnelle dans bash

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.

Emprunter du code de 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 l'instruction if. Si je comprends bien, le -q sur la commande grep fournira un code de sortie pour l'instruction if. Cependant, je n'arrive pas à le faire fonctionner. Où ai-je mal tourné?

24

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 condition if est remplie si grep retourne avec le code de sortie 0 (ce qui signifie une correspondance). Le ! le point d'exclamation annulera cela.

32
Guido

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
5
Jeff Schaller

C'est pas une réponse à votre question, mais quelques suggestions d'un autre scripteur:

  • Utilisez $() au lieu de backticks, ne les utilisez pas tous les deux
  • Indentation des instructions conditionnelles if
  • Supprimez 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
3
Vikyboss