Klingelton am Terminal unterbricht

Klingelton am Terminal unterbricht
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

Ich habe ein Skript, in dem ich eine lokale Textdatei in eine Variable im HERE-Dokument lade. Die Textdatei hat ca. 370 Zeilen. Dann nehme ich Firewall-Regeln von einem anderen Server und versuche zu vergleichen, ob die FW-Regeln übereinstimmen. Nach Zeilefw_orig="$fw_loc"Die Shell erweitert die Variable automatisch (was eigentlich nicht nötig ist) und das Terminal gibt einen Piepton aus und unterbricht den Text etwa so:

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

Der Text wird bei jedem Ausführen in verschiedenen Zeilen unterbrochen. Warum treten diese Unterbrechungen mit Ton auf und wie kann ich sie vermeiden? Interessant ist, dass ich später in meinem Skript beide Variablen vergleiche und die Anzahl der Zeilen übereinstimmt, aber der Befehl „diff“ Unterschiede zwischen den Variablen in allen Unterbrechungen von „$fw_orig“ findet.

BEARBEITEN als ich versucht habe, die Variable in eine Datei zu schreiben und sie dann zu vergleichen:

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

Der Befehl „dif“ hat zurückgegeben:

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

vielleicht hilft es zu verstehen, was los ist. Der Vergleich Datei <> Variable funktioniert jedoch, der Vergleich Variable <> Variable funktioniert nicht.

Antwort1

Vereinfachen wir das Beispiel, konzentrieren uns nur auf die fehlerhafte Zeile und einige ihrer Voraussetzungen und eliminieren die unnötigen Schritte (wie etwa ssh).

Die fw_locVariable enthält den Inhalt einer Datei. Sie enthält mit Sicherheit viele Zeilenumbrüche und Leerzeichen; vermutlich auch andere Sonderzeichen.

Obwohl ich den Inhalt dieser Datei nicht sehe, versuche ich, böse zu sein. Hier ist also die abgespeckte Version dessen, was Sie tun, mit einigen imaginären bösen Inhalten aus dieser Datei:

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

cat <<ABC
fw_orig="$fw_loc"
ABC

Wenn Sie dies ausführen, werden Sie sehen, dass dies druckt

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

In Ihrem speziellen Fall wird es nicht catexportiert, sondern zur Ausführung an den Remote-Host gesendet.

Das Escape-Level ist eindeutig nicht ausreichend. Ich glaube, das ist der Grund für das seltsame Verhalten, das Sie erleben, obwohl ich nicht sicher bin, bei welchen Sonderzeichen es in Ihrem Fall fehlschlägt.

Ein möglicher Ansatz besteht darin, den Wert zu escapen, sodass eine nachfolgende Zuweisung in Bash (auf der Remote-Seite) mit folgendem Befehl ordnungsgemäß funktioniert printf %q:

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

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

Achten Sie darauf, doppelte Anführungszeichen direkt um die Variablenreferenz zu verwenden $fw_loc(sonst printffunktioniert es nicht richtig), aber nicht um die $(...)Befehlsersetzung herum (weil printf %qdiese darauf angewiesen ist, dass ihre Ausgabe nicht in Anführungszeichen steht)!

Dieser Druck

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

fw_locwas der obigen Definition entspricht .

Eventuell musst du diesen Trick weiter hinten in deinem Skript noch ein paar Mal anwenden, ich habe da nicht genauer hingeschaut.

Eine alternative Lösung könnte darin bestehen, diese komplexe Logik in kleinere Schritte aufzuteilen, z. B. die Datei mithilfe von zu übertragen scp, vielleicht sogar auf den lokalen Host, und den Vergleich lokal durchzuführen.

verwandte Informationen