Завершить каждый фоновый процесс

10

У меня есть несколько Stoppedфоновых процессов.

kill $(jobs -p)и не kill `jobs -p`имеют никакого эффекта

kill %1, kill %2И т.д. успешно завершать отдельные процессы

Как я могу убить каждый фоновый процесс с помощью одной команды?

Кроме того, почему первые две команды не работают для меня?

Я использую Linux Mint 15, 64 бит

user49888
источник

Ответы:

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сначала, а затем - 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.

SLM
источник
почему у нас есть +символ для первого процесса и -символ для второго процесса и нет символа в третьем?
Рамеш
Я получил те же результаты, что и вы. Однако я хочу terminateвместо kill, так как я прочитал, что это безопаснее. Я пытался kill -15 $(jobs -p), но это не имело никакого эффекта. Я догадывался, что остановленные процессы могут быть только уничтожены, но затем снова kill %numberзавершает (отдельные) остановленные процессы.
user49888
@Ramesh +и -- это только последние процессы, к которым я прикасался, когда настраивал примеры. В +означает , что все команды , которые явно не включают в себя %#будут действовать по этой команде. Тире ( -) - это вторая, последняя команда, к которой я прикоснулся.
СЛМ
@ 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

На вики- странице Killкоманды

Процессу может быть отправлен сигнал 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 был отправлен процессу, то с остановленными процессами, как в примере OP, kill -9в моем примере не сработало бы.
СЛМ
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).

Graeme
источник
Если вы сделаете это, man signalвы можете получить справочный материал, подтверждающий это.
SLM
Это более мягкая форма того, что предлагает мой А. В прошлом я сталкивался с случаями, когда это все равно не будет полностью очищено, поэтому, если вы делаете это из скрипта, kill -9 ..метод будет работать в большинстве случаев. Иногда это приводит к зависанию процессов, поэтому чаще всего происходит сбой. Это компромисс, который вы должны решить. Лучше быть жестким и убивать все, рискуя данными / очисткой, чем более мягкой очисткой, но при этом нужно больше анализировать, поскольку ваши убийства становятся все более жесткими.
SLM
@slm, вам следует избегать, kill -9когда это возможно, так как это просто отключает штепсель, не давая программе возможность правильно очиститься. Я буду обновлять с некоторыми альтернативами.
Грэм
Как я уже сказал, ваш вкус мягче, чем то, что я предложил, все сводится к тому, что вы пытаетесь сделать против желания терпеть с точки зрения риска. Я использовал твой метод так же хорошо, как и мой. Они оба верны ИМО. Также kill ..; sleep <time>; kill -18 ..; сон <время>; убить -9 ... . Basically working up to the -9`.
SLM
@slm, kill -18это определенно то, что следует использовать, поскольку обычно прекращают работу (а в некоторых случаях кажется, что bashкаким- то образом останавливается выполнение заданий перед отправкой SIGTERM). Как добавлено выше SIGHUP, также стоит попробовать, так как многие программы, которые не отвечают на другие, ответят на это (попробуйте с помощью оболочки). Помимо этого, да, это не так выгодно, как, SIGKILLвероятно, неизбежно.
Грэм
0

Это завершит все задания в вашей текущей оболочке один за другим:

while kill %; do :; done

Объяснение: %относится к последнему заданию в списке, поэтому оно будет зацикливаться до тех пор, пока не killвернет ненулевое значение, что будет означать, что больше нет заданий для завершения.

Другим подходом может быть сначала отправка SIGTERM, затем SIGCONTваша работа может продолжаться, и первое, что они сделают, это получат вашу SIGTERM.

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

(по какой-то причине встроенная система killстранная, поэтому я использовал внешнюю здесь).

ДНТ
источник