ทำซ้ำเอาต์พุตของคำสั่งใน bash โดยไม่มีเชลล์ย่อย


9

ฉันต้องการวนลูปผลลัพธ์ของคำสั่งโดยไม่สร้าง sub-shell หรือใช้ไฟล์ชั่วคราว

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

sysctl -a 2>/dev/null | grep '\.rp_filter' | while read -r -a RPSTAT ; do

  if [[ "0" != "${RPSTAT[2]}" ]] ; then
    echo >&2 "RP Filter must be disabled on all interfaces!"
    echo >&2 "The RP filter feature is incompatible with policy routing"
    exit 1
  fi
done

ดังนั้นหนึ่งในทางเลือกที่แนะนำคือการใช้คำสั่งเช่นนี้เพื่อหลีกเลี่ยงการ subshell

while read BLAH ; do echo $BLAH; done </root/regularfile

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

while read BLAH ; do echo $BLAH; done <(sysctl -a 2>/dev/null | grep '\.rp_filter')

น่าเสียดายที่การใช้คำสั่งนั้นส่งผลให้เกิดข้อผิดพลาดนี้

-bash: syntax error near unexpected token `<(sysct ...

ฉันสับสนจริงๆเพราะใช้งานได้

cat <(sysctl -a 2>/dev/null | grep '\.rp_filter')

ฉันสามารถบันทึกผลลัพธ์ของคำสั่งนั้นเป็นไฟล์ชั่วคราวและใช้การเปลี่ยนเส้นทางในไฟล์ชั่วคราว แต่ฉันต้องการหลีกเลี่ยงการทำเช่นนั้น

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


คำตอบ:


13

<คุณพลาด ควรจะเป็น:

while read BLAH ; do echo $BLAH; done < <(sysctl -a 2>/dev/null | grep '\.rp_filter')

คิดว่า<(sysctl -a 2>/dev/null | grep '\.rp_filter')เป็นไฟล์


ขอบคุณมาก. เพียงแค่การแก้ไขของฉันฉันสามารถชี้ไปที่หน้า man, help, หรือเว็บเพจได้หรือไม่? ฉันไม่สามารถให้ Google ชี้ให้ฉันเห็นสิ่งใดที่มีประโยชน์ในขณะที่พยายามค้นหาสิ่งนี้
Zoredache

2
Google "กระบวนการทดแทน" เช่นtldp.org/LDP/abs/html/abs-guide.html#PROCESS-SUB
dogbane

ควรสังเกตว่าการแทนที่ <() การใช้ตัวอธิบายไฟล์และในบางระบบปฏิบัติการจะสร้างและใช้ไฟล์ชั่วคราวอย่างโปร่งใส
ewindisch

@Zoredache: เพียงค้นหา<(ในคู่มือทุบตี (ภายใต้“ การทดแทนกระบวนการ”)
Gilles 'หยุดชั่วร้าย'

@ Windows ถ้าเครื่องมือสร้าง tempfile ที่ใช้ได้ฉันไม่ต้องการสร้างด้วยตนเองเมื่อฉันค่อนข้างแน่ใจว่าฉันไม่ต้องการ
Zoredache

0

สำหรับทางเลือกอีกสองสามถ้าใครมาที่นี่อีกครั้ง ...

ขึ้นอยู่กับเชลล์คุณอาจใช้set -o errexitเพื่อให้พาเรนต์เชลล์ออกเมื่อคำสั่ง (รวมถึงเชลล์ย่อย) ออกจากการเป็นศูนย์โดยไม่ต้องติดอยู่ในifบล็อกหรือต่อท้าย&&หรือ||ในขณะที่

/bin/false || echo "ignoring error"

หรือคุณอาจให้ subshell ส่งสัญญาณให้ parent โดยใช้ kill และตัวแปรสภาพแวดล้อม $ PPID หากมี

หรือคุณอาจจะย้ายในขณะที่บล็อกในการทำงานและกลับ 0/1 (อย่างชัดเจนกลับ 0 หลังจากที่ในขณะที่บล็อก) sysctl | grep | function || exitและเพียงแค่ทำท่อของคุณเช่น ฉันคิดว่าคุณสามารถใส่ผลตอบแทนในบล็อกแบบอินไลน์ได้เช่นกัน แต่ฟังก์ชั่นเป็นเพื่อนของคุณ ;)

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