ใช้ grep ในคำสั่งเงื่อนไขในทุบตี


22

ฉันยังใหม่ต่อการเขียนสคริปต์ในการทุบตีและลองทำในสิ่งที่ฉันคิดว่าจะเป็นสิ่งพื้นฐาน ฉันต้องการเรียกใช้ DDNS ที่อัปเดตจากเซิร์ฟเวอร์ของฉันที่ใช้ Ubuntu 14.04

ยืมรหัสจาก 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 ฉันต้องการตรวจสอบผลลัพธ์ของ curl เพื่อดูว่าสถานะเป็น "200" หรืออื่น ๆ หากเป็นอย่างอื่นฉันต้องการบันทึกผลลัพธ์ไปยังไฟล์

สิ่งที่ฉันไม่สามารถทำงานได้คือifแถลงการณ์ ตามที่ฉันเข้าใจแล้วคำสั่ง-qon grepจะจัดเตรียมโค้ดออกสำหรับifคำสั่ง อย่างไรก็ตามฉันไม่สามารถทำงานได้ ฉันไปผิดที่ไหน


สคริปต์ของคุณใช้งานได้ไหมถ้าคุณลบการifตรวจสอบและสะท้อนไปยังไฟล์บันทึกทุกครั้งหรือไม่ dnssimpleแสดง$LOGINก่อนหน้า$TOKENนี้ แต่คุณพลาดไป บางทีนั่นอาจทำให้สิ่งต่าง ๆ ล้มเหลว
มิเคล

1
ฉันแก้ไขมันเล็กน้อย ฉันใช้สิ่งDNSimple-Domain-Tokenที่ไม่ต้องการLOGINตัวแปร
CircularRecursion

ถ้าฉันเป็นคุณฉันจะเรียกใช้สิ่งนี้ก็ต่อเมื่ออินเทอร์เฟซเครือข่ายอินเทอร์เน็ตสูงขึ้นทุก ๆ 5 นาทีจาก cron หรืออย่างน้อยแคช "$ IP" ในไฟล์บางแห่ง (อาจ/var/tmp/icanhazip) และถ้ามันไม่ได้เปลี่ยนไปจากการใช้งานครั้งสุดท้ายexit 0ก่อนที่จะทำอะไรอย่างอื่น คุณไม่จำเป็นต้องอัปเดตรายการ DDNS ของคุณทุก ๆ 5 นาทีเฉพาะเมื่อที่อยู่ IP ของคุณเปลี่ยนไป
cas

ความคิดที่ดี - ฉันจะพยายามเพิ่มสิ่งนั้น
CircularRecursion

คำตอบ:


28

คุณเกือบจะอยู่ที่นั่น เพียงละเว้นเครื่องหมายอัศเจรีย์:

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

ผลลัพธ์:

MATCH

ifสภาพเป็นจริงถ้าผลตอบแทน grep ด้วยรหัส 0 ออก (ซึ่งหมายถึงการแข่งขัน) !เครื่องหมายอัศเจรีย์จะลบล้างนี้


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

นี่ไม่ใช่คำตอบสำหรับคำถามของคุณ แต่มีข้อเสนอแนะเล็กน้อยจากสแครปเตอร์เพื่อน:

  • ใช้$()แทน backticks อย่าใช้ทั้งสองอย่าง
  • เงื่อนไขเยื้อง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.