2

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

Если я хочу найти какие-либо файлы, которые были изменены с момента развертывания программного обеспечения, я могу просто найти файлы, которые имеют новое время модификации, чем файл метаданных:

find . -newer deployment_metadata.txt

Это красиво и прямо.

Теперь я хотел бы также найти файлы, которые старше, чем файл метаданных развертывания. Можно предположить, что вы можете использовать символ взрыва, чтобы отменить "более новую" проверку

find . ! -newer deployment_metadata.txt

Но "не новее" не совсем эквивалентно "старому", поскольку любые файлы с той же временной меткой также "не новее", поэтому команда также включает все файлы, которые я только что развернул!

Итак, мне было интересно, если я пропустил трюк, когда дело доходит до (строго) старых файлов?

Мое текущее решение состоит в том, чтобы создать новый файл (в временном каталоге) с помощью touch , время модификации которого составляет одну минуту перед файлом deploy_metadata.txt. Тогда я могу использовать следующие аргументы ! -newer /var/tmp/metadtata_minus_1 .

Это работает, но кажется пустой тратой времени на создание, а затем очистку файла в временном каталоге - тем более, что разные пользователи могут использовать мой скрипт для проверки этого (не хотят проблем с владением файлами, поэтому На самом деле я зашел так далеко, что добавил ${USER} к имени файла.

2 ответа2

2

Может быть, направить результаты find в цикл команды test которая позволит вам использовать тест «старше чем»:

find ... | while read file;
do
  [ "$file" -ot deployment_metadata.txt ] && echo "$file"
done
1

Один из способов - использовать время эпохи. Вот тестовый прогон, в котором я сначала последовательно создаю семь файлов в пустой директории, где файлы c# получают "одинаковое" время ctime что касается find :

$ for i in a b "c1 c2 c3" d e; do touch $i; sleep 1; done
$ find -newer c2
.
./d
./e
$ find -not -newer c2
./c3
./c2
./a
./b
./c1
$ find -newerct @$(($(stat -c %Z c2)-1))
.
./c3
./d
./c2
./e
./c1
$ find -not -newerct @$(($(stat -c %Z c2)-1))
./a
./b

Это должно представлять все возможные наборы ctime относительно c2:

  1. ctime > c2
  2. ctimec2
  3. ctimec2
  4. ctime < c2

по крайней мере, с нечетким соответствием.

Третья команда получает эпоху ctime для файла c2 , вычитает 1 с помощью арифметики оболочки и передает ее как ссылку на -newerct (для @ нужно интерпретировать символ find как такую временную метку), чтобы найти все файлы с ctime более новые, чем эта интерпретированная временная метка (см. -newerXY в man find). Четвертая команда отменяет это соответствие и должна на практике делать то, что вы хотите, если я правильно понял вопрос, если вы поместите ваш справочный файл как c2 в моем примере.

Обратите внимание, что смещение "1 секунда" несколько произвольно (что я имел в виду под "нечетким соответствием"), и можно представить ситуацию, когда ошибка может быть создана. Однако временные метки файлов в любом случае не являются "определенными", и им нельзя доверять, поэтому я не могу представить, чтобы они создавали проблемы безопасности или практические проблемы в реальных ситуациях.

На самом деле, на практике вы можете даже захотеть увеличить смещение в 1 секунду (я вижу в вашем вопросе, что вы сейчас используете 1 минуту), но это деталь реализации.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .