Determinar se um arquivo foi modificado

10

No Linux (atualmente usando o sistema de arquivos ext4), como verificar rapidamente se o conteúdo de um arquivo foi modificado sem a leitura de qualquer conteúdo?

O statcomando é uma abordagem recomendada? Eu atualmente

$ stat --format "%Y" hello.txt

e depois posso verificar se o mesmo comando produz a mesma saída. Nesse caso, concluo que o hello.txt não mudou.

Meu sentimento é que alguém quer acrescentar mais parâmetros para ter ainda mais certeza. Por exemplo, adicionar o tamanho, o nome do arquivo etc. forneceria uma "impressão digital" ainda melhor do arquivo?

Nesse tópico, lembro que um volume TrueCrypt que eu já tive foi sempre ignorado pelo meu programa de backup incremental, possivelmente porque o TrueCrypt se certificou de não deixar nenhuma alteração nos metadados. Suponho que é realmente possível alterar todos os dados retornados por stat, portanto, não é possível garantir a cada modificação possível do arquivo?

DustByte
fonte
md5sum filename?
Ramsh
md5sumou qualquer tipo de soma de verificação lê o conteúdo do arquivo. Eu não quero fazer isso, pois é muito lento para os meus propósitos.
DustByte
ls -tclassificará o conteúdo em um diretório pela hora da modificação.
ryekayo
"foi modificado"? Cada arquivo foi modificado, a questão é quando foi modificado. Você pode usar 'find' para procurar um intervalo específico de tempos de modificação.
Ray Andrews

Respostas:

5

Se você deseja detectar se um arquivo foi modificado por meios normais (editando-o em algum aplicativo, verificando uma nova versão de um sistema de controle de revisões, reconstruindo-o etc.), verifique se o tempo de modificação (mtime) mudou de a última verificação. Isso é o que stat -c %Yinforma.

O horário da modificação pode ser definido pelo touchcomando Se você deseja detectar se o arquivo foi alterado de alguma forma (incluindo o uso touch, extração de um arquivo morto etc.), verifique se o tempo de alteração do inode ( ctime ) mudou desde a última verificação. Isso é o que stat -c %Zinforma. O ctime não pode ser falsificado, exceto pelo administrador do sistema (e mesmo assim, apenas por meios indiretos: alterando o relógio do sistema ou acessando o disco diretamente, ignorando o sistema de arquivos).

Gilles 'SO- parar de ser mau'
fonte
Obrigado, entendo que ctime é o que devo usar. Não resultou da minha pergunta que o objetivo disso é usá-lo em meu próprio script de backup, onde as somas de verificação serão computadas apenas para novos arquivos ou arquivos que foram alterados. Posso pagar somas de verificação computacionais para arquivos que mudaram apenas "levemente", digamos que as permissões foram alteradas etc. Eu prefiro estar o mais próximo possível de realmente observar o conteúdo do arquivo para determinar uma alteração.
DustByte
3

O comando stat possui apenas uma resolução de segundo. Portanto, se o arquivo foi modificado duas vezes no mesmo segundo, você poderá perder uma modificação. Os sistemas de arquivos mais recentes, como o ext4, fornecem registros de data e hora de resolução mais alta em nanossegundos, mas algumas das ferramentas antigas ainda não foram atualizadas.

Além disso, é possível para outros programas definir um tempo de modificação arbitrário. Você pode ver como isso pode acontecer através do comando touch.

Se você estiver preocupado com uma dessas duas possibilidades, não seria uma má idéia examinar também o tamanho do arquivo. É isso que o rsync faz quando procura arquivos modificados.

Steve Sether
fonte
1

Meu sentimento é que alguém quer acrescentar mais parâmetros para ter ainda mais certeza.

O que você tem é o método correto. A única razão para isso falhar seria se o sistema de arquivos não estiver sendo atualizado corretamente - nesse caso, você terá vários problemas mais sérios.

Obviamente, presumo que alguém com o conhecimento e acesso root adequados a um sistema em que a partição esteja acessível possa alterar as informações para parecer que o arquivo não foi alterado. No entanto, nesse caso, eles certamente teriam feito o mesmo com o tamanho, etc.

Cachinhos Dourados
fonte
0

Eu faço a impressão digital mais detalhada.

Eu criei uma pequena função wrapper que gera saída idêntica para as versões MacOS / BSD e GNU do stat(também detecta a versão instalada pelo Homebrew com um gprefixo).

init() {
  if command -v gstat > /dev/null; then
    # GNU coreutils with g prefix.
    statCmdArgs=("gstat" "--format=%n %s %b %u %g %i %h %Y %Z %W %o");
  elif ! stat --version > /dev/null 2> /dev/null; then
    # MacOS/BSD stat
    statCmdArgs=("stat" "-f" "%N %z %b %u %g %i %l %m %c %B %k");
  else
    # Assume GNU version without prefix.
    statCmdArgs=("stat" "--format=%n %s %b %u %g %i %h %Y %Z %W %o");
  fi;
}

getFileStatus() {
  "${statCmdArgs[@]}" "$1";
}

A initfunção é chamada uma vez durante a inicialização do script e getFileStatuspode ser chamada repetidamente sem a sobrecarga de detecção.

devstuff
fonte