Bash koşullu ifadesinde grep kullanma


22

Bash dilinde senaryo yazma konusunda hala çok yeniyim ve sadece temel şeyler olacağını düşündüğüm birkaçını deniyorum. Ubuntu 14.04 çalıştıran sunucumdan güncelleştirilen DDNS'yi çalıştırmak istiyorum.

Dnsimple bazı kod ödünç almak, bu şimdiye kadar var:

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

Fikir, bir cronjob kullanarak çalıştığım her 5 dakikada bir çalışıyor olmasıdır. Daha sonra durumun "200" veya diğer olup olmadığını görmek için kıvrımın çıkışını kontrol etmek istiyorum. Başka bir şeyse, çıktıyı bir dosyaya kaydetmek istiyorum.

Çalışamadığım ififade. Anladığım kadarıyla -q, grepkomutta ifade için bir çıkış kodu sağlanacaktır if. Ancak çalışmasını sağlayamıyorum. Nerede yanlış yaptım?


ifÇeki kaldırırsanız ve günlük dosyasına her zaman yankı verirseniz komut dosyanız çalışır mı ? dnssimple daha $LOGINönce gösterir $TOKEN, ancak bunu kaçırıyorsunuz. Belki de bu durumun başarısız olmasına neden olur?
Mikel

1
Biraz değiştirdim. Değişken DNSimple-Domain-Tokengerektirmeyen bir kullanıyorum LOGIN.
CircularRecursion

Eğer sen olsaydım, bunu sadece internet ağ arayüzü cron'dan her 5 dakikada bir yükseldiğinde çalıştırırdım. veya en azından, "$ IP" yi bir dosyada (belki de /var/tmp/icanhazip) ve son çalıştırmadan bu yana değişmediyse, exit 0başka bir şey yapmadan önbelleğe alın . DDNS girişinizi her 5 dakikada bir güncellemeniz gerekmez, yalnızca IP adresiniz değiştiğinde.
cas

İyi fikir - Bunu eklemek için çalışacağım.
CircularRecursion

Yanıtlar:


28

Neredeyse bitti. Sadece ünlem işaretini atlayın:

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

Sonuç:

MATCH

ifDurum çıkış kodu 0 (bir eşleşme anlamına gelir) ile grep döner yerine getirilir. !Ünlem işareti bu boşa çıkaracak.


5

Zaten bash kullandığınız için, bash için dahili tutabilirsiniz:

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

Örnek çalışmalar:

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


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

3

Bu, sorunuzun yanıtı değil , diğer bir betikten birkaç öneri:

  • $()Ters tırnak yerine kullanın , ikisini de kullanmayın
  • Koşullu ififadeleri girintileme
  • Gereksiz kullanımını kaldırın $()

Tutarlılık ve basit kurallar, komut dosyalarını uzun vadede hata ayıklamanıza ve korumanıza yardımcı olur ...

#!/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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.