มีวิธีการเขียนโครงสร้างคำสั่งอีกครั้ง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 || CD
sh:)
Aอยู่ภายใน subshell นี้ยังรวมถึงA.)
คุณสามารถเขียนสิ่งนี้เป็น
if A; then B; else C; fi | D
คุณบอกว่าคุณต้องการที่จะทำงานอย่างใดอย่างหนึ่งBหรือCแต่A && B || Cไม่ประสบความสำเร็จ หากAประสบความสำเร็จ แต่วิ่งและล้มเหลวก็จะดำเนินการBC
หมายเหตุ 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 ล้มเหลว