[ UNIX ] 

find  



 

O comando find tem como finalidade procura arquivos, satisfazendo determinadas condições. Para cada arquivo localizado, é possível executar uma operação. A sintaxe do find é: 

    find  diretório  condições  operação 

Onde: 

Diretório: é o nome do diretório inicial onde  o comando find deve começar a pesquisa. Condição: é uma cadeia de caracteres que é usada para selecionar os nomes dos arquivos que servirão para operação. Entenda-se por operação a execução de um comando qualquer do sistema. 
 
 
condição Significado
-atime n Verdadeiro, se o arquivo foi acessado n dias atrás.
-ctime n Verdadeiro, se o arquivo foi criado n dias atrás.
-exec comando Executa o comando
-mtime n Verdadeiro, se o arquivo foi modificado n dias atrás.
-name padrão Verdadeiro, se o nome do arquivo combina com o padrão 
-print Imprime o nome dos arquivos encontrados.
-type c Verdadeiro, se o arquivo é do tipo c (onde c pode ser: d - diretório; f - arquivo; l - vínculo
-user nome Verdadeiro, se o arquivo é do propriedade do usuário nome.
O comando find verifica as condições especificada, da esquerda para a direita, uma vez para cada arquivo encontrado. 

Na sua forma mais básica podemos usar o comando find para montra uma lista de todos os arquivos e diretórios abaixo do diretório atual: (isso pode gerar uma lista muito grande) 

    %  find . -print 
    . 
    ./mail 
    ./mail/inbox 
    ./mail/trash 
    ./mail/send 
    ./mail/saved 
    ./mail/amigos 
    ./temp 
    ./temp/teste 
    ./temp/teste1 
    ./temp/teste2 
    ./bolsistas.txt 
    ./scan.pl 

Para realizarmos uma busca apenas pelos arquivos da Perl (com sufixo .pl), devemos usar a condição -name antes da condição -print

    %  find . -name "*.pl"  -print 
    ./temp/busca.pl 
    ./temp/verifica.pl 
    ./temp/scan.pl 
    ./perl/analisa.pl 
    ./perl/procura.pl 

Para localizar os arquivos que foram modificado nos últimos sete dias, podemos usar -mtime com o argumento -7: 

    %  find  .  -mtime -7 -name  "*.pl" -print 

    ./temp/busca.pl 
    ./perl/analisa.pl 
    ./perl/procura.pl 

Se usarmos apenas o número 7 (sem o hífen), reculperamos apenas os arquivos que foram modificados há exatamente sete dias atrás: 

    %  find  .  -mtime 7  -name  "*.pl" -print 
    ./temp/verifica.pl 

Para localizar os arquivos nos quais não mexi por pelo menos 30 dias, usamos +30: 

    %  find  .  -mtime  +30  "*.pl" -print 
    ./cadastra.pl 
    ./deleta.pl 
    ./temp/procura.pl 
    ./tempo/remove.pl 
    ./perl/compila.pl 
    ./perl/troca.pl 

Para procurarmos por arquivos que contenham o padrão cp, nos diretórios /etc e /usr, podemos usar: 

    %  find  /etc  /usr  -name "*cp*" -print 
    /usr/spool/uucp 
    /usr/spool/news/comp/mail/uucp 
    find: cannot open <"/usr/spool/nqs"> 
    /use/man/man1/cpio.c 
    /usr/man/man2/strcp.3f 

Este tipo de pesquisa pode tomar muito tempo em um sistema ocupado. 

Para localizar uma lista de diretórios dentro do diretório /etc, podemos usar a condição -type com o valor d, como vimos na tabela acima: 

    %  find  /etc  -type d -print 
    /etc/bin 
    /etc/spool 
    /etc/var 
    /etc/usr 

 Podemos obter mais informações sobre os diretórios usando a condição -exec, a codição -exec deve ser usada com {  }, que será substituida pelo nome do arquivo com que combina e  \;   no final do comando, se você esquecer a  o C shell interpreta o como o final do comando find outra opção é colocar o ; entre aspas duplas ";". Você também deve se certificar de que haja um espaço  entre {  }  e a  \;. O nome do arquivo selecionado é colocado no lugar de {  } e depois o comando especificado é executado. 

    %  find /etc -type d  -exec  ls  -alp  {  }  \; 
    drwx------        2    maristela    staff        512    Apr    11    10:20    /etc/bin 
    drwxrw----       3    maristela    staff        512    Apr    11    10:45    /etc/spool 
    drwxr--r--        2    maristela    staff        512    Nov    04    22:35    /etc/var 
    drwx------       2    maristela    staff        521    Dec     25    23:59    /etc/usr 

Que tal remover os arquivos core mais antigos automaticamente, (isso se você não analisa seus core) 

    % find . -name core  -ctime +4  -exec  /bin/rm -f {  }  \; 

O flag -f no rm e para remover sem pedir cofirmação. 

Bem, agora você quer reculper um arquivo que não lembra onde esta, muito menos o nome do danado, mas..... você lembra do conteúdo do arquivo. Entã, o que acontecerá se usarmos o find e fizermos o arqgumento -exec chamar grep para localizar arquivod que contenhasm um padrão especifico? 

    % find / -type f  -exec  grep -i  remover  {  }  \; 
    /** com a funcao de remover os arquivos dos diretorios especificados **/ 
    # após remover os dados realiza uma chamada a função 

Então o que acontece... é que o find vai andar em todo o seu sistema de arquivos, lendo todos ao arquivos que puder atrás do padrão  "remover", mas não vai trazer o que realmente queremos que é o nome dos arquivos. 

Vamos evoluir e colocar o flag -l com grep, de forma que o grep especifique apenas o nome do arquivo: 

    %  find   / -type f  -exec  grep -i -l  remover  {  }  \; 
    /var/spool/remove.pl 
    /home/ricardo/mural.txt 

O problema do comando acima é que todas as vezes que o find encontrar um arquivo, ele vai chamar o grep, o que vai gastar muitos recursos do seu sistema (se ele encontra 700 arquivos vai executar grep 700 vezes), para evitar este desperdício de recursos devemos incluir um novo elemento ao nosso comando o xargs, com o xargs podemos ler a saída do find e construir chamadas para o grep, o xargs inclui a lista de nomes de arquivos no final do comando especificado, então  grep será chamado seis ou sete vezes e em cada uma das chamadas ele pode verificar 100 ou 200 arquivos. 

    %  find   / -type f  -print  |  xargs  grep -i -l  remover 
    /var/spool/remove.pl 
    /home/ricardo/mural.txt 

A saida será a mesma, mas mais rápida devido ao menor número de chamadas ao comando grep. 

Agora que mudamos nosso comando e temos a condição -print, podemos tira o flag -l que coloca somente o nome do arquivo, assim temos: 

    %  find   / -type f  -print  |  xargs  grep -i remover 
    /var/spool/remove.pl              /** com a funcao de remover os arquivos dos diretorios especificados **/ 
    /home/ricardo/mural.txt         # após remover os dados realiza uma chamada a função 

 Agora você quer procura por dois padrões simutaneamente, vejamos como fazer isso: 

    %  find /  \(-name  "*.pl" -o  "*.c" \)  -atime +5  -exec  rm { } \; 
 

  • O primeiro parametro passado é a /, isso indica que deve procura em todo o sistema de arquivos
  • Em seguida note que os parêntese estão precedidos de uma barra invertida, isso é para evitar que eles sejam interpretados pelo shell como subshell
  • Os parêntes serve para indicar ao find que a pesquisa é composta de um ou lógico que indicamos com -o
  • A opção -atime +5 selecuiona somente os arquivos que não foram acessados a mais de cinco dias
  • E finalmente -exec rm { }, informa ao find para realizar o comando rm
Agora vejamos como identificar arquivos muito grande dentro do sistema de arquivos: 

    %  find /home -mtime -2  -size  +100k  -exec  ls -alp { }  \; 
    -rwxr--r--     2    maristela    staff        116003    Apr    11    10:20    busca.sql 

  • Realizamos a pesquisa no diretório /home
  • -mtime -2 seleciona  arquivos cujos conteúdos foram modificados nos últimos dois dias
  • -size +100k é para selecionar apenas os nomes de arquivos cujo tamanhos são maiores que cem blocos, o que em algumas isntituições representa 100 Kbytes
  • -exec ls -alp { } \; é para executar o comando ls e devolver mais detalhes sobre o arquivo
 O comando find pode estender-se por mais de uma linha física. Podemos usar o caractere contrabarra (\) para tirar o efeito do caractere de nova linha, permitindo, desta forma, que uma linha lógica seja excrita em duas linhas físicas, ou seja, o caractere de contrabarra (\) no final da linha é para avisar ao shell que a linha lógica continua na próxima linha física. 

     %  find /  \(-name  "*.pl" -o \ 
         "*.c" \)  -atime +5 \ 
         -exec  rm { } \; 

  Para localizar todos os arquivos do sistema com os bits setuid ou setgid ligados, use : 

   % find / -type f -a \( -perm 0400 -o -perm 0200 \) -print 

  Para identificar todos os arquivos com permisão de escrita universal, use: 

   % find / -perm -2 -print 

  Para identificar arquivos que não perntencem a nenhum usuário ou a nenhum grupo, use: 

   % find / -nouser -o -nogroup -print 
 
 
 

Referência : 

  • Teach yourself Unix in 24 hours (0-672-31107-0)
  • Aumentando Produtividade e Qualidade em Sistemas Abertos - Guia Avançado para Ambientes UNIX
  • man page - man find
  • Administração de Redes TCP/IP (Maria Ivete Lovato / Rubens Queiros de Almeida) - UNICAMP
 
<=

http://www.absoluta.org      ---oOo---      verdade@absoluta.org

Copyright © 1998 - 2000  Verdade @bsoluta