Перенаправить все приостановленные процессы на завершение

Перенаправить все приостановленные процессы на завершение

Я запускаю скрипт, который должен быть приостановлен перед завершением. Когда я запускаю его в первый раз, у процесса есть только один pid. Я завершаю его и запускаю снова, и число PID увеличивается. Во-первых, почему такое поведение? И как мне завершить все приостановленные процессы, не указав явно каждый PID?

./toplog.sh

Приостановление:

Ctrl-Z

Список приостановленных процессов:

jobs -l

Выход:

[1]  12055 Stopped                 ./toplog.sh
[2]  12752 Stopped                 ./toplog.sh
[3]- 13276 Stopped                 ./toplog.sh
[4]+ 13579 Stopped                 ./toplog.sh

Убийство:

kill 12055 12752 13276 13579

решение1

Я запускаю скрипт, который необходимо приостановить перед завершением.

Э, нет. Скрипт не нужно останавливать перед уничтожением. Вы можете уничтожить его в любое время.

При первом запуске у процесса только один pid. Я его убиваю и запускаю снова, и число PID увеличивается.

Тогда вы на самом деле не убиваете его! Если вы запустите ./toplog.shи приостановите его, это создаст только одно задание, т. е. одну строку в выводе jobs. Сам скрипт может создать несколько процессов, но jobsперечисляет только сам скрипт (лидер группы процессов, технически говоря). Если вы видите все больше и больше заданий, это означает, что вы все еще видите старые задания, которые вы безуспешно пытались убить.

Причина, по которой вам не удалось завершить задания, вероятно, в том, что они приостановлены. Когда процесс приостановлен, он не может реагировать на сигналы. Если вы отправляете сигнал приостановленному процессу, сигнал оказывает влияние только при возобновлении процесса. Исключениями являются сигналы, которые управляются ядром напрямую, без участия процесса. Одним из таких исключений является сигнал возобновления процесса (SIGCONT), который, очевидно, немедленно пробуждает процесс. Другая категория исключений — это сигналы, которые завершают процесс без запроса: это всегда включает SIGKILL, а также другие сигналы (SIGINT, SIGHUP, SIGTERM, SIGQUIT, …), если процесс не установил обработчик для этого сигнала.

Если kill %1убивает задание 1, то оболочка сообщит вам, что задание завершено. Если процесс установил обработчик для SIGTERM, то kill %1не имеет никакого эффекта, пока процесс приостановлен; чтобы убить процесс, вам также нужно возобновить его:

kill %1; kill -CONT %1

Если вы хотите принудительно завершить процесс, не давая ему возможности для очистки, то сделайте следующее:

kill -KILL %1

(или kill -9 %1для краткости).

Если вы хотите завершить все toplog.shпроцессы, независимо от того, были ли они запущены из этого терминала или нет, вы можете использовать pkill toplog.sh.

решение2

Вы можете завершить все экземпляры вашего скрипта, если знаете, как ваш процесс вызывается во время выполнения (в этом примере toplog.sh).

ps x | grep toplog.sh | grep -v grep | cut -d" " -f1 | xargs kill -9

пс хдает вам список всех ваших процессов, из которых будет grep'нся целевой процесс. Второй grep просто удаляет сам вызов grep из списка. В противном случае вы получите ошибку (которая на самом деле тоже не проблема, но она уродлива).вырезать -d" " -f1разрезает каждую строку на несколько частей, разделенных пробелами, причем *-f1** берет первую часть.xargs убить -9убивает каждый pid, который был выброшен из цепочки команд ранее.

Для удобства вы можете поместить эту строку в скрипт kill, заменив имя процесса аргументом скрипта kill:

#!/bin/bash
ps x | grep $1 | grep -v grep | cut -d" " -f1 | xargs kill -9

Затем скрипт вызывается с указанием имени процесса, который необходимо завершить.

./kill.sh toplog.sh

Связанный контент