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: Julio Cezar Neves
Data da Publicação: 14 de dezembro de 2022
Dando continuidade ao nosso estudo do comando xargs, vamos apresentar aqui
mais algumas opções desse poderoso utilitário.
Esta opção recebe uma quantidade INT de linhas de cada vez:
Exemplo
Para vermos a diferença entre essas duas opções, vamos salvar a saída do
comando do exemplo anterior no arquivo teste:
$ echo {1..3} | xargs -n1 echo Linha > teste
Agora vamos ver o uso da opção -n e em seguida a opção -L:
$ cat teste | xargs -n1 Linha 1 Linha 2 Linha 3 $ cat teste | xargs -L2 Linha 1 Linha 2 Linha 3
Mas prefiro usar a sintaxe a seguir por ser mais rápida que o cat:
$ echo "$(<teste)" | xargs -L2
Linha 1 Linha 2
Linha 3
Esta opção recebe uma linha de cada vez e a insere onde o ALVO estiver
colocado. Se ALVO não for especificado, o padrão será um par de chaves ({}).
Exemplo
$ seq 3 | xargs -i echo Esta é a {}a. linha
Esta é a 1a linha
Esta é a 2a linha
Esta é a 3a linha
Mais um, mas especificando PonhaAqui como alvo:
$ seq 2 | xargs -iPonhaAqui echo PonhaAqui é o seu número
1 é o seu número
2 é o seu número
Observação: O padrão POSIX, indica a opção -I para cumprir esta função. A
única diferença que notei entre o uso do -I e do -i, é que a primeira não
tem um alvo padrão, ao contrário da segunda, que como já vimos aceita o {}
como default.
$ seq 3 | xargs -I echo Esta é a {}a. linha
xargs: Esta: Arquivo ou diretório inexistente
$ seq 3 | xargs -I{} echo Esta é a {}a. linha
Esta é a 1a. linha
Esta é a 2a. linha
Esta é a 3a. linha
Esta opção exibe a linha que será executada pronta, antes de executá-la.
Exemplo
Vamos executar o exemplo anterior, porém inserindo também a opção -t.
$ seq 2 | xargs -tiPonhaAqui echo PonhaAqui é o seu número
echo 1 é o seu número
1 é o seu número
echo 2 é o seu número
2 é o seu número
Agora já preparei o terreno básico para explicar o melhor de tudo, a cereja do bolo, que é o paralelismo de processos.
Esta opção dispara PROCS processos em paralelo, limitando PROCS ao número
de CPUs de seu computador, que pode ser obtido com o comando nproc. Se PROCS
for igual a zero, o xargs usará todas as CPUs.
Exemplo
$ nproc
4
Esse comando nos informa a quantidade de processadores que dispomos e que
em parceria com o xargs com a opção -P PROCS, podemos melhorar muito o
desempenho, utilizando não apenas um, mas quantos desejarmos até, neste caso, 4.
$ time echo {1..4} | xargs -tn1 -P0 sleep # usando meus 4 processadores
sleep 1
sleep 2
sleep 3
sleep 4
real 0m4.007s
user 0m0.000s
sys 0m0.000s
$ time echo {1..4} | xargs -tn1 sleep # Usando somente 1 processador
sleep 1
sleep 2
sleep 3
sleep 4
real 0m10.007s
user 0m0.000s
sys 0m0.000s
Nas duas linhas de comandos acima o xargs passava para o sleep valores
de 1 a 4 e isso foi exibido pelo uso da opção -t que mostra as linhas que
estão sendo executadas. Para analisar o que aconteceu, medimos os tempos de
execução das linhas de comandos, o que nos permite notar que no primeiro
caso, quando usei os meus 4 processadores (-P0 é o mesmo que -P$(nproc)),
o tempo foi aproximadamente igual ao do maior de todos os sleep, isto é,
4 porque rodaram simultaneamente e os de menor tempo encerraram antes.
Já na segunda linha de comandos, o tempo encontrado foi aproximadamente a soma de todos, porque os quatro sleep foram executados sequencialmente por somente um processador.
$ time echo {1..6} | xargs -n1 -P0 sleep # usando 4 procs
real 0m6,006s
user 0m0,007s
sys 0m0,003s
Este exemplo serve para mostrar que essa opção é preemptiva. O xargs notou
que os sleep 3 4 5 e 6 seriam os mais demorados e tratou-os primeiro. Quando
o sleep 3 terminou, trouxe para a CPU vaga o sleep 2 e quando o sleep 4
terminou, processou o sleep 1.
Depois disso surgiu o comando GNU parallel com função semelhante a essa
opção e até um pouco mais completo, porém não vem instalado por padrão na
grande maioria das distros.
O onde você pode usar isso? Em tudo!!! Um exemplo bem simples seria para
zipar diversos arquivos. Uso muito para converter imagens com o convert do
Image Magick