Киндер / нежнее / тоньше эквивалентная альтернатива killall (например, "endall")?


17

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


Смотрите также:

Как убить процессы в Ubuntu?

В чем разница между процессом Kill Process и End Process в системном мониторе?

Почему killall (иногда?) Нужно применять дважды?

ТЛ; др


1
И твой вопрос?
— Pilot6

@ Pilot6 перефразировал: что такое "более мягкая" альтернатива killall?
— Сумасшедший о Натти

1
Что такое "мягче"?
— Pilot6

Ответы:


43

1. `killall` уже приятно (SIGTERM)

killallпо умолчанию отправляет SIGTERM. Это уже хороший подход, который оставляет приложениям возможность убирать за собой. "Иди умри уже, прямо сейчас!" Подход заключается в отправке SIGKILLсигнала, который требует указать это в качестве опции killall. Из библиотеки GNU C: Сигналы завершения :

Макрос: int SIGTERM

[...] Это нормальный способ вежливо попросить программу завершиться.


2. «Завершить процесс» в системном мониторе одинаково хорошо (тоже SIGTERM)

Вы ссылаетесь на вопрос о системном мониторе GNOME. Это также используется SIGTERMдля его действия «Завершить процесс» (и я понимаю, что я противоречу ответу на этот вопрос). Вы можете найти его в исходном коде, чтобы проверить себя:

data / menus.ui :

<item>
  <attribute name="label" translatable="yes">_End</attribute>
  <attribute name="action">win.send-signal-end</attribute>
  <attribute name="accel">&lt;Primary&gt;e</attribute>
  <attribute name="target" type="i">15</attribute>
</item>

15 здесь - это номер сигнала. Сигнал 15 есть SIGTERM. И Системный Монитор использовал SIGTERMзадолго до того, как на другой вопрос был задан и дан ответ.


Техническое приложение (в ответ на комментарий)

Просматривая представление Github для git blame, вот изменения, которые были внесены в то, как сигналы записаны в исходном коде GNOME System Monitor:

383007f2 24 июля 2013 г. Заменен дублированный код для отправки сигналов с параметрами
GAction 0e766b2d 18 июля 2013 г. Всплывающее меню процесса порта для GAction
97674c79 3 октября 2012 г. Избавьтесь от структуры
ProcData 38c5296c 3 июля 2011 г. Сделайте одинаковые отступы в исходных файлах.

Ничего из этого не изменилось с SIGQUITна SIGTERM, а последнее было до того, как был задан связанный вопрос.


7
+1 за ссылку на исходный код! (+2 за противоречащие «общепринятые», как это было;)
— ореховое о Natty

Ну, прежде чем заявить, что вы противоречите ответу: проверяли ли вы, что все версии исходного кода используются 15? Возможно, в какой-то момент он был изменен, поэтому старый ответ может быть на 100% правильным по сравнению со старой версией.
— Бакуриу

1
@Bakuriu Я так или иначе не согласен с этим ответом, но, честно говоря, я постараюсь не забыть проверить это в следующий раз.
— HVD

@Bakuriu в исходном дереве git git grep 'SIGQUIT'ничего не раскрывает. Ничего, связанного с сигналами, не найдено git grep '>3<'ни для одного. Я делаю вывод, что, скорее всего, gnome-system-monitor никогда не использовал SIGQUIT.
— Руслан

@Ruslan git grepищет только текущее дерево, а не всю историю. Я использовал git blame(фактически эквивалент Github), чтобы копать немного глубже, но все еще ничего.
— HVd

5

Ответ @hvd в основном правильный. Чтобы поддержать это еще больше, initпроцесс сначала отправит SIGTERMпроцессам, когда вы выключаете компьютер, а затем с задержкой отправит, SIGKILLесли они еще не вышли. Процессы не могут обрабатывать / игнорировать SIGKILL.

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

Иными словами, на основе других ответов, если у вас есть программа, написанная @Jos или @AlexGreg, то они, вероятно, будут обрабатывать, SIGQUITно, возможно, нет SIGTERM, и, следовательно, отправка SIGTERMбудет менее "мягкой", чем SIGQUIT.

Я написал некоторый код, чтобы вы могли поиграть с ним самостоятельно. Сохранить ниже какsignal-test.c , затем скомпилируйте с

gcc -o signal-test signal-test.c

Вы можете запустить его ./signal-test и посмотреть, что происходит, когда вы отправляете различные сигналы с помощью killall -s <signal>.

#include <stdio.h>
#include <signal.h>
#include <unistd.h>

int flag = 0;

void handle_signal(int s)
{
    flag = s;
}

int main(int argc, char *argv[])
{
    signal(SIGTERM, handle_signal);
    signal(SIGQUIT, handle_signal);

    while(flag == 0){
        sleep(1);
    }
    printf("flag is %d\n", flag);
    return flag;
}

Как он есть, код обрабатывает как SIGTERM, так и SIGQUIT изящно. Вы можете попробовать закомментировать строкиsignal(SIG... (используя a //в начале строки), чтобы удалить обработчик сигналов, затем запустить и снова отправить сигналы. Вы должны увидеть эти разные результаты:

$ ./signal-test
Terminated

$ ./signal-test
Quit (core dumped)

$ ./signal-test
flag is 15

$ ./signal-test
flag is 3

в зависимости от того, обрабатываете ли вы сигналы или нет.

Вы также можете попробовать игнорировать сигналы:

signal(SIGTERM, SIG_IGN);

Если вы сделаете это, то отправка SIGTERMничего не даст, вам придется использовать SIGKILLдля завершения процесса.

Подробнее в man 7 signal. Обратите внимание, что использование signal()таким способом считается непереносимым - это намного проще, чем альтернатива!

Еще одна второстепенная сноска - на Солярисе killallделается попытка уничтожить все процессы. Все они. Если вы запустите его как root, вы можете быть удивлены :)


1
Это одна из причин, по которой я предпочитаю pkill. Другая причина в том, что он соединяется с pgrep, что упрощает точную проверку того, какие процессы будут убиты, а какая сама семантика соответствия лучше, чем ps | grep.
— Random832

1

«Конец всего» будет killall -s SIGQUIT [process name]. Если вы хотите модное решение, определите alias endall='killall -s SIGQUIT'.


13
SIGQUITэто как процесс abort(3): он сбрасывает ядро, а затем убивает процесс. Это ни в коем случае не лучше / мягче / добрее, чем SIGTERMпо умолчанию killall.
— Руслан

3
Для процесса, который обрабатывает сигналы SIGQUIT(или даже лучше SIGINT), его можно обрабатывать более «мягко», чем это SIGTERM, но это зависит от приложения. Необработанные, любой из них вызывает немедленное прекращение.
— R .. GitHub ОСТАНОВИТЬ ЛЬДА

1
Это отличная идея, если вам нравится чистить основные файлы на всем диске.
— Нейт Элдредж,

2
@Qix: Одна вещь, которая варьируется в зависимости от сигнала, это то, создает ли он основной файл или нет в действии по умолчанию (если не обрабатывается приложением). Вероятно, предпочтительнее использовать сигналы, которые не генерируют файлы ядра.
— R .. GitHub ОСТАНОВИТЬ ЛЬДА

1
Стоит отметить, что ubuntu по умолчанию устанавливает ограничение размера файла ядра равным 0, поэтому SIGQUIT фактически не создаст файл ядра (если он не обработан), если вы не измените ограничение.
— Роджер Лайт
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.