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.

  • Как grep файл для отметки времени? Я ищу цифры часа
  • Преобразование файла машинописного текста в список команд (история)
  • Как скобки интерпретируются в командной строке?
  • Как удалить дубликаты в моем .bash_history, сохраняя заказ?
  • Опишите подсказку, которую я вижу, когда я впервые зашел на компьютер Linux
  • cp с единственным аргументом, содержащим подстановочные знаки
  • Как анализировать переменную env в цитируемой строке?
  • Как получить отчет о делах для дифференциации по часам дня
  • 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 - лучшая ОС в мире.