Faça o exec diretamente com o find e não via xargs.
sudo find . -name '*.png' -exec optipng -o {} +
Eu tenho uma estrutura de diretórios profunda, com um grande número de arquivos (cerca de 1M). Eu gostaria de executar um comando contra cada um. (No meu caso, os arquivos são pngs que eu gostaria de executar optipng contra.)
Eu tentei isso:
find . -name *.png | xargs sudo optipng -o2
mas estou recebendo o erro argument list too long
.
Estou assumindo que os xargs devem ser capazes de lidar com isso e que deve haver um problema com minha sintaxe.
Faça o exec diretamente com o find e não via xargs.
sudo find . -name '*.png' -exec optipng -o {} +
Usar o comando sudo as para executar por xargs
não está funcionando, como você vê. Tente o contrário:
find . -name '*.png' | sudo xargs optipng -o2
A diferença é que sua versão cria um comando como
sudo optipng -o2 file1 file2 file3 file4 ......
e o sudo não consegue lidar com tantos parâmetros.
Fazendo o contrário, executa o sudo uma vez, que por sua vez inicia o xargs
, que gera um comando como
optipng -o2 file1 file2 file3 file4 ......
e se optipng
puder manipular muitos arquivos como parâmetros, isso deve funcionar.
Se isso ainda não funcionar, você terá que usar -exec
, como na resposta de Geraint, mas este deve ser seu último recurso.
Mais uma chance:
find . -name '*.png' | sudo xargs -n x -P y optipng -o2
O qual iniciará uma otimização para x
arquivos e y
desses processos em paralelo (pode ajudar você a fazer as coisas mais rapidamente se tiver alguns núcleos de sobra).
Ter x
maior que 10 provavelmente não causará grande impacto no desempenho.
Isso ajudará a manter a lista de argumentos curta. Então, você provavelmente poderia mover sudo
para onde você o tinha, mas esse seria apenas outro comando que teria que ser executado para cada lote.