Como usar o comando xargs no Linux

Precisa encadear alguns comandos do Linux, mas um deles não aceita entrada canalizada? xargs pode pegar a saída de um comando e enviá-la para outro comando como parâmetros.

Todos os utilitários padrão do Linux têm três fluxos de dados associados a eles. Eles são o fluxo de entrada padrão (stdin), o fluxo de saída padrão (stdout) e o fluxo de erro padrão (stderr).

Esses fluxos funcionam com texto. Enviamos a entrada (stdin) para um comando usando texto e a resposta (stdout) é gravada na janela do terminal como texto. As mensagens de erro também são gravadas na janela do terminal como texto (stderr).

Um dos grandes recursos do Linux e dos sistemas operacionais semelhantes ao Unix é a capacidade de canalizar a saída stdout de um comando para a entrada stdin de um segundo comando. O primeiro comando não se importa se sua saída não está indo para uma janela de terminal, e o segundo comando não se importa se sua entrada não está vindo de um teclado.

Embora todos os comandos do Linux tenham os três fluxos padrão, nem todos aceitam o stdout de outro comando como entrada para seu stdin. Isso significa que você não pode enviar entrada para eles.

xargs é um comando para construir pipelines de execução usando os fluxos de dados padrão. Usando xargs, podemos fazer com que comandos como echo, rm e mkdir aceitem entradas padrão como argumentos.

O Comando xargs

xargs aceitará entrada canalizada. Ele também pode aceitar a entrada de um arquivo. xargs usa essa entrada como parâmetros para os comandos com os quais dissemos para trabalhar. Se não dissermos ao xargs para trabalhar com um comando específico, ele usará echo como padrão.

Podemos usar isso para demonstrar como xargs sempre gerará uma única linha de saída, mesmo a partir de entrada de várias linhas.

Se usarmos a opção -1 (listar um arquivo por linha) com ls, obteremos um coluna única de nomes de arquivos.

ls -1 ./*.sh

Isso lista os arquivos de script de shell no diretório atual.

  Como instalar o SABnzbd no Linux

Obtemos uma única coluna conforme o esperado. Se canalizarmos através de xargs, o que obteremos?

ls -1 ./*.sh | xargs

A saída é gravada na janela do terminal, como um longo fluxo de texto.

É esse recurso que permite ao xargs alimentar parâmetros em outros comandos.

Usando xargs com wc

Podemos usar xargs para fazer com que contemos facilmente palavras, caracteres e linhas em vários arquivos.

ls *.page | xargs wc

Isto é o que acontece:

ls lista os arquivos * .page e passa a lista para xargs.
xargs passa os nomes dos arquivos para wc.
O wc trata os nomes dos arquivos como se os tivesse recebido como parâmetros da linha de comandos.

As estatísticas de cada arquivo são exibidas junto com um total geral.

Usando xargs com confirmação

Podemos usar a opção -p (interativo) para que o xargs nos solicite a confirmação de que estamos felizes com sua continuação.

Se passarmos uma sequência de nomes de arquivos para tocar, por meio de xargs, o toque irá crie os arquivos para nós.

echo 'one two three' | xargs -p touch

O comando a ser executado é exibido e xargs espera que respondamos digitando “y” ou “Y”, ou “n” ou “N” e pressionando Enter.

Se você apenas pressionar Enter, será tratado como “n”. O comando só é executado se você digitar “y” ou “Y”.

Nós pressionamos “y” e pressionamos Enter. Podemos usar ls para verificar se os arquivos foram criados.

ls one two three

Usando xargs com vários comandos

Podemos usar vários comandos com xargs usando a opção -I (argumentos iniciais).

Esta opção define uma “string de substituição”. Sempre que o token para a string de substituição aparecer na linha de comando, os valores fornecidos a xargs serão inseridos.

Vamos usar o comando tree para ver os subdiretórios do diretório atual. A opção -d (diretório) faz com que a árvore ignore os arquivos e relate apenas os diretórios.

tree -d

Existe um único subdiretório chamado “imagens”.

Em um arquivo chamado “diretórios.txt”, temos os nomes de alguns diretórios que desejamos ter criado. Podemos ver seu conteúdo usando cat.

cat directories.txt

Vamos usar isso como dados de entrada para xargs. O comando que vamos usar é este:

cat directories.txt | xargs -I % sh -c 'echo %; mkdir %'

Isso se divide assim:

cat directory.txt |: Isso envia o conteúdo do arquivo directrories.txt (todos os novos nomes de diretório) para xargs.
xargs -I%: Isso define uma “string de substituição” com o token “%”.
sh -c: Isso inicia um novo subshell. O -c (comando) diz ao shell para ler os comandos da linha de comando.
‘echo%; mkdir% ‘: cada um dos tokens “%” será substituído pelos nomes de diretório que são passados ​​por xargs. O comando echo imprimirá o nome do diretório; o comando mkdir criará o diretório.

  Como jogar Sniper Elite no Linux

Os diretórios são listados um por um.

Podemos usar a árvore mais uma vez para verificar se os diretórios foram criados.

tree -d

Copiando arquivos para vários locais

Podemos usar o xargs para nos permitir copiar arquivos para vários locais com um único comando.

Vamos canalizar os nomes de dois diretórios em xargs como parâmetros de entrada. Diremos ao xargs para passar apenas um desses parâmetros por vez para o comando com o qual está trabalhando.

Nesse caso, o comando é cp. Portanto, o efeito é chamar cp duas vezes, cada vez com um dos dois diretórios como um parâmetro de linha de comando. O parâmetro xargs que permite que isso aconteça é a opção -n (número máximo). Vamos definir isso como um.

Também estamos usando a opção -v (verbose) com cp para relatar o que está acontecendo.

echo ~/Backups/ ~/Documents/page-files/ | xargs -n 1 cp -v ./*.page

Os arquivos são copiados para os dois diretórios, um de cada vez. cp relata cada ação de cópia de arquivo para que possamos vê-las ocorrendo.

Excluindo arquivos em diretórios aninhados

Se os nomes dos arquivos contiverem espaços e caracteres estranhos – como caracteres de nova linha – xargs não será capaz de interpretá-los corretamente. Podemos superar esse problema usando a opção -0 (terminador nulo). Isso diz ao xargs para usar o caractere nulo como o delimitador final para nomes de arquivos.

Vamos usar find neste exemplo. find tem sua própria opção para lidando com espaços em branco e caracteres estranhos em nomes de arquivos. É a opção -print0 (nome completo, caractere nulo).

find . -name "*.png" -type f -print0 | xargs -0 rm -v -rf "{}"

Isso se divide assim:

achar . -name “* .png”: find irá pesquisar a partir do diretório atual “.” para objetos com nomes que correspondem a “* .png” que são arquivos (tipo -f).
-print0: os nomes serão encerrados por um caractere nulo, e espaços e caracteres estranhos serão atendidos.
xargs -0: xargs também irá considerar nomes de arquivos com terminação nula, e espaços e caracteres estranhos não causarão problemas.
rm -v -rf “{}”: rm vai ser prolixo e relatar o que está acontecendo (-v). Ele será recursivo (-r), examinará os subdiretórios aninhados e removerá os arquivos sem avisar (-f). O “{}” é substituído por cada nome de arquivo.

  Como realizar uma tarefa quando um novo arquivo é adicionado a um diretório no Linux

achar .  -nome

Todos os subdiretórios são pesquisados ​​e os arquivos que correspondem ao padrão de pesquisa são excluídos.

Removendo diretórios aninhados

Digamos que queremos remover um conjunto de subdiretórios aninhados. árvore vai nos deixar vê-los.

tree -d

find . -name "level_one" -type d printo | xargs -o rm -v -rf "{}"

Este comando usará find para pesquisar recursivamente no diretório atual. O destino da pesquisa é um diretório chamado “level_one”. Os nomes dos diretórios são passados ​​de xargs para rm.

achar .  -nome

As únicas mudanças significativas entre este comando e o comando anterior são, o termo de pesquisa é o nome do diretório mais alto e -type d diz ao find para procurar por diretórios, não por arquivos.

O nome de cada diretório é impresso à medida que é removido. Podemos verificar com árvore:

tree -d

Todos os subdiretórios aninhados são excluídos.

Excluindo todos os arquivos, exceto um tipo de arquivo

Podemos usar find, xargs e rm para excluir todos os arquivos, exceto um tipo que queremos reter. É um pouco contra-intuitivo, mas fornecemos o nome do tipo de arquivo que desejamos manter, não o nome daqueles que desejamos excluir.

A opção -not diz ao find para retornar os nomes dos arquivos que não correspondem ao padrão de pesquisa. Estamos usando a opção -I (argumentos iniciais) com xargs mais uma vez. Desta vez, o token de string de substituição que estamos definindo é “{}”. Ele se comportará exatamente da mesma forma que o token de string de substituição que geramos anteriormente, que por acaso era um “%”.

find . -type f -not - name "*.sh" -print0 | xargs -0 -I {} rm -v {}

achar .  -tipo f -não - nome

Podemos verificar com o ls. Os únicos arquivos restantes no diretório são aqueles que correspondem ao padrão de pesquisa “* .sh”.

ls -l

Criação de um arquivo de arquivo com Xargs

Podemos usar find para pesquisar arquivos e passá-los por meio de xargs para tar, para criar um arquivo compactado.

Vamos pesquisar no diretório atual. O padrão de pesquisa é “* .page”, então vamos procurar por arquivos “.page”.

find ./ - name "*.page" -type f -print0 | xargs -0 -tar -cvzf page_files.tar.gz

encontrar ./ ​​- nome

Os arquivos são listados conforme o esperado, conforme o arquivo compactado é criado.

O Mediador de Dados

Às vezes, você precisa de um pequeno andaime ao empilhar as coisas. O xargs preenche a lacuna entre os comandos que podem bombear informações e os comandos que não foram criados para recebê-las.

Tanto o xargs quanto o find têm um grande número de opções. Você é encorajado a verificar suas páginas de manual para aprender mais.