som da campainha do terminal interrompendo

som da campainha do terminal interrompendo
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_locvariá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 é cateditado, 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, printfnão faz seu trabalho corretamente), mas não ao redor da $(...)substituição do comando (porque printf %qdepende de sua saída não estar entre aspas)!

Isso imprime

fw_orig=foo\"\;\ rm\ -rf\ \"/ouch

o que é equivalente à fw_locdefiniçã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.

informação relacionada