Utilizando os comandos Find e Locate para buscar arquivos num VPS Linux
Introdução
Um problema que usuários enfrentam ao lidar com uma máquina Linux é o de localizar os arquivos que estão buscando. Este guia explica como usar os comandos find
e locate
para realizar buscas, utilizando uma gama de filtros e parâmetros.
Buscando por Nome
A maneira mais elementar de buscar arquivos é por nome. Para encontrar um arquivo a partir do seu nome exato, use:
find -name <<arquivo>>
O comando é sensível à caixa, de modo que uma busca por “arquivo” é diferente de uma por “Arquivo”. Se desejar que o comando ignore a caixa, digite:
find -iname <<arquivo>>
Se você quiser encontrar todos os arquivos que não correspondam a um padrão específico, é possível utilizar o parâmetro “-not”:
find -not -name <<arquivo>>
Buscando por Tipo
Você também pode especificar o tipo de arquivos que quer encontrar com o parâmetro “-type”:
find -type <<descritor_de_tipo>> <<tipo>>
Alguns dos descritores mais comuns que podem ser usados são:
- f: arquivo comum
- d: diretório
- l: link simbólico
- c: dispositivos de caracteres
- b: dispositivos de blocos
Por exemplo, se quiséssemos encontrar todos os dispositivos de caracteres no nosso sistema:
find / -type c
/dev/parport0
/dev/snd/seq
/dev/snd/timer
/dev/autofs
/dev/cpu/microcode
/dev/vcsa7
/dev/vcs7
/dev/vcsa6
/dev/vcs6
/dev/vcsa5
/dev/vcs5
/dev/vcsa4
. . .
É possível buscar por todos os arquivos que terminam em “.conf” da seguinte forma:
find / -type f -name *.conf
/var/lib/ucf/cache/:etc:rsyslog.d:50-default.conf
/usr/share/base-files/nsswitch.conf
/usr/share/initramfs-tools/event-driven/upstart-jobs/mountall.conf
/usr/share/rsyslog/50-default.conf
/usr/share/adduser/adduser.conf
/usr/share/davfs2/davfs2.conf
/usr/share/debconf/debconf.conf
/usr/share/doc/apt-utils/examples/apt-ftparchive.conf
. . .
Filtrando por Tamanho e Tempo
Há uma variedade de formas de filtrar resultados por tamanho e tempo.
Tamanho
Você pode filtrar por tamanho com o uso do parâmetro “-size”, concatenando ao valor do tamanho um sufixo que especifica a escala da contagem:
- c: bytes
- k: Kilobytes
- M: Megabytes
- G: Gigabytes
- b: 512-byte blocks
Por exemplo, para encontrar todos os arquivos que possuem exatamente 50 bytes:
find / -size 50c
Já para encontrar todos os arquivos menores que 50 bytes:
find / -size -50c
E para encontrar todos os arquivos com mais de 700 Megabytes:
find / -size +700M
Tempo
O Linux armazena informação de tempo de acesso, tempo de modificação e de alteração.
- Tempo de acesso: Última vez em que o arquivo foi lido ou escrito.
- Tempo de modificação: Última vez em que o conteúdo do arquivo foi alterado.
- Tempo de alteração: Última vez em que os metadados do inode foram alterados.
Podemos utilizar os parâmetros “-atime”, “-mtime”, e “-ctime”, em conjunto com os sinais “+” e “-“, para construir filtros baseados nos tempos acima descritos.
Por exemplo, para encontrar todos os aquivos cujo tempo de modificação foi há 1 dia:
find / -mtime 1
Para encontrar aquivos que foram acessados há menos de 1 dia:
find / -atime -1
Já para encontrar arquivos cujos metadados foram alterados há mais de 3 dias:
find / -ctime +3
Find também pode realizar comparações com um arquivo de referência e retornar todos aqueles que forem mais novos:
find / -newer arquivo
Filtrando por Dono e Permissão
Também é possível buscar por arquivos filtrando por dono, dono do grupo ou permissão. Por exemplo, para encontrar um arquivo cujo dono é o usuário “syslog”:
find / -user syslog
Analogamente, podemos especificar que queremos encontrar arquivos cujo dono é o grupo “dev” da seguinte forma:
find / -group dev
Também é possível buscar por arquivos com permissões específicas:
find / -perm 644
O comando acima irá retornar arquivos contendo exatamente as permissões especificadas. Se a intenção for pesquisar por quaisquer arquivos contendo pelo menos aquelas permissões, então a forma correta é:
find / -perm -644
No exemplo acima, tando um arquivo com permissões “644” quanto um com “744” seriam retornados.
Filtrando por Profundidade
Nesta seção, vamos criar uma estrutura de diretórios num diretório temporário. Cada diretório (incluindo o temporário) conterá dez arquivos e dez subdiretórios. Para criar a estrutura de diretórios, use:
mkdir -p ~/teste/nivel1dir{1..10}/nivel2dir{1..10}/nivel3dir{1..10}
touch ~/teste/{arquivo{1..10},nivel1dir{1..10}/{arquivo{1..10},nivel2dir{1..10}/{arquivo{1..10},nivel3dir{1..10}/arquivo{1..10}}}}
cd ~/teste
Vamos trabalhar em como retornar arquivos específicos desta estrutura. Primeiramente, uma busca simples para fins de comparação:
find -name arquivo1
./nivel1dir7/nivel2dir8/nivel3dir9/arquivo1
./nivel1dir7/nivel2dir8/nivel3dir3/arquivo1
./nivel1dir7/nivel2dir8/nivel3dir4/arquivo1
./nivel1dir7/nivel2dir8/nivel3dir1/arquivo1
./nivel1dir7/nivel2dir8/nivel3dir8/arquivo1
./nivel1dir7/nivel2dir8/nivel3dir7/arquivo1
./nivel1dir7/nivel2dir8/nivel3dir2/arquivo1
./nivel1dir7/nivel2dir8/nivel3dir6/arquivo1
./nivel1dir7/nivel2dir8/nivel3dir5/arquivo1
./nivel1dir7/nivel2dir8/arquivo1
. . .
A lista é grande. Se canalizarmos o resultado para um contador, podemos observar que há um total de 1111 resultados:
find -name arquivo1 | wc -l
1111
Isto é provavelmente muito para ser útil na maioria das circunstâncias. Vamos tentar afunilar um pouco mais, especificando a profundidade máxima abaixo do diretório topo. Para buscar “arquivo1” apenas no primeiro nível e acima, você pode especificar uma profundidade máxima de 2 (1 para o diretório topo, e 1 para o primeiro nível):
find -maxdepth 2 -name arquivo1
./nivel1dir7/arquivo1
./nivel1dir1/arquivo1
./nivel1dir3/arquivo1
./nivel1dir8/arquivo1
./nivel1dir6/arquivo1
./arquivo1
./nivel1dir2/arquivo1
./nivel1dir9/arquivo1
./nivel1dir4/arquivo1
./nivel1dir5/arquivo1
./nivel1dir10/arquivo1
Você também pode especificar uma profundidade mínima se você souber que todos os arquivos existem abaixo de determinado ponto. Por exemplo, podemos buscar somente os arquivos nos ramos da estrutura de diretórios:
find -mindepth 4 -name <<arquivo>>
./nivel1dir7/nivel2dir8/nivel3dir9/arquivo1
./nivel1dir7/nivel2dir8/nivel3dir3/arquivo1
./nivel1dir7/nivel2dir8/nivel3dir4/arquivo1
./nivel1dir7/nivel2dir8/nivel3dir1/arquivo1
./nivel1dir7/nivel2dir8/nivel3dir8/arquivo1
./nivel1dir7/nivel2dir8/nivel3dir7/arquivo1
./nivel1dir7/nivel2dir8/nivel3dir2/arquivo1
. . .
Mais uma vez, por causa da nossa estrutura ramificada de diretórios, a consulta acima retornará uma grande quantidade de resultados (1000). É possível combinar os parâmetros “mindepth” e “maxdepth” para focar numa banda mais estreita:
find -mindepth 2 -maxdepth 3 -name <<arquivo>>
./nivel1dir7/nivel2dir8/arquivo1
./nivel1dir7/nivel2dir5/arquivo1
./nivel1dir7/nivel2dir7/arquivo1
./nivel1dir7/nivel2dir2/arquivo1
./nivel1dir7/nivel2dir10/arquivo1
./nivel1dir7/nivel2dir6/arquivo1
./nivel1dir7/nivel2dir3/arquivo1
./nivel1dir7/nivel2dir4/arquivo1
./nivel1dir7/arquivo1
. . .
Executando e Combinando Comandos Find
Você pode executar um comando auxiliar arbitrário em qualquer resultado que o comando find retorne utilizando o parâmetro “-exec”:
find <<parametros>> -exec <<comandos_e_parametros>> {} \;
O “{}” é usado como marcador para os arquivos que o comando localizar. O “\;” é usado para denotar o final do comando. Por exemplo, poderíamos buscar os arquivos da seção anterior que tivessem permissão “644” e modificá-los para que tenham permissão “664”:
cd ~/teste
find . -type f -perm 644 -exec chmod 664 {} \;
E então poderíamos alterar as permissões de diretório da seguinte forma:
find . -type d -perm 755 -exec chmod 700 {} \;
Se você quiser encadear vários resultados distintos, pode usar os parâmetros “-and” ou “-or”. O “-and” é assumido por padrão:
find . -name arquivo1 -or -name file9
Buscando Arquivos com o Locate
Uma alternativa ao find
é o comando locate
. Este comando é, em geral, mais rápido e pode realizar buscas em todo o sistema de arquivos com facilidade. O motivo é que ele usa uma base de dados indexada dos arquivos do sistema.
A base de dados é normalmente atualizada diariamente por meio de um script cron., mas é possível atualizá-la manualmente:
sudo updatedb
Lembre-se que para encontrar arquivos recentemente adicionados ou criados, é importante que a base esteja atualizada..
Para buscar arquivos, use o comando com a sintaxe a seguir:
locate <<consulta>>
É possível filtrar o resultado de algumas formas. Por exemplo, para retornar somente arquivos contendo o termo da consulta, excluindo arquivos que possuem o termo da consulta no caminho de diretórios que levam até ele, você pode usar o parâmetro “-b”:
locate -b <<consulta>>
Para verificar algumas estatísticas sobre as informações catalogadas pela ferramenta, utilize a opção “-S”:
locate -S
Database /var/lib/mlocate/mlocate.db:
3,315 directories
37,228 files
1,504,439 bytes in file names
594,851 bytes used to store database
Conclusão
Tanto Find quanto Locate são boas ferramentas para buscar arquivos no seu sistema, ficando a seu cargo qual delas utilizar em cada situação. Elas são poderosas sozinhas, mas podem ser ainda mais úteis quando combinadas com outras através de pipes. Experimente filtrar os resultados utilizando-as em conjunto com os comandos wc
, sort
e grep
.