web-dev-qa-db-ja.com

bashの条件ステートメントでgrepを使用する

私はまだbashでのスクリプト作成に非常に慣れていません。 Ubuntu 14.04を実行しているサーバーから更新するDDNSを実行したい。

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

アイデアは、私がcronjobを使用して作業している5分ごとに実行されるということです。次に、curlの出力をチェックして、ステータスが「200」かどうかを確認します。それ以外の場合は、出力をファイルに保存します。

機能しないのはifステートメントです。私が理解しているように、-qgrepコマンドの_は、ifステートメントの終了コードを提供します。しかし、私はそれを動作させるようには思えません。どこが間違っているのですか?

24

あと少しです。感嘆符を省略するだけです。

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

結果:

MATCH

if条件は、grepが終了コード0(一致を意味する)で戻る場合に満たされます。 !感嘆符はこれを否定します。

32
Guido

すでに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
5
Jeff Schaller

これは質問に対する回答ではありませんですが、他のスクリプト作成者からの提案はほとんどありません。

  • バックティックの代わりに$()を使用し、両方を使用しないでください
  • 条件付き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
3
Vikyboss