ฉันสามารถ nohup / กลั่นกรองกระบวนการที่เริ่มต้นแล้วหรือไม่


260

ฉันกำลังดำเนินการทดสอบสคริปต์การย้ายข้อมูลระยะยาวผ่าน SSH สมมติว่าฉันเริ่มเรียกใช้สคริปต์รอบ 16:00; ตอนนี้ 18:00 screenม้วนรอบและฉันแช่งตัวเองไม่ได้ทำเช่นนี้ทั้งหมดใน

มีวิธีใดในการ "ย้อนnohupกระบวนการ" หรือฉันต้องออกจากคอมพิวเตอร์ออนไลน์ตลอดทั้งคืน? หากไม่สามารถแนบscreenกับ / nohupa โพรเซสที่ฉันเริ่มแล้วทำไม? มีบางอย่างเกี่ยวกับวิธีที่ผู้ปกครอง / เด็กโพรเซสโต้ตอบ? (ฉันจะไม่ยอมรับคำตอบที่ "ไม่" อย่างน้อยก็ไม่ได้ตอบคำถาม 'ทำไม' - ขอโทษ;)


4
disownเพียงแค่เห็นการโพสต์บล็อกน่าสนใจเกี่ยวกับ blogs.oracle.com/ksplice/entry/disown_zombie_children_and_the
ojrac

คำตอบ:


212

หากคุณใช้ Bash คุณสามารถเรียกใช้ disown -h job

บอกปัด

disown [-ar] [-h] [jobspec ...]

หากไม่มีตัวเลือกงานแต่ละงานจะถูกลบออกจากตารางของงานที่ใช้งานอยู่ หากได้รับ-hตัวเลือกงานจะไม่ถูกลบออกจากตาราง แต่จะถูกทำเครื่องหมายเพื่อไม่ให้ SIGHUP ส่งไปยังงานหากเชลล์ได้รับ SIGHUP หาก jobspec ไม่มีอยู่และไม่มีการจัดหา-aหรือไม่มี-rตัวเลือกงานปัจจุบันจะถูกใช้ หากไม่มีการจัดหา jobspec -a ตัวเลือกหมายถึงการลบหรือทำเครื่องหมายงานทั้งหมด; -rตัวเลือกโดยไม่ต้องอาร์กิวเมนต์ jobspec จำกัด การดำเนินงานการทำงาน


น่ากลัว; ฉันหวังว่าบางอย่างเช่นนี้จะเปิดขึ้น
ojrac

7
ชีวิตอาจไม่ยุติธรรม gharper และฉันได้รับการโพสต์นี้ที่เกี่ยวกับเวลาเดียวกัน :)
serverhorror

4
คุณเป็นฮีโร่ของฉัน
โทมัสดิจญัน

9
การปฏิเสธไม่เฉพาะเจาะจงกับการทุบตี นอกจากนี้ยังอยู่ใน zsh, ksh93, ...
ฟิล P

2
ฉันพบว่าคุณต้องใช้จริงdisown %1ถ้า 1 คือ jobspec ไม่เหมือนกับ fg หรือ bg ที่คุณใช้bg 1 serverwatch.com/tutorials/article.php/3935306/ …
mltsy

81

ใช้reptyr

จาก README:

reptyr - A tool for "re-ptying" programs.
-----------------------------------------

reptyr is a utility for taking an existing running program and
attaching it to a new terminal. Started a long-running process over
ssh, but have to leave and don't want to interrupt it? Just start a
screen, use reptyr to grab it, and then kill the ssh session and head
on home.

USAGE
-----

  reptyr PID

"reptyr PID" will grab the process with id PID and attach it to your
current terminal.

After attaching, the process will take input from and write output to
the new terminal, including ^C and ^Z. (Unfortunately, if you
background it, you will still have to run "bg" or "fg" in the old
terminal. This is likely impossible to fix in a reasonable way without
patching your shell.)

บล็อกบางโพสต์โดยผู้เขียน:


ฉันจะใช้เครื่องมือในตัว (เช่นบอกว่าไม่ชอบ) แต่ก็ไม่ยืดหยุ่นเหมือน reptyr +1
ojrac

22

หากต้องการขโมยกระบวนการจาก tty หนึ่งถึง tty ปัจจุบันของคุณคุณอาจต้องการลองแฮ็คนี้:

http://www.ucc.asn.au/~dagobah/things/grab.c

จำเป็นต้องทำการฟอร์แมตใหม่เพื่อรวบรวมเป็นเวอร์ชั่น Linux / glibc ปัจจุบัน แต่ก็ยังใช้งานได้


1
เด็ดสุด ๆ
ojrac

16

เมื่อกระบวนการเริ่มต้น STDIN, STDOUT และ STDERR เชื่อมต่อกับบางสิ่งบางอย่าง โดยทั่วไปคุณไม่สามารถเปลี่ยนแปลงได้ว่าเมื่อคำสั่งเริ่มต้นขึ้น ในกรณีที่คุณกำลังอธิบายอาจเป็น tty ที่เกี่ยวข้องกับเซสชัน ssh nohup สวยมากแค่ทำ ...

command < /dev/null > nohup.out 2>&1

นั่นคือตั้งค่า STDIN เป็น / dev / null, STDOUT เป็นไฟล์และ STDERR เป็น STDOUT หน้าจอทำสิ่งที่ซับซ้อนมากขึ้นที่เกี่ยวข้องกับการตั้งค่า ttys ที่ตรงไปยังตัวเอง

ฉันไม่รู้วิธีใดเลยที่จะไม่เร่งความเร็วย้อนกลับหรือคัดกรองกระบวนการทำงาน หากคุณ cd to / proc / $ pid / fd และดูว่า 0, 1 และ 2 ชี้ไปที่อะไร

คุณอาจมีโชคกับการปฏิเสธ แต่ไม่ใช่ถ้ากระบวนการพยายามทำอะไรกับ STDIN, STDOUT หรือ STDERR


2
+1 สำหรับความคิดเห็นที่ดี st (din | out | err) เป็นอีกครึ่งหนึ่งของปัญหาและฉันขอขอบคุณคำแนะนำเกี่ยวกับสถานที่ที่จะเริ่มมองหาครั้งต่อไปที่ฉันติดขัด
ojrac

6
คุณสามารถเปลี่ยนได้จริงบน Unixes ส่วนใหญ่ มันเป็นแฮ็คที่น่าขยะแขยง ฉันรักมัน. :) สิ่งที่คุณทำคือเชื่อมต่อกระบวนการโดยใช้การสนับสนุนการดีบักเช่น ptrace จากนั้นบังคับให้กระบวนการเรียก dup2 () เพื่อเชื่อมต่อ 0,1,2 ไปยัง filehandle อื่น
Zan Lynx

2
ใช่คุณสามารถเปลี่ยนได้ เกี่ยวข้องกับการหยุดกระบวนการชั่วคราว (SIGSTOP) และแก้ไขตัวอธิบายไฟล์สำหรับ fd 0, 1, 2 จากนั้นเริ่มต้นใหม่ (SIGCONT)
Michael Martinez

13

Cryopidเป็นการพัฒนาเพิ่มเติมจากผู้เขียน grab.c ที่หยุดกระบวนการเป็นไฟล์ซึ่งคุณเรียกใช้ (หน้าจอภายใน) เพื่อดำเนินการกระบวนการต่อ


1
ดี! ฉันพยายามใช้ cryopid ในวิทยานิพนธ์ปริญญาโทของฉันเกี่ยวกับการย้ายกระบวนการ แต่มันล้มเหลวในการทำงานตลอดเวลาไม่ว่าฉันจะทำอะไร ในที่สุดฉันต้องใช้ dynckpt กับ Linux เวอร์ชันโบราณ คุณอาจมีส่วนร่วมในการพัฒนา cryopid หรือไม่? ฉันเห็นว่าชื่อของคุณคล้ายกับโดเมนของผู้แต่ง
Juliano

1
ฉันไม่ได้เกี่ยวข้องกับการพัฒนาฉันเพิ่งรู้จักผู้แต่งจากมหาวิทยาลัย เขาไม่มีเวลาที่จะรักษา cryopid ในขณะนี้ดังนั้นดูเหมือนว่าบางคนเริ่มทำงานกับมันที่Sharesource.org/project/cryopid
TRS-80

12

ฉันสามารถให้คุณ "ไม่" ง่าย ๆ โดยไม่มีเหตุผลสำหรับส่วนของหน้าจอฉันจะสนใจในเหตุผลที่ตัวเอง

อย่างไรก็ตามคุณได้ลองแล้วdisown(bash builtin)

~ $ echo $SHELL
/bin/bash
~ $ type disown
disown is a shell builtin
~ $ help disown
disown: disown [-h] [-ar] [jobspec ...]
     By default, removes each JOBSPEC argument from the table of active jobs.
    If the -h option is given, the job is not removed from the table, but is
    marked so that SIGHUP is not sent to the job if the shell receives a
    SIGHUP.  The -a option, when JOBSPEC is not supplied, means to remove all
    jobs from the job table; the -r option means to remove only running jobs.


5

ฉันเพิ่งเห็นลิงค์ไปยังneercsซึ่งเป็นยูทิลิตี้เหมือนหน้าจอที่สร้างขึ้นโดยใช้ libcaca ซึ่งเป็นห้องสมุดสี ASCII-art ท่ามกลางคุณสมบัติอื่น ๆ มันภูมิใจที่มีความสามารถในการคว้ากระบวนการที่มีอยู่และ re-parent มันในเซสชั่น neercs (หน้าจอ) ของคุณ

อย่างไรก็ตามฉันไม่ได้ใช้งานดังนั้นฉันไม่สามารถแสดงความคิดเห็นว่าทำงานได้หรือไม่


2

ฉันอาจไม่เข้าใจเรื่องนี้ดังนั้นโปรดแก้ไขให้ถูกต้อง (ฉันเรียนรู้เกี่ยวกับการปฏิเสธแล้ว) ... จะไม่มี ctrl-Z และ "bg" ทำงานอย่างน้อยจะทำให้กระบวนการทำงานในพื้นหลังหรือไม่ หรือเป็นปัญหาสำคัญที่คุณยังต้องการเห็น STDOUT ในขณะที่ทำงานอยู่


1
ที่ยังคงฆ่ากระบวนการเมื่อ TTY เจ้าของตายเพื่อ OP ต้องการที่จะออกจากกล่องที่เขา intiated คำสั่งการทำงานซึ่งเป็นสิ่งที่เขาต้องการที่จะหลีกเลี่ยง
serverhorror

ตกลงฉันจะซื้อมัน ขอบคุณสำหรับคำอธิบาย ดังนั้นข้อเสนอแนะปฏิเสธ -h แน่ใจว่าดูมากฉลาดกว่า :-) เหมือง
Chris_K

1
คุณยังสามารถทำสิ่งนี้ได้หลังจากที่คุณต้องปฏิเสธ -h: stackoverflow.com/a/625436/705198
AndrewPK

2

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


2

คุณสามารถเปลี่ยนเส้นทางผลลัพธ์กระบวนการไปยังไฟล์ด้วย gdb

https://blog-en.openalfa.com/how-to-detach-from-the-terminal-a-running-process-in-linux

จากนั้นบอกเลิกมัน

อัปเดต: ฉันต้องเรียกใช้ gdb ด้วย sudo และคำสั่ง gdb ที่แตกต่างกันเล็กน้อยใน Ubuntu 18.04:

p (int)dup2(open("/tmp/test.stdout", 1), 1)


ใช้ GDB ได้ดีมากขอบคุณ!
ojrac

1

ฉันต้องการใช้nohup(หรือคล้ายกัน) เพื่อเริ่มlinksเบราว์เซอร์บรรทัดคำสั่งและแนบไฟล์หลังจากดาวน์โหลดไฟล์จากเว็บไซต์ ASP.NET ที่มีกระบวนการตรวจสอบที่ซับซ้อนและสถานะการดูที่ซ่อนอยู่มากมายทำให้ยากต่อการใช้งาน ด้วย/curlwget

ในที่สุดฉันก็ลงเอยด้วยการใช้tmuxซึ่งแก้ไขงานที่ยอดเยี่ยมเพียง:

  1. วิ่ง tmux
  2. เปิดใช้งานแอปของคุณ ( linksในกรณีของฉัน) และปล่อยให้มันทำงาน
  3. ปิดเซสชัน SSH แอปจะยังคงทำงานอยู่
  4. เชื่อมต่อกับ SSH กับเครื่องเดียวกันในภายหลังและเรียกใช้tmux attachเพื่อนำแอปกลับไปที่หน้าจอ

tmux นั้นยอดเยี่ยม - แต่อย่าง nohup หรือหน้าจอมันจะใช้ได้ก็ต่อเมื่อคุณใช้มันก่อนเริ่มกระบวนการของคุณ คำถามนี้เกี่ยวกับเวลาที่คุณรู้ว่าคุณต้องการ tmux หลังจากกระบวนการทำงานอยู่
ojrac

-1

เป็นเพราะคุณกังวลเกี่ยวกับการหมดเวลาหรือไม่? ในกรณีนั้นคุณสามารถกด Ctrl-z และ bg ได้จากนั้นใส่ Somthing เพื่อทำให้เซสชั่นมีชีวิตเหมือน "ping -t localhost" หรือ "top"

หากคุณต้องการออกจากระบบฉันกลัวว่าจะไม่สามารถเพิ่มความคิดเห็นอื่น ๆ ได้


มันเป็นสิ่งที่ออกจากระบบ
ojrac

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