Localizar arquivos (estritamente) mais antigos que outro arquivo

2

Quando implanto meu software, envio um arquivo compactado para o servidor de destino e extraio seu conteúdo. Além disso, ao mesmo tempo, também coloco um arquivo de metadados no diretório, detalhando o que foi implantado.

Se eu quiser encontrar os arquivos que foram alterados desde que implantei o software, posso simplesmente encontrar arquivos com uma nova hora de modificação que o arquivo de metadados:

find . -newer deployment_metadata.txt

Isso é legal e direto.

Agora, também gostaria de encontrar arquivos antigos que o arquivo de metadados de implantação. Alguém poderia assumir que você poderia usar o símbolo de estrondo para negar a verificação "mais recente"

find . ! -newer deployment_metadata.txt

Mas 'not newer' não é exatamente equivalente a 'mais antigo', já que todos os arquivos com o mesmo registro de data e hora também não são mais novos - portanto, o comando também inclui todos os arquivos que acabei de implantar!

Então, eu queria saber se estava faltando um truque quando se trata de encontrar (estritamente) arquivos antigos?

Minha solução atual é criar um novo arquivo (no diretório dir) usando touchum tempo de modificação de um minuto antes do arquivo deployment_metadata.txt. Então eu sou capaz de usar os seguintes argumentos: ! -newer /var/tmp/metadtata_minus_1.

Isso funciona, mas parece uma perda de tempo ter que criar e depois limpar o arquivo no diretório temp - especialmente porque usuários diferentes podem estar usando meu script para verificar isso (não deseja problemas de propriedade do arquivo, portanto Na verdade, eu vou até o anexo ${USER}do nome do arquivo.

jwa
fonte
1
Não tenho certeza se ele vai fazer muita diferença, mas eu deveria ter realmente anexado a versão findque estou usando find --version GNU find version 4.2.27 Features enabled: D_TYPE O_NOFOLLOW(enabled) LEAF_OPTIMISATION SELINUX
JWA

Respostas:

1

Uma maneira é (ab) usar o tempo da época. Aqui está um teste em que eu primeiro criei sete arquivos em sequência em um diretório vazio, onde os c#arquivos ficam "iguais" no ctimeque diz findrespeito:

$ 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

Isso deve representar todos os conjuntos possíveis de ctimerelativos a c2:

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

com correspondência um pouco confusa, pelo menos.

O terceiro comando obtém a época ctimedo arquivo c2, subtrai 1 via aritmética do shell e o alimenta como referência a -newerct(o @necessário para findinterpretar é como um carimbo de data / hora) para encontrar todos os arquivos com ctimemais novo que esse carimbo de data / hora interpretado (veja -newerXYem man find). O quarto comando nega essa correspondência e, na prática, deve fazer o que você deseja, se entendi a pergunta corretamente, se você colocar seu arquivo de referência como c2no meu exemplo.

Observe que o deslocamento de "1 segundo" é um tanto arbitrário (que é o que eu quis dizer com "correspondência difusa"), e pode-se imaginar uma situação em que um erro possa ser construído. No entanto, os registros de data e hora dos arquivos não são "definidos" de qualquer maneira e não podem ser confiáveis; portanto, não consigo imaginá-lo para gerar problemas práticos ou de segurança em situações reais.

Na verdade, na prática, você pode querer aumentar o deslocamento de 1 segundo (vejo na sua pergunta que você usa 1 minuto agora), mas esse é um detalhe da implementação.

Daniel Andersson
fonte
2

Talvez canalize a findsaída em um loop do testcomando que permitirá que você use um teste "mais antigo que":

find ... | while read file;
do
  [ "$file" -ot deployment_metadata.txt ] && echo "$file"
done
njd
fonte
Isso funciona mesmo no traço!
Ярослав Рахматуллин