ฉันจะแยกกระบวนการที่ไม่ตายเมื่อเชลล์ออกได้อย่างไร


31

ถ้าฉันใช้ emacs จากเปลือก:

$ emacs foo &

แล้วฆ่าเปลือกหอยนั้น emacs ก็ตาย

ฉันจะรันคำสั่งเพื่อที่จะไม่ตายเมื่อเชลล์ตายได้อย่างไร

ฉันพบการอ้างอิงถึง nohup แต่ดูเหมือนจะไม่ช่วย:

$ nohup emacs foo &

ยังคงฆ่า emacs เมื่อกระสุนตาย

คำตอบ:


13

คุณไม่ต้องพูดถึงว่านี่เป็นแอพ X หรือแอพคอนโซล

หากเป็นแอปคอนโซลแน่นอนว่าต้องปิด คุณกำจัดมันเป็นอินพุต / เอาท์พุตยิ่งเทคนิค (หลอก) tty มันเป็นบน มันไม่น่าเป็นไปได้อย่างมากนี่คือสิ่งที่คุณหมายถึงดังนั้นสมมติว่าคุณกำลังพูดถึงแอพ X

nohupควรทำงานไม่แน่ใจว่าทำไมมันไม่ เมื่อเชลล์ปิดมันจะส่งSIGHUPไปยังกระบวนการทั้งหมดในกลุ่มกระบวนการ nohup บอกให้คำสั่งละเว้น SIGHUP

คุณยังสามารถลอง setsid ซึ่งตัดการเชื่อมต่อกระบวนการจากกลุ่มกระบวนการ

alias emacs='setsid emacs'

หรือเพิ่มdisownหลังจาก&


อางานที่ยอดเยี่ยม ขออภัยที่ยังไม่ชัดเจน ใช่ฉันหมายถึงแอพ X ที่ไม่ได้ทำงานในเปลือก โดยทั่วไปฉันต้องการเริ่มต้น emacs (หรือกระบวนการอื่น ๆ ) จากเชลล์ แต่ฉันไม่ต้องการให้เชื่อมโยงกับเชลล์ ฉันเพิ่งเริ่มต้นที่นั่นเพื่อความสะดวก
sligocki

41

วิธีที่น่าเชื่อถือที่สุดดูเหมือนจะเป็น:

(setsid emacs &)

สิ่งนี้ใช้( &)เพื่อแยกเป็นแบ็คกราวด์และsetsidแยกออกจากการควบคุม tty

คุณสามารถใส่สิ่งนี้ในฟังก์ชั่นเชลล์

fork() { (setsid "$@" &); }

fork emacs

ความเป็นไปได้คือ:

  • disownคำสั่ง builtin:

    emacs &
    disown $!
    

    &ทำหน้าที่เป็นตัวคั่นคำสั่งและdisownจะใช้ค่าเริ่มต้นกับงานล่าสุดดังนั้นสิ่งนี้สามารถย่อให้เป็น:

    emacs & disown
    
  • สองครั้งfork():

    (emacs &)
    

    คำสั่งในวงเล็บ( )ถูกรันในกระบวนการเชลล์ที่แยกต่างหาก

  • setsidตามที่แนะนำโดย Rich อาจเป็นตัวเลือกที่ดีที่สุดเนื่องจากไม่สามารถควบคุม TTY ของกระบวนการได้โดยสร้างเซสชันใหม่:

    setsid emacs
    

    อย่างไรก็ตามมันก็เป็นสิ่งที่คาดเดาไม่ได้เช่นกัน - มันจะfork()เป็นแบ็คกราวน์ถ้ามันเป็นหัวหน้าของกลุ่มกระบวนการ (ซึ่งจะไม่เกิดขึ้นหากsetsidใช้ในshสคริปต์ตัวอย่างเช่นในโอกาสเช่นนี้มันจะทนต่อ Ctrl- เท่านั้น ซี)


ที่ดี! ทั้งหมดนี้ใช้ได้กับฉัน ยินดีที่ได้มีเครื่องมือเพิ่มเติมในคลังแสงของฉัน
sligocki

หืม ... จะ(exec emacs)ทำงานอย่างไร
Hello71

@Hello: (emacs)มันจะไม่แตกต่างจาก หาก subshell จะได้รับคำสั่งเดียวที่จะบอกเป็นนัยอย่างน้อยในกรณีของexec bashเช่นเดียวกับเมื่อเทียบกับbash -c 'foo' bash -c 'exec foo'( แต่โปรดทราบว่า emacs ตัวเองอาจจะถูกถอดจากสถานี.. gvim ตัวอย่างเช่นทำอย่างนี้มันจะดีกว่าในการทดสอบด้วยโปรแกรมที่มีพฤติกรรมเป็นที่รู้จัก)
grawity

ยอดเยี่ยมในการเรียนรู้เทคนิค double-fork; ขอบคุณ!
Dave Abrahams

พบสิ่งนี้ในขณะที่หมุนรอบเพื่อแก้ไขปัญหาของฉันเอง (setsid emacs &) ได้ผลสำหรับฉัน ขอบคุณสำหรับคำตอบที่เขียนดี
Paulb

5

ตรวจสอบการตั้งค่าเปลือกของคุณ นอกจากนี้คุณยังสามารถลองหน้าจอnohupแทน


หน้าจออนุญาตให้คุณกลับเข้าสู่กระบวนการในภายหลังด้วยscreen -rหากคุณใช้Ctrl-A Ctrl-Dเพื่อยกเลิกการเชื่อมต่อก่อนออกจากระบบ
Broam

นี่เป็นจุดที่ดีมาก ฉันต้องการสิ่งที่ตรงกันข้ามนั่นคือการฟอร์คเซลล์ย่อยและดำเนินงานอื่น ๆ โดยไม่ต้องรอให้เสร็จ แต่ก็screen -d -m sh -c "{do stuff } exit"มีเหตุผลมากกว่า
Nemo
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.