Почему bash фоновая задача игнорирует SIGINT? - PullRequest
5 голосов
/ 11 марта 2020

Я заметил, что sleep не может быть убит SIGINT при порождении:

(sleep 1000 &)

Интересно, почему это так.
SIGINT уничтожает все следующее:

sleep 1000
sleep 1000 &
(sleep 1000)
( ( (sleep 1000) ) )
( ( (sleep 1000)& ) )

, поэтому я считаю, что это должно иметь какое-то отношение к неинтерактивному bash (для ввода в подоболочку требуются скобки), и задача должна быть бегать в фоновом режиме.

Я написал короткую C программу для проверки поведения и обнаружил, что sa_handler установлен в SIG_IGN - объяснение явления, но почему именно так?

Я не нашел никакой информации, является ли это предполагаемой функцией (хотя, учитывая объем руководства, я, возможно, просто пропустил ее), и если да, то какова была причина, по которой это произошло.

Я включаю C код для тех, кто заинтересован:

#include <stdlib.h>
#include <stdio.h>

#include <signal.h>

int main() {
    struct sigaction oldact;
    if(sigaction(SIGINT, NULL, &oldact) != 0) {
        printf("Error in sigaction\n");
        exit(1);
    }

    if(oldact.sa_flags & SA_SIGINFO) {
        printf("Using sa_sigaction\n");
    } else {
        if(oldact.sa_handler == SIG_DFL) {
            printf("Default action\n");
        } else if(oldact.sa_handler == SIG_IGN) {
            printf("Ignore signal\n");
        } else {
            printf("Other action\n");
        }
    }
    return 0;
}

РЕДАКТИРОВАТЬ:

ответ Пилкроу отлично, и я принял его. Я хотел бы добавить к , почему posix говорит так, что согласно signal (7) и SIGINT, и SIGQUIT находятся с клавиатуры . Поэтому имеет смысл игнорировать их в процессах, отсоединенных от одного (а не задания, управляемого bash).

EDIT2:

Оформить заказ Пометить комментарий Плотника для истинного объяснение ПОЧЕМУ.

1 Ответ

3 голосов
/ 11 марта 2020

Эта конструкция (sleep 1000 &) помещает вашу команду sleep в подоболочку внука без контроля задания:

your-shell
      \
      a compound-list in a subshell
          \
         an asynchronous list in a subshell

Первый подоболочек, (составной список) ( групповая конструкция ), просто запускает фоновую команду & ( асинхронный список ) и затем завершается. Асинхронный список запускается в своей собственной подоболочке.

Этот окончательный подоболочек слишком далеко удален от вашей начальной оболочки, чтобы управление заданиями не имело смысла.

Для POSIX, "[i] f Управление заданиями отключено ... когда оболочка выполняет асинхронный список, команды в списке должны наследовать от оболочки действие игнорируемых сигналов (SIG_IGN) для сигналов SIGINT и SIGQUIT. "

Таким образом, ваш sleep запускается с SIGINT, установленным на игнорирование.

...