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, отправленного в оболочку.