ตรวจสอบว่าเอาต์พุตของคำสั่งมีสตริงที่แน่นอนในเชลล์สคริปต์หรือไม่


117

ฉันกำลังเขียนเชลล์สคริปต์และฉันกำลังพยายามตรวจสอบว่าผลลัพธ์ของคำสั่งมีสตริงที่แน่นอนหรือไม่ ฉันคิดว่าฉันอาจต้องใช้ grep แต่ฉันไม่แน่ใจว่าจะทำอย่างไร มีใครรู้บ้าง?


คำสั่งต้องทำงานต่อไปหลังจากสร้างสตริงเอาต์พุตที่คุณกำลังมองหาหรือสามารถปิดได้ทันทีในเวลานั้น? (สองคำตอบของคุณแตกต่างกันในแง่ของความหมายในแง่นี้)
Charles Duffy

คำตอบ:


97

ทดสอบค่าส่งคืนของ grep:

./somecommand | grep 'string' &> /dev/null
if [ $? == 0 ]; then
   echo "matched"
fi

ซึ่งทำโดยสำนวนดังนี้:

if ./somecommand | grep -q 'string'; then
   echo "matched"
fi

และนอกจากนี้ยังมี:

./somecommand | grep -q 'string' && echo 'matched'

2
รหัสนี้ใช้ไม่ได้กับเชลล์ POSIX ทั้งหมด: มาตรฐาน POSIX กำหนด=ให้เป็นตัวดำเนินการเปรียบเทียบเท่านั้นไม่ใช่==; ดูpubs.opengroup.org/onlinepubs/9699919799/utilities/test.html
Charles Duffy

4
นอกจากนี้ยังgrep 'string' &>/dev/nullเป็นทั้งที่ไม่ใช่ POSIX สอดคล้องและช้ามากในการดำเนินการ (ถ้าปรากฏขึ้นในช่วงต้นกระแสออกยาวกว่า)string grep -q string[มีข้อแม้คือถ้าคุณต้องการให้แน่ใจว่าsomecommandจะทำงานต่อไปแม้จะปล่อยออกมาstringแล้วก็ตามซึ่งในกรณีนี้การใช้grep -q- โดยการปิด stdin และออกหลังจากเห็นอินสแตนซ์แรกstring- สามารถต่อต้านได้] (Re: "non-POSIX-compliant" &>เป็นส่วนขยาย - ดูที่pubs.opengroup.org/onlinepubs/009695399/utilities/…อธิบายการสนับสนุนการเปลี่ยนเส้นทางที่ได้รับคำสั่ง POSIX)
Charles Duffy

จะช่วยได้ถ้ามีการอธิบายว่าเหตุใดจึงทำงาน / สิ่งที่แต่ละพารามิเตอร์ทำเพื่อกระตุ้นให้เข้าใจไวยากรณ์อย่าง
เต็มที่

158

การทดสอบ$?เป็นการต่อต้านรูปแบบ

if ./somecommand | grep -q 'string'; then
  echo "matched"
fi

หากมีโอกาสเพียงใดที่คุณต้องการทดสอบสตริงคงที่ให้เพิ่มตัวเลือกFและx : grep -Fxq Fย่อมาจากคงที่ (ไม่ตีความ) และxสำหรับทั้งบรรทัด
Erdal G.

4
ทำไมการทดสอบถึง$?ต่อต้านรูปแบบ?
Vitaly Zdanevich

1
@VitalyZdanevich ฉันคิดว่าเพราะมันไม่แข็งแกร่งกับการทำงานพร้อมกัน
Konrad Reiche

@VitalyZdanevich สำหรับหนึ่งการทดสอบ$?ไม่ได้ตั้งค่าคำสั่งก่อนหน้านี้เป็น "ตรวจสอบ" สำหรับวัตถุประสงค์ของset -eหรือERRกับดักดังนั้นโปรแกรมของคุณจึงสามารถออกในกรณีที่คุณต้องการให้ส่งคืนเส้นทางโดยเจตนา - เท็จในภายหลัง อีกประการหนึ่ง$?คือสภาวะโลกที่ผันผวน - มันเป็นเรื่องง่ายที่จะทิ้งคุณค่าของมันไปโดยไม่ได้ตั้งใจ ตัวอย่างเช่นถ้าคุณเพิ่มสายของการเข้าสู่ระบบเช่นecho "Exit status is $?"ค่าใหม่ในการกลายเป็นสถานะออกจาก$? echo
Charles Duffy

6

อีกทางเลือกหนึ่งคือตรวจสอบการจับคู่นิพจน์ทั่วไปในเอาต์พุตคำสั่ง

ตัวอย่างเช่น:

[[ "$(./somecommand)" =~ "sub string" ]] && echo "Output includes 'sub string'"

1

เชลล์สคริปต์เงื่อนไข if / else ที่สะอาด:

if ./somecommand | grep -q 'some_string'; then
  echo "exists"
else
  echo "doesn't exist"
fi
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.