Precisa entender o conceito de xargs e pipes

3

Eu tenho lutado com essa questão por um tempo agora e realmente aprecio se alguém puder esclarecer isso para mim. Suponha que eu esteja tentando canalizar os dois comandos juntos. readlink e cat

readlink Command output
$ readlink -f SUService.log
/cygdrive/c/SUService.log

Agora, se eu tentar algo assim (falha)

$ readlink -f SUService.log | cat

Embora algo assim funcione

$ readlink -f SUService.log | xargs cat

Eu queria saber porque é isso? Eu li este post aqui em que o OP tinha uma pergunta semelhante e este post que tenta Explicar a diferença entre um argumento e uma entrada no entanto eu ainda não poderia envolver minha cabeça em torno da resposta aceita (s). Pelo que entendi é que readlink retorna o resultado para stdout, que é a tela do terminal, enquanto cat quer uma entrada como argumento. Isso, em troca, me leva a perguntar como posso saber se a saída de um comando (como locate ou readlink) pode funcionar como um argumento ou não para o próximo comando? Eu tenho feito mais leituras e acontece que eu gostaria de saber quando devo usar o comando xarg?

    
por MistyD 16.03.2015 / 20:33

3 respostas

3

seu exemplo é bastante confuso.

Você normalmente não envia caracteres para o gato.

Você normalmente envia um arquivo para o gato.

No entanto, quando você envia alguns caracteres para o gato, ele imprime os caracteres.

$ echo abc12123 | cat
abc12123

Normalmente você envia um nome de arquivo para o gato

$ cat abc12123
cat: abc12123: No such file or directory

Portanto, observe que o próprio gato lida de maneira diferente com os personagens engraçados transmitidos a ele, em vez de transmiti-los como parâmetro.

$ cat b.b
textofb.b

$ echo b.b | cat
b.b

$ cat b.b
textofb.b

vou usar um exemplo mais simples que o seu

$ echo b.b | xargs cat
textofb.b

veja que imprime o conteúdo de b.b porque asdfasdfs | xargs cat , enviará a saída de asdfasdfs como um parâmetro para cat.

Então

echo b.b | xargs cat   
=  
cat b.b

Considerando que echo b.b | cat não é o mesmo que cat b.b

    
por 16.03.2015 / 21:20
6

O seguinte comando não não falha. Simplesmente faz algo que você não esperava:

readlink -f SUService.log | cat

Quando cat recebe stdin, copia para stdout. Não procura nomes de arquivos.

Como alternativa, isso será lido no arquivo nomeado:

cat "$(readlink -f SUService.log)"

xargs também colocará o nome na linha de comando cat , produzindo o mesmo resultado:

readlink -f SUService.log | xargs cat
    
por 16.03.2015 / 21:06
2

Dê uma olhada nas páginas de manual para cat e xargs para ver o que eles fazem.

man cat

cat - concatenate files and print on the standard output

E:

man xargs

xargs - build and execute command lines from standard input

Aqui está uma pequena demonstração

Vamos criar um arquivo de teste:

echo "a" > test
echo "b" >> test
echo "c" >> test

cat

cat test

Lê o arquivo e fornece:

a
b
c

echo | gato

echo test | cat

De acordo com man cat , isso faz o mesmo que:

echo test | cat -

Que canaliza test no stdin do gato, e diz ao gato para ler do stdin.

echo | xargs cat

echo test | xargs cat

Gera e executa o seguinte comando:

cat test

A saída disso já foi mostrada.

Se corrermos

<test xargs -n1 cat

Xargs vê isso na entrada:

a
b
c

E gera os seguintes comandos:

cat a
cat b
cat c

O que deve resultar em três erros, pois esses arquivos não existem.

Por que o -n1 ?

De acordo com man xargs , o -n1 diz ao xargs para usar um argumento (lido de stdin) em cada comando que ele gera.

Se usarmos -n2 , geramos o seguinte, que usa até dois parâmetros por comando:

cat a b
cat c

E se usarmos -n3 ou superior, ou simplesmente omitirmos o -n :

< test xargs cat

Recebemos:

cat a b c
    
por 17.03.2015 / 10:49

Tags