Bunuh semua pekerjaan latar belakang


63

Apakah ada bentuk pembunuhan latar belakang yang lebih ringkas daripada:

for i in {1..5}; do kill %$i; done

Juga, {1..5} jelas memiliki angka ajaib hard-coded di dalamnya, bagaimana saya bisa membuatnya "N" dengan N menjadi angka yang tepat, tanpa melakukan:

$(jobs | wc -l)

Saya benar-benar menggunakan \ j di PS1 untuk mendapatkan # pekerjaan terkelola, apakah ini setara?


3
kill $(jobs -p)sepertinya lebih mudah.
jw013

Saya lebih suka untuk membunuh pekerjaan secara individu, jika memungkinkan. (Saya mungkin salah paham dengan komentar Anda)
Robottinosino

for pid in $(jobs -p); do kill $pid; done?
jw013

3
@ jw013 Ini bukan hanya lebih mudah, itu sebenarnya benar (tolong posting sebagai jawaban), tidak seperti solusi berdasarkan menghitung garis-garis output jobsyang hanya berfungsi jika pekerjaan diberi nomor secara berurutan. Oh, dan “bunuh pekerjaan sendiri-sendiri” tidak ada artinya: meneruskan beberapa PID ke killperintah melakukan hal yang persis sama dengan melewatkannya secara terpisah.
Gilles 'SO- stop being evil'

Saya salah memasukkan perintah, membunuh kata-kata $ (pekerjaan -p) dan terlihat sangat benar juga bagi saya. Siap menerima.
Robottinosino

Jawaban:


101

Untuk killsemua pekerjaan latar belakang yang dikelola oleh bash, lakukan

kill $(jobs -p)

Perhatikan bahwa karena keduanya jobsdan killdibangun ke dalam bash, Anda tidak boleh mengalami kesalahan jenis daftar Argumen terlalu lama .


2
Juga untuk anak cucu, apa yang dipikirkan bahamat adalah cara untuk melakukannya dalam zshmendiskualifikasi mereka sebagai pihak yang berwenang dalam topik tersebut.
peth

Saya merasa saya harus tahu ini, tetapi bagaimana '$' bekerja di sini?
fersarr

1
@fersarr Ini dia
jw013

@ Bahahamat Itu tidak benar-benar berfungsi karena PID mungkin di bidang 2 atau 3 tergantung pada apakah pekerjaan itu salah satu dari% + atau% - atau tidak. Apa yang berhasil kill %${(k)^jobdirs}, yang memang lebih panjang; jika Anda perlu membuat daftar PID maka Anda dapat menggunakannya lebih lama lagi ${${jobstates#*:*:}%%=*}.
Gilles 'SO- stop being evil'

Pada CentOS, prompt saya menunggu input lebih banyak>
Janac Meena

15

Gunakan xargsalih-alih $(jobs -p)sub- perintah , karena jika jobs -pkosong maka perintah kill akan gagal.

jobs -p | xargs kill

1
Ini memiliki efek yang persis sama, ia mencetak bantuan dan keluar dengan kode 123
cat

1
Perintah ini berfungsi dengan baik pada OSX tetapi tidak bekerja pada Debian
brunocascio

Ini bekerja dengan baik pada CentOS 6
Janac Meena

jobs -p | xargs -rn10 killakan lebih baik jika jobs -ptidak mengembalikan PID. Perhatikan bahwa -ropsi adalah ekstensi GNU.
NarūnasK

Seperti disebutkan di atas, -rini adalah format pendek untuk --no-run-if-emptyekstensi GNU xargsyang memerintahkannya untuk tidak menjalankan perintah jika stdin tidak memiliki data.
Anthony G - keadilan untuk Monica

3

Saya lebih suka memeriksa apakah ada pekerjaan yang ada sebelum membunuh mereka - dengan cara ini skrip tidak akan gagal jika tidak ada yang berjalan.

Ini juga lebih pendek untuk diketik. Lemparkan ini ke Anda .bash_profile:

function killjobs () {
    JOBS="$(jobs -p)";
    if [ -n "${JOBS}" ]; then;
        kill -KILL ${JOBS};
    fi
}

Lalu lari:

killjobs

Untuk mematikan pekerjaan yang sedang berjalan.


1

Saya memiliki beberapa perintah majemuk latar belakang yang ingin saya akhiri dengan anggun, dengan mengirimkan SIGINT ke setiap proses, di macOS. Tidak ada solusi lain yang bekerja dengan baik untuk itu, jadi saya datang dengan ini:

jobs -p | xargs -n1 pkill -SIGINT -g

jobs -p daftar proses latar belakang yang dimulai oleh shell saat ini.

xargs -n1 mengeksekusi pkill sekali untuk setiap pekerjaan.

pkill -SIGINT -g mengirimkan SIGINT (sama seperti ctrl + c) ke semua proses dalam grup proses.


1

Saya kira tergantung pada apa yang jobs -pmemberikan output , solusinya bisa sedikit berbeda. Dalam hal ini

$ jobs -p
[1]  - 96029 running    some job
[2]  + 96111 running    some other job

Karena itu, melakukan yang berikut ini tidak baik.

$ jobs -p | xargs kill
kill: illegal process id: [1]

Di sisi lain, menjalankan kill $(jobs -p)tidak berfungsi tetapi memerlukan banyak pesan kesalahan, karena string non-PID diteruskan killjuga.

Oleh karena itu, solusi saya adalah dengan grepPID terlebih dahulu dan kemudian gunakan xargs, sebagai berikut:

$ jobs -p | grep -o -E '\s\d+\s' | xargs kill

1
Shell apa yang Anda gunakan? Apa yang echo $0ditunjukkan? Apa yang help jobsditunjukkan? Output yang diilustrasikan tidak sesuai dengan POSIX ; implementasi apa punjobs harus memiliki -popsi dengan perilaku yang dimaksud.
Wildcard

1
Terima kasih telah menunjukkan ini. Saya menggunakan zsh, dan itulah alasan untuk output yang aneh. Saya beralih ke bash dan jobs -phanya menghasilkan PID. Saya baru saja belajar bahwa zsh tidak sepenuhnya kompatibel dengan POSIX.
Fanchen Bao

0

Sepertinya jobs -p | xargs killmelakukan pekerjaan itu, namun menghasilkan beberapa keluaran yang tidak diinginkan untuk dimatikan. Di sini saya mengelompokkan output jobs -pdengan memiliki / tidak memiliki karakter + atau -

function killjobs() {
    JOBS=$(jobs -p)
    echo $JOBS | grep -v "+\|-"| awk '{print $2}' | xargs kill -9
    echo $JOBS | grep "+\|-"| awk '{print $3}' | xargs kill -9
}

Dan nanti Anda bisa menelepon killjobs

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.