Поиск с использованием -mtime не удается при проверке файлов текущего дня

Вопрос или проблема

Рассмотрим две команды, которые запланированы на выполнение одновременно (через Autosys, ровно в 8 утра).

Команда find удаляет файлы старше 15 дней, но завершилась с ненулевым статусом с сообщением:

???find отсутствует /app/source/a.txt нет такого файла или каталога

Однако a.txt всего один день. Почему команда find проверяет недавний файл, который был в наличии во время ее выполнения, но переместился в другую папку в то же время?

find /app/source -type f -name -mtime +15 rm -f {} \;

mv /app/source/a.txt /app/backup/

Это то, что называется состоянием гонки. Единственный способ для find узнать, что это новый файл, который не должен быть удален, — это посмотреть на файл. Поэтому find сначала находит файл, а затем проверяет его дату.

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

Каталог в основном является списком имен файлов. 
Когда вы запускаете find и задаете тесты,
которые проверяют атрибуты/свойства файлов (а не только имя файла),
find должен запрашивать файловую систему для получения атрибутов/свойств
каждого файла, указанного в каждом каталоге. 
Таким образом, find не имеет способа узнать, что a.txt является недавним файлом,
кроме как вызвав stat("a.txt").

Как вы, вероятно, понимаете, ваша команда mv переместила файл
между моментом, когда find прочитал каталог, и моментом, когда она вызвала stat().

Ответ или решение

Почему команда find с -mtime не работает корректно для файлов, созданных в текущий день

Когда вы выполняете команду find с использованием параметра -mtime, вы сталкиваетесь с интересным поведением, касающимся определения времени модификации файлов. Рассмотрим случай, в котором две команды запускаются одновременно: одна команда предназначена для поиска и удаления файлов старше 15 дней, а другая — для перемещения файла a.txt, который всего лишь на один день старше.

Распределение времени выполнения

В этом сценарии команда find рассматривает содержимое директории и затем проверяет атрибуты файлов. Когда вы запускаете следующую команду:

find /app/source -type f -mtime +15 -exec rm -f {} \;

Команда find сначала считывает список файлов в директории /app/source, а затем для каждого найденного файла выполняет проверку по атрибутам, включая дату модификации. Это означает, что find не знает ничего о состоянии файлов в момент, когда команда начинает выполняться, и делает отдельные запросы для проверки каждого файла.

Условия гонки (Race Condition)

Проблема, с которой вы столкнулись, является классическим примером условия гонки. В момент, когда команда find начинает работать и уже считает, что файл a.txt присутствует в директории, другая команда, выполняющая перемещение (mv /app/source/a.txt /app/backup/), может исполниться и удалить файл из директории до того, как find успевает проверить его атрибуты.

Это приводит к тому, что в момент, когда find пытается выполнить проверку на наличие файла, он уже недоступен. Результатом будет ошибка "нет такого файла или директории", поскольку файл не существует в момент выполнения команды stat(). В результате команда find выдает ненулевой статус, что означает возникновение ошибки.

Решение проблемы

Для решения этой проблемы можно рассмотреть несколько подходов:

  1. Отключение одновременного выполнения: Избегайте запуска команд, которые могут затрагивать одни и те же файлы одновременно. Например, синхронизируйте их выполнение с помощью блокировок или очередей.

  2. Проверка состояния файлов перед выполнением: Можно использовать промежуточное состояние, в котором перед удалением файлов вы проверяете их существование заново, чтобы убедиться, что они не были перемещены или удалены.

  3. Логирование и уведомления: Настройте логирование для того, чтобы отслеживать состояние файлов перед и после выполнения скриптов. Таким образом, можно будет отследить, что именно вызвало ошибку.

  4. Использование безопасных инструментов: Рассмотрите возможность использования более совершенных инструментов для управления файлами, которые могут справляться с условиями гонки или предлагают более высокий уровень контроля.

Заключение

Понимание того, как командные строки взаимодействуют с файловой системой и особенностями работы команд, таких как find, является ключевым моментом для избежания проблем в будущем. Условия гонки могут привести к неожиданным ошибкам, и важно учитывать их в своей стратегии автоматизации и администрирования. Следуя лучшим практикам и применяя предложенные рекомендации, вы сможете повысить надежность работы ваших скриптов и системы в целом.

Оцените материал
Добавить комментарий

Капча загружается...