ฉันจะใช้ค่าจากไพพ์ในโปรแกรมทดสอบได้อย่างไร


10
wc -l | test -eq 1

มันใช้งานไม่ได้ ฉันต้องการเปรียบเทียบผลลัพธ์ของ wc กับค่า 1 ฉันจะทำอย่างไร

คำตอบ:



4

หากคุณกำลังใช้ Bash คุณอาจต้องการศึกษาตัวแปร PIPESTATUS ตามที่ระบุไว้ในคู่มืออ้างอิง Bash PIPESTATUS คือ

ตัวแปรอาร์เรย์ (ดูอาร์เรย์) ที่มีรายการค่าสถานะการออกจากกระบวนการในไปป์ไลน์เบื้องหน้าที่เพิ่งเรียกใช้งานล่าสุด (ซึ่งอาจมีเพียงคำสั่งเดียว)

เราสามารถค้นหารหัสทางออกสำหรับไพพ์ไลน์นี้ด้วย PIPESTATUS:

dmesg | grep -iw 'nnse' | wc -l

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

echo ${PIPESTATUS[@]}
0 1 0

(ในอาร์เรย์ที่มีการทำดัชนีรหัสทางออกข้างต้นจะถูกแสดงด้วย 0 1 และ 2 ในอาร์เรย์เนื่องจากอาร์เรย์จะเริ่มต้นที่ 0 ใน Bash เสมอ)

ที่นี่เราเห็นคำสั่งที่สองคืน 1 และที่เหลือ 0; อย่างไรก็ตามwc -lส่งกลับค่า 0 หากไม่มีการจับคู่เป็นศูนย์ซึ่งไม่ใช่ข้อผิดพลาด ความล้มเหลวแสดงด้วยค่าที่ไม่เป็นศูนย์และมีค่าข้อผิดพลาดอื่น ๆ เช่น 127 ซึ่งไม่พบคำสั่งและยังมีรหัสเพิ่มเติมซึ่งอาจเฉพาะเจาะจงกับโปรแกรมที่เกี่ยวข้อง

หากคุณต้องการดูรหัสทางออกของคำสั่งเฉพาะในไปป์ไลน์คุณสามารถเข้าถึงค่านั้นได้ คำสั่ง grep เป็นคำสั่งที่สองในไปป์ไลน์ข้างต้น แต่เมื่ออาร์เรย์เริ่มต้นจาก 0 เราต้องป้อนหนึ่งรายการ

ดังนั้นหากต้องการทราบรหัสทางออกของคำสั่ง grep ให้รันขั้นตอนข้างต้นอีกครั้ง (เนื่องจากเนื้อหาของ PIPESTATUS จะหมดลงหากคุณเรียกใช้echo ${PIPESTATUS[@]}) จากนั้นเรียกใช้คำสั่งด้านล่างซึ่งจะส่งคืน 1 (รหัสทางออก):

echo ${PIPESTATUS[1]}
1

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

สำหรับตัวอย่างของการใช้งานที่น่าสนใจของตัวแปรอาร์เรย์ PIPESTATUS ให้ดูคำตอบนี้เกี่ยวกับการรวมคำสั่งทุบตีการจัดกลุ่มและสถานะท่อ คุณสามารถทดสอบตัวแปรอาร์เรย์ตามวิธีที่ Gilles แนะนำในความคิดเห็นแม้ว่าคุณจะต้องเรียกใช้ขั้นตอนอีกครั้ง:

dmesg | grep -iw 'nnse' | wc -l
[ ${PIPESTATUS[1]} -eq 1 ] && do_something_here

นี่เป็นเพียงส่วนหนึ่งเนื่องจากฉันไม่ทราบว่าคุณตั้งใจจะใช้สคริปต์ประเภทใด แต่ฉันหวังว่าการรู้เกี่ยวกับ PIPESTATUS อาจเป็นประโยชน์สำหรับคุณ มีตัวแปรอาเรย์ของ Bash มากมายเช่น PIPESTATUS ที่มีประโยชน์มาก ดูคู่มืออ้างอิง Bashสำหรับรายการทั้งหมดและไซต์ Stackexchange อื่น ๆ สำหรับตัวอย่างการใช้งาน



1

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

cat file | wc -l | grep -qE '^\s*1\s*$'

นิพจน์ทั่วไปแบบขยายช่วยให้คุณครอบคลุมหลายกรณีด้วยเทคนิคนี้ สำหรับหัวเราะคิกคักกรณีทดสอบ:

for i in 1 11 '' foo; do 
  if echo $i | grep -qE '^\s*1\s*$'; then 
    echo "'$i' matched"
  else
    echo "'$i' didn't match."
  fi
done

เอาท์พุท:

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