Suponha que eu queira remover todos os arquivos em um diretório, exceto um chamado "notes.txt". Eu faria isso com o pipeline ls | grep -v "notes.txt" | xargs rm
. Por que preciso de xargs se a saída do segundo canal é a entrada que a rm deve usar?
Para fins de comparação, o pipeline echo "#include <knowledge.h>" | cat > foo.c
insere o texto ecoado no arquivo sem o uso de xargs. Qual é a diferença entre esses dois pipelines?
ls | grep -v "notes.txt" | xargs rm
remover tudo, excetonotes.txt
, ou em geral, nunca analisa als
saída . Seu comando seria interrompido se um único arquivo contivesse um espaço, por exemplo. A maneira mais segura seriarm !(notes.txt)
em Bash (comshopt -s extglob
set), ourm ^notes.txt
no Zsh (comEXTENDED_GLOB
) etc.find . -maxdepth 1 -mindepth 1 -print0 | xargs -0
em vez dels | xargs
:-)Respostas:
Você está confundindo dois tipos muito diferentes de entrada: STDIN e argumentos. Argumentos são uma lista de cadeias de caracteres fornecidas ao comando quando ele é iniciado, geralmente especificando-as após o nome do comando (por exemplo,
echo these are some arguments
ourm file1 file2
). STDIN, por outro lado, é um fluxo de bytes (às vezes texto, às vezes não) que o comando pode (opcionalmente) ler após o início. Aqui estão alguns exemplos (observe quecat
pode aceitar argumentos ou STDIN, mas faz coisas diferentes com eles):xargs
pode ser pensado como a conversão de entrada no estilo STDIN em argumentos:echo
na verdade, faz mais ou menos o contrário: ele converte seus argumentos em STDOUT (que pode ser canalizado para o STDIN de algum outro comando):fonte
cat
recebe entradaSTDIN
erm
não recebe . Para esses comandos, você precisaxargs
percorrerSTDIN
linha por linha e executar os comandos com os parâmetros da linha de comando.fonte