você está aqui: Home  → Arquivo de Mensagens

xargs - construção e execução de linhas de comando a partir da entrada padrão - Parte 2/2

Colaboração: Júlio Neves

Data de Publicação: 03 de outubro de 2017

Continuamos hoje o que começamos ontem, isto é, a ver as facilidades oferecidas pelo comando xargs.

O xargs é também uma excelente ferramenta de criação de one-liners (scripts de somente uma linha). Veja este para listar todos os donos de arquivos (inclusive seus links) "pendurados" no diretório /bin e seus subdiretórios.

$ find /bin -type f -follow | \
xargs ls -al | tr -s ' ' | cut -f3 -d' ' | sort -u

Muitas vezes o /bin é um link (se não me engano, no Solaris o é) e a opção -follows obriga o find a seguir o link. O comando xargs alimenta o ls -al e a seqüência de comandos seguinte é para pegar somente o 3º campo (dono) e classificá-lo devolvendo somente uma vez cada dono (opção -u do comando sort).

Você pode usar as opções do xargs para construir comandos extremamente poderosos. Para exemplificar isso e começar a entender as principais opções desta instrução, vamos supor que temos que remover todos as arquivos com extensão .txt sob o diretório corrente e apresentar os seus nomes na tela. Veja o que podemos fazer:

$ find . -type f -name "*.txt" | \ 
xargs -i bash -c "echo removendo {}; rm {}"

A opção -i do xargs troca pares de chaves ({}) pela cadeia que está recebendo pelo pipe (|). Então neste caso as chaves ({}) serão trocadas pelos nomes dos arquivos que satifaçam ao comando find.

Olha só a brincadeira que vamos fazer com o xargs:

$ ls | xargs echo > arq.ls
$ cat arq.ls
arq.ls arq1 arq2 arq3
$ cat arq.ls | xargs -n1
arq.ls
arq1
arq2
arq3

Quando mandamos a saída do ls para o arquivo usando o xargs, comprovamos o que foi dito anteriormente, isto é, o xargs manda tudo que é possível (o suficiente para não gerar um estouro de pilha) de uma só vez. Em seguida, usamos a opção -n 1 para listar um por vez. Só para dar certeza veja o exemplo a seguir, quando listaremos dois em cada linha:

$ cat arq.ls | xargs -n 2

arq.ls arq1
arq2 arq3

Mas a linha acima poderia (e deveria) ser escrita sem o uso de pipe (|), da seguinte forma:

$ xargs -n 2 < arq.ls

Outra opção legal do xargs é a -p, na qual o xargs pergunta se você realmente deseja executar o comando. Digamos que em um diretório você tenha arquivo com a extensão .bug e .ok, os .bug estão com problemas que após corrigidos são salvos como .ok. Dá uma olhadinha na listagem deste diretório:

$ ls dir
arq1.bug
arq1.ok
arq2.bug
arq2.ok
...
arq9.bug
arq9.ok

Para comparar os arquivos bons com os defeituosos, fazemos:

$ ls | xargs -p -n2 diff -c

diff -c arq1.bug arq1.ok ?...y
....
diff -c arq9.bug arq9.ok ?...y

Para finalizar, o xargs também tem a opção -t, onde vai mostrando as instruções que montou antes de executá-las. Gosto muito desta opção para ajudar a depurar o comando que foi montado.

Então podemos resumir o comando de acordo com a tabela a seguir:

Opção Ação
-i Substitui o par de chaves ({}) pelas cadeias recebidas
-nNum Manda o máximo de parâmetros recebidos, até o máximo de Num para o comando a ser executado
-lNum Manda o máximo de linhas recebidas, até o máximo de Num para o comando a ser executado
-p Mostra a linha de comando montada e pergunta se deseja executá-la
-t Mostra a linha de comando montada antes de executá-la

Acabou! Foi bom para mim, foi bom para você também? :)

Sobre o autor

Júlio Cézar Neves

O 4º UNIX do mundo nasceu na Cidade Maravilhosa, mais precisamente na Cobra Computadores, onde à época trabalhava o Julio. Foi paixão à 1ª vista! Desde então, (1980) atua nessa área como especialista em Sistemas Operacionais e linguagens de programação. E foi por essa afinidade que quando surgiu o Linux foi um dos primeiros a estudá-lo com profundidade e adotá-lo como Sistema Operacional e filosofia de vida. É autor dos livros Programação Shell Linux, 11ª edição e Bombando o Shell.


Veja a relação completa dos artigos de Júlio Neves

 

 

Opinião dos Leitores

Gustavo Chaves
03 Out 2017, 15:20
Foi ótimo! Eu não conhecia as opções -n, -p e -t. Vão ser muito úteis.

Há duas opções que eu acho que merecem ser mencionadas também: -r e -0.

A opção -r (ou --no-run-if-empty na versão longa) diz pro xargs não executar o comando caso a entrada seja vazia. Por default ele sempre executa o comando, mesmo quando a entrada é vazia, o que pode causar probelemas como este:

$ echo | xargs rm
rm: missing operand
Try 'rm --help' for more information.

Usando a opção -r o comando não é executado e não causa problemas:

$ echo | xargs -r rm

A opção -0 é usada, normalmente, em conjunto com a opção -print0 do comando find pra evitar problemas com arquivos contendo caracteres especiais ou espaços nos seus nomes. Veja o que acontece sem elas quando temos um arquivo com espaço no nome:

$ touch 'com espaco' 'sem_espaco'

$ ls -b
com\ espaco sem_espaco

$ find . -type f | xargs ls
ls: cannot access './com': No such file or directory
ls: cannot access 'espaco': No such file or directory
./sem_espaco

O problema é que o xargs "quebra" a entrada em espaços em branco pra passá-los para o comando 'ls'. Como o primeiro arquivo tem um espaço em branco no nome, o xargs passou o nome dele quebrado em dois argumentos para o ls, que não conseguiu encontrar os arquivos.

A opção -print0 do comando find faz com que ele separe as linhas da saída com o caractere '\0' em vez de com o '\n' (newline). E a opção -0 do xargs faz com que ele quebre a entrada em caracteres '\0' em vez de nos '\n'. Assim, os espaços no nome do arquivo não vão atrapalhar o comando:

$ find . -type f -print0 | xargs -0 ls
./com espaco ./sem_espaco
*Nome:
Email:
Me notifique sobre novos comentários nessa página
Oculte meu email
*Texto:
 
  Para publicar seu comentário, digite o código contido na imagem acima
 


Powered by Scriptsmill Comments Script