#!/bin/bash --

echo "$$"

LC_ALL=C sed 's/[!-~]/b/g' /tmp/bigfile > /tmp/outfile

echo end of script

Если я отправлю сигнал QUIT с помощью Ctrl + \, я получу следующий вывод:

# ./script.sh
6739
^\./script.sh: line 5:  6740 Quit                    LC_ALL=C sed 's/[!-~]/b/g' /tmp/bigfile > /tmp/outfile
end of script

Это убивает sed и вызывает дамп ядра, как и ожидалось, но сценарий продолжает работу. Это ожидаемое поведение? Это происходит со мной с bash и ash, но не с dash или ksh93.

2
Harold Fischer 3 Дек 2019 в 08:42

1 ответ

Лучший ответ

Да, bash игнорирует SIGQUIT. Цитата из его руководства (выделено мной):

3.7.6 Сигналы

Когда Bash является интерактивным, при отсутствии каких-либо ловушек он игнорирует SIGTERM (так что kill 0 не уничтожает интерактивную оболочку), а SIGINT перехватывается и обрабатывается (так что wait встроенный прерываемый). Когда Bash получает SIGINT, он выходит из всех циклов выполнения. Во всех случаях Bash игнорирует SIGQUIT. Если действует управление заданиями, Bash игнорирует SIGTTIN, SIGTTOU и SIGTSTP.

Это нестандартное поведение, и большинство других оболочек этого не делают.


Если вы не находите это убедительным, вы можете взглянуть на его исходный код: shell_initialize() -> initialize_signals(0) -> initialize_shell_signals() -> set_signal_handler (SIGQUIT, SIG_IGN) безоговорочно вызывается из main().

4
mosvy 3 Дек 2019 в 10:35