มีวิธีการเขียนโครงสร้างคำสั่งอีกครั้งA && B || C | D
เพื่อให้ B หรือ C ถูกไพพ์ลงใน D หรือไม่?
ด้วยคำสั่งปัจจุบันเพียง B หรือทั้ง C และ D จะทำงาน
ตัวอย่างเช่น:
มีวิธีการเขียนโครงสร้างคำสั่งอีกครั้งA && B || C | D
เพื่อให้ B หรือ C ถูกไพพ์ลงใน D หรือไม่?
ด้วยคำสั่งปัจจุบันเพียง B หรือทั้ง C และ D จะทำงาน
ตัวอย่างเช่น:
คำตอบ:
ใช่ในทุบตีคุณสามารถใช้วงเล็บ:
(A && B || C) | D
วิธีนี้การส่งออกของจะได้รับการประปาเข้าA && B || C
D
sh
:)
A
อยู่ภายใน subshell นี้ยังรวมถึงA
.)
คุณสามารถเขียนสิ่งนี้เป็น
if A; then B; else C; fi | D
คุณบอกว่าคุณต้องการที่จะทำงานอย่างใดอย่างหนึ่งB
หรือC
แต่A && B || C
ไม่ประสบความสำเร็จ หากA
ประสบความสำเร็จ แต่วิ่งและล้มเหลวก็จะดำเนินการB
C
หมายเหตุ 1: หากคุณสามารถรับประกันได้ว่าB
จะประสบความสำเร็จและต้องการติดอยู่กับรุ่นสั้น ๆ อยู่เสมอฉันก็ยังคงเลือกใช้
{ A && B || C; } | D
ใน( ... )
ขณะที่หลังบังคับให้สร้างเชลล์ย่อยใหม่โดยไม่จำเป็นซึ่งอาจหรือไม่ได้รับการปรับให้เหมาะสม
หมายเหตุ 2: ทั้งสองรูปแบบสมมติว่าA
ไม่มีผลผลิตซึ่งเป็นจริงในตัวอย่างของคุณ แต่ไม่จำเป็นต้องเป็นเช่นนั้นโดยทั่วไป ที่สามารถหลีกเลี่ยงได้ด้วย
A; if [ "$?" -eq 0 ]; then B; else C; fi | D
{ … }
ไม่ว่าไม่บังคับให้สร้างเชลล์ย่อยเนื่องจากไปป์ ผมสังเกตพฤติกรรมต่อไปนี้: pgrep bash
และpgrep bash | cat
และif true; then pgrep bash; fi
และ{ pgrep bash; }
มีเส้นหนึ่งของการส่งออก; ( pgrep bash; )
และ( pgrep bash; ) | cat
และ{ pgrep bash; } | cat
และif true; then pgrep bash; fi | cat
มีเอาต์พุตสองบรรทัด
... | ...
เป็นสาเหตุให้สร้างเชลล์ย่อยซึ่งไม่สามารถหลีกเลี่ยงได้ ( ... )
อย่างน้อยในทางทฤษฎีทำให้เกิดการสร้างsubshell เพิ่มเติมเพื่อ{ ...; }
หลีกเลี่ยง แต่นั่นคือสิ่งที่ฉันหมายถึงด้วย "อาจหรืออาจไม่ได้รับการปรับปรุงให้ดีที่สุด": เป็นไปได้ว่าในกรณีนี้เชลล์รู้ตัวว่ามันไม่สำคัญ ผลกระทบจะเหมือนกัน
คำตอบยินดีรับถูกต้อง แต่ก็ไม่ได้ครอบคลุมถึงกรณีการใช้งานที่มีศักยภาพที่จะไม่ได้มีการส่งออกของA
เป็น input D
ของ เพื่อให้บรรลุว่าคุณจะต้องมีการเปลี่ยนเส้นทางสตรีมA
ขึ้นอยู่กับความต้องการของคุณ
หากคุณต้องการยกเลิกผลลัพธ์ของA
อย่างไรก็ตาม:
{ A >/dev/null && B || C; } | D
หากคุณต้องการเห็นผลลัพธ์ของA
บนเทอร์มินัล:
{ A >/dev/tty && B || C; } | D
หากคุณต้องการผลลัพธ์A
เป็นอินพุตของคำสั่งต่อมาE
คุณจะต้องมีกลุ่มคำสั่งเพิ่มเติมและการเปลี่ยนเส้นทางสตรีม:
{ { A >&3 && B || C; } | D; } 3>&1 | E
หากทั้งหมดนี้ดูลึกลับเกินไปสำหรับคุณ (เช่นเดียวกับฉัน) ฉันขอแนะนำให้คุณใช้ตัวแปรเชลล์พิเศษสำหรับสถานะทางออกA
และทำงานกับมัน:
A
if [ $? -eq 0 ]; then
B
else
C
fi |
D
ถ้าคุณต้องการที่จะกระชับมากกว่า แต่ไม่ลึกลับเกินไปฉันแนะนำสิ่งนี้:
A; { [ $? -eq 0 ] && B || C; } | D
(ดูส่วนสุดท้ายของคำตอบของ hvdซึ่งฉันไม่ได้สังเกตเมื่อฉันเขียนคำตอบดั้งเดิม)
A
ออกจากท่อ
A && (B || C) | D
หากคุณไม่ต้องการให้ B, C หรือ D ทำงานเมื่อ A ล้มเหลว