ทำให้กระบวนการ linux ทำงานต่อไปหลังจากที่ฉันออกจากระบบ


142

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

ฉันสงสัยว่าการรันสคริปต์ด้วยตัวดำเนินการแบ็คกราวน์, the ampersand ( &) จะทำเคล็ดลับได้เพราะฉันลองแล้วพบว่ากระบวนการไม่เสร็จสมบูรณ์ ฉันจะออกจากระบบและให้กระบวนการทำงานต่อไปได้อย่างไร

คำตอบ:


135

วิธีที่ดีที่สุดคือเริ่มกระบวนการในเทอร์มินัลมัลติเพล็กเซอร์ หรือคุณสามารถทำให้กระบวนการไม่ได้รับสัญญาณ HUP


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

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

สอง multiplexers มินัลที่เป็นที่นิยมหน้าจอและtmux

หน้าจอมีเส้นโค้งการเรียนรู้ที่สูงชัน นี่คือบทแนะนำที่ดีพร้อมไดอะแกรมอธิบายแนวคิด: http://www.ibm.com/developerworks/aix/library/au-gnu_screen/


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

สองวิธีง่ายๆในการทำเช่นนั้นคือnohupและdisown.

สำหรับข้อมูลเพิ่มเติมเกี่ยวกับวิธีการnohupและdisownผลงานอ่านคำถามนี้และตอบ: https://unix.stackexchange.com/questions/3886/difference-between-nohup-disown-and

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


3
ฉันชอบคำตอบนี้เพราะมันเป็นทางออกสำหรับสถานการณ์แบบโต้ตอบและไม่โต้ตอบ ในกรณีที่การโต้ตอบและscreenช่วยให้คุณมีตัวเลือกมากขึ้น แต่ถ้าคุณกำลังใช้authorized_keysเพื่อให้คนเรียกใช้สคริปต์ระยะไกลผ่านทางsshที่nohupตัวเลือกเป็นวิธีที่ง่ายที่ดีสำหรับสคริปต์เพื่อเริ่มต้นกระบวนการซึ่งมีอายุยาวนานกว่าsshเซสชั่นที่ใช้ในการเริ่มต้นพวกเขา .
Mark Booth

1
@rahmanisback - จำไว้ว่าคุณสามารถเปลี่ยนคำตอบที่ยอมรับได้ตลอดเวลา เพียงเพราะคำตอบของ EricA นั้นได้รับการโหวตมากที่สุดไม่ได้หมายความว่ามันเป็นคำตอบที่ดีที่สุดสำหรับคุณการทำให้คำตอบที่คุณยอมรับอาจช่วยกระตุ้นให้ผู้คนจำนวนมากโหวตให้เป็นคำตอบที่ดี
Mark Booth

3
* ไอ * tmuxisbetter * อาการไอ *
crasic

3
หน้าจอtmux > ลองเลยคุณจะไม่ย้อนกลับไป
h0tw1r3

1
@TheLQ - byobu เป็นหน้าจอ GNU คุณยังคงใช้หน้าจออยู่ด้วย. screenrc ที่ปรับแต่งได้สูง
EEAA

92

มีไม่กี่วิธีที่จะทำนี้อย่างใดอย่างหนึ่งที่ผมพบว่ามีประโยชน์มากที่สุดคือการใช้มี แต่หน้าจอ GNU

หลังจากที่คุณทำงานscreenแล้วให้เรียกใช้ นี่จะเป็นการเริ่มเชลล์อื่นที่ทำงานภายในหน้าจอ เรียกใช้คำสั่งของคุณแล้วทำ-Ctrla d

การดำเนินการนี้จะ "ยกเลิกการเชื่อมต่อ" ของคุณจากเซสชันหน้าจอ ณ จุดนี้คุณสามารถออกจากระบบหรือทำสิ่งอื่นที่คุณต้องการ

เมื่อคุณต้องการเชื่อมต่อกับเซสชั่นหน้าจออีกครั้งเพียงเรียกใช้screen -RDจากเชลล์พรอมต์ (เช่นเดียวกับผู้ใช้ที่ใช้งานที่สร้างเซสชั่น)


6
หน้าจอมีทั้งคำสั่งทั้งหมดเริ่มต้นด้วย Ctrl-a หากคุณเรียนรู้เพิ่มเพียงหนึ่งรายการเริ่มต้นด้วย "Ctrl-a?" จากนั้นคุณจะไม่ต้องการเรียนรู้ "Ctrl-a c" และ "Ctrl-a n"
olafure

@olafure +1 ขอบคุณ ดูเหมือนว่าหน้าจอจะเป็นกล่องเครื่องมือหลักของฉัน
doc_id

หน้าจอtmux > ลองเลยคุณจะไม่ย้อนกลับไป
h0tw1r3

+1 สำหรับ tmux ฉันยอมแพ้หน้าจอ 5 สัปดาห์ที่ผ่านมา
ไบรอันฮันต์

73

ในbashการdisownคำหลักที่เหมาะสมที่สุดนี้ ก่อนอื่นให้รันกระบวนการของคุณในพื้นหลัง (อาจใช้&หรือ^Zพิมพ์bg):

$ wget --quiet http://server/some_big_file.zip &
[1] 1156

ด้วยการพิมพ์jobsคุณจะเห็นว่ากระบวนการยังคงเป็นของเชลล์:

$ jobs
[1]+  Running  wget

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

$ disown

คุณสามารถยืนยันสิ่งนี้:

$ jobs
$ logout

คุณสามารถรวม&และdisownบนบรรทัดเดียวกันได้เช่น:

$ wget --quiet http://server/some_big_file.zip & disown
$ logout

นี้ดีกว่าทำงานnohupในความคิดของฉันเพราะมันไม่ทิ้งnohup.outไฟล์ที่เกลื่อนไปทั่วระบบไฟล์ของคุณ นอกจากนี้nohupต้องเรียกใช้ก่อนที่คุณจะรันคำสั่ง - disownสามารถใช้งานได้หากคุณตัดสินใจในภายหลังว่าคุณต้องการแบ็คกราวน์และแยกงานออก


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

ใช่ - นี่คือทุบตี - เฉพาะเนื่องจากทุบตีเป็นเปลือกเดียวที่ฉันเคยใช้ ฉันสงสัยว่ากระสุนตัวอื่นรองรับอะไรที่คล้ายกัน (เช่นการเปิดตัวในพื้นหลังโดยไม่ต้อง nohup) - มันจะยอดเยี่ยมถ้ามีใครสามารถโพสต์คำตอบอื่น ๆ สำหรับเชลล์อื่น ๆ ได้
Jeremy Visser

1
ดูคำตอบของฉันแสดงให้เห็นว่าจะทำอย่างไรกับสิ่งที่ดูคล้ายกันเลย
w00t

1
+1 เนื่องจากไม่สามารถตัดสินใจได้ในภายหลัง เมื่อครู่นี้ฉันต้องการสิ่งนี้ ทำงานตามที่โฆษณาไว้
code_monk

37

เครื่องมือ nohup ที่มีอยู่ในกล่อง Linux ส่วนใหญ่จะทำเช่นนี้


1
นี่คือคำตอบที่ง่ายที่สุด เอาต์พุตใด ๆ จากจะถูกนำไปที่ nohup.out โดยอัตโนมัติและสามารถตรวจสอบได้ในภายหลัง
Julian

3
nohup ไม่ต้องการ zsh เลย
Aaron Brown

nohup เป็นคำตอบที่ถูกต้องมันสั้นสำหรับไม่มี hangup
Kinjal Dixit

2
Nohup พบได้ในเครื่องจักรมากกว่าหน้าจอดังนั้นคุณควรรู้วิธีใช้
Zenon

27

เพื่อให้ละเอียดฉันจะชี้ให้เห็นtmuxซึ่งมีความคิดพื้นฐานเช่นเดียวกับหน้าจอ:

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

  • อินเทอร์เฟซคำสั่งที่มีประสิทธิภาพสอดคล้องเอกสารที่ดีและสคริปต์ได้อย่างง่ายดาย
  • หน้าต่างอาจถูกแบ่งในแนวนอนและแนวตั้งเป็นบานหน้าต่าง
  • บานหน้าต่างสามารถเคลื่อนย้ายและปรับขนาดได้อย่างอิสระหรือจัดเป็นเค้าโครงที่ตั้งไว้ล่วงหน้า
  • รองรับเทอร์มินัล UTF-8 และ 256 สี
  • คัดลอกและวางด้วยบัฟเฟอร์หลายตัว
  • เมนูแบบโต้ตอบเพื่อเลือก windows เซสชันหรือไคลเอนต์
  • เปลี่ยนหน้าต่างปัจจุบันโดยค้นหาข้อความในเป้าหมาย
  • การล็อคเทอร์มินัลด้วยตนเองหรือหลังจากหมดเวลา
  • ฐานโค้ดที่สะอาดและขยายได้อย่างง่ายดายและได้รับอนุญาตจาก BSD ภายใต้การพัฒนาที่ใช้งานอยู่

อย่างไรก็ตามการค้นหาบน Google นั้นทำได้ง่ายขึ้นอย่างไม่สิ้นสุด


2
ใช้"gnu screen"เป็นคำค้นหาของคุณทำงานได้ค่อนข้างดี
gnur

4
+1000 สำหรับ tmux!
mbq

11

หน้าจอเป็น overkill เพียงทำให้กระบวนการทำงานเมื่อคุณออกจากระบบ

ลองdtach :

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

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

หน้าจอยังรบกวนการใช้งานแอปพลิเคชันแบบเต็มหน้าจอเช่น emacs และ ircII เนื่องจากมีการตีความกระแสข้อมูลมากเกินไประหว่างโปรแกรมและเทอร์มินัลที่ต่ออยู่ dtach ไม่มีเลเยอร์การจำลองเทอร์มินัลและส่งผ่านสตรีมเอาต์พุตดิบของโปรแกรมไปยังเทอร์มินัลที่แนบ การประมวลผลอินพุตเฉพาะที่ dtach ดำเนินการคือการสแกนหาอักขระ detach (ซึ่งเป็นสัญญาณ dtach ที่จะแยกออกจากโปรแกรม) และประมวลผลคีย์ suspend (ซึ่งบอกให้ dtach หยุดชั่วคราวโดยไม่ส่งผลกระทบต่อโปรแกรมที่กำลังทำงาน) และทั้งสองสิ่งนี้ ถูกปิดใช้งานหากต้องการ

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


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

9

นี่เป็นวิธีที่จะทำให้กระบวนการเชลล์ใด ๆ ไม่ต้องใช้โปรแกรมภายนอก:

( while sleep 5; do date; done ) <&- >output.txt &

เมื่อคุณปิดเซสชันของคุณแล้วงานจะยังคงทำงานต่อไปตามที่เห็นในไฟล์ output.txt (ซึ่งมีบัฟเฟอร์ดังนั้นจึงใช้เวลาสักครู่ในการแสดงที่ไม่เป็นศูนย์) อย่าลืมฆ่างานของคุณหลังจากการทดสอบ

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

สิ่งนี้ทำงานได้แม้ใน sh ง่าย ๆ ภายใต้ Solaris


น่าสนใจ นั่นเป็นคำถามที่น่าสังเกต ฉันเห็นว่าคุณตั้งค่า STDIN เป็น-โอเปอเรเตอร์หรือไม่ ความแตกต่างระหว่าง< /dev/nullและ&-คืออะไร? ฉันเดาว่า STDIN (และอื่น ๆ STDOUT และ STDERR) สามารถกำหนดได้ทั้งไฟล์โดย< fileหรือสตรีม<& streamในกรณีของ STDIN มันจะเหมือนกับการใช้< /dev/nullในตัวอย่างของคุณด้านบน และตัวดำเนินการ-ด้านบนอ้างถึง null เป็นสตรีมหรือไม่
doc_id

เมื่อคุณทำ x <& - นั่นจะเป็นการปิดไฟล์ descriptor x ในกรณีนี้ไม่มี x ซึ่งทำให้ bash เป็นค่าเริ่มต้นที่ 1 คืออินพุตมาตรฐาน หากคุณใช้ </ dev / null คุณไม่ได้ปิด stdin คุณเพียงแค่ให้ไฟล์เปล่ากับโปรแกรมเป็นอินพุต
w00t

1
และตามจริงแล้วฉันไม่รู้จริง ๆ ว่าทำไมสิ่งนี้ทำให้คุณทำงานได้ดี :-) มันใช้งานได้ แต่เราใช้มันในการผลิต ฉันค้นพบมันในขณะที่ทำสิ่งต่าง ๆ โดยหวังว่าฉันจะสามารถทำให้เป็นกระบวนการในเชลล์โดยไม่ต้องการอะไรเป็นพิเศษ - ดังนั้นฉันจึงเริ่มต้นด้วยการปิด stdin และนั่นก็เพียงพอแล้ว ฉันควรจะไปอ่านแหล่งที่มาของเชลล์ แต่ฉันคิดว่าถ้าคุณปิด stdin และเบื้องหลังกระบวนการมันจะแยกกระบวนการออกไป
w00t

2
ฉันคิดว่าเหตุผลก็คือ SIGHUP (สัญญาณจริงที่ทำให้เด็กออกเมื่อเปลือกตาย) ถูกกระตุ้นเมื่อกระบวนการผู้ปกครองปิดการจัดการ stdin ของเด็ก อย่างไรก็ตามหาก stdin เริ่มต้นเป็นโมฆะแทนที่จะถูกปิดหลังจากความเป็นจริงไม่มีวิธีใดที่ผู้ปกครองจะเรียก SIGHUP หาดีแม้ว่า - จะไม่คิดอย่างนั้น
Jeremy Visser

@JeremyVisser ที่ฟังดูน่าเชื่อถือจริงๆ!
w00t

7

atคำสั่งจะมีประโยชน์สำหรับชนิดของสถานการณ์นี้ ตัวอย่างเช่นพิมพ์:

at now

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

แทนที่จะคุณสามารถระบุเวลาที่ตัวเลือกที่มีวันที่หรือการแสดงออกเวลาเช่นnow now + 15 minutesดูman atรายละเอียดเพิ่มเติมได้ที่


7

byobuบน Ubuntu เป็น front-end หน้าจอที่ดี โดยการกดCtrl- ?คุณจะได้รับรายการแป้นพิมพ์ลัดทั้งหมด มันเพิ่มแถบสถานะที่มีประโยชน์สำหรับการดูโหลด CPU พื้นที่ดิสก์และอื่น ๆ โดยรวมมันให้ประสบการณ์ที่ฉันจะอธิบายว่าเป็นการเชื่อมต่อ VNC แบบใช้ขั้ว

nohup อนุญาตให้เริ่มต้นงานในพื้นหลังโดยเอาต์พุตถูกส่งไปยังล็อกไฟล์ซึ่งสามารถเปลี่ยนเส้นทางไปยัง / dev / null ได้หากไม่ต้องการ

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