De acordo com as Leis 12.965/2014 e 13.709/2018, que regulam o uso da Internet e o tratamento de dados pessoais no Brasil, ao me inscrever na newsletter do portal DICAS-L, autorizo o envio de notificações por e-mail ou outros meios e declaro estar ciente e concordar com seus Termos de Uso e Política de Privacidade.
Colaboração: Daniel Duclos
Data de Publicação: 15 de Junho de 2007
Pode ser que você já tenha tentado dar um comando usando o asterisco * na bash e tenha obtido este erro:
bash: comando: Argument list too long
Aonde comando pode ser um rm, ou um cp, ou qualquer outro. Por exemplo:
daniduc@nicholas:~/teste$ rm -f * bash: /bin/rm: Argument list too long daniduc@nicholas:~/teste$
Quem imprimiu esse erro não foi o comando (o rm, no exemplo), mas a bash, que é responsável por expandir o wildcard *, substituindo-o pela lista de arquivos no diretório. Em sistemas UNIX, há um limite fixo de memória reservado para o ambiente e lista de parâmetros de um comando. No caso do meu servidor Linux, esse limite é 128K, mas isso varia de sistema para sistema. Você pode descobrir no seu sistema usando o comando getconf. Veja:
daniduc@nicholas:~/teste$ getconf ARG_MAX 131072 daniduc@nicholas:~/teste$
Agora, ao que interessa. Como fazer para remover os arquivos do meu exemplo acima? Existem diversas saídas, variando a eficiência dependendo de qual é o seu comando, na verdade. Mas vamos ver o rm, pois o exemplo dele pode ser aplicado a outros, como por exemplo o cp, ou o mv.
Se você puder eliminar o diretório inteiro no qual estão os arquivos, não há problemas:
daniduc@nicholas:~$ rm -rf teste/ daniduc@nicholas:~$
Se você só pode eliminar os arquivos, uma saída é usar o comando find.
daniduc@nicholas:~/teste$ find . -type f -exec rm -f {} \; daniduc@nicholas:~/teste$
Nesse caso, eu pedi para o find encontrar no diretório em que estou (.) todos os arquivos (-type f) e para cada um deles executar (-exec) o comando rm. As chaves {} são substituídas por cada arquivo encontrado pelo find. Dessa forma o rm é executado uma vez para cada arquivo, tendo assim apenas aquele arquivo como parâmetro, o que evita ultrapassar o limite de memória imposto. O final \; é para fechar o comando do -exec com um ponto e vírgula, que precisa ser precedido da contra barra (\) para que a bash não o interprete (uma vez que ; é um caractere com sentido especial para a bash) e apenas o passe para o find.
Caso, por exemplo, você precise remover somente os arquivos html e não os arquivos .php em um diretório, basta usar o find novamente:
daniduc@nicholas:~/teste$ ls *.php 1.php 2.php daniduc@nicholas:~/teste$ ls (saida resumida:) 23497.html 36998.html 50498.html 6399.html 774.html 9.html 23498.html 36999.html 50499.html 639.html 77500.html 23499.html 3699.html 5049.html 63.html 77501.html 2349.html 369.html 504.html 64000.html 77502.html 234.html 36.html 50500.html 64001.html 77503.html
daniduc@nicholas:~/teste$ find . -name \*.html -exec rm -f {} \; daniduc@nicholas:~/teste$ ls 1.php 2.php daniduc@nicholas:~/lixo
Aqui o asterisco funciona porque está precedido pela contrabarra o que faz com que a bash não o interprete, apenas o find. E o find não expande o asterisco em todos os arquivos do diretório, como a bash. Para o find, o asterisco é parte de uma expressão regular, que quer dizer encontre arquivos cujo nome seja qualquer coisa seguida de um .html .
Eu uso a versão da GNU do find, presente na maioria dos sistemas Linux. Caso o seu find não entenda o parâmetro -exec, use-o em conjunto com comando xargs:
daniduc@nicholas:~/teste$ find . -name \*.html | xargs rm -f daniduc@nicholas:~/teste$ ls 1.php 2.php daniduc@nicholas:~/teste$
Referências:
http://www.gnu.org/software/coreutils/faq/coreutils-faq.html#Argument-list-too-long
Essa dica foi publicada também no Blog UNIX Notes, que mantenho em conjunto com minha esposa.
This policy contains information about your privacy. By posting, you are declaring that you understand this policy:
This policy is subject to change at any time and without notice.
These terms and conditions contain rules about posting comments. By submitting a comment, you are declaring that you agree with these rules:
Failure to comply with these rules may result in being banned from submitting further comments.
These terms and conditions are subject to change at any time and without notice.
Comentários