Por que os xargs são necessários?

19

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 pipe for a entrada que o 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 oleodutos?

    
por seewalker 27.05.2013 / 05:35

2 respostas

29

Você está confundindo dois tipos muito diferentes de entrada: STDIN e argumentos. Argumentos são uma lista de strings fornecidas ao comando quando ele é iniciado, normalmente, especificando-as após o nome do comando (por exemplo, echo these are some arguments ou rm file1 file2 ). STDIN, por outro lado, é um fluxo de bytes (às vezes texto, às vezes não) que o comando pode (opcionalmente) ler depois de iniciado. Aqui estão alguns exemplos (observe que cat pode pegar argumentos ou STDIN, mas faz coisas diferentes com eles):

echo file1 file2 | cat    # Prints "file1 file2", since that's the stream of
                          # bytes that echo passed to cat's STDIN
cat file1 file2    # Prints the CONTENTS of file1 and file2
echo file1 file2 | rm    # Prints an error message, since rm expects arguments
                         # and doesn't read from STDIN

xargs pode ser considerado como convertendo entrada no estilo STDIN para argumentos:

echo file1 file2 | cat    # Prints "file1 file2"
echo file1 file2 | xargs cat    # Prints the CONTENTS of file1 and file2

echo na verdade faz mais ou menos o contrário: ele converte seus argumentos para STDOUT (que pode ser canalizado para o STDIN de outro comando):

echo file1 file2 | echo    # Prints a blank line, since echo doesn't read from STDIN
echo file1 file2 | xargs echo    # Prints "file1 file2" -- the first echo turns
                                 # them from arguments into STDOUT, xargs turns
                                 # them back into arguments, and the second echo
                                 # turns them back into STDOUT
echo file1 file2 | xargs echo | xargs echo | xargs echo | xargs echo    # Similar,
                                 # except that it converts back and forth between
                                 # args and STDOUT several times before finally
                                 # printing "file1 file2" to STDOUT.
    
por 27.05.2013 / 07:08
8

cat aceita a entrada de STDIN e rm não. Para tais comandos, você precisa de xargs para percorrer STDIN linha por linha e executar os comandos com parâmetros de linha de comando.

    
por 27.05.2013 / 05:53