SIGINT обрабатывает различия между bash 3 и 4

У меня есть сценарий, который отлично работает в bash 4.3, но дает мне неожиданное поведение с bash 3.2. Вот упрощенная версия:

set -o errexit -o pipefail task() { local name=${1} local duration=${2} trap 'echo "[${SECONDS} secs] ${name}: SIGINT"; exit 255' INT echo "[${SECONDS} secs] ${name}: Running" sleep "${duration}" echo "[${SECONDS} secs] ${name}: Done" } trap 'echo "[${SECONDS} secs] SIGINT"; exit 255' INT task 'Task 1' 5 & task 'Task 2' 5 & wait echo "[${SECONDS} secs] Done" 

Вот результат при запуске с bash 4.3 (4.3.42 (1) -release) после CTRL-C'ing в течение двух секунд:

 [0 secs] Task 1: Running [0 secs] Task 2: Running ^C[2 secs] SIGINT [2 secs] Task 2: SIGINT [2 secs] Task 1: SIGINT prompt> 

То же самое, но с bash 3.2 (3.2.57 (1) -release):

 [0 secs] Task 1: Running [0 secs] Task 2: Running ^C[2 secs] SIGINT prompt> [5 secs] Task 2: Done [5 secs] Task 1: Done 

Известны ли проблемы, препятствующие правильному функционированию вышеприведенного скрипта в bash 3.2? Существуют ли обходные пути?

Вот несколько вещей, которые я пробовал:

  • Нет обработчика сигнала в родительском объекте:

     # bash 4.3 [0 secs] Task 1: Running [0 secs] Task 2: Running ^C[2 secs] Task 2: SIGINT [2 secs] Task 1: SIGINT prompt> # bash 3.2 [0 secs] Task 1: Running [0 secs] Task 2: Running ^C prompt> [5 secs] Task 2: Done [5 secs] Task 1: Done 
  • Нет обработчиков сигналов:

     # bash 4.3 [0 secs] Task 1: Running [0 secs] Task 2: Running ^C prompt> # bash 3.2 [0 secs] Task 1: Running [0 secs] Task 2: Running ^C prompt> [5 secs] Task 2: Done [5 secs] Task 1: Done 
  • Обработчик сигналов в родителе, который убивает группу процессов с помощью SIGINT ( kill -INT -- -$$ ):

     [0 secs] Task 1: Running [0 secs] Task 2: Running ^C[2 secs] SIGINT [2 secs] Task 2: SIGINT [2 secs] Task 1: SIGINT prompt> [0 secs] Task 1: Running [0 secs] Task 2: Running ^C[2 secs] SIGINT prompt> [5 secs] Task 2: Done [5 secs] Task 1: Done 
  • Обработчик сигналов в родителе, который убивает группу процессов с помощью SIGTERM (задачи ловушки SIGTERM):

     # bash 4.3 [0 secs] Task 1: Running [0 secs] Task 2: Running ^C[2 secs] SIGINT [2] 92813 terminated bash minimal_example.sh prompt> # bash 3.2 [0 secs] Task 1: Running [0 secs] Task 2: Running ^C[2 secs] SIGINT Terminated: 15 Terminated: 15 [2 secs] Task 2: SIGTERM [2 secs] Task 1: SIGTERM [1] 92836 terminated /bin/bash minimal_example.sh prompt> 

Последнее самое близкое к правильной работе в 3.2, но тот же код ведет себя по-разному в 4.3.

  • Работа с вспомогательными подкомандами последних инструментов CLI
  • Как написать тест для входа в систему?
  • Удаление всех гласных, но первый из набора строк
  • Прочитать строку из файла, затем удалить
  • Подключиться к сеансу сеанса byobu и выполнить команду?
  • команда для массового переименования файлов в соответствии с шаблоном
  • Повторить последние команды N
  • Труба к моему собственному сценарию
  • One Solution collect form web for “SIGINT обрабатывает различия между bash 3 и 4”

    Возможно, вы являетесь жертвой известной проблемы с bash которая часто поражает пользователей.

    Я еще не проверял bash 4, но bash 3 неправильно справляется с работой внутри скриптов. Обычно это приводит к тому, что make-файлы, содержащие цикл над несколькими подкаталогами, не могут быть легко уничтожены с помощью ^C потому что подпроцессы выполняются в отдельных группах процессов, хотя эти команды не являются интерактивными.

    smake включает в себя обходной путь для /bin/sh bash и явно перенаправляет SIGINT в группу procress текущей команды. Но это программное обеспечение, написанное на языке C

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

    Linux и Unix - лучшая ОС в мире.