อะไรคือความแตกต่างระหว่าง
$ 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
ไม่มีอะไรเกิดขึ้นตามที่คาดไว้