อะไรคือความแตกต่างระหว่าง
$ nohup foo
และ
$ foo &
และ
$ foo &
$ disown
foo &!ซึ่งควรจะเท่ากับการปฏิเสธมันตั้งแต่เริ่มต้น
foo & disownจะบอกเลิกทันที
setsidและมันเกี่ยวข้องกับdisownและnohup
อะไรคือความแตกต่างระหว่าง
$ nohup foo
และ
$ foo &
และ
$ foo &
$ disown
foo &!ซึ่งควรจะเท่ากับการปฏิเสธมันตั้งแต่เริ่มต้น
foo & disownจะบอกเลิกทันที
setsidและมันเกี่ยวข้องกับdisownและnohup
คำตอบ:
ก่อนอื่นเรามาดูกันว่าจะเกิดอะไรขึ้นถ้าโปรแกรมเริ่มต้นจากเชลล์แบบโต้ตอบ (เชื่อมต่อกับเทอร์มินัล) โดยไม่มี&(และไม่มีการเปลี่ยนทิศทาง) ดังนั้นสมมติว่าคุณเพิ่งพิมพ์foo:
fooถูกสร้างขึ้นSIGHUPมันจะส่ง a SIGHUPไปยังกระบวนการ (ซึ่งโดยปกติจะทำให้กระบวนการยุติ)ทีนี้มาดูกันว่าจะเกิดอะไรขึ้นถ้าคุณใส่โพรเซสในแบ็คกราวน์นั่นคือพิมพ์foo &:
fooถูกสร้างขึ้นjobsและสามารถเข้าถึงได้โดยใช้%n(ซึ่งnเป็นหมายเลขงาน)fgซึ่งในกรณีนี้จะดำเนินต่อไปราวกับว่าคุณไม่ได้ใช้งาน&(และหากหยุดทำงานเนื่องจากพยายามอ่านจากอินพุตมาตรฐานตอนนี้สามารถดำเนินการอ่านจากเทอร์มินัลได้)SIGHUPก็จะส่ง a SIGHUPไปยังกระบวนการ ขึ้นอยู่กับเชลล์และตัวเลือกที่ตั้งค่าไว้สำหรับเชลล์เมื่อยกเลิกเชลล์มันจะส่งSIGHUPกระบวนการไปให้ตอนนี้disownลบงานออกจากรายการงานของเชลล์ดังนั้นจุดย่อยทั้งหมดข้างต้นจึงไม่นำไปใช้เพิ่มเติม (รวมถึงกระบวนการที่ส่งSIGHUPโดยเชลล์) อย่างไรก็ตามโปรดทราบว่ามันยังคงเชื่อมต่อกับเทอร์มินัลดังนั้นหากเทอร์มินัลถูกทำลาย (ซึ่งสามารถเกิดขึ้นได้หากเป็น pty เช่นที่สร้างโดยxtermหรือหรือsshและโปรแกรมควบคุมถูกยกเลิกโดยปิด xterm หรือยกเลิกการเชื่อมต่อSSH ) โปรแกรมจะล้มเหลวทันทีที่พยายามอ่านจากอินพุตมาตรฐานหรือเขียนไปยังเอาต์พุตมาตรฐาน
สิ่งที่nohupไม่อยู่ในมืออื่น ๆ ที่เป็นไปได้อย่างมีประสิทธิภาพแยกกระบวนการจากท่าเรือ:
EOF)nohup.outดังนั้นโปรแกรมจะไม่ล้มเหลวในการเขียนไปยังเอาต์พุตมาตรฐานหากเทอร์มินัลล้มเหลวดังนั้นสิ่งที่กระบวนการเขียนจะไม่สูญหายSIGHUP(เช่นชื่อ)โปรดทราบว่าnohupไม่ไม่เอากระบวนการตั้งแต่การควบคุมงานของเปลือกและยังไม่ได้ใส่ไว้ในพื้นหลัง ( แต่ตั้งแต่เบื้องหน้าnohupงานจะมากหรือน้อยไร้ประโยชน์โดยทั่วไปคุณต้องการใส่มันลงไปในพื้นหลังโดยใช้&) ตัวอย่างเช่นไม่เหมือนกับdisownเชลล์เชลล์จะยังคงบอกคุณเมื่องาน nohup เสร็จสมบูรณ์ (ยกเว้นกรณีที่เชลล์ถูกยกเลิกก่อนแน่นอน)
ดังนั้นเพื่อสรุป:
& วางงานไว้ในพื้นหลังนั่นคือทำให้มันบล็อคในการพยายามอ่านอินพุตและทำให้เชลล์ไม่รอให้เสร็จสมบูรณ์disownลบกระบวนการออกจากการควบคุมงานของเชลล์ แต่ยังคงปล่อยให้เชื่อมต่อกับเทอร์มินัล SIGHUPหนึ่งในผลที่ได้คือว่าเชลล์จะไม่ส่งมัน เห็นได้ชัดว่ามันสามารถใช้ได้กับงานแบ็คกราวน์เท่านั้นเนื่องจากคุณไม่สามารถป้อนได้เมื่อมีการทำงานเบื้องหน้าnohupยกเลิกการเชื่อมต่อกระบวนการจาก terminal, เปลี่ยนเส้นทางการส่งออกไปยังและโล่จากnohup.out SIGHUPหนึ่งในผลกระทบ (ตั้งชื่อหนึ่ง) คือกระบวนการที่จะไม่ได้รับการใด ๆ SIGHUPที่ส่ง มันเป็นอิสระอย่างสมบูรณ์จากการควบคุมงานและในหลักการสามารถใช้สำหรับงานเบื้องหน้าได้ด้วย (แม้ว่ามันจะไม่ได้มีประโยชน์มาก)disown %1และdisown -h %1คืออะไร คนที่สองจะยังคงเป็นงานประจำ (แต่ไม่สนใจสัญญาณ HUP) จนกว่าขั้วจะออก?
(foo&)subshell
การใช้&ทำให้โปรแกรมทำงานในพื้นหลังดังนั้นคุณจะได้รับพรอมต์เชลล์ใหม่แทนที่จะปิดกั้นจนกว่าโปรแกรมจะจบ nohupและdisownไม่เกี่ยวข้องส่วนใหญ่; พวกเขาระงับสัญญาณ SIGHUP (hangup) ดังนั้นโปรแกรมจะไม่ถูกฆ่าโดยอัตโนมัติเมื่อปิดเทอร์มินัลการควบคุม nohupทำสิ่งนี้เมื่อเริ่มงานเป็นครั้งแรก หากคุณไม่ได้nohupงานเมื่อเริ่มต้นคุณสามารถใช้disownเพื่อแก้ไขงานที่กำลังทำงานอยู่ โดยไม่มีข้อโต้แย้งมันแก้ไขงานปัจจุบันซึ่งเป็นงานที่เพิ่งมีพื้นหลัง
nohupและdisownทั้งคู่สามารถพูดเพื่อปราบปรามSIGHUPแต่ในวิธีที่ต่างกัน nohupทำให้โปรแกรมไม่สนใจสัญญาณในตอนแรก (โปรแกรมอาจเปลี่ยนแปลงสิ่งนี้) nohupพยายามจัดเรียงโปรแกรมไม่ให้มีเทอร์มินัลการควบคุมเพื่อที่SIGHUPเคอร์เนลจะไม่ถูกส่งเมื่อปิดเทอร์มินัล disownอยู่ภายในอย่างหมดจดเพื่อเปลือก; มันทำให้เชลล์ไม่ส่งSIGHUPเมื่อมันยกเลิก
disownลบงานออกจากรายการงาน หากคุณไม่ได้ระบุตัวเลือกมันจะลบออกจากรายการงาน อย่างไรก็ตามหากคุณระบุ-hตัวเลือกแต่ละงานจะไม่ถูกลบออกจากตาราง แต่ก็จะทำให้มันเพื่อที่จะไม่ถูกส่งไปทำงานถ้าเปลือกได้รับSIGHUP SIGHUP
&ไม่ได้ให้เทอร์มินัลคุณจะแยกออกstdinจากกระบวนการและทำให้มันทำงานในพื้นหลัง แต่ทั้งสองอย่างstdoutและstderrยังคงแนบกับ tty ปัจจุบัน ซึ่งหมายความว่าคุณอาจได้รับข้อความจากโปรแกรมต่าง ๆ มารวมกันซึ่งอาจน่ารำคาญถ้าคุณทำgimp &และรับข้อผิดพลาด GTK + จำนวนมากในขณะที่พยายามใช้ tty นั้นเพื่อสิ่งอื่น
นี่คือประสบการณ์ของฉันพยายามเรียกใช้ soffice ในพื้นหลังตามคำสั่งไม่สิ้นสุด (เช่นtail) sleep 100สำหรับตัวอย่างนี้ผมจะใช้
#!/bin/bash
/opt/libreoffice4.4/program/soffice -invisible -nofirststartwizard &
sleep 100
ผมเห็น soffice บันทึก / โดยการกดCtrl- Cหยุด soffice
#!/bin/bash
nohup /opt/libreoffice4.4/program/soffice -invisible -nofirststartwizard &
sleep 100
ฉันไม่เห็น soffice บันทึก / โดยการกดCtrl- Cหยุด soffice
#!/bin/bash
/opt/libreoffice4.4/program/soffice -invisible -nofirststartwizard & disown
sleep 100
ผมเห็น soffice บันทึก / โดยการกดCtrl- Cหยุด soffice
#!/bin/bash
setsid /opt/libreoffice4.4/program/soffice -invisible -nofirststartwizard &
sleep 100
ฉันเห็นไฟล์บันทึก soffice / โดยกดCtrl- CSoffice ไม่ได้หยุด
เพื่อประหยัดพื้นที่:
nohup setsid ..: ไม่แสดง logs / soffice ไม่หยุดบนCtrl-C
nohupมี& disownที่สิ้นสุด: ไม่แสดง logs / soffice หยุดบนCtrl-C
nohup ⟨command⟩ & disown Ctrl+C
sofficeหรือยัง sofficeคำสั่งดูเหมือนจะมีสิ่งที่แตกต่าง ดังนั้นฉันจึงพิจารณาเพิ่มที่นี่เป็นข้อยกเว้นกฎ เช่นเมื่อใช้: nohup .. &กดCtrl-cตามปกติไม่ก่อให้เกิดคำสั่งที่จะหยุด แต่ด้วยความsofficeที่มันไม่ ฉันรอจนกว่าจะมีใครสักคนเหยียบย่ำเรื่องนี้และอธิบายว่าทำไมสิ่งนี้จึงเกิดขึ้นกับ soffice :)
nohup soffice & Ctrl+Cไม่มีอะไรเกิดขึ้นตามที่คาดไว้