A РЕШЕНИЕ:
Добавьте эту строку поверх work.sh
сценария trap exit SIGINT
, чтобы иметь явный обработчик SIGINT:
#! /bin/bash
trap exit SIGINT
COUNTER=0
while true
do
((COUNTER+=1))
echo "#${COUNTER} Working..."
sleep 1
done
Running work
исполняемый файл теперь печатает:
#1 Working...
#2 Working...
#3 Working...
#4 Working...
#5 Working...
, после чего возвращается обратно в оболочку.
ПРОБЛЕМА:
Я нашел эту веб-страницу , связанную в комментарии к этому вопросу на Unix-стеке (дляради полноты, вот также веб-страница, связанная в принятом ответе.) Вот цитата, которая может объяснить, что происходит:
bash - одна из немногих оболочек, которые реализуют ожиданиеи совместный подход к выходу при обработке доставки SIGINT / SIGQUIT. При интерпретации скрипта, получив SIGINT, он не сразу выходит, а вместо этого ожидает возврата работающей в данный момент команды и завершает работу (убивая себя с помощью SIGINT), если эта команда также была убита этим SIGINT. Идея состоит в том, что если ваш скрипт вызывает vi, например, и вы нажимаете Ctrl + C в vi, чтобы отменить действие, это не должно рассматриваться как запрос на прерывание скрипта.
Итак, представьте, что вы пишетескрипт и этот скрипт обычно завершаются при получении SIGINT. Это означает, что если этот сценарий вызывается из другого сценария bash, Ctrl-C больше не будет прерывать этот другой сценарий.
Такого рода проблемы можно увидеть с реальными командами, которые по умолчанию выходят из SIGINT.
РЕДАКТИРОВАТЬ:
Я нашел еще один Unix стек обмена ответ , который объясняет это еще лучше. Если вы посмотрите на bash(1)
справочные страницы, то следующее также довольно объяснительно:
Для не встроенных команд, запускаемых bash, обработчикам сигналов присвоены значения, унаследованные оболочкой от ее родителя. Когда управление заданиями не действует, асинхронные команды игнорируют SIGINT и SIGQUIT в дополнение к этим унаследованным обработчикам.
особенно с учетом того, что:
Сигналы, игнорируемые при входе в оболочку, не могут быть перехвачены, сброшены или перечислены.
В основном, работаетwork.sh
запускает его в отдельной среде выполнения:
Когда должна выполняться простая команда, отличная от встроенной функции или функции оболочки, она вызывается в отдельной среде выполнения.
Сюда входят обработчики сигналов, которые (если они не указаны явно) будут игнорировать SIGINT
и SIGQUIT
по умолчанию.