ใช่bash
เช่นเดียวกับในksh
(ซึ่งเป็นคุณลักษณะที่มาจาก) กระบวนการภายในการทดแทนกระบวนการจะไม่รอ (ก่อนเรียกใช้คำสั่งถัดไปในสคริปต์)
สำหรับ<(...)
อันที่ปกติแล้วก็ดีเหมือนใน:
cmd1 <(cmd2)
เชลล์จะรอcmd1
และcmd1
โดยทั่วไปจะรอcmd2
โดยอาศัยการอ่านจนกว่าจะสิ้นสุดของไฟล์บนไพพ์ที่ถูกทดแทนและโดยทั่วไปจุดสิ้นสุดของไฟล์จะเกิดขึ้นเมื่อcmd2
ตาย นั่นเป็นเหตุผลเดียวกันกับเปลือกหอยหลายคน (ไม่bash
) ไม่รำคาญรอให้ในcmd2
cmd2 | cmd1
สำหรับcmd1 >(cmd2)
อย่างไรก็ตามนั่นไม่ใช่กรณีทั่วไปเนื่องจากเป็นเรื่องcmd2
ปกติที่รออยู่ที่cmd1
นั่นดังนั้นโดยทั่วไปจะออกหลังจาก
ที่ได้รับการแก้ไขในzsh
ที่รออยู่ที่cmd2
นั่น (แต่ไม่ใช่ถ้าคุณเขียนเป็นcmd1 > >(cmd2)
และcmd1
ไม่ได้สร้างขึ้นให้ใช้{cmd1} > >(cmd2)
แทนเอกสาร )
ksh
ไม่ต้องรอเป็นค่าเริ่มต้น แต่ให้คุณรอด้วยwait
builtin (มันทำให้ pid ใช้งานได้$!
แม้ว่ามันจะไม่ช่วยถ้าคุณทำcmd1 >(cmd2) >(cmd3)
)
rc
(ที่มีcmd1 >{cmd2}
ไวยากรณ์) เช่นเดียวกับการksh
ยกเว้นคุณจะได้รับ PIDs $apids
ของทุกกระบวนการพื้นหลังด้วย
es
(พร้อมกับcmd1 >{cmd2}
) รอcmd2
เหมือนในzsh
และรอcmd2
ใน<{cmd2}
การเปลี่ยนเส้นทางกระบวนการ
bash
จะทำให้ pid ของcmd2
(หรือมากกว่าของ subshell ตามที่มันทำงานcmd2
ในกระบวนการลูกของ subshell นั้นแม้ว่ามันจะเป็นคำสั่งสุดท้ายที่นั่น) $!
แต่ก็ไม่ยอมให้คุณรอ
หากคุณจำเป็นต้องใช้bash
คุณสามารถแก้ไขปัญหาได้โดยใช้คำสั่งที่จะรอคำสั่งทั้งสองด้วย:
{ { cmd1 >(cmd2); } 3>&1 >&4 4>&- | cat; } 4>&1
นั่นทำให้ทั้งคู่cmd1
และให้cmd2
fd 3 ของพวกเขาเปิดสู่ท่อ cat
จะรอให้ไฟล์สิ้นสุดที่ปลายอีกด้านหนึ่งดังนั้นโดยทั่วไปจะออกเฉพาะเมื่อทั้งคู่cmd1
และcmd2
ตาย และเชลล์จะรอcat
คำสั่งนั้น คุณสามารถเห็นได้ว่าในฐานะที่เป็นเครือข่ายในการยุติกระบวนการพื้นหลังทั้งหมด (คุณสามารถใช้มันเพื่อสิ่งอื่น ๆ ที่เริ่มต้นในพื้นหลังเช่นเดียวกับ&
coprocs หรือแม้แต่คำสั่งที่พื้นหลังของตัวเองหากพวกเขาไม่ปิดไฟล์ )
โปรดทราบว่าด้วยกระบวนการ subshell ที่สูญเปล่าดังกล่าวข้างต้นมันทำงานได้แม้ว่าcmd2
จะปิด fd 3 แล้ว (โดยปกติคำสั่งจะไม่ทำเช่นนั้น แต่มีบางอย่างที่ชอบsudo
หรือssh
ทำ) ในที่สุดเวอร์ชันในอนาคตbash
อาจทำการปรับให้เหมาะสมเช่นเดียวกับในเชลล์อื่น ๆ จากนั้นคุณต้องมีสิ่งต่อไปนี้:
{ { cmd1 >(sudo cmd2; exit); } 3>&1 >&4 4>&- | cat; } 4>&1
เพื่อให้แน่ใจว่ายังคงมีกระบวนการเชลล์พิเศษที่เปิด fd 3 นั้นรอsudo
คำสั่งนั้น
โปรดทราบว่าcat
จะไม่อ่านอะไรเลย (เนื่องจากกระบวนการไม่ได้เขียนลงใน fd 3) มันมีไว้สำหรับการซิงโครไนซ์เท่านั้น มันจะทำการread()
เรียกระบบเพียงครั้งเดียวที่จะกลับมาโดยไม่มีอะไรสิ้นสุด
คุณสามารถหลีกเลี่ยงการทำงานcat
โดยใช้การทดแทนคำสั่งเพื่อทำการซิงก์ไปป์:
{ unused=$( { cmd1 >(cmd2); } 3>&1 >&4 4>&-); } 4>&1
เวลานี้มันเป็นเปลือกแทนการcat
ที่อ่านจากท่อที่มีส่วนอื่น ๆ เปิดให้บริการใน FD 3 และcmd1
cmd2
เรากำลังใช้การกำหนดตัวแปรเพื่อออกจากสถานะของการอยู่ในที่มีอยู่cmd1
$?
หรือคุณสามารถทำการทดแทนกระบวนการด้วยมือจากนั้นคุณสามารถใช้ระบบของคุณsh
เพื่อที่จะกลายเป็นไวยากรณ์เชลล์มาตรฐาน:
{ cmd1 /dev/fd/3 3>&1 >&4 4>&- | cmd2 4>&-; } 4>&1
แม้ว่าบันทึกย่อตามที่ระบุไว้ก่อนหน้านี้ว่าsh
การใช้งานบางอย่างจะไม่รอcmd1
หลังจากcmd2
เสร็จสิ้น (แม้ว่าจะดีกว่าวิธีอื่น ๆ ) เวลานั้น$?
มีสถานะออกจากcmd2
; แม้ว่าbash
และzsh
ทำให้cmd1
สถานะการออกของพร้อมใช้งานใน${PIPESTATUS[0]}
และ$pipestatus[1]
ตามลำดับ (ดูpipefail
ตัวเลือกในเปลือกบางอย่างเพื่อให้$?
สามารถรายงานความล้มเหลวของคอมโพเนนต์ท่ออื่นที่ไม่ใช่ครั้งสุดท้าย)
โปรดทราบว่าyash
มีปัญหาคล้ายกันกับคุณสมบัติการเปลี่ยนเส้นทางของกระบวนการ cmd1 >(cmd2)
จะเขียนที่cmd1 /dev/fd/3 3>(cmd2)
นั่น แต่cmd2
ไม่ได้รอและคุณไม่สามารถใช้wait
เพื่อรอได้และ pid ของมันไม่ได้ทำให้พร้อมใช้งานใน$!
ตัวแปรเช่นกัน คุณต้องการใช้ arounds bash
การทำงานเช่นเดียวกับ