Sử dụng grep trong câu lệnh có điều kiện trong bash


18

Tôi vẫn còn rất mới với kịch bản trong bash, và chỉ thử một vài điều tôi nghĩ sẽ là những điều cơ bản. Tôi muốn chạy DDNS cập nhật từ máy chủ của tôi chạy Ubuntu 14.04.

Mượn một số mã từ dnsimple, đây là những gì tôi có cho đến nay:

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

Ý tưởng là nó chạy cứ sau 5 phút, mà tôi đã làm việc bằng cách sử dụng một cronjob. Sau đó tôi muốn kiểm tra đầu ra của cuộn tròn để xem trạng thái là "200" hay khác. Nếu nó là một cái gì đó khác, thì tôi muốn lưu kết quả đầu ra vào một tập tin.

Những gì tôi không thể làm việc là iftuyên bố. Theo tôi được biết, các -qtrên greplệnh sẽ cung cấp một mã thoát cho iftuyên bố. Tuy nhiên tôi dường như không thể làm cho nó hoạt động. Tôi đã đi sai ở đâu?


Tập lệnh của bạn có hoạt động không nếu bạn loại bỏ ifkiểm tra và luôn lặp lại tệp nhật ký? dnssimple hiển thị $LOGINtrước đó $TOKEN, nhưng bạn đang thiếu điều đó. Có lẽ đó là nguyên nhân khiến mọi thứ thất bại?
Mikel

1
Tôi đã sửa đổi nó một chút. Tôi đang sử dụng một DNSimple-Domain-Tokencái không cần LOGINbiến.
Thông tư

nếu tôi là bạn, tôi chỉ chạy cái này khi giao diện mạng internet tăng lên thay vì cứ sau 5 phút từ cron. hoặc, ít nhất, lưu trữ "$ IP" trong một tệp ở đâu đó (có lẽ /var/tmp/icanhazip) và nếu nó không thay đổi kể từ lần chạy exit 0trước , trước khi làm bất cứ điều gì khác. bạn không cần cập nhật mục nhập DDNS của mình sau mỗi 5 phút, chỉ khi địa chỉ IP của bạn thay đổi.
cas

Ý tưởng tốt - tôi sẽ làm việc để thêm vào đó.
Thông tư

Câu trả lời:


24

Bạn đã gần tới. Chỉ cần bỏ qua dấu chấm than:

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

Kết quả:

MATCH

Điều ifkiện được đáp ứng nếu grep trả về với mã thoát 0 (có nghĩa là khớp). Dấu !chấm than sẽ phủ nhận điều này.


5

Vì bạn đã sử dụng bash, bạn có thể giữ nội bộ cho bash:

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

Chạy mẫu:

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


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

3

Đây không phải là một câu trả lời cho câu hỏi của bạn, nhưng một vài gợi ý từ một người viết kịch bản:

  • Sử dụng $()thay vì backticks, không sử dụng cả hai
  • ifBáo cáo điều kiện thụt lề
  • Loại bỏ việc sử dụng không cần thiết của $()

Quy tắc nhất quán và các quy tắc đơn giản sẽ giúp bạn gỡ lỗi và duy trì các tập lệnh trong một thời gian dài ...

#!/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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.