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 comandos como echo
, rm
e mkdir
aceitar a entrada padrão como argumentos.
Índice
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 xargs
para trabalhar com um comando específico, ele usará como padrão echo
.
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 uma única coluna de nomes de arquivos .
ls -1 ./*.sh
Isso lista os arquivos de script de shell no diretório atual.
Obtemos uma única coluna conforme o esperado. Se canalizarmos, xargs
o que obtemos?
ls -1 ./*.sh | xargs
A saída é gravada na janela do terminal, como um longo fluxo de texto.
É esse recurso que permite xargs
inserir parâmetros em outros comandos.
Usando xargs com wc
Podemos usar xargs
para wc
contar facilmente as 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 paraxargs
.xargs
passa os nomes dos arquivos parawc
.wc
trata os nomes dos arquivos como se os tivesse recebido como parâmetros da linha de comando.
As estatísticas de cada arquivo são exibidas junto com um total geral.
Usando xargs com confirmação
Podemos usar a -p
opção (interativa) para xargs
solicitar a confirmação de que estamos felizes com sua continuação.
Se passar uma cadeia de nomes de arquivos para touch
, através xargs
, touch
irá criar os arquivos para nós.
echo 'um dois três' | xargs -p touch
O comando que vai 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.
é um dois três
Usando xargs com vários comandos
Podemos usar vários comandos 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 xargs
serão inseridos.
Vamos usar o tree
comando para ver os subdiretórios do diretório atual. A -d
opção (diretório) faz tree
com que os arquivos sejam ignorados e apenas relatados nos diretórios.
árvore -d
Existe um único subdiretório chamado “imagens”.
Em um arquivo chamado “diretórios.txt”, temos os nomes de alguns diretórios que desejamos criar. Podemos ver seu conteúdo usando cat
.
cat directory.txt
Vamos usar isso como dados de entrada para xargs
. O comando que vamos usar é este:
cat directory.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
xargs
. Oecho
comando imprimirá o nome do diretório; omkdir
comando criará o diretório.
Os diretórios são listados um por um.
Podemos usar tree
mais uma vez para verificar se os diretórios foram criados.
árvore -d
Copiando arquivos para vários locais
Podemos usar xargs
para nos permitir copiar arquivos para vários locais com um único comando.
Vamos canalizar os nomes de dois diretórios xargs
como parâmetros de entrada. Diremos 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 parâmetro de linha de comando. O xargs
parâmetro que permite que isso aconteça é a opção -n
(número máximo). Vamos definir isso como um.
Também estamos usando a -v
opção (detalhada) com cp
para que ele relate 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á possível interpretá-los corretamente. Podemos superar esse problema usando a opção -0 (terminador nulo). Isso diz 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 lidar com espaços em branco e caracteres estranhos em nomes de arquivos. É a opção -print0
(nome completo, caractere nulo).
encontrar . -name "* .png" -tipo f -print0 | xargs -0 rm -v -rf "{}"
Isso se divide assim:
- encontrar . -name “* .png” :
find
vai pesquisar no diretório atual “.” para objetos com nomes que correspondem a “* .png” que são arquivos (type -f
). - -print0 : os nomes serão encerrados com um caractere nulo e espaços e caracteres estranhos serão atendidos.
- xargs -0 : xargs também vai considerar nomes de arquivos como terminados em nulo, 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) e examinará subdiretórios aninhados, e removerá arquivos sem solicitar (-f
). O “{}” é substituído por cada nome de arquivo.
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 desejamos remover um conjunto de subdiretórios aninhados. tree
vai nos deixar vê-los.
árvore -d
encontrar . -name "level_one" -tipo 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 xargs
para rm
.
As únicas mudanças significativas entre este comando e o comando anterior são: o termo de pesquisa é o nome do diretório superior e -type d
indica find
para procurar por diretórios, não por arquivos.
O nome de cada diretório é impresso à medida que é removido. Podemos verificar com tree
:
árvore -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 separados um do tipo que deseja manter. É um pouco contra-intuitivo, mas fornecemos o nome do tipo de arquivo que desejamos manter , não o nome daqueles que desejamos excluir.
A -not
opção informa 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 “%”.
encontrar . -tipo f -não - nome "* .sh" -print0 | xargs -0 -I {} rm -v {}
Podemos verificar com ls
. Os únicos arquivos restantes no diretório são aqueles que correspondem ao padrão de pesquisa “* .sh”.
ls -l
Criando um arquivo de arquivo com Xargs
Podemos usar find
para pesquisar arquivos e transferi-los 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" -tipo f -print0 | xargs -0 -tar -cvzf page_files.tar.gz
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 quando empilhar as coisas. xargs
preenche a lacuna entre os comandos que podem bombear informações e os comandos que não foram criados para recebê-las.
Ambos xargs
e find
têm um grande número de opções. Você é encorajado a verificar suas páginas de manual para aprender mais.