อะไรคือความแตกต่างระหว่างการเรียกใช้โปรแกรมเป็น daemon และฟอร์กมันลงในพื้นหลังด้วย '&'


45

อะไรคือความแตกต่างในทางปฏิบัติจากมุมมองดูแลระบบเมื่อปรับใช้บริการบนระบบที่ใช้ระบบปฏิบัติการยูนิกซ์?

คำตอบ:


31

วิธีการแบบดั้งเดิมของการ daemonizing คือ:

fork()
setsid()
close(0) /* and /dev/null as fd 0, 1 and 2 */
close(1)
close(2)
fork()

สิ่งนี้ทำให้มั่นใจได้ว่ากระบวนการไม่ได้อยู่ในกลุ่มกระบวนการเดียวกันกับเทอร์มินัลอีกต่อไปและจะไม่ถูกฆ่าพร้อมกัน การเปลี่ยนเส้นทาง IO คือการทำให้การส่งออกไม่ปรากฏบนขั้ว


5
ดังนั้นหากเทอร์มินัลที่วางกระบวนการพื้นหลัง (&) ถูกปิดกระบวนการพื้นหลังจะยุติด้วยเช่นกัน
user1561108

9
กระบวนการจะได้รับ SIGHUP เมื่อเทอร์มินัลออกตัวจัดการเริ่มต้นสำหรับสัญญาณนั้นคือการยุติกระบวนการ
Dennis Kaarsemaker

12
โปรดเพิ่ม&คำอธิบายชิ้นส่วนลงในคำตอบของคุณ ดูเหมือนว่าจะไม่สมบูรณ์ .. หากคุณตรวจสอบคำถามเดิม
mtk

1
นั่นเป็นเพราะการทำงานสิ่งที่อยู่ในพื้นหลังที่มีและไม่ได้ทำให้กระบวนการทำอะไรเป็นพิเศษ :)
เดนนิส Kaarsemaker

33

สำหรับดีมอนสิ่งที่คุณต้องการคือกระบวนการที่ไม่ผูกอะไรเลย อย่างน้อยที่สุดคุณต้องการให้มันอยู่ในเซสชั่นของตัวเองไม่ได้เชื่อมต่อกับเทอร์มินัลไม่มีไฟล์ descriptor ใด ๆ ที่สืบทอดจากพาเรนต์ที่เปิดให้กับสิ่งใด ๆ ไม่มีแม่ที่ดูแลคุณ ไดเรกทอรี/เพื่อที่จะไม่ป้องกัน umount ...

เมื่อต้องการแยกออกจากเทอร์มินัลคุณสร้างเซสชันใหม่อย่างไรก็ตามในการสร้างเซสชันคุณต้องไม่เป็นผู้นำกลุ่ม (หรือเซสชัน) ดังนั้นวิธีที่ดีที่สุดคือการแยกกระบวนการใหม่ สมมติว่าการออกจากพาเรนต์นั้นก็หมายความว่ากระบวนการนั้นจะไม่ได้มีพาเรนต์อีกต่อไปและจะถูกนำไปใช้โดย init จากนั้นให้ปิดตัวอธิบายไฟล์ที่เป็นไปได้ทั้งหมดคุณchdir("/")(หนึ่งไม่สามารถปิดไดเรกทอรีการทำงานปัจจุบันเพื่อปล่อยทรัพยากรนั้นเช่นสำหรับตัวอธิบายไฟล์การสร้าง/ไดเรกทอรีการทำงานปัจจุบันอย่างน้อยก็ไม่ได้ป้องกันการ unmounting ไดเรกทอรี)

เนื่องจากกระบวนการนั้นเป็นผู้นำเซสชันดังนั้นจึงมีความเสี่ยงที่หากอุปกรณ์นั้นเปิดอุปกรณ์เทอร์มินัลจึงกลายเป็นกระบวนการควบคุมของเทอร์มินัลนั้น การแยกครั้งที่สองทำให้มั่นใจได้ว่าจะไม่เกิดขึ้น

อีกด้านหนึ่ง & ในเชลล์แบบโต้ตอบให้ค้นหาและสร้างกลุ่มกระบวนการใหม่ (เพื่อไม่ให้อยู่ในกลุ่มกระบวนการพื้นหน้าของเทอร์มินัล) และในเชลล์ที่ไม่มีการโต้ตอบใช้กระบวนการและละเว้น SIGINT ที่อยู่ในนั้น ไม่แยกออกจากเทอร์มินัลไม่ปิดตัวให้คำอธิบายไฟล์ (แม้ว่าเชลล์บางตัวจะเปิด stdin อีกครั้งเพื่อ/dev/null... )


สิ่งที่ใช้สำหรับ chdir ("/")? การปิดไฟล์ descriptor?
Timothy Leung

@TimothyLeung ดูการแก้ไข
Stéphane Chazelas

8

ความแตกต่างระหว่างการรันโปรแกรม / กระบวนการเป็น daemon และการฟอร์กมันไปยังพื้นหลังโดยใช้เครื่องหมายและมีความสัมพันธ์กับความเป็นเจ้าของ

ส่วนใหญ่มักจะการปกครองของภูตเป็นinitกระบวนการ (กระบวนการแรกมากที่จะเริ่มต้นในระบบ Unix) ภูตเป็นลูกของกระบวนการที่หมายถึงว่ามันไม่ได้อยู่ภายใต้การควบคุมโดยตรงของคุณเป็นผู้ใช้ที่ไม่ใช่สิทธิพิเศษ . ในขณะที่การฟอร์กโปรแกรม / กระบวนการเป็นแบ็คกราวด์หมายความว่าคุณสามารถโทรกลับไปที่เบื้องหน้าและ / หรือฆ่ามันได้ตลอดเวลา


1
นอกจากนี้เพื่อตอบด้านเทคนิคด้านบนของการแยกกระบวนการเมื่อเทียบกับการทำให้เป็นเทอร์มินัลคุณสามารถลองเรียกใช้ "nohup firefox &"
Odaym

7

ด้วยcommand &กระบวนการของคุณจะถูกฆ่าโดยสัญญาณ SIGHUP เมื่อผู้ปกครองตาย

แม้ว่า Sysadmins สามารถเข้าถึงวิธีแก้ไขปัญหาบางอย่างได้

บนระบบทุบตีคุณสามารถใช้:

(trap '' HUP; command) &

สิ่งนี้จะเปิด subshell ดักHUPสัญญาณด้วยตัวจัดการที่ว่างเปล่าและเครื่องหมาย / แยกมัน

ttyการส่งออกอาจจะยังคงได้รับการเปลี่ยนเส้นทางไปยังที่ไม่ถูกต้อง หรือหลงทาง
คุณอาจจะแก้ไขปัญหาที่มี&>command.out, 1>output.outหรือ2>errors.out

คุณอาจเข้าถึงnohupคำสั่งได้ในระบบส่วนใหญ่
nohupทำให้กระบวนการนี้ง่ายขึ้นอย่างมาก เป็นมาตรฐานค่อนข้างมาก แต่ฉันพบว่าการจัดสรร ARM แบบยุ่ง ๆ หลายอย่างไม่ได้เกิดขึ้น คุณเพิ่งเขียน:

nohup command &

.. และคุณทำเสร็จแล้ว เอาต์พุตถูกเปลี่ยนเส้นทาง IIRC ไปยังnohup.outแต่ชื่อไฟล์นี้สามารถเปลี่ยนแปลงได้ด้วยตัวเลือก


2
เพียงแค่ต้องทราบว่าด้วย ZSH คุณสามารถแยกได้ในcommand &ภายหลังจากเปลือกdisownซึ่งจะทำงานเป็น post-nohup
คณิตศาสตร์
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.