Se interrumpe el sonido de la campana del terminal.

Se interrumpe el sonido de la campana del terminal.
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

Tengo un script donde cargo un archivo de texto local en una variable en el documento AQUÍ. El archivo de texto tiene aprox. 370 líneas. Luego tomo reglas de firewall de otro servidor e intento comparar si las reglas de FW coinciden. Sin embargo, después de la líneafw_orig="$fw_loc"Shell expande automáticamente la variable (aunque en realidad no es necesaria) y el terminal emite un pitido y realiza interrupciones en el texto, así:

[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'
/

El texto se interrumpe en diferentes líneas cada vez que lo ejecuto. ¿Por qué ocurren esas interrupciones del sonido y cómo puedo evitarlas? Lo interesante es que más adelante en mi script comparo ambas variables y el número de líneas coincide, pero el comando diff encuentra diferencias entre las variables en todas las interrupciones de "$fw_orig".

EDITAR cuando intenté escribir una variable en un archivo y luego compararla:

echo "\$fw_orig">/home/user2/file
..
..
diff -s <(echo "\$fw_orig") /home/user2/file

comando dif devuelto:

Files /dev/fd/63 and /home/user2/file are identical

tal vez pueda ayudar a comprender qué está pasando ... sin embargo, la comparación de archivo <> variable funciona, la comparación de variable <> variable no funciona ...

Respuesta1

Simplifiquemos el ejemplo, centrándonos solo en la línea defectuosa y algunos de sus requisitos previos, y eliminemos los pasos innecesarios (como ssh).

La fw_locvariable contiene el contenido de un archivo. Seguro que tiene muchas líneas nuevas y muchos espacios; presumiblemente también otros caracteres especiales.

Mientras que no veo el contenido de ese archivo, trato de ser malvado. Así que aquí está la versión simplificada de lo que estás haciendo, con algunos contenidos malvados imaginarios de ese archivo:

fw_loc='foo"; rm -rf "/ouch'

cat <<ABC
fw_orig="$fw_loc"
ABC

Si ejecuta esto, verá que se imprime.

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

En su caso particular, no se catedita sino que se envía al host remoto para su ejecución.

El nivel de escape claramente no es suficiente. Creo que esta es la razón del comportamiento extraño que estás experimentando, aunque no estoy seguro de en qué caracteres especiales falla en tu caso.

Un posible enfoque es escapar del valor para que una asignación posterior en bash (en el lado remoto) funcione correctamente usando printf %q:

fw_loc='foo"; rm -rf "/ouch'

cat <<ABC
fw_orig=$(printf %q "$fw_loc")
ABC

¡Tenga cuidado de usar comillas dobles inmediatamente alrededor de la referencia de la variable $fw_loc(de lo contrario printfno hace su trabajo correctamente), pero no alrededor de la $(...)sustitución del comando (porque printf %qdepende de que su salida no esté entre comillas)!

Esto imprime

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

que es equivalente a fw_locla definición anterior.

Es posible que tengas que aplicar este truco unas cuantas veces más más adelante en tu script, no lo he mirado más de cerca.

Una solución alternativa podría ser dividir esta lógica compleja en pasos más pequeños, por ejemplo, transferir el archivo usando scp, tal vez incluso a localhost y hacer la comparación localmente.

información relacionada