Bagaimana saya bisa membunuh semua pekerjaan yang terhenti?

91

Ketika saya mencoba keluar dari server Linux saya, saya mendapatkan pesan:

Ada pekerjaan yang berhenti.

: Apakah ada satu perintah untuk membunuh ini?

Zubair
sumber
Contoh tambahan dalam U&L Tanya Jawab: unix.stackexchange.com/questions/124428/…
slm
Saya memiliki masalah yang berlawanan sekarang, tidak akan memperingatkan tentang berhentinya pekerjaan ketika saya keluar dari shell! Harus memasukkan shopt -s checkjobs.bashrc saya
Sam Watkins
1
tekan ctrl + d lagi, itu akan membiarkan Anda keluar sekarang, membunuh pekerjaan itu dalam proses
Jens Timmerman

Jawaban:

73

Untuk dengan cepat membunuh semua pekerjaan yang dihentikan di bawah bash, masukkan:

kill -9 `jobs -ps`

jobs -psdaftar ID proses ( -p) dari pekerjaan yang dihentikan ( -s).
kill -9 `jobs -ps`mengirimkan sinyal SIGKILL ke semuanya.

ooshro
sumber
22
-1 untuk "kill Jobs"
1
tidak bekerja ketika pekerjaan itu "sudo su". yaitu sudo kill `jobs -p`tidak bekerja tetapi secara eksplisit mengetik PID berhasil.
user13107
14
Mengapa hal ini sangat dijunjung tinggi? Itu salah. Jika proses dihentikan, maka killseperti ini tidak akan melakukan apa-apa, karena proses dihentikan, mereka tidak akan memproses SIGTERM (-15) yang dikirim kepada mereka secara default.
slm
6
kill -9 akan melakukan trik.
tepat waktu
84

Coba ketikkan ini:

kill -9 $(jobs -p)
dukevin
sumber
9
Itu harus dilakukan, tapi saya pikir dia harus mengirim dulu SIGTERM (-15) sebelum mengirim SIGKILL (-9). Jadi mungkin mengusulkan sesuatu seperti "kill $ (jobs -p); sleep 3s; kill -9 $ (jobs -p)" akan lebih baik. Mengirim SIGTERM terlebih dahulu pekerjaan mungkin dapat melakukan jalan keluar yang bersih (membebaskan sumber daya yang dialokasikan, dll).
rem
3
Kevin Duke, jawaban Anda adalah yang bekerja untuk saya. Saya tidak dapat memilih karena saya tidak memiliki 15 reputasi. kill -9 $ (jobs -p)
2
@rems Kecuali, seperti yang ditunjukkan slm, mereka tidak akan mendapatkan SIGTERM karena mereka dihentikan.
Paul Gear
1
Tidak berfungsi di zsh. Karena zsh tidak mematuhi POS IX dengan pekerjaan .
Max Coplan
Lalu, bagaimana cara berurusan dengan zsh?
fx-kirin
16

Jawaban yang diterima akan mematikan semua pekerjaan (yang cukup dalam kasus ini) dan bukan hanya yang berhenti. Jika Anda ingin hanya membunuh yang Berhenti, jalankan:

kill $(jobs -l | grep Stopped | cut -d' ' -f3)
Kit Sunde
sumber
grep / cut dapat digabungkan dalam satu perintah awk: awk '/Stopped/{print $3}')
laebshade
2
yang -sargumen pada filter jawaban yang diterima hanya yang berhenti
79E09796
12

Cara termudah sebenarnya adalah dengan segera mencoba kembali pintu keluar; bashakan menganggap itu berarti "bunuh semua pekerjaan yang berhenti dan keluar".

geekosaurus
sumber
4
Itu akan mengirim HUP yang tidak serta merta menghentikan pekerjaan apa pun.
Stephen Niedzielski
7
for x in `jobs -p` ; do kill -9 $x ; done
monu
sumber
2
Anda dapat menambahkan pemformatan kode untuk baris ini agar lebih mudah dibaca.
drcelus
Dapatkah Anda melihat format lagi - gunakan empat spasi di awal baris untuk menandai blok sebagai kode (daripada menggunakan backtick). Saat ini tidak jelas apakah Anda menggunakan backticks dalam kode Anda, atau mencoba menampilkan kode menggunakan backticks.
dunxd
Formatnya baik-baik saja. kita harus melewati pekerjaan -p menggunakan backticks yang lain itu tidak akan dianggap sebagai perintah, dan itu akan menimbulkan kesalahan.
monu
5

Kalau-kalau ini membantu orang lain - kebanyakan orang di sini karena mereka memiliki beberapa proses berhenti yang mereka mulai, mungkin latar belakang melalui shell. Saya perlu menemukan proses, sebagai root, dihentikan oleh pengguna lain, untuk mana varian pada jobsperintah tidak akan melakukannya.

Sedikit menggali dengan man psmembuat saya melakukan ini:

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

Penjelasan: -abendera mengatakan tunjukkan semua proses, kemudian -okontrol output, info apa yang akan ditampilkan tentang setiap proses. Saya memilih pid, user, cmd(baris perintah), dan state, yang merupakan negara proses .

Dari 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

jadi akhirnya saya menyalurkannya ke grep T$yang mengatakan, tunjukkan semua proses yang memiliki T di kolom terakhir.

Dan kemudian saya memiliki daftar yang bagus dari semua proses dari pengguna yang berbeda yang dalam keadaan berhenti.

$ 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
hwjp
sumber
Untuk menghentikan pekerjaan yang terkait dengan shell saat ini, jobs -pslebih sederhana dari jawaban ini. Karena itu, jawaban ini tidak hanya menampilkan pekerjaan yang dihentikan melalui Ctrl-Zshell, tetapi semua menghentikan pekerjaan: shell lain , pengguna lain , termasuk pekerjaan yang sedang di-debug (mis. Oleh gdb).
Stéphane Gourichon
Bagi saya jawaban terbaik, tetapi tidak sepenuhnya bekerja. Saya harus menggunakan ps -el | grep Tuntuk menemukan proses dalam keadaan 'T'.
dr0i
4

Jika Anda ingin menghapus beberapa pekerjaan yang terhenti tetapi tidak semua, coba ini:

Pertama, daftar pekerjaan, Anda akan mendapatkan sesuatu seperti ini:

$ jobs -l

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

kirim kill ke pekerjaan yang dihentikan, ia tidak akan melakukan apa-apa selain mengantri daripada membawanya di latar depan, itu akan berakhir

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

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

Biasanya jika Anda mendapat pesan itu, Anda harus keluar dua kali. Misalnya pertama Ctrl+Dmemberi Anda pesan peringatan untuk memberi tahu Anda tentang pekerjaan yang berhenti, menekan untuk kedua kalinya akan mengeluarkan Anda dari membunuh pekerjaan. Ini berlaku untuk logoutdan exitperintah yang sama.

Untuk membunuh mereka secara manual, coba: kill $(jobs -p).


Jika Anda tidak ingin mematikan pekerjaan dari shell Anda saat ini, Anda dapat menghapusnya dari tabel pekerjaan aktif tanpa membunuh dengan menggunakan disownperintah. Misalnya

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

Pekerjaan yang dihentikan juga dapat ditentukan oleh keadaan proses ( Tkarakter) yang berarti proses dihentikan oleh sinyal seperti SIGSTOP, SIGTSTPatau lainnya (seperti SIGTTIN, atau SIGTTOU).

Jika jobsperintah shell builtin tidak tersedia, proses yang dihentikan dapat didaftar dengan perintah berikut:

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

Untuk membunuh mereka semua, pada dasarnya Anda dapat mengetik:

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

Berikut ini adalah tes sederhana:

$ 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
kenorb
sumber