Припинення кожного фонового процесу


10

У мене є кілька Stoppedфонових процесів.

kill $(jobs -p)і kill `jobs -p`не мають ефекту

kill %1, kill %2тощо успішно припиняють окремі процеси

Як я можу вбити кожен фоновий процес однією командою?

Крім того, чому перші дві команди не працюють для мене?

Я працюю під Linux Mint 15, 64 біт

Відповіді:


10

Коли вони бігають

Здається, ви можете просто зробити це за допомогою killі виходу jobs -p.

Приклад

$ sleep 1000 &
[1] 21952
$ sleep 1000 &
[2] 21956
$ sleep 1000 &
[3] 21960

Зараз у мене працює 3 підроблені роботи.

$ jobs
[1]   Running                 sleep 1000 &
[2]-  Running                 sleep 1000 &
[3]+  Running                 sleep 1000 &

Вбийте їх усіх так:

$ kill $(jobs -p)
[1]   Terminated              sleep 1000
[2]-  Terminated              sleep 1000
[3]+  Terminated              sleep 1000

Підтвердження, що вони всі пішли.

$ jobs
$

Коли вони зупиняються

Якщо у вас зупиняються завдання, а не запущені, ви робите це замість цього.

Приклад

$ kill $(jobs -p)

$ jobs
[1]+  Stopped                 sleep 1000
[2]-  Stopped                 sleep 1000
[3]   Stopped                 sleep 1000

Гаразд, щоб не вбити їх, але це тому, що сигнал вбивства не може оброблятися самим процесом, він зупиняється. Тож скажіть ОС зробити замість цього вбивство. Ось для чого -9це.

$ kill -9 $(jobs -p)
[1]+  Killed                  sleep 1000
[2]-  Killed                  sleep 1000
[3]   Killed                  sleep 1000

Так краще.

$ jobs
$ 

Коли деякі працюють, а деякі зупиняються

Якщо у вас змішаний пакет процесів, коли деякі зупиняються, а деякі працюють, ви можете зробити killперший, а потім a kill -9.

$ kill $(jobs -p); sleep <time>; \
    kill -18 $(jobs -p); sleep <time>; kill -9 $(jobs -p)

Трохи продовжуючи час, якщо вам потрібно більше, щоб процеси спочатку зупинялися.

Сигнали

Ні HUP (-1), ні SIGTERM (-15) вбити не вдасться. Але чому? Це тому, що ці сигнали добріші в тому сенсі, що вони говорять програмі припинити себе. Але оскільки програма перебуває у зупиненому стані, вона не може обробляти ці сигнали. Таким чином, ви єдиний курс - використовувати SIGKILL (-9).

Ви можете бачити всі сигнали, які killнадає kill -l.

$ kill -l | column -t
1)   SIGHUP       2)   SIGINT       3)   SIGQUIT      4)   SIGILL       5)   SIGTRAP
6)   SIGABRT      7)   SIGBUS       8)   SIGFPE       9)   SIGKILL      10)  SIGUSR1
11)  SIGSEGV      12)  SIGUSR2      13)  SIGPIPE      14)  SIGALRM      15)  SIGTERM
16)  SIGSTKFLT    17)  SIGCHLD      18)  SIGCONT      19)  SIGSTOP      20)  SIGTSTP
21)  SIGTTIN      22)  SIGTTOU      23)  SIGURG       24)  SIGXCPU      25)  SIGXFSZ
26)  SIGVTALRM    27)  SIGPROF      28)  SIGWINCH     29)  SIGIO        30)  SIGPWR
31)  SIGSYS       34)  SIGRTMIN     35)  SIGRTMIN+1   36)  SIGRTMIN+2   37)  SIGRTMIN+3
38)  SIGRTMIN+4   39)  SIGRTMIN+5   40)  SIGRTMIN+6   41)  SIGRTMIN+7   42)  SIGRTMIN+8
43)  SIGRTMIN+9   44)  SIGRTMIN+10  45)  SIGRTMIN+11  46)  SIGRTMIN+12  47)  SIGRTMIN+13
48)  SIGRTMIN+14  49)  SIGRTMIN+15  50)  SIGRTMAX-14  51)  SIGRTMAX-13  52)  SIGRTMAX-12
53)  SIGRTMAX-11  54)  SIGRTMAX-10  55)  SIGRTMAX-9   56)  SIGRTMAX-8   57)  SIGRTMAX-7
58)  SIGRTMAX-6   59)  SIGRTMAX-5   60)  SIGRTMAX-4   61)  SIGRTMAX-3   62)  SIGRTMAX-2
63)  SIGRTMAX-1   64)  SIGRTMAX

Якщо ви хочете дізнатися ще більше про різні сигнали я настійно рекомендую один поглянути на сторінці сигналів людини, man 7 signal.


чому ми маємо +символ першого процесу та -символ другого процесу, а символ третього немає?
Рамеш

Я отримав ті ж результати, що і ви. Однак terminateзамість цього я хочу kill, оскільки я читав, що це безпечніше. Я спробував kill -15 $(jobs -p), але це не мало ефекту. Я здогадався, що зупинені процеси можна лише вбити, але потім знову kill %numberприпиняються (окремі) зупинені процеси.
user49888

@Ramesh +і -лише останні процеси , які я доторкнувся , коли я налаштовував приклади. Це +означає, що будь-які команди, які не містять явно, %#будуть діяти на цю команду. Dash ( -) - це друга за останню команду, яку я торкнувся.
slm

@ user49888 - kill -9 .. повинен був працювати. які процеси? Вони є неіснуючими чи осиротілими процесами?
slm

1
@ user49888 - так, якщо процес опинився в середині чогось, йому не дається можливість зробити будь-яку очистку до того, як його припинити.
slm

2

Ви можете спробувати це.

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

Однак якщо ви хочете припинити процес, ви можете видати команду як

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

На сторінці команди WikiKill ,

Процес може бути надісланий сигналом SIGTERM чотирма способами (ідентифікатор процесу в цьому випадку "1234"):

kill 1234
kill -s TERM 1234
kill -TERM 1234
kill -15 1234

Процес може надсилати сигнал SIGKILL трьома способами:

kill -s KILL 1234
kill -KILL 1234
kill -9 1234

Як пояснено у цій відповіді, це різниця між припиненням і вбивством .

Сигнал закінчення, SIGTERM , - це сигнал, який можна перехопити в програмі. Часто процеси, які призначені для запуску у фоновому режимі, вловлюють цей сигнал і запускають процес відключення, в результаті чого виходить чистий вихід. Сигнал вбивства SIGKILL не може бути перехоплений. Коли це надсилається до процесу, це призведе до різкого припинення дії цієї програми.

Наприклад, коли ви вимикаєте або перезавантажуєте комп'ютер, зазвичай, SIGTERM надсилається до запущених процесів спочатку, дозволяючи їм вийти чистим способом, якщо вони підтримують його. Потім через кілька секунд SIGKILL надсилається процесам, які все ще запущені, щоб ресурси, які використовуються, примусово звільняються (наприклад, використовувані файли), і послідовність відключення може продовжуватися (наприклад, відключення файлових систем).


Це робить killкожен фоновий процес. Однак чи є terminateнатомість їм спосіб , оскільки я вважаю, що це безпечніше?
user49888

Якщо ви хочете припинити, ви можете використовувати -15в команді kill.
Рамеш

-15тут також не буде працювати. Дивіться мій А.
slm

@Ramesh - останні 2 абзаци не вірні. SIGTERM не надсилається (не спочатку). Процеси намагаються спочатку зупинити через сервісні сценарії зупинки / запуску. Якби у такому випадку 9 було надіслано до процесу, тоді при зупиненні процесів, як у прикладі ОП, kill -9у моєму прикладі не працювало.
slm

1

Гаразд, граючи з цим, я бачу, що коли ви вбиваєте роботу, яку зупиняють (коли виконання було призупинено, але не припинено), воно не закінчиться, поки його не виведуть на перший план. Програми зазвичай зупиняються натисканням Ctrl- Zна терміналі. SIGSTOPУ цьому випадку більшість терміналів надсилає вхід, але, звичайно, є й інші способи надіслати його, наприклад, з kill -STOPабо kill -19.

Це нормальна поведінка, щоб програма не закінчувалася відразу, оскільки програма повинна працювати, щоб обробляти SIGTERMсигнал за замовчуванням, який надсилає повідомлення kill. Більше того, іноді після bashнадсилання SIGTERMу фоновий процес він якось закінчується зупиненим (хоча процес SIGTERMвсе ще триває).

Найбезпечніший спосіб домогтися завершення всіх завдань ( не вдаючись до цього kill -9) - це спочатку відправити SIGTERMзвичайну kill, а потім надіслати SIGCONTбудь-які інші завдання, наприклад:

kill $(jobs -p)
kill -18 $(jobs -p)

SIGCONT( 18Це номер сигналу) принесе якісь - або зупиняли роботу на передній план так , щоб вони могли обробляти , SIGTERMяк зазвичай.

Якщо всі програми не закінчуються цим, то є кілька інших сигналів, які ви можете спробувати, які зазвичай дозволяють закінчити процес, перш ніж вдаватися до цього kill -9. Перший, який я рекомендую, SIGHUPтак як багато програм, які зазвичай блокують інші сигнали припинення, реагують на них SIGHUP. Зазвичай він надсилається, коли керуючий термінал закривається, зокрема він надсилається, коли sshсеанс ttyзакінчується. Багато інтерактивних програм, таких як оболонки, не реагуватимуть на інші сигнали припинення, але будуть на це, оскільки для них буде проблемою продовжувати працювати після sshзакінчення сеансу (або після закриття терміналу управління). Спробувати це ви можете так

kill -1 $(jobs -p)
kill -18 $(jobs -p)

Звичайно, вам потрібно переконатися, що програма не зупинена, щоб вона могла обробляти сигнал. Інші сигнали припинення, які ви можете спробувати, є SIGINT( kill -2) і SIGQUIT( kill -3). Але, звичайно, користь від спроб усього діапазону зменшується і може призвести до неминучого SIGKILL(ака kill -9).


Якщо ви робите це, man signalви можете отримати довідковий матеріал, щоб підтвердити це.
slm

Це більш м'яка форма того, що пропонує мій А. Є випадки, коли я раніше стикався, коли це все ще не очистить речі повністю, тому, якщо ви робите це за сценарієм, kill -9 ..метод буде працювати в більшості випадків. Це іноді залишатиме процеси, що звисають навколо, тому більше часу втрачає збій. Ви повинні вирішити цю угоду. Краще бути важкою рукою і вбивати все, ризикуючи даними / очищенням порівняно з м'якішою очищенням, але робити більше аналізу, оскільки ваші вбивства прогресивно стають більш жорсткими.
slm

@slm, вам слід уникати, kill -9коли це можливо, оскільки це просто витягує штекер, не даючи програмі шансу правильно очистити. Я оновлю деякі варіанти.
Graeme

Як я сказав, ваш аромат м'якший, ніж те, що я запропонував, воно зводиться до того, що ви намагаєтесь зробити, порівняно з готовністю терпіти з точки зору ризику. Я використовував ваш метод так само, як і мій. Вони обидва правильні ІМО. Також a kill ..; sleep <time>; kill -18 ..; сон <час>; вбити -9 ... . Basically working up to the -9`.
slm

@slm, kill -18це, безумовно, те, що слід використовувати, оскільки зазвичай припинено роботу (а в деяких випадках виявляється, що bashякимось чином перестає виконувати завдання перед надсиланням SIGTERM). Як додано вище SIGHUP, також варто спробувати, оскільки багато програм, які не відповідають іншим, відповідуть на це (спробуйте з оболонкою). Крім цього, так, це не так варто, як SIGKILLце, мабуть, неминуче.
Graeme

0

Це припинить усі завдання у вашій поточній оболонці по черзі:

while kill %; do :; done

Пояснення: %посилається на останнє завдання у списку, тому воно буде циклічно, поки killне поверне нульове значення, що означатиме, що немає більше завдань, які потрібно припинити.

Інший підхід може бути спочатку надсиланням SIGTERM, а потім SIGCONTваші завдання можуть продовжуватися, і перше, що вони зроблять - це отримати ваше SIGTERM.

/bin/kill $(jobs -p) && /bin/kill -CONT $(jobs -p)

(чомусь вбудований killдивний, тому я тут використовував зовнішній).

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.