loc="locationA"
usr="user1"
fw_loc=$(</home/user/Desktop/FW_RULES.txt)
ssh -A -tt [email protected] <<ABC
fw_orig="$fw_loc"
fw_cmpr=\$(ssh root@$loc -o LogLevel=ERROR uci show firewall)
wc --lines <<<"\$fw_orig"
wc --lines <<<"\$fw_cmpr"
diff -s <(echo "\$fw_orig") <(echo "\$fw_cmpr")
exit
ABC
Eu tenho um script onde carrego o arquivo de texto local na variável do documento AQUI. O arquivo de texto tem aprox. 370 linhas. Então pego regras de firewall de outro servidor e tento comparar se as regras de FW correspondem. Porém, depois da linhafw_orig="$fw_loc"O shell expande automaticamente a variável (embora não seja realmente necessário) e o terminal emite um bipe e faz interrupções no texto, assim:
[user2@jump ~]$ fw_orig="firewall.defaults=defaults
>firewall.poplanhttp3=rule
l
> firewall.poplanhttp3.name='poplanhttp3'
> firewall.lanpopchhttp2.name='lanpopahttp5'
> firewal
> firewall.lanpopchhttp2.dest='POPA'
.
firewall.poplanssh2.dest_port='27'
i
> firewall.poplanssh2.target='ACCEPT'
/
o texto é interrompido em linhas diferentes cada vez que eu o executo. por que essas interrupções no som acontecem e como posso evitá-las? O interessante é que mais tarde em meu script eu comparo ambas as variáveis, e o número de linhas corresponde, mas o comando diff encontra diferenças entre as variáveis em todas as interrupções de "$fw_orig".
EDITAR quando tentei escrever a variável no arquivo e compará-la:
echo "\$fw_orig">/home/user2/file
..
..
diff -s <(echo "\$fw_orig") /home/user2/file
Comando dif retornado:
Files /dev/fd/63 and /home/user2/file are identical
talvez possa ajudar a entender o que está acontecendo. No entanto, a comparação de variáveis de arquivo <> funciona, a comparação de variáveis <> variáveis não funciona.
Responder1
Vamos simplificar o exemplo, focando apenas na linha com defeito e em alguns de seus pré-requisitos, e eliminar as etapas desnecessárias (como ssh).
A fw_loc
variável contém o conteúdo de um arquivo. Com certeza tem muitas novas linhas e muitos espaços; presumivelmente outros caracteres especiais também.
Embora não veja o conteúdo desse arquivo, tento ser mau. Então aqui está a versão simplificada do que você está fazendo, com alguns conteúdos malignos imaginários desse arquivo:
fw_loc='foo"; rm -rf "/ouch'
cat <<ABC
fw_orig="$fw_loc"
ABC
Se você executar isso, verá que isso imprime
fw_orig="foo"; rm -rf "/ouch"
No seu caso específico, não é cat
editado, mas enviado ao host remoto para execução.
O nível de fuga claramente não é suficiente. Acredito que esse seja o motivo do comportamento estranho que você está enfrentando, embora não tenha certeza de quais caracteres especiais ele falha no seu caso.
Uma abordagem possível é escapar do valor para que uma atribuição subsequente no bash (no lado remoto) funcione corretamente usando printf %q
:
fw_loc='foo"; rm -rf "/ouch'
cat <<ABC
fw_orig=$(printf %q "$fw_loc")
ABC
Tome cuidado ao usar aspas duplas imediatamente ao redor da referência da variável $fw_loc
(caso contrário, printf
não faz seu trabalho corretamente), mas não ao redor da $(...)
substituição do comando (porque printf %q
depende de sua saída não estar entre aspas)!
Isso imprime
fw_orig=foo\"\;\ rm\ -rf\ \"/ouch
o que é equivalente à fw_loc
definição de acima.
Talvez você precise aplicar esse truque mais algumas vezes em seu script, mas não dei uma olhada mais de perto.
Uma solução alternativa poderia ser dividir essa lógica complexa em etapas menores, por exemplo, transferir o arquivo usando scp
, talvez até para localhost e fazer a comparação localmente.