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

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


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

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

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

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

ТЛ; др

3 ответа

Решение

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:

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

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

Ответ @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... (используя // в начале строки), чтобы удалить обработчик сигнала, затем запустите и снова отправьте сигналы. Вы должны увидеть эти разные результаты:

$ ./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, вы можете быть удивлены:)

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

Другие вопросы по тегам