วิธีใช้คำสั่ง nohup ใน Linux

เผยแพร่แล้ว: 2022-06-25
แล็ปท็อป Linux แสดง bash prompt
fatmawati achmad zaenuri/Shutterstock.com

คำสั่ง Linux nohup ให้กระบวนการที่สำคัญทำงานต่อไปแม้ว่าหน้าต่างเทอร์มินัลที่เปิดใช้งานจะถูกปิด เราแสดงให้คุณเห็นถึงวิธีการใช้คำสั่งที่น่ายกย่องนี้บน Linux ในปัจจุบัน

HUP และ SIGHUP

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

พวกเขาถูกเรียกว่าเป็นใบ้เพราะพลังการประมวลผลอยู่ในคอมพิวเตอร์ที่คุณเชื่อมต่อ ไม่ใช่เทอร์มินัลที่คุณพิมพ์ โปรแกรมกำลังทำงานบนคอมพิวเตอร์—ทุกที่ที่อาจเคยอยู่—และไม่ใช่บนอุปกรณ์บนโต๊ะทำงานของคุณ

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

วิธีฆ่าแอปพลิเคชันเดสก์ท็อปหรือกระบวนการพื้นหลังบน Linux
ที่เกี่ยวข้อง วิธีการฆ่าแอปพลิเคชันเดสก์ท็อปหรือกระบวนการพื้นหลังบน Linux

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

มีเอฟเฟกต์น้ำตกเกิดขึ้น หากกระบวนการได้เปิดกระบวนการย่อยใด ๆ SIGHUP จะถูกส่งต่อไปยังพวกเขาด้วยเพื่อที่พวกเขาจะได้รู้ว่าพวกเขาควรจะยุติ

คำสั่ง nohup เรียกใช้กระบวนการย่อย แต่ปฏิเสธที่จะส่งสัญญาณ SIGHUP ไปยังกระบวนการเหล่านั้น นั่นอาจฟังดูเป็นปัญหา แต่จริงๆ แล้วมันเป็นฟังก์ชันที่มีประโยชน์

คำสั่ง nohup

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

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

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

ใช้ nohup

เราสร้างโปรแกรมที่ไม่มีประโยชน์อะไรเลย แต่จะรันและรันจนกว่าจะสิ้นสุด มันพิมพ์เวลาไปที่หน้าต่างเทอร์มินัลทุก ๆ สามวินาที เรียกว่า long-proc สำหรับ "กระบวนการที่ยาวนาน"

 ./long-proc 

โปรแกรม proc แบบยาวที่รันหน้าต่างเทอร์มินัล

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

 nohup ./long-proc 

เปิดตัวโปรแกรม proc แบบยาวจาก nohup

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

ตอนนี้คุณต้องรีบูตเพื่อยุติกระบวนการนี้หรือไม่? ไม่ หากต้องการหยุดกระบวนการ nohup ที่คุณยังไม่ได้เปิดใช้เป็นกระบวนการพื้นหลัง ให้กดแป้น Ctrl+C ร่วมกัน

หยุดกระบวนการ proc แบบยาวด้วย Ctrl+C

เอาต์พุตจากโปรแกรมได้รับการบันทึกสำหรับเราในไฟล์ชื่อ "nohup.out" เราสามารถตรวจทานได้น้อยลง

 nohup.out น้อย 

เปิดไฟล์ nohup.out น้อยลง

อะไรก็ตามที่มักจะถูกส่งไปยังหน้าต่างเทอร์มินัลจะถูกบันทึกไว้ในไฟล์ การรัน nohup ที่ตามมาจะถูกผนวกเข้ากับไฟล์ “nohup.out” ที่มีอยู่

เอาต์พุตจาก long-proc ที่เขียนไปยังไฟล์ nohup.out แสดงเป็น less

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

 nohup ./long-proc & 

เปิดตัวโปรแกรม proc แบบยาวด้วย nohup และทำให้เป็นงานพื้นหลัง

คุณจะต้องกด "Enter" อีกครั้งเพื่อกลับไปที่พรอมต์คำสั่ง เราได้รับแจ้งว่าหมายเลขงานของกระบวนการคือ 1—หมายเลขในวงเล็บปีกกา “ [] “— และ ID กระบวนการคือ 13115

เราสามารถใช้อย่างใดอย่างหนึ่งเหล่านี้เพื่อยุติกระบวนการ “Ctrl+C” จะไม่ทำงานในขณะนี้ เนื่องจากโปรแกรมไม่มีการเชื่อมโยงกับหน้าต่างเทอร์มินัลหรือเชลล์

หากคุณลืมว่าหมายเลขงานคืออะไร คุณสามารถใช้คำสั่ง jobs เพื่อแสดงรายการงานพื้นหลังที่เรียกใช้จากหน้าต่างเทอร์มินัลนั้น

 งาน 

แสดงรายการงานพื้นหลังที่เปิดใช้งานจากหน้าต่างเทอร์มินัล

เพื่อฆ่างานของเรา เราสามารถใช้คำสั่ง kill และหมายเลขงาน นำหน้าด้วยเครื่องหมายเปอร์เซ็นต์ “ % “ เช่นนี้

 ฆ่า %1

หากคุณปิดหน้าต่างเทอร์มินัล คุณจะต้องค้นหา ID กระบวนการและใช้กับคำสั่ง kill คำสั่ง pgrep จะค้นหา ID กระบวนการสำหรับกระบวนการที่ตรงกับคำใบ้การค้นหาที่คุณระบุ เราจะค้นหาชื่อกระบวนการ

 pgrep long-proc 

ค้นหา ID กระบวนการของกระบวนการตามชื่อ

ตอนนี้เราสามารถใช้ ID กระบวนการเพื่อยุติกระบวนการได้

 ฆ่า 13115 

การใช้คำสั่ง kill และ ID กระบวนการเพื่อยุติกระบวนการ

ครั้งถัดไปที่คุณกด "Enter" คุณจะได้รับแจ้งว่ากระบวนการนี้สิ้นสุดลงแล้ว

ตอนนี้เรามาดูสิ่งที่ ไม่ ยุติกระบวนการ เราจะเปิดใหม่ จากนั้นปิดหน้าต่างเทอร์มินัล

 nohup ./long-proc 

การปิดหน้าต่างเทอร์มินัลด้วยกระบวนการที่ทำงานอยู่

หากเราเปิดหน้าต่างเทอร์มินัลใหม่และค้นหากระบวนการของเราด้วย pgrep เราจะเห็นว่ายังทำงานอยู่ การปิดหน้าต่างเทอร์มินัลที่เปิดใช้กระบวนการไม่มีผลใดๆ

 pgrep long-proc 

ใช้ pgrep เพื่อค้นหากระบวนการตามชื่อ

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

ต้องบอกว่า ในการเปิดหลายกระบวนการพร้อมกัน ให้ใช้ nohup เพื่อเรียกใช้ Bash shell และใช้ตัวเลือก -c (คำสั่ง) กับสตริงคำสั่ง ใช้เครื่องหมายคำพูดเดี่ยว “ ' ” เพื่อรวมรายการคำสั่งและเครื่องหมายและคู่ “ && ” เพื่อแยกคำสั่ง

 nohup bash -c 'ls /bin && ls /sbin' 

เปิดตัวสองกระบวนการด้วย nohup

หากคุณใช้ less เพื่อดูไฟล์ “nohup.out” คุณจะเห็นผลลัพธ์จากกระบวนการแรก จากนั้นจึงเห็นผลลัพธ์จากกระบวนการที่สอง

 nohup.out น้อย 

เปิดไฟล์ nohup.out น้อยลง

เอาต์พุตจากคำสั่งทั้งสองถูกบันทึกในไฟล์ "nohup.out" ไม่มีการพันกัน เอาต์พุตจากกระบวนการที่สองจะเริ่มเมื่อกระบวนการแรกสิ้นสุดลงเท่านั้น

เนื้อหาของไฟล์ nohup.out ใน less

หากคุณต้องการใช้ไฟล์ของคุณเองแทน "nohup.out" คุณสามารถเปลี่ยนเส้นทางคำสั่งไปยังไฟล์ที่คุณเลือกได้

 nohup bash -c 'ls /bin && ls /sbin' > myfile.txt 

การเปลี่ยนเส้นทางเอาต์พุตจากกระบวนการไปยังไฟล์ที่ผู้ใช้ให้มา

โปรดทราบว่าข้อความไม่ได้ระบุว่า "กำลังต่อท้ายเอาต์พุตไปยัง nohupo.out" แต่ระบุว่า "กำลังเปลี่ยนเส้นทาง stderr ไปที่ stdout" และเรากำลังเปลี่ยนเส้นทาง stdout ไปยังไฟล์ "myfile.txt" ของเรา

เราสามารถมองเข้าไปในไฟล์ “myfile.txt” ได้น้อยลง

 น้อยกว่า myfile.txt 

ก่อนหน้านี้มีเอาต์พุตจากทั้งสองคำสั่ง


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

ที่เกี่ยวข้อง: 37 คำสั่ง Linux ที่สำคัญที่คุณควรรู้