ตัวดำเนินการ“ และ” สำหรับคำสั่ง“ if” ใน Bash


168

ฉันกำลังพยายามสร้างสคริปต์ Bash แบบง่าย ๆ เพื่อตรวจสอบว่าเว็บไซต์ดังกล่าวขัดข้องและด้วยเหตุผลบางอย่าง "และ" โอเปอเรเตอร์ไม่ทำงาน:

#!/usr/bin/env bash

WEBSITE=domain.com
SUBJECT="$WEBSITE DOWN!"
EMAILID="an@email.com"
STATUS=$(curl -sI $WEBSITE | awk '/HTTP\/1.1/ { print $2 }')
STRING=$(curl -s $WEBSITE | grep -o "string_to_search")
VALUE="string_to_search"

if [ $STATUS -ne 200 ] && [[ "$STRING" != "$VALUE" ]]; then
    echo "Website: $WEBSITE is down, status code: '$STATUS' - $(date)" | mail -s "$SUBJECT" $EMAILID
fi

ตัวดำเนินการ "-a" ยังใช้งานไม่ได้:

if [ $STATUS -ne 200 ] -a [[ "$STRING" != "$VALUE" ]]

คุณสามารถกรุณาแนะนำเมื่อใช้:

  • วงเล็บเหลี่ยมเดี่ยวและคู่
  • วงเล็บ

?


3
คุณช่วยให้แม่นยำกว่านี้กับสิ่งที่ "ไม่ทำงาน" ได้ไหม? คุณมีข้อความแสดงข้อผิดพลาดเฉพาะหรือไม่เพียงให้ผลลัพธ์ที่คาดหวัง
Julien Vivenot

จริง ๆ แล้วฉันได้รับ "ผู้ดำเนินการที่ไม่คาดหวัง" ดังนั้นดูเหมือนว่าข้อความช่วย
HTF

-aมีความซ้ำซ้อน เมื่อนำมาใช้กับรูปแบบบอร์นเปลือกtestคำสั่งอาคาที่มันหมายถึง[ andเมื่อใช้เป็นนิพจน์เงื่อนไขก็เป็นการทดสอบเพื่อดูว่ามีไฟล์อยู่หรือไม่ ใช่มันสับสนหลีกเลี่ยงที่ดีที่สุด
cdarke

คำตอบ:


254

สิ่งที่คุณควรทำงานยกเว้นว่า${STATUS}จะว่างเปล่า มันอาจจะดีกว่าที่จะทำ:

if ! [ "${STATUS}" -eq 200 ] 2> /dev/null && [ "${STRING}" != "${VALUE}" ]; then

หรือ

if [ "${STATUS}" != 200 ] && [ "${STRING}" != "${VALUE}" ]; then

เป็นการยากที่จะบอกว่าเนื่องจากคุณไม่ได้แสดงให้เราเห็นอย่างชัดเจนว่าสคริปต์ของคุณเกิดอะไรขึ้น

ความเห็นส่วนตัว: [[ไม่เคยใช้ มันระงับข้อความแสดงข้อผิดพลาดที่สำคัญและไม่สามารถพกพาไปยังกระสุนที่แตกต่าง


2
ถ้าSTATUSเป็นที่ว่างเปล่ารหัสจาก @HTF -ne: unary operator expectedจะได้ล้มเหลวใน ในกรณีของคุณมันจะล้มเหลวinteger expression expectedใช่มั้ย
Julien Vivenot

1
ฉันเข้าใจ. แต่คุณเน้นปัญหาที่$STATUSอาจว่างเปล่าและแนะนำวิธีแก้ปัญหา (อ้างถึง) วิธีการแก้ปัญหาของคุณยังคงล้มเหลวด้วยความว่างเปล่าSTATUSนั่นคือทั้งหมดที่ฉันหมายถึง
Julien Vivenot

1
@jvivenot คุณมีประเด็น (การตอบสนองต่อความคิดเห็นของคุณถูกสร้างขึ้นก่อนที่คุณจะแก้ไขความคิดเห็นของคุณเมื่อความคิดเห็นของคุณเพียงแค่อ่าน "รหัส ... จะล้มเหลว" วิธีแก้ปัญหาง่าย ๆ คือการใช้${STATUS:-0"จะแก้ไขได้
William Pursell

ขออภัยการแก้ไขของคุณยังไม่ทำงาน ตัวอย่างเช่น: STATUS=; [ $STATUS -ne 13 ] 2>/dev/null && echo fooไม่ส่งออกfooถึงแม้ว่ามันควรจะ (ว่างเปล่าแตกต่างจาก 13) สิ่งที่คุณแนะนำครั้งแรก${STATUS:-0}ดูดีกว่ามาก
Julien Vivenot

@ jvivenot การใช้${STATUS:-0}จะล้มเหลวหากSTATUS=fooแต่ใช้! [ "$STATUS" -eq 200 ] 2> /dev/null && echo fooงานได้ IMO จะดีกว่าที่จะหลีกเลี่ยง-eqและการใช้งาน!=แม้ว่า
วิลเลียม Pursell

28

ลองสิ่งนี้:

if [ $STATUS -ne 200 -a "$STRING" != "$VALUE" ]; then

ทำงานให้ฉัน ฉันคิดว่าอาจมีมากกว่าหนึ่งวิธี แต่ตอนนี้ฉันพอใจกับสิ่งนี้แล้ว
Kushal Ashok

27

ลองสิ่งนี้:

if [ ${STATUS} -ne 100 -a "${STRING}" = "${VALUE}" ]

หรือ

if [ ${STATUS} -ne 100 ] && [ "${STRING}" = "${VALUE}" ]

บวกสำหรับตัวอย่างที่สะอาด
Pawel Cioch

12

อ้างถึง:

ตัวดำเนินการ "-a" ยังใช้งานไม่ได้:

if [$ STATUS -ne 200] -a [["$ STRING"! = "$ VALUE"]]

สำหรับคำอธิบายที่ละเอียดยิ่งขึ้น: [และ]ไม่ใช่คำที่สงวนไว้ของ Bash ifคำหลักแนะนำเงื่อนไขที่จะได้รับการประเมินโดยงาน (เงื่อนไขเป็นจริงถ้าค่าตอบแทนของงานเป็น0หรือเท็จอย่างอื่น)

สำหรับการทดสอบเล็กน้อยมีtestโปรแกรม ( man test)

ในขณะที่บางคนพบบรรทัดเช่นif test -f filename; then foo bar; fiฯลฯ ที่น่ารำคาญในระบบส่วนใหญ่คุณจะพบโปรแกรมที่เรียกว่า[ซึ่งอันที่จริงแล้วเป็นเพียง symlink ของtestโปรแกรม เมื่อtestเรียกว่าเป็น[คุณจะต้องเพิ่ม]เป็นอาร์กิวเมนต์ตำแหน่งสุดท้าย

ดังนั้นif test -f filenameเป็นพื้นเดียวกัน (ในแง่ของกระบวนการกระบอกไม้ไผ่) if [ -f filename ]เช่น ในทั้งสองกรณีtestโปรแกรมจะเริ่มทำงานและกระบวนการทั้งสองควรทำงานเหมือนกัน

นี่คือข้อผิดพลาดของคุณ: if [ $STATUS -ne 200 ] -a [[ "$STRING" != "$VALUE" ]]จะแยกif+ งานบางงานเป็นทุกอย่างยกเว้นงานของifตัวเอง งานเป็นเพียงคำสั่งง่ายๆ (Bash พูดถึงบางสิ่งบางอย่างซึ่งส่งผลให้เกิดกระบวนการเดียว) ซึ่งหมายถึงคำแรก ( [) คือคำสั่งและส่วนที่เหลือจะเป็นอาร์กิวเมนต์ตำแหน่ง มีข้อโต้แย้งที่เหลือหลังจากที่ครั้งแรกที่มี]

นอกจากนี้ไม่ใช่[[เป็นคำหลักของ Bash แต่ในกรณีนี้จะมีการแยกวิเคราะห์เป็นอาร์กิวเมนต์คำสั่งปกติเท่านั้นเนื่องจากไม่ใช่คำสั่งด้านหน้า

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.