ฉันจะใช้การเปรียบเทียบ grep ไฟล์ใน bash if / else ได้อย่างไร


138

เมื่อเซิร์ฟเวอร์ของเราเกิดขึ้นเราจำเป็นต้องตรวจสอบไฟล์เพื่อดูว่ามีการกำหนดค่าเซิร์ฟเวอร์อย่างไร

เราต้องการค้นหาสตริงต่อไปนี้ในไฟล์ /etc/aws/hosts.conf ของเรา:

MYSQL_ROLE=master

จากนั้นเราต้องการทดสอบว่าสตริงนั้นมีอยู่หรือไม่และใช้คำสั่ง if / else เพื่อรันหนึ่งในสองตัวเลือกขึ้นอยู่กับว่าสตริงนั้นมีอยู่หรือไม่

ไวยากรณ์ BASH ของคำสั่ง if คืออะไร

if [ ????? ]; then
  #do one thing
else
  #do another thing
fi

คำตอบ:


205

จากgrep --helpแต่ยังเห็นgrep คน :

สถานะการออกคือ 0 หากมีการเลือกบรรทัดใด ๆ 1 มิฉะนั้น; หากมีข้อผิดพลาดเกิดขึ้นและไม่ได้ระบุ -q สถานะการออกคือ 2

if grep --quiet MYSQL_ROLE=master /etc/aws/hosts.conf; then
  echo exists
else
  echo not found
fi

คุณอาจต้องการใช้ regex ที่เฉพาะเจาะจงมากขึ้นเช่น ^MYSQL_ROLE=master$เพื่อหลีกเลี่ยงสตริงนั้นในความคิดเห็นชื่อที่เริ่มต้นด้วย "master" เป็นต้น

สิ่งนี้ได้ผลเพราะถ้าใช้คำสั่งและเรียกใช้และใช้ค่าส่งคืนของคำสั่งนั้นเพื่อตัดสินใจว่าจะดำเนินการต่อไปอย่างไรโดยไม่มีความหมายที่เป็นศูนย์และที่ไม่เป็นศูนย์หมายถึงความผิดที่เป็นเท็จ และตรงข้ามของภาษาเช่น C


> ที่มีค่าศูนย์หมายถึงจริงและไม่เป็นศูนย์หมายถึงเท็จ - เช่นเดียวกับที่โค้ดส่งคืนอื่นถูกตีความโดยเชลล์และตรงกันข้ามกับภาษาเช่น C แต่ทำไมตรงกันข้าม ....
kchoi

เพราะโดยทั่วไปจะมีการตีความศูนย์ว่า "ไม่มีข้อผิดพลาด" ในขณะที่สิ่งอื่นหมายถึง "ข้อผิดพลาดบางอย่าง" ถ้าสมมติว่าเราต้องการทราบว่าคำสั่งเสร็จสมบูรณ์หรือไม่
timelmer


23

โปรดทราบว่าสำหรับPIPEการเป็นคำสั่งหรือลำดับของคำสั่งแล้ว:

if PIPE ; then
  # do one thing if PIPE returned with zero status ($?=0)
else 
  # do another thing if PIPE returned with non-zero status ($?!=0), e.g. error
fi 

สำหรับบันทึกที่[ expr ]เป็นเปลือก builtin test exprชวเลข

เนื่องจากgrepส่งกลับด้วยสถานะ 0 ในกรณีของการจับคู่และสถานะที่ไม่ใช่ศูนย์ในกรณีที่ไม่มีการจับคู่คุณสามารถใช้:

if grep -lq '^MYSQL_ROLE=master' ; then 
  # do one thing 
else 
  # do another thing
fi 

โปรดสังเกตว่าการใช้งาน-lที่มีความสำคัญเกี่ยวกับไฟล์ที่มีอย่างน้อยหนึ่งการแข่งขัน (เพื่อให้grepส่งคืนทันทีที่พบการแข่งขันหนึ่งโดยไม่จำเป็นต้องแยกวิเคราะห์ไฟล์อินพุตต่อไปโดยไม่จำเป็น)

บนแพลตฟอร์มบางส่วน[ expr ]ไม่ builtin แต่ปฏิบัติการจริง/bin/[(ซึ่งอาร์กิวเมนต์สุดท้ายจะเป็น]) ซึ่งเป็นเหตุผลที่[ expr ]ควรมีช่องว่างรอบวงเล็บและทำไมมันจะต้องตามมาด้วยการเป็นหนึ่งในตัวคั่นรายการคำสั่ง ( ;, &&, ||, |, &ขึ้นบรรทัดใหม่)


4
-lมีการซ้ำซ้อนgrepส่งคืนทันทีเมื่อพบการแข่งขันใด ๆ กับ-q
Reinstate Monica Please

3

เพียงใช้ทุบตี

while read -r line
do
  case "$line" in
    *MYSQL_ROLE=master*)
       echo "do your stuff";;
    *) echo "doesn't exist";;      
  esac
done <"/etc/aws/hosts.conf"
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.