Concatena o comando find com outros commans

0

Estou tentando indexar meu sistema de arquivos. O que eu quero fazer é: executar o comando find , e para cada entrada salvar o último horário de acesso, a última hora modificada, calcular o hash e outras operações. Para fazer isso, pensei em fazer o seguinte comando:

find . -printf 'PATHNAME=%p -- NAME=%f -- SIZE=%s -- LAT=%a -- LCT=%c -- LMT=%t  \n' -exec file {} \; -exec md5sum {} \;

A saída é algo como:

PATHNAME=./script -- NAME=script -- SIZE=807 -- LAT=Fri Apr 15 16:39:52.0874615579 2016 -- LCT=Tue Apr 12 12:20:57.0767950320 2016 -- LMT=Tue Apr 12 12:20:57.0767950320 2016 <br>
./script: ASCII text <br>
cf1b934c226b194bee96106ea3f019a4  ./script

Agora eu gostaria de pegar todos esses parâmetros (por exemplo, analisá-los com awk ) e colocá-los em algum lugar (por exemplo, em um banco de dados). Então, minha pergunta é: como posso redirecionar cada vez que estas 3 linhas para um script para a análise? Existe uma maneira melhor de escrever o comando?

    
por Labo29 15.04.2016 / 17:21

1 resposta

0

Eu usaria algo assim (sem a parte de inserção no banco de dados)

while read EMPTY_LINE; do
  read FILE_SIZE
  read FILE_AT
  read FILE_MT
  read FILE_CT
  read MIME_INFO
  read HASH FILE_PATH

  echo
  echo 'File path: '"$FILE_PATH"
  echo 'File size: '"$FILE_SIZE"
  echo 'File times (access - modified - changed): '"$FILE_AT - $FILE_MT - $FILE_CT"
  echo 'MIME stuff: '"$MIME_INFO"
  echo 'Hash: '"$HASH"
done < <(find . -type f -printf '\n' -exec stat --printf '%s\n%X\n%Y\n%Z\n' {} \; -exec file -b {} \; -exec md5sum {} \; )

Ok, então o que exatamente acontece aqui, e por que eu fiz assim?

Comando de localização

Primeiro, o comando find . -type f -printf '\n' -exec stat --printf '%s\n%X\n%Y\n%Z\n' {} \; -exec file -b {} \; -exec md5sum {} \; é executado.

Vamos analisar isso.

find . encontra coisas em . (que é o diretório atual)

-type -f encontra apenas arquivos

-printf '\n' imprime um arquivo vazio para cada correspondência de arquivo

-exec stat --printf '%s\n%X\n%Y\n%Z\n' {} \; executa o comando stat imprimindo várias estatísticas de arquivos que eu mesmo especifiquei - consulte stat --help para as estatísticas disponíveis

-exec file -b {} \; executa o comando do arquivo para determinar as informações MIME. -b garante que o nome do arquivo não seja impresso junto com ele. Nós ignoraríamos mesmo assim.

-exec md5sum {} \; execute o comando md5sum para calcular o hash md5 do conteúdo do arquivo.

Então, tudo bem. Os argumentos -exec são processados na ordem especificada. Isso significa que, por correspondência de arquivo, obteremos as seguintes linhas como

[FILE SIZE - from stat command]
[FILE LAST ACCESS TIME - from stat command]
[FILE LAST MODIFICATION TIME - from stat command]
[FILE LAST CHANGE TIME - from stat command]
[MIME INFO - from file command]
[HASH - from md5sum command] [FILE PATH - from md5sum command]

Vamos testar o comando find para ver se ele gera tudo como esperávamos.

[~/somedir]:$ find . -type f -printf '\n' -exec stat --printf '%s\n%X\n%Y\n%Z\n' {} \; -exec file -b {} \; -exec md5sum {} \;

1752
1441609114
1441609114
1441609114
ASCII text
4fb6f64ce9d07be553a81644b17fe69b  ./README.md

./tuptime-install.sh
1649
1441609114
1441609114
1441609114
Bourne-Again shell script, ASCII text executable
9ee7ad860bfa049d1d5f589fba218c6a  ./tuptime-install.sh

Processar as linhas

Há muita coisa que pode dar errado ao analisar essas coisas. O que acontece se houver um espaço no nome do arquivo? Ou algum outro personagem estranho? Ou nos outros parâmetros. Para me livrar deste problema e outros eu usei newlines explicitamente. Então podemos ler uma linha completa e processá-la de acordo. Nenhuma análise especial é necessária. (exceto para a parte hash, mas chegaremos a essa parte daqui a pouco)

O loop while será alimentado com a saída do comando find . O loop while será executado enquanto houver uma linha à esquerda. Nós lemos a linha vazia em que cada partida começa. A linha vazia na verdade não é realmente necessária, mas vamos usá-la para manter a saída limpa.

O script é bastante auto-explicativo. Ele lê as linhas uma por uma em variáveis na ordem em que esperamos que elas estejam presentes. Depois disso nós os imprimimos.

A maneira como o comando read funciona, se um único nome de variável for fornecido, ele lerá a linha inteira no nome da variável fornecida. Se múltiplas variáveis são dadas, a linha é dividida com o caractere de espaço (por padrão) e colocada nas variáveis dadas. Usamos isso apenas para o comando md5sum , pois não foi possível especificar uma opção que eliminaria o nome do arquivo. Poderíamos ter obtido o nome do arquivo de find 'ou stat , mas como o md5sum não tem a opção de omiti-lo por motivos de eficiência, usaremos esse nome.

Eu também usei o formato unixtime em vez do legível para timestamps. Ter dados na forma mais bruta, se possível, é na maioria dos casos preferido.

A única coisa que permaneceria seria colocar os dados no banco de dados.

Exemplo de saída do script

File path: ./README.md
File size: 1752
File times (access - modified - changed): 1441609114 - 1441609114 - 1441609114
MIME stuff: ASCII text
Hash: 4fb6f64ce9d07be553a81644b17fe69b

File path: ./tuptime-install.sh
File size: 1649
File times (access - modified - changed): 1441609114 - 1441609114 - 1441609114
MIME stuff: Bourne-Again shell script, ASCII text executable
Hash: 9ee7ad860bfa049d1d5f589fba218c6a
    
por Serrie 15.04.2016 / 19:35