ฉันจะฆ่างานที่หยุดทั้งหมดได้อย่างไร


91

เมื่อฉันพยายามออกจากเซิร์ฟเวอร์ Linux ฉันได้รับข้อความ:

มีงานที่หยุด

: มีคำสั่งเดียวที่จะฆ่าพวกนี้เหรอ


ตัวอย่างเพิ่มเติมในคำถาม & คำตอบ U: L unix.stackexchange.com/questions/124428/…
slm

ฉันมีปัญหาตรงข้ามตอนนี้มันจะไม่เตือนเกี่ยวกับงานที่หยุดเมื่อฉันออกจากเปลือก! ต้องใส่shopt -s checkjobsใน. bashrc ของฉัน
Sam Watkins

1
กด ctrl + d อีกครั้งมันจะช่วยให้คุณออกตอนนี้ฆ่างานเหล่านั้นในกระบวนการ
Jens Timmerman

คำตอบ:


73

หากต้องการฆ่างานที่หยุดทั้งหมดภายใต้ bash อย่างรวดเร็วให้ป้อน:

kill -9 `jobs -ps`

jobs -psแสดงรายการ ID กระบวนการ ( -p) ของงานที่หยุด ( -s)
kill -9 `jobs -ps`ส่งสัญญาณ SIGKILL ให้กับพวกเขาทั้งหมด


22
-1 สำหรับ "kill Jobs"

1
ไม่ทำงานเมื่องานเป็น "sudo su" เช่นsudo kill `jobs -p`ทำงานไม่ได้ แต่พิมพ์ PID อย่างชัดเจน
user13107

14
ทำไม upvoted นี้ถึงสูงมาก? มันผิด. หากกระบวนการหยุดทำงานkillเช่นนี้จะไม่ทำอะไรเลยเนื่องจากกระบวนการหยุดทำงานกระบวนการเหล่านั้นจะไม่ประมวลผล SIGTERM (-15) ที่ส่งไปยังกระบวนการเหล่านั้นตามค่าเริ่มต้น
slm

6
kill -9 จะทำการหลอกลวง
กำหนดเวลา

84

ลองพิมพ์สิ่งนี้:

kill -9 $(jobs -p)

9
ที่ควรทำ แต่ฉันคิดว่าเขาควรส่ง SIGTERM (-15) ก่อนที่จะส่ง SIGKILL (-9) ดังนั้นอาจเสนอบางสิ่งเช่น "kill $ (jobs -p); sleep 3s; kill -9 $ (jobs -p)" จะดีกว่า การส่ง SIGTERM ก่อนงานอาจสามารถทำการ clean exit ได้ (การจัดสรรทรัพยากร ฯลฯ )
rems

3
Kevin Duke คำตอบของคุณคือคำตอบที่เหมาะกับฉัน ฉันไม่สามารถลงคะแนนได้เพราะฉันไม่มีชื่อเสียง 15 คน kill -9 $ (jobs -p)

2
@rems ยกเว้นตามที่ slm ชี้ให้เห็นพวกเขาจะไม่ได้รับ SIGTERM เพราะหยุดทำงาน
พอลเกียร์

1
ไม่ทำงานบน zsh เนื่องจากzsh ไม่เป็น POS ทรงเครื่องสอดคล้องกับงาน
Max Coplan

แล้วจะจัดการกับ zsh ได้อย่างไร?
fx-kirin

16

คำตอบที่ยอมรับจะฆ่างานทั้งหมด (ซึ่งเพียงพอในกรณีนี้) และไม่เพียง แต่งานที่หยุด หากคุณต้องการที่จะฆ่าเพียงคนที่หยุดให้เรียกใช้:

kill $(jobs -l | grep Stopped | cut -d' ' -f3)

สามารถรวม grep / cut ได้ในคำสั่ง awk เดียว: awk '/Stopped/{print $3}')
laebshade

2
-sโต้แย้งเกี่ยวกับฟิลเตอร์ตอบรับเพียงคนหยุด
79E09796

12

วิธีที่ง่ายที่สุดคือการพยายามออกจากทางออกในทันที bashจะหมายความว่า "ฆ่างานที่หยุดและออก"


4
ที่จะส่ง HUP ซึ่งไม่จำเป็นต้องหยุดงานใด ๆ
Stephen Niedzielski

7
for x in `jobs -p` ; do kill -9 $x ; done

2
คุณสามารถเพิ่มการจัดรูปแบบรหัสสำหรับบรรทัดนี้เพื่อให้อ่านง่ายขึ้น
drcelus

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

การจัดรูปแบบเป็นเรื่องปกติ เราต้องผ่านงาน -p โดยใช้ backticks อื่นมันไม่ถือว่าเป็นคำสั่งและมันจะส่งข้อผิดพลาด
monu

5

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

บิตของการขุดไปรอบ ๆ กับman psฉันได้ที่:

ps -a -o pid,user,cmd,state | grep 'T$'

คำอธิบาย: -aแฟล็กแจ้งว่าแสดงกระบวนการทั้งหมดจากนั้น-oควบคุมเอาต์พุตข้อมูลใดที่จะแสดงเกี่ยวกับแต่ละกระบวนการ ฉันเลือกpid, user, cmd(บรรทัดคำสั่ง) และstateซึ่งเป็นกระบวนการของรัฐ

จากman ps:

PROCESS STATE CODES
   Here are the different values that the s, stat and state output specifiers (header "STAT" or "S") will display to describe the
   state of a process:
           D    uninterruptible sleep (usually IO)
           R    running or runnable (on run queue)
           S    interruptible sleep (waiting for an event to complete)
           T    stopped, either by a job control signal or because it is being traced
           W    paging (not valid since the 2.6.xx kernel)
           X    dead (should never be seen)
           Z    defunct ("zombie") process, terminated but not reaped by its parent

ดังนั้นในที่สุดฉันก็ส่งไปgrep T$ที่ที่แสดงให้ฉันเห็นกระบวนการทั้งหมดที่มี T ในคอลัมน์สุดท้าย

แล้วฉันมีรายการที่ดีของกระบวนการทั้งหมดจากผู้ใช้ที่แตกต่างกันที่อยู่ในสถานะหยุด

$ ps -a -o pid,user,cmd,state | grep 'T$'
  865 joson74+ python                      T
  885 joson74+ sh -c less                  T
  886 joson74+ less                        T
 1014 minames+ python3.4 -i /home/minames  T
 5352 MooKo    nano stdio.h                T
 7851 harry    tmux attach                 T
12083 harry    tmux attach                 T
13495 gorylla+ python3.4 -i /home/gorylla1 T
18009 conr1d   vim                         T
19664 enythin+ python                      T
24906 wardlist python                      T

ในการหยุดงานที่แนบกับเชลล์ปัจจุบันjobs -psนั้นง่ายกว่าคำตอบนี้ คำตอบนี้ไม่แสดงเฉพาะงานที่หยุดทำงานCtrl-Zในเชลล์ แต่งานที่หยุดทั้งหมด: เชลล์อื่นผู้ใช้อื่นรวมถึงงานที่กำลังดีบั๊ก (เช่นโดย gdb)
Stéphane Gourichon

สำหรับฉันคำตอบที่ดีที่สุด แต่ไม่ได้ทำงานอย่างแน่นอน ฉันต้องใช้ps -el | grep Tเพื่อค้นหากระบวนการในสถานะ 'T'
dr0i

4

หากคุณต้องการลบงานที่หยุดบางงาน แต่ไม่ใช่ทั้งหมดลองทำสิ่งนี้:

ก่อนอื่นทำรายการคุณจะได้รับสิ่งนี้:

$ jobs -l

[2]   4813 Stopped                 ./parse < call.txt
[3]-  4819 Stopped                 ./parse < call.txt

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

$ fg %2
./parse < call.txt
Terminated

$ jobs -l
[3]-  4819 Stopped                 ./parse < call.txt

4

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

หากต้องการฆ่าด้วยตนเองให้ลอง: kill $(jobs -p).


หากคุณไม่ต้องการฆ่างานจากเชลล์ปัจจุบันของคุณคุณสามารถลบงานออกจากตารางของงานที่กำลังทำงานอยู่โดยไม่ต้องฆ่าโดยใช้disownคำสั่ง เช่น

$ sleep 1000 &
[1] 19404
$ jobs
[1]+  Running                 sleep 1000 &
$ disown

งานหยุดนอกจากนี้ยังสามารถกำหนดโดยรัฐของกระบวนการ (ที่Tตัวอักษร) ซึ่งหมายความว่ากระบวนการหยุดสัญญาณเช่นSIGSTOP, SIGTSTPหรืออื่น ๆ (เช่นSIGTTINหรือSIGTTOU)

ในกรณีที่jobsคำสั่ง shell builtin ไม่พร้อมใช้งานกระบวนการที่หยุดทำงานสามารถแสดงรายการโดยคำสั่งต่อไปนี้:

ps wuax | awk '$8 ~ "T"'

หากต้องการฆ่าพวกเขาทั้งหมดคุณสามารถพิมพ์:

kill -9 $(ps wuax | awk 'NR>1 && $8 ~ "T" {print $2}')

นี่คือการทดสอบอย่างง่าย:

$ sleep 1000 &
[1] 2014
$ sleep 1000 &
[2] 2015
$ sleep 1000 &
[3] 2016
$ sleep 1000 &
[4] 2017
$ killall -STOP sleep
[1]   Stopped                 sleep 1000
[2]   Stopped                 sleep 1000
[3]   Stopped                 sleep 1000
[4]   Stopped                 sleep 1000
$ ps wuax | awk '$8 ~ "T"'
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
vagrant   2014  0.0  0.0   7228   832 pts/0    T    20:38   0:00 sleep 1000
vagrant   2015  0.0  0.0   7228   708 pts/0    T    20:38   0:00 sleep 1000
vagrant   2016  0.0  0.0   7228   760 pts/0    T    20:38   0:00 sleep 1000
vagrant   2017  0.0  0.0   7228   828 pts/0    T    20:38   0:00 sleep 1000
$ kill -9 $(awk 'NR>1 && $8 ~ "T" {print $2}' <(ps wuax))
$ jobs
[1]   Killed                  sleep 1000
[2]   Killed                  sleep 1000
[3]   Killed                  sleep 1000
[4]   Killed                  sleep 1000
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.