Resultado inesperado ao usar o operador pipe dentro de uma variável shell

0

Eu tenho um processo que despeja alguma saída zipada no stdout. O que eu faço com esta saída é pipe e enviá-lo através de um túnel SSH para outra máquina, onde é despejado em um arquivo.

Assim:

/usr/bin/myapp | ssh root@remotemachine "cat > /path/to/output/file.gz"

quando eu ssh para a máquina e invoco esta linha, tudo vai bem. Mas quando eu coloco este comando em um script de shell como

#!/bin/sh
APP=/usr/bin/myapp
OPTS=--gzip
OUTPUT= "| ssh root@remotemachine \"cat > /path/to/output/file.gz\""
$APP $OPTS $OUTPUT

E, em seguida, invoco o script, vejo lixo no console, que só posso supor que é a saída de myapp e, em seguida, isso

Unknown parameter '|'
Unknown parameter 'ssh'
Unknown parameter 'root@remotemachine'
Unknown parameter '"cat'
Unknown parameter '>'
Unknown parameter '/path/to/output/file.gz"'

Acredito que o shell enviou a seção $OUTPUT como um argumento para myapp em vez de agir sobre eles. Então, esses "parâmetros desconhecidos" vinham de myapp não do shell.

Como posso consertar isso?

    
por hebbo 30.04.2018 / 23:10

2 respostas

0

Seu shell analisa qualquer linha de comando em uma determinada seqüência. Quando encontra $APP $OPTS $OUTPUT , não há operador de pipe; mais tarde essas variáveis são expandidas e | aparece, mas não tem um significado especial porque já é tarde demais para isso.

O resultado pode ser reavaliado com eval (sua resposta mostra que você já descobriu isso), mas eval pode se tornar para ser um evil incorretamente .

Sua abordagem original é falha porque as variáveis do shell não devem conter código. Funções são para código. Exemplo:

app=/usr/bin/myapp
opts=--gzip
output() { ssh root@remotemachine "cat > /path/to/output/file.gz"; }
$app $opts | output

Nota é uma boa prática usar nomes de variáveis em minúsculas .

    
por 01.05.2018 / 00:07
0

Ok .... Eu encontrei o que eu precisava. Foi o comando eval . Isso de fato foi respondido aqui .

Assim, o script pode ser modificado desta maneira:

#!/bin/sh
APP=/usr/bin/myapp
OPTS=--gzip
OUTPUT= "| ssh root@remotemachine \"cat > /path/to/output/file.gz\""
eval "$APP $OPTS $OUTPUT"
    
por 30.04.2018 / 23:39