ป้องกันการรันงาน linux ที่จะถูกฆ่าหลังจากออกจากระบบ SSH


18

ฉันมีงานคอมพิวเตอร์ใช้งานอยู่สองสามวันบนเซิร์ฟเวอร์ linux ผ่านการเชื่อมต่อ SSH ไม่ได้อยู่ในพื้นหลังดังนั้นการเชื่อมต่อ SSH จึงถูกระงับงาน

ฉันต้องการรีสตาร์ทเครื่องโลคัล (ไม่ใช่เซิร์ฟเวอร์) ที่ฉันได้เปิดเซสชัน ssh แต่ต้องการให้งานทำงานต่อไป เป็นไปได้ไหม?

คำตอบ:


22

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

หากการสนับสนุนกระบวนการของคุณจะอยู่ในพื้นหลังและโดยเฉพาะอย่างยิ่งไม่แขวนเมื่อstdoutและstderrเป็นไม่สามารถเขียนทับ / ปิดคุณสามารถวางไว้ในพื้นหลังก่อนที่จะเข้าสู่ระบบออกมาด้วยControlZและbgจากนั้นแยกได้จากเปลือกของคุณด้วยdisownในตัว

เช่น:

$ ssh localhost
You have new mail.
Last login: Fri Jun  6 11:26:56 2014

$ /bin/sleep 3600    


^Z[1] + Stopped                  /bin/sleep 3600
$ bg
[1] /bin/sleep 3600&
$ jobs
[1] +  Running                 /bin/sleep 3600
$ disown %1
$ exit
Connection to localhost closed.
$ ps -ef|grep sleep
jlliagre 12864     1  0 21:12 ?        00:00:00 /bin/sleep 3600
jlliagre 13056 12477  0 21:13 pts/18   00:00:00 grep sleep
$ 

*ตามที่บ๊อบให้ความเห็นมีหลายวิธีที่แฮ็กจริงในการซ่อมแซมเซสชั่น tty ภายใต้ Linux repty, Retty , injcodeและneercs รูปลักษณ์ที่ทันสมัยที่สุดจะเป็นreptyrแต่คุณอาจต้องการสิทธิ์รูทเพื่อเปิดใช้งาน ptrace เพื่อแฮกกระบวนการของคุณ


ฉันใช้ Ctrl + Z งานหยุดและย้ายไปที่พื้นหลังจากนั้นทำdisownคำสั่ง มันกลับมา: bash: คำเตือน: การลบงานที่หยุด 1 กับกลุ่มกระบวนการ 24876 ตอนนี้งานของฉันอยู่ในรายการps -allแต่ดูเหมือนจะไม่ทำงาน (การใช้งาน CPU คือ 0%)
Ali

ดูเหมือนว่ากระบวนการของฉันจะหยุด ฉันเดาว่าฉันควรจะให้รหัส proces กับdisownคำสั่ง
อาลี

@Ali ฉันคิดว่าคุณลืมรันคำสั่ง bg เพื่อกลับมาทำงานที่ถูกระงับอีกครั้ง
Jason Zhu

1
@ JasonZhu ขอบคุณที่ชี้ให้เห็นว่า มันไม่ชัดเจนว่าbgจำเป็นต้องมีคำสั่งในส่วนแรกของคำตอบของฉัน แก้ไข
jlliagre

2
หากคุณลืมคำสั่ง bg และรันคำสั่ง disown เพียงอย่างเดียวคุณควรจะสามารถทำให้กระบวนการทำงานอีกครั้งโดยkill -CONTที่ไม่เหมือนกับ bg
kasperd

5

ทางออกหนึ่งคือการใช้หน้าจอ GNU คุณสามารถเริ่มต้นขึ้นเรียกใช้คำสั่งของคุณแล้วถอดด้วยscreen C-a dต่อมาในการเชื่อมต่อทำscreen -rและคุณกลับมาที่เซสชันก่อนหน้า

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

แก้ไข: ดังที่ระบุไว้ในความคิดเห็นสิ่งนี้จะทำงานได้ก็ต่อเมื่อคุณจำได้ว่าต้องเริ่มscreenก่อนที่จะรันคำสั่ง หากคำสั่งกำลังทำงานอยู่คุณจะต้องแก้ปัญหาของ @ jlliagre


2
tmuxเป็นอีกโปรแกรมscreenที่ช่วยให้คุณมีเซสชันระยะไกลซึ่งไม่ได้เชื่อมโยงกับการเชื่อมต่อ SSH ปัจจุบันของคุณ
Darth Android

2
ทางออกของคุณยอดเยี่ยม แต่มันไม่ได้สมบูรณ์พอดีกับคำถามของฉัน - screenฉันถามเกี่ยวกับการทำงานในขณะนี้กระบวนการไม่ได้กระบวนการที่จะทำงานในอนาคตโดยใช้
อาลี

อ่าโอเค. ในกรณีนี้ฉันคิดว่าคุณจะต้องใช้โซลูชันของ @ jlliagre (เท่าที่ฉันรู้ไม่มีวิธีที่จะเชื่อมต่อกระบวนการที่กำลังทำงานอยู่กับบางสิ่งบางอย่างเช่นscreenหรือtmux.)
Scott Weldon

1

หนึ่งในวิธี "มาตรฐาน" ที่จะทำคือการใช้nohupคำสั่งรวมอยู่ในcoreutilsเช่นนี้

nohup COMMAND [ARGS] &

แต่คำสั่งจะเปลี่ยนเส้นทางเอาต์พุต ( STDOUT& STDERRAFAIK) ของโปรแกรมไปเป็นไฟล์nohup.outทำให้บางครั้งน่ารำคาญ (เช่นการสร้างไฟล์บันทึกขนาดใหญ่) ดังนั้นคุณอาจต้องการเปลี่ยนเส้นทางของคุณเองหรือเปลี่ยนเส้นทางไปยัง / dev / null ถ้าคุณต้องการ.


2
อ่านอีกครั้ง. กระบวนการกำลังทำงานอยู่
การแข่งขัน Lightness กับโมนิก้า

/ ละอายใจไม่ได้อ่านอย่างละเอียด ขอโทษ
wangguoqin1001

จริง ๆ แล้วnohupสามารถใช้สำหรับสิ่งนี้ เพียงแค่ระงับกระบวนการทำงานและส่งไปยังพื้นหลัง ( Ctrl+ Zและเรียกใช้bg) nohup %1และจากนั้นคุณสามารถออก
ไมค์

0

นอกจากนี้nohupคุณสามารถเปิดใช้งานกระบวนการในพื้นหลังโดยใช้ "&" และ subshell:

ต่อท้ายคำสั่งด้วย & และล้อมรอบในวงเล็บ

$ (thecommand args &)

ให้บอกว่ากระบวนการของคุณได้รับ pid 1922:

$ ps -f
UID        PID  PPID  C STIME TTY          TIME CMD
usr      11473  2643  0 15:07 pts/1    00:00:00 bash
usr      11922     1  0 15:11 pts/1    00:00:00 thecommand

ดูว่ามันไม่ได้เชื่อมต่อจากกระบวนการเชลล์ 11473 ซึ่งเป็นพาเรนต์ดั้งเดิม ดังนั้นหากคุณออกหรือฆ่าเชลล์ปัจจุบัน (11473) กระบวนการ 11922 จะยังคงทำงานต่อไปและมันจะถูกตัดการเชื่อมต่อจาก pts

ลองออกจากเปลือกและใส่ในเปลือกใหม่ แม้ว่าเชลล์นี้เชื่อมต่อกับ pts เดียวกันคุณสามารถดูกระบวนการได้โดยไม่ต้องใช้ pts:

$ ps -fp 11922
UID        PID  PPID  C STIME TTY          TIME CMD
usr      11922     1  0 15:11 ?        00:00:00 thecommand

ฉันไม่ได้เรียกหรือจัดทำเป็นเอกสารใน Posix แต่ฉันใช้วิธีนี้มาตั้งแต่ปี 1990 ใน bsh, ksh และตอนนี้ทุบตี

สุดท้ายคุณสามารถใช้bgคำสั่ง builtin shell:

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

$ thecommand
^Z
[1] Stopped          thecommand

ตอนนี้ปล่อยให้มันทำงานในพื้นหลังต่อไป:

$ bg
[1]+ thecommand &

หากคุณดูที่กระบวนการข่าวสารนั้นยังมีกระบวนการหลัก:

$ ps -f
UID        PID  PPID  C STIME TTY          TIME CMD
usr      12046  2643  0 15:18 pts/6    00:00:00 bash
usr      12571 12046  0 16:00 pts/6    00:00:00 thecommand
usr      12601 12046  0 16:04 pts/6    00:00:00 ps -f

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

$ exit

เข้าสู่ระบบอีกครั้งและดูข้อมูลกระบวนการ:

$ ps -f 12571
UID        PID  PPID  C STIME TTY          TIME CMD
usr      12571     1  0 16:00 ?        00:00:00 thecommand
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.