подтвержденный выход с ловушкой

Я пытаюсь захватить сигнал Ctrl+C запрашивая подтверждение у пользователя. Улавливающая часть работает нормально. Но как только сигнал попадает в ловушку, он не возвращается к нормальному исполнению. Вместо этого он выходит из сценария. Как заставить его возобновить выполнение, когда пользователь нажимает «нет».

вот мой код

 hell() { echo "Do you want to quit? Press 1 for yes and 0 for no"; read n; if [ $n == 1 ]; then exit 1; fi } trap "hell" SIGINT find / 

  • Добавить расширение ко всем файлам в каталоге, содержащем точную строку
  • массив сценариев оболочки для элементов файлов
  • одновременное торможение
  • Какие команды Unix можно использовать в качестве семафора / блокировки?
  • Измените значение в файле конфигурации или добавьте параметр, если он не существует?
  • Выполнить скрипт автоматически при выключении Fedora 15/16
  • Как удалить префиксы и суффиксы из имен файлов в заданном каталоге?
  • Как запустить сценарий при обновлении папки в Solaris 5.10?
  • One Solution collect form web for “подтвержденный выход с ловушкой”

    Что происходит

    Когда вы нажимаете Ctrl + C , сигнал SIGINT доставляется во всю группу процессов переднего плана . Здесь он отправляется как find процесса find процесса вызывающей оболочки. find реагирует, выйдя немедленно, и оболочка реагирует, вызывая ловушку.

    Если код в ловушке возвращается (т. Е. Не вызывает exit ), выполнение продолжается с помощью команды после той, которая была прервана сигналом. Здесь, после того, как команда find наступает в конце скрипта, так что скрипт выйдет немедленно. Но вы можете увидеть разницу между входом 0 и 1, добавив еще одну команду:

     find / echo "find returned $?" 

    Способ делать то, что вы хотите (но, вероятно, не следует делать)

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

    • В качестве элемента дизайна перезапускаемый сигнал – это не то, что вы обычно ожидаете в виде относительно простых программ, которые обычно выполняются в сценариях оболочки. Ожидается, что Ctrl + C убьет скрипт.
    • Как вы увидите ниже, в любом случае он немного расширяет возможности оболочки.

    Если вы хотите избежать find , вам нужно запустить его в фоновом режиме : find / & . Затем используйте wait builtin, чтобы дождаться, когда он выйдет нормально. Сигнал прерывает функцию wait , которую вы можете запускать в цикле, пока не получите сигнал, который хотите передать. Затем используйте kill чтобы убить задание.

     hell () { echo "Do you want to quit? Press 1 for yes and 0 for no" read n if [ "$n" = 1 ]; then # Kill the job if it's running, then exit if [ -n "$job_pid" ]; then kill $job_pid; fi exit 1 fi } job_pid= trap "hell" SIGINT # Start a demo job in the background for i in 1 2 3 4 5; do date; sleep 1; done & job_pid=$! # Call wait in a loop; wait will return 0 if the job exits, and 128+$signum if interrupted by a signal. while ! wait; do echo "resuming wait" done job_pid= echo last exit code: $? 

    Существуют ограничения этого подхода в оболочке:

    • Состояние гонки: если вы нажмете Ctrl + C сразу после завершения задания, но до job_pid= обработчик сигнала попытается убить $jobpid , но процесс больше не существует (даже как зомби, потому что wait уже заработал его), и идентификатор процесса может быть повторно использован другим процессом. Это не легко устранить в оболочке (возможно, установив обработчик для SIGCHLD ?).
    • Если вам нужен статус возврата из задания, вам нужно использовать форму wait $job_pid . Но тогда вы не можете отличить « wait было прервано сигналом» от «задание было убито сигналом» (или от «прекращенного по своему усмотрению задания с возвратным статусом ≥128», но это общий факт в программирование оболочки).
    • Это не будет распространяться легко, если вообще на несколько подзаголовков. Обратите внимание, что поведение ловушек и сигналов часто удивительно, когда вы выходите за рамки основ большинства реализаций оболочки (только ksh делает это хорошо).

    Чтобы преодолеть эти ограничения, используйте более привлекательный язык, например Perl или Python.

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