bash shell: может ли control-c заставить shell писать пустой файл?

У меня есть скрипт оболочки bash. Он записывает в текстовый файл. Большинство из них работает, если я остановлю скрипт с помощью control-c на командном уровне. Иногда файл, который был записан в такой как

echo "hello world" >myfile.txt

окажется пустым. Так что вполне возможно, что когда я нажимаю control-c, чтобы остановить выполнение сценария оболочки, он перехватывает его в тот момент, когда он открывает запись в файл, и, прежде чем он что-то в него помещает, не получает шанса и оставляет его пусто?

Если это так. Что я могу сделать в скрипте оболочки bash, чтобы он корректно завершил работу после записи в файл и до того, как у него появится возможность снова записать в файл, потому что он делает это в цикле while. Спасибо!

1 ответ

Да, возможно, что вы получите пустой файл.

Решением было бы перехватить сигнал, вызванный ^ C (SIGINT) и установите флаг, который вы можете проверить в цикле:

triggered=0

trap "triggered=1" SIGINT

while true
do
  if [ $triggered = 1 ]
  then
    echo "quitting"
    exit
  fi
  ...do stuff...
done

РЕДАКТИРОВАТЬ: не понимал, что даже если собственная обработка оболочки SIGINT будет захвачена, она все равно передаст SIGINT своим подпроцессам, и они будут убиты, если они сами не будут обрабатывать SIGINT.

поскольку echo это встроенная оболочка, она может пережить убийство, но я не совсем уверен. Быстрый тест, кажется, работает нормально (файл всегда записывается, тогда как без перехвата SIGINT я иногда получаю пустой файл).

Как подсказывает @spbnick в комментариях, в Linux вы можете использовать setsid команда для создания новой группы процессов для любых запускаемых вами подпроцессов, которая предотвратит их уничтожение с помощью SIGINT, отправленного в оболочку.

Другие вопросы по тегам