วิธีทุบตีปฏิบัติต่อ“>> ()”


9

ขณะทำการทดลองกับการเปลี่ยนเส้นทางเอาต์พุตและการทดแทนกระบวนการฉันพบคำสั่งต่อไปนี้และผลลัพธ์ที่ได้:

    me @ elem: ~ $ echo foo>> (cat); แถบสะท้อนเสียง
    บาร์
    me @ elem: ~ $ foo

(ใช่แล้วบรรทัดใหม่ที่ว่างที่สุดจะเป็นเจตนา)

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

ฉันคาดหวังว่ามันจะเขียน foo ให้กับ file descriptor cat อ่านมันและ echo's foo แถบ echo echo ที่สองจากนั้นกลับไปที่ command prompt แต่นั่นไม่ใช่กรณีที่ชัดเจน

ใครช่วยอธิบายหน่อยได้ว่าเกิดอะไรขึ้น?


ฉันอยากจะแนะนำให้ค้นหาคำตอบเกี่ยวกับสิ่งนี้: unix.stackexchange.com/questions/182800/ ......มันอธิบายการเปลี่ยนเส้นทางสองครั้งและจะอธิบายว่าทำไมคุณถึงลงท้ายด้วยผลลัพธ์ที่แตกต่างกัน ทั้ง Muru และ Michael Hormers
ไม่มีเวลา

สำหรับคำถามอย่างชัดเจนว่าทำไมการจัดการกับการส่งออกของการทดแทนกระบวนการปรากฏขึ้นหลังจากที่พรอมต์ (และในบางสถานการณ์ที่ไม่ปรากฏที่ทั้งหมด) ในบางรุ่นของบอร์นอีกครั้งเปลือกดูunix.stackexchange.com/questions/471987
JdeBP

คำตอบ:


9

คุณอาจเห็นการfooแสดงก่อนbarหลังbarหรือแม้กระทั่งหลังจากการแจ้งให้ขึ้นอยู่กับเวลา เพิ่มความล่าช้าเล็กน้อยเพื่อให้ได้เวลาที่สอดคล้องกัน:

$ echo foo > >(sleep 1; cat); echo bar; sleep 2 
bar
foo
$

barปรากฏขึ้นทันทีจากนั้นfooหลังจากหนึ่งวินาทีจากนั้นจะปรากฏพรอมต์ถัดไปหลังจากนั้นอีกหนึ่งวินาที

สิ่งที่เกิดขึ้นคือทุบตีดำเนินการแทนกระบวนการในพื้นหลัง

  1. กระบวนการทุบตีหลักเริ่ม subshell เพื่อดำเนินการsleep 1; catและตั้งค่าไปป์
  2. echo fooหลักรันกระบวนการทุบตี เนื่องจากสิ่งนี้ไม่ได้เติมบัฟเฟอร์ของไปป์echoคำสั่งจึงสิ้นสุดลงโดยไม่มีการบล็อก
  3. echo barหลักรันกระบวนการทุบตี
  4. sleep 2กระบวนการทุบตีหลักเปิดตัวคำสั่ง
  5. ในขณะเดียวกัน subshell ฯ sleep 1จะเปิดคำสั่ง
  6. หลังจากผ่านไปประมาณ 1 วินาทีsleep 1ผลตอบแทนในกระบวนการย่อย catกระบวนการย่อยวิธีการที่จะดำเนินการ
  7. cat คัดลอกอินพุตไปยังเอาต์พุต (ซึ่งแสดงบนหน้าจอ) และส่งคืน
  8. เชลล์ย่อยทำงานของมันเสร็จแล้ว
  9. หลังจากนั้นอีกสองวินาทีsleep 2ผลตอบแทน กระบวนการเชลล์หลักเสร็จสิ้นการดำเนินการและคุณจะเห็นพรอมต์ถัดไป

3

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

( echo foo | cat & )

คุณจะได้รับผลลัพธ์ที่เหมือนกัน (โดยไม่ต้องbar; ฉันจะปล่อยให้มันเป็นแบบฝึกหัด) และด้วยเหตุผลเดียวกัน ในทั้งสองกรณีcatเริ่มต้นเป็นงานพื้นหลัง ในบรรทัดของฉันที่นี่นั่นชัดเจน ในกรณีของการทดแทนกระบวนการมันยังชัดเจน - เป็นกระบวนการแยกต่างหากที่แนบมากับตัวบอกชื่อไฟล์ - แต่อาจไม่ชัดเจน

กระบวนการลูกไม่จำเป็นต้องยุติก่อนที่จะbashพิมพ์พรอมต์ต่อไป และเนื่องจากเอาต์พุตถูกบัฟเฟอร์จึงไม่เอาต์พุตใด ๆ จนกว่าจะถูกยกเลิก ณ จุดนี้ทุบตีเพิ่งพิมพ์$บน stderr และตอนนี้กระบวนการพื้นหลังออกหลังจากพิมพ์fooและขึ้นบรรทัดใหม่

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