Vamos simplificar o exemplo, concentrando-nos apenas na linha defeituosa e em alguns de seus pré-requisitos e eliminando as etapas desnecessárias (como o ssh).
A variável fw_loc
contém o conteúdo de um arquivo. Com certeza, tem muitas linhas novas e muitos espaços; presumivelmente outros caracteres especiais também.
Considerando que não vejo o conteúdo desse arquivo, tento ser malvado. Então aqui está a versão simplificada do que você está fazendo, com algum conteúdo imaginário do arquivo:
fw_loc='foo"; rm -rf "/ouch'
cat <<ABC
fw_orig="$fw_loc"
ABC
Se você executar isso, verá que isso é impresso
fw_orig="foo"; rm -rf "/ouch"
Em seu caso específico, ele não é cat
ed, mas enviado para o host remoto para ser executado.
O nível de escape claramente não é suficiente. Eu acredito que esta é a razão para o comportamento estranho que você está experimentando, embora eu não tenha certeza de quais caracteres especiais ele falha no seu caso.
Uma abordagem possível é escapar do valor para que uma subseqüente associação 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 de variável $fw_loc
(caso contrário, printf
não faz seu trabalho corretamente), mas não em torno da substituição do comando $(...)
(porque printf %q
depende de sua saída não estando entre aspas)!
Isto imprime
fw_orig=foo\"\;\ rm\ -rf\ \"/ouch
que é equivalente à definição de fw_loc
acima.
Você pode precisar aplicar esse truque mais algumas vezes no seu script, não olhei mais de perto.
Uma solução alternativa pode ser dividir essa lógica complexa em etapas menores, por exemplo, transfira o arquivo usando scp
, talvez até para localhost e faça a comparação localmente.