Comando xargs no Linux: Passar Argumentos em Lote com Exemplos Práticos
O comando xargs é uma das ferramentas mais poderosas do terminal Linux. Ele resolve um problema simples mas frequente: muitos comandos (rm, chmod, cp, ssh) não lêem da entrada padrão — eles precisam receber os argumentos diretamente na linha de comando. O xargs faz essa ponte, transformando a saída de um pipe em argumentos.
Sem xargs, um find . -name "*.log" | rm simplesmente não funciona. Com xargs, vira find . -name "*.log" | xargs rm e processa centenas de arquivos de uma vez.
Sintaxe do xargs
comando | xargs [opções] [comando_destino]
O xargs lê itens da entrada padrão (separados por espaço, tabulação ou nova linha por padrão) e os passa como argumentos para o comando_destino.
Exemplo básico
# Sem xargs — não funciona como esperado
echo "arquivo.txt" | cat
# Com xargs — passa "arquivo.txt" como argumento para cat
echo "arquivo.txt" | xargs cat
# Vários arquivos de uma vez
ls *.conf | xargs wc -l
Principais opções do xargs
| Opção | O que faz | Exemplo |
|---|---|---|
-n N | Máximo de N argumentos por chamada | xargs -n 2 |
-I {} | Substitui {} pelo argumento no comando | xargs -I{} mv {} {}.bak |
-P N | Executa N processos em paralelo | xargs -P 4 |
-0 | Usa null como separador (para nomes com espaços) | find -print0 | xargs -0 |
-t | Mostra o comando antes de executar (verbose) | xargs -t rm |
-p | Pede confirmação antes de cada execução | xargs -p rm |
-L N | N linhas de entrada por chamada | xargs -L 1 |
--no-run-if-empty | Não executa se a entrada estiver vazia | xargs --no-run-if-empty rm |
Casos de uso práticos
1. Deletar arquivos encontrados pelo find
Esta é a combinação mais comum. O find lista os arquivos e o xargs passa todos para o rm de uma vez, muito mais eficiente do que find -exec rm {} \;:
# Deletar todos os arquivos .log com mais de 30 dias
find /var/log -name "*.log" -mtime +30 | xargs rm -f
# Ver quais seriam deletados antes de executar
find /var/log -name "*.log" -mtime +30 | xargs -t rm -f
2. Nomes de arquivos com espaços — use -0
O maior problema do xargs padrão é que espaços quebram os argumentos. A solução é usar find -print0 junto com xargs -0:
# ERRADO — quebra em nomes com espaço
find . -name "*.jpg" | xargs rm
# CORRETO — separador null preserva nomes com espaço
find . -name "*.jpg" -print0 | xargs -0 rm
3. Substituição com -I {} para renomear e transformar
Com -I {} você define onde o argumento vai aparecer no comando — não necessariamente no final:
# Criar backup de cada arquivo .conf
ls *.conf | xargs -I{} cp {} {}.bak
# Mover arquivos para outro diretório mantendo o nome
find . -name "*.py" | xargs -I{} mv {} /opt/scripts/{}
# Criar diretórios com base em uma lista
cat projetos.txt | xargs -I{} mkdir -p /var/www/{}
# Fazer curl para múltiplos endpoints
cat urls.txt | xargs -I{} curl -s {} -o /dev/null -w "%{http_code} {}\n"
4. Execução paralela com -P
O flag -P N executa N processos simultâneos — ideal para operações que podem ser paralelizadas como downloads, compressão ou processamento de imagens:
# Comprimir 8 arquivos em paralelo (usa múltiplos núcleos)
find . -name "*.log" -print0 | xargs -0 -P 8 gzip
# Baixar múltiplos arquivos em paralelo
cat lista_de_urls.txt | xargs -P 5 -I{} wget -q {}
# Redimensionar imagens em paralelo com ImageMagick
find . -name "*.png" -print0 | xargs -0 -P 4 -I{} convert {} -resize 800x600 {}
5. Controlar quantidade de argumentos com -n
Por padrão, o xargs passa todos os argumentos de uma vez. Com -n N você limita quantos vão em cada chamada — útil quando o comando tem um limite ou quando você quer processar em grupos:
# Mostrar 2 arquivos por vez com cat
ls *.txt | xargs -n 2 cat
# Verificar 10 URLs por vez
cat urls.txt | xargs -n 10 curl --head
# Ver como os argumentos são agrupados (verbose)
seq 1 10 | xargs -n 3 echo
# Saída:
# 1 2 3
# 4 5 6
# 7 8 9
# 10
6. Buscar texto em muitos arquivos com grep
# Buscar "erro crítico" em todos os logs do mês passado
find /var/log -name "*.log" -mtime -30 -print0 | xargs -0 grep -l "erro crítico"
# Contar ocorrências por arquivo
find . -name "*.php" -print0 | xargs -0 grep -c "sql_query"
# Buscar e substituir em múltiplos arquivos (com sed)
grep -rl "texto_antigo" . | xargs sed -i 's/texto_antigo/texto_novo/g'
7. Operações em servidores remotos
# Verificar status de serviço em múltiplos servidores
cat servidores.txt | xargs -I{} ssh {} "systemctl status nginx | grep Active"
# Copiar chave pública para vários servidores
cat servidores.txt | xargs -I{} ssh-copy-id user@{}
# Reiniciar serviço em todos os nós do cluster
cat nodes.txt | xargs -I{} -P 5 ssh {} "sudo systemctl restart app"
8. Verificar se entrada está vazia
Sem --no-run-if-empty, o xargs executa o comando mesmo sem argumentos, o que pode causar problemas:
# PERIGOSO — rm sem argumentos pode falhar ou apagar coisas erradas
find . -name "*.tmp" | xargs rm
# SEGURO — não executa rm se não houver arquivos .tmp
find . -name "*.tmp" | xargs --no-run-if-empty rm
xargs vs find -exec
Ambos resolvem problemas parecidos, mas com comportamentos diferentes:
| xargs | find -exec {} \; | find -exec {} + | |
|---|---|---|---|
| Velocidade | Rápido (poucos processos) | Lento (1 processo por arquivo) | Rápido (agrupa argumentos) |
| Nomes com espaço | Precisa de -print0 / -0 | Funciona nativamente | Funciona nativamente |
| Controle de paralelo | Sim (-P) | Não | Não |
| Pipelines complexos | Sim | Não | Não |
# find -exec equivalente ao xargs (mais lento, 1 processo por arquivo)
find . -name "*.log" -exec rm {} \;
# find -exec + agrupa argumentos (similar ao xargs padrão)
find . -name "*.log" -exec rm {} +
# xargs com -print0/-0 é a opção mais segura e flexível
find . -name "*.log" -print0 | xargs -0 rm
Referência rápida
# Deletar em lote com segurança
find . -name "*.tmp" -print0 | xargs -0 --no-run-if-empty rm
# Renomear adicionando extensão
ls *.txt | xargs -I{} mv {} {}.bak
# Comprimir em paralelo
find . -name "*.log" -print0 | xargs -0 -P $(nproc) gzip
# Buscar e substituir em múltiplos arquivos
grep -rl "padrão" . | xargs sed -i 's/padrão/novo/g'
# Executar em múltiplos servidores
cat hosts.txt | xargs -I{} -P 10 ssh {} "uptime"
# Ver como os argumentos serão divididos (dry run)
echo "a b c d e" | xargs -n 2 echo
Dicas e armadilhas
- Sempre use
-print0 | xargs -0quando os nomes dos arquivos podem ter espaços — que é quase sempre em sistemas de uso geral. - Use
-tpara depurar antes de executar operações destrutivas comorm. - Combine
-P $(nproc)para aproveitar todos os núcleos disponíveis em operações paralelizáveis. - O
-I{}implica-L 1— cada linha vira uma chamada separada ao comando. - Cuidado com aspas na substituição:
xargs -I{} sh -c 'echo "valor: {}"'pode ter comportamento inesperado com espaços nos argumentos.