ความแตกต่างระหว่าง nohup และเครื่องหมายและคืออะไร


243

ทั้งสองอย่างnohup myprocess.out &หรือmyprocess.out &ตั้งค่า myprocess.out เพื่อให้ทำงานในพื้นหลัง หลังจากฉันปิดเทอร์มินัลกระบวนการยังคงทำงานอยู่ ความแตกต่างระหว่างพวกเขาคืออะไร


คุณใช้เปลือกอะไร พฤติกรรมจะแตกต่างกันไปตามแต่ละเชลล์
shx2

1
ทุบตี. และฉันรู้ว่าทำไมตอนนี้ตามคำตอบของ @nemo
Yarkee

@Yarkee หากคำตอบนั้นตรงกับปัญหาของคุณโปรดทำเครื่องหมายคำถามว่ายอมรับแล้ว (ช่องทำเครื่องหมายด้านล่างโหวตของคำตอบ) ดังนั้นมันจึงไม่ห้อยต่องแต่งเหมือนที่ยังไม่ได้ตอบ คุณควรทำเช่นนั้นสำหรับคำถามทั้งหมดของคุณ :)
nemo

1
shutdownควรหลีกเลี่ยงคำที่มีความหมายเฉพาะลินุกซ์. exitและถูกแทนที่ด้วย
Patrizio Bertoni

คำตอบ:


317

nohupจับสัญญาณ Hangup (ดูman 7 signal) ในขณะที่เครื่องหมายและไม่ได้ (ยกเว้นเชลล์จะได้รับการปกป้องด้วยวิธีการดังกล่าวหรือไม่ส่งSIGHUPเลย)

โดยปกติเมื่อรันคำสั่งโดยใช้&และออกจากเชลล์หลังจากนั้นเชลล์จะยกเลิกคำสั่งย่อยด้วยสัญญาณ hangup ( kill -SIGHUP <pid>) สิ่งนี้สามารถป้องกันได้โดยใช้nohupเนื่องจากมันจับสัญญาณและละเว้นมันเพื่อไม่ให้เข้าถึงแอปพลิเคชันจริง

ในกรณีที่คุณใช้ bash คุณสามารถใช้คำสั่งshopt | grep huponเพื่อค้นหาว่าเชลล์ของคุณส่ง SIGHUP ไปยังกระบวนการลูกหรือไม่ หากปิดอยู่กระบวนการจะไม่ถูกยกเลิกเนื่องจากเป็นกรณีของคุณ ข้อมูลเพิ่มเติมเกี่ยวกับวิธีการทุบตียุติการใช้งานที่สามารถพบได้ที่นี่

มีหลายกรณีที่nohupไม่สามารถทำงานได้ตัวอย่างเช่นเมื่อกระบวนการที่คุณจะเริ่ม reconnects SIGHUPสัญญาณตามที่มันเป็นกรณีที่นี่


มันอาจจะคุ้มค่าที่จะสังเกตว่าเพียงแค่&ทำให้คำสั่งย่อยไม่ได้รับสัญญาณบางอย่าง (เช่น SIGINT) nohupเป็นหลักเพิ่มSIGHUPในรายการของสัญญาณที่ไม่ได้เผยแพร่
studgeek

46

myprocess.out &จะเรียกใช้กระบวนการในพื้นหลังโดยใช้ subshell หากเชลล์ปัจจุบันถูกยกเลิก (พูดโดยออกจากระบบ), subshells ทั้งหมดจะถูกยกเลิกด้วยดังนั้นกระบวนการพื้นหลังก็จะถูกยกเลิก nohupคำสั่งละเว้นHUPสัญญาณและทำให้แม้ว่าเปลือกปัจจุบันถูกยกเลิกการ subshell และmyprocess.outจะทำงานในพื้นหลังอย่างต่อเนื่อง ข้อแตกต่างก็คือการที่&ไม่ได้เปลี่ยนเส้นทาง stdout / stderr เพียงอย่างเดียวดังนั้นหากมีเอาต์พุตหรือข้อผิดพลาดใด ๆ จะแสดงบนเทอร์มินัล nohup ในมืออื่น ๆ เปลี่ยนเส้นทาง stdout / stderr ไปหรือnohup.out$HOME/nohup.out


6
ฉันเรียกใช้myprocess.out &และออกจากเปลือก อย่างไรก็ตามเมื่อฉันใช้ps aux | grep myprocess.outในเชลล์อื่นฉันยังสามารถหา "myprocess.out" หมายความว่ากระบวนการยังทำงานอยู่และจะไม่ถูกยกเลิก
Yarkee

1
@amit_g เมื่อฆ่าเชลล์พาเรนต์ด้วยkill -9จะไม่มี SIGHUP เนื่องจากต้องใช้เชลล์พาเรนต์เพื่อจัดการ SIGKILL ซึ่งไม่สามารถทำได้
nemo

2
ตรวจสอบ shopt | grep hupon ดังกล่าวในคำตอบอื่น ๆ
amit_g

31

ส่วนใหญ่เวลาที่เราเข้าสู่เซิร์ฟเวอร์ระยะไกลโดยใช้ ssh หากคุณเริ่มเชลล์สคริปต์และคุณล็อกเอาต์กระบวนการจะถูกทำลาย Nohup ช่วยในการเรียกใช้สคริปต์ในพื้นหลังต่อไปแม้ว่าคุณจะออกจากระบบ

Nohup command name &
eg: nohup sh script.sh &

Nohup จับสัญญาณ HUP Nohup ไม่ได้วางงานโดยอัตโนมัติในพื้นหลัง เราจำเป็นต้องบอกว่าใช้ &


ขอบคุณ ไม่ได้คาดหวังคำตอบของคุณ แต่ความจริงที่ว่าที่นี่ดีมาก มันตอบคำถามที่ฉันไม่ได้ถาม: D
Vaibhav Kaushal

26

การใช้เครื่องหมายและ (&) จะใช้คำสั่งในกระบวนการลูก (ลูกไปยังเซสชันทุบตีปัจจุบัน) อย่างไรก็ตามเมื่อคุณออกจากเซสชันกระบวนการลูกทั้งหมดจะถูกฆ่า

การใช้ nohup + ampersand (&) จะทำสิ่งเดียวกันยกเว้นเมื่อสิ้นสุดเซสชันผู้ปกครองของกระบวนการลูกจะถูกเปลี่ยนเป็น "1" ซึ่งเป็นกระบวนการ "init" ซึ่งทำให้เด็กไม่ต้องถูกฆ่า


7

ช่วยแก้ให้ด้วยนะถ้าฉันผิด

  nohup myprocess.out &

nohupจับสัญญาณ hangup ซึ่งหมายความว่ามันจะส่งกระบวนการเมื่อปิดเทอร์มินัล

 myprocess.out &

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

nohup myprocess.out

กระบวนการสามารถทำงานได้แม้ปิดเทอร์มินัล แต่คุณสามารถหยุดกระบวนการได้โดยกดctrl+ zในเทอร์มินัล Crt+ zไม่ทำงานหาก&มีอยู่


2

คำสั่ง nohup เป็นยูทิลิตี้ปิดบังสัญญาณและจับสัญญาณ Hangup ในฐานะที่เป็นเครื่องหมายแอมเปอร์แซนด์ไม่จับสัญญาณวางสาย เชลล์จะยุติคำสั่งย่อยด้วยสัญญาณวางสายเมื่อใช้คำสั่งโดยใช้ & และออกจากเชลล์ สิ่งนี้สามารถป้องกันได้โดยใช้ nohup ขณะที่มันจับสัญญาณ คำสั่ง Nohup ยอมรับสัญญาณวางสายซึ่งสามารถส่งไปยังกระบวนการโดยเคอร์เนลและบล็อกพวกเขา คำสั่ง Nohup มีประโยชน์ในกรณีที่ผู้ใช้ต้องการเริ่มต้นใช้งานแอพพลิเคชั่นยาวออกจากระบบหรือปิดหน้าต่างที่กระบวนการเริ่มต้น โดยปกติแล้วการกระทำเหล่านี้จะแจ้งให้เคอร์เนลวางสายบนแอปพลิเคชัน แต่ตัวตัดคำที่ไม่มีส่วนจะทำให้กระบวนการดำเนินการต่อ การใช้เครื่องหมายและจะเรียกใช้คำสั่งในกระบวนการลูกและลูกของเซสชันทุบตีปัจจุบัน เมื่อคุณออกจากเซสชั่น กระบวนการลูกทั้งหมดของกระบวนการนั้นจะถูกฆ่า เครื่องหมายและที่เกี่ยวข้องกับการควบคุมงานสำหรับเชลล์ที่ใช้งานอยู่ สิ่งนี้มีประโยชน์สำหรับการรันโปรเซสในเซสชั่นในพื้นหลัง


0

มีหลายกรณีที่ความแตกต่างเล็กน้อยระหว่างสภาพแวดล้อมสามารถกัดคุณได้ นี่คือสิ่งที่ฉันได้วิ่งไปเมื่อเร็ว ๆ นี้ ความแตกต่างระหว่างสองคำสั่งเหล่านี้คืออะไร?

1 ~ $ nohup myprocess.out &
2 ~ $ myprocess.out &

คำตอบเหมือนกันตามปกติ - ขึ้นอยู่กับ

nohup จับสัญญาณ hangup ขณะที่เครื่องหมายและไม่ทำ

สัญญาณ Hangup คืออะไร?

SIGHUP - ตรวจพบ Hangup ในเทอร์มินัลการควบคุมหรือการตายของกระบวนการควบคุม (ค่า: 1)

โดยปกติเมื่อรันคำสั่งโดยใช้ & และออกจากเชลล์หลังจากนั้นเชลล์จะยุติคำสั่งย่อยด้วยสัญญาณ Hangup (เช่น kill -SIGHUP $ PID) สิ่งนี้สามารถป้องกันได้โดยใช้ nohup เนื่องจากมันจับสัญญาณและละเว้นมันเพื่อไม่ให้เข้าถึงแอปพลิเคชันจริง

สบายดี แต่ในกรณีนี้มี 'buts' อยู่เสมอ ไม่มีความแตกต่างระหว่างวิธีการเรียกใช้เหล่านี้เมื่อเชลล์ถูกกำหนดค่าในลักษณะที่ไม่ส่ง SIGHUP เลย

ในกรณีที่คุณใช้ bash คุณสามารถใช้คำสั่งที่ระบุด้านล่างเพื่อค้นหาว่าเชลล์ของคุณส่ง SIGHUP ไปยังกระบวนการลูกหรือไม่:

~ $ shopt | grep hupon

และยิ่งกว่านั้น - มีหลายกรณีที่ nohup ไม่ทำงาน ตัวอย่างเช่นเมื่อกระบวนการที่คุณเริ่มเชื่อมต่อสัญญาณ NOHUP อีกครั้ง (เสร็จสิ้นภายในระดับรหัสแอปพลิเคชัน)

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

ในสภาพแวดล้อม Linux หนึ่งทุกอย่างทำงานได้อย่างราบรื่นในแอปพลิเคชั่นที่สองออกจากทันทีที่สคริปต์ที่สองออกมา (การตรวจสอบกรณีนั้นแน่นอนว่าใช้เวลากับฉันมากกว่านี้แล้วคุณอาจคิดว่า:

หลังจากเพิ่ม nohup เป็นวิธีการเรียกใช้กับสคริปต์ที่สองแอปพลิเคชันจะยังคงทำงานต่อไปแม้ว่าสคริปต์จะออกและพฤติกรรมนี้ก็สอดคล้องกันในทั้งสองสภาพแวดล้อม

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