Como canalizar a saída do netcat? Problemas com xargs e citações

1

Estou tentando canalizar o que o nc recebe com isso:

nc -l 20000 | xargs /root/test

... e funciona bem, exceto quando xargs recebe argumentos citados - os divide como se estivessem separados ...

Iterar sobre argumentos ( /root/test ) mostra que eles não foram passados corretamente:

for i in $*; do 
    echo "$i"
done

O envio de echo 'test1 test2' para a porta 20000 (nc) resulta em:

echo
'test1
test2'

Eu tentei encapsular o pedido (o que o nc recebe) entre aspas duplas e escapar de quaisquer aspas (por exemplo, "echo \'test1 test2\'" ) de acordo com esta resposta: link , mas não ajudou, acabei de receber:

echo
\'test1
test2\'
    
por user224371 20.04.2017 / 14:34

1 resposta

3

O netcat não deve afetar os dados enviados por ele, então eu vou pular isso e concentre-se apenas em canalizar para xargs.

Aqui:

echo "aa 'bb cc'" | xargs     

o shell remove um conjunto de aspas, enviando a string aa 'bb cc' para xargs. xargs, por padrão, pega strings entre aspas como elementos únicos (removendo as aspas), passando as strings aa e bb cc para o comando que executa.

Aqui, por outro lado:

echo "aa \'bb cc\'" | xargs   

o shell remove novamente um conjunto de aspas, deixando aa \'bb cc\' . Aspas simples (com ou sem barras invertidas) não são especiais entre aspas duplas. Aspas duplas entre aspas duplas precisariam ser escapadas, no entanto.

xargs vê essa string, faz sua própria remoção de aspas, mas como as aspas escapam agora, ela apenas remove as barras invertidas e as divide no espaço em branco. Deixando três sequências: aa , 'bb e cc' . O que você viu.

Normalmente, queremos o oposto: evitar que os xargs manipulem aspas, pois podem ser partes de um nome de arquivo. Então você vê cinco dúzias de perguntas aqui, recomendando xargs -0 ou xargs -d'\n' . Mas se você quiser que o xargs lide com strings entre aspas, você precisa enviar as aspas para ele sem escape.

Outra questão é que seu script de teste usa $* . Sem aspas, isso dividirá todos os argumentos no espaço em branco e executará a globalização nas palavras resultantes. (Com aspas, isso resultará na concatenação dos argumentos como uma única string.) Você quase sempre deseja usar "$@" . Ou aqui apenas:

for i do
  echo "$i"
done

ou até mesmo:

printf '%s\n' "$@"

Portanto, verifique o escape das cotações e use "$@" em vez de $* .

$ cat args.sh 
for x in "$@" ; do echo ":$x" ; done

$ echo "aa 'bb cc' \"dd ee\""
aa 'bb cc' "dd ee"

$ echo "aa 'bb cc' \"dd ee\"" | xargs ./args.sh 
:aa
:bb cc
:dd ee
    
por 20.04.2017 / 14:40