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


18

私はまだ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

これは5分ごとに実行されるという考え方で、cronjobを使用して作業しています。次に、カールの出力をチェックして、ステータスが「200」またはその他であるかどうかを確認します。それが他の何かである場合、出力をファイルに保存したいと思います。

私が働けないのはif声明です。私の理解では、コマンドの-qon grepifステートメントの終了コードを提供します。しかし、私はそれを機能させることができないようです。どこがおかしいの?


ifチェックを削除し、常にログファイルにエコーする場合、スクリプトは機能しますか? dnssimpleのショー$LOGINの前に$TOKEN、しかし、あなたはそれを逃しています。たぶんそれは物事を失敗させているのでしょうか?
ミケル

1
少し修正しました。私は変数をDNSimple-Domain-Token必要としないを使用していLOGINます。
CircularRecursion

私があなただったら、cronから5分ごとではなく、インターネットネットワークインターフェイスが起動したときにのみ実行します。または、少なくともどこか(おそらく/var/tmp/icanhazip)のファイルに「$ IP」をキャッシュし、最後の実行以降に変更されていない場合は、exit 0他の操作を行う前に。IPアドレスが変更された場合にのみ、5分ごとにDDNSエントリを更新する必要はありません。
cas

良いアイデア-私はそれを追加する作業をします。
CircularRecursion

回答:


24

あなたはほとんどそこにいます。感嘆符を省略するだけです:

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

結果:

MATCH

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


5

すでに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

3

これはあなたの質問への答えでなく、仲間のスクリプト作成者からのいくつかの提案です。

  • 使用$()の代わりに、バッククォートは、それらの両方を使用していません
  • 条件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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.