端末のベル音が中断する

端末のベル音が中断する
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

HEREドキュメントの変数にローカルテキストファイルをロードするスクリプトがあります。テキストファイルには約370行あります。次に、別のサーバーからファイアウォールルールを取得し、FWルールが一致するかどうかを比較します。ただし、行の後にfw_orig="$fw_loc"シェルは変数を自動的に展開し (実際には必要ありませんが)、ターミナルはビープ音を鳴らしてテキストを中断します。次のようになります。

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

実行するたびに、テキストが異なる行で中断されます。なぜサウンドによる中断が発生するのでしょうか。また、これを回避するにはどうすればよいですか。興味深いのは、スクリプトの後半で両方の変数を比較し、行数は一致しているのに、diff コマンドは "$fw_orig" のすべての中断で変数間の違いを検出することです。

編集 変数をファイルに書き込んで比較しようとしたとき:

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

dif コマンドが返した内容:

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

何が起こっているのか理解するのに役立つかもしれませんが、ファイル <> 変数の比較は機能しますが、変数 <> 変数の比較は機能しません。

答え1

例を簡略化して、障害のある行とその前提条件の一部のみに焦点を当て、不要な手順 (ssh など) を削除してみましょう。

変数fw_locにはファイルの内容が含まれています。改行やスペースが多数含まれており、おそらく他の特殊文字も含まれているでしょう。

私はそのファイルの内容を見ていないのに、悪事を働こうとしています。そこで、そのファイルから想像上の悪事を働かせた内容をいくつか抜き出した、あなたが行っていることの簡略版を以下に示します。

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

cat <<ABC
fw_orig="$fw_loc"
ABC

これを実行すると、次のように印刷されます。

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

あなたの特定のケースでは、それはcated ではなく、実行するためにリモート ホストに送信されます。

エスケープのレベルが明らかに不十分です。これが、発生している奇妙な動作の原因だと思いますが、あなたのケースではどの特殊文字で失敗するのかはわかりません。

1 つの可能なアプローチは、値をエスケープして、bash (リモート側) での後続の割り当てが次のように適切に機能するようにすることですprintf %q

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

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

変数参照の直後には二重引用符を使用するように注意してください$fw_loc(そうしないと、printf正しく機能しません)。ただし、$(...)コマンド置換の周囲には使用しないでください (出力が引用符で囲まれていないことに依存するためprintf %q)。

これは印刷されます

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

fw_locこれは上記の の定義と同等です。

スクリプトの後のほうでこのトリックを数回適用する必要があるかもしれませんが、私はそこを詳しく調べていません。

別の解決策としては、この複雑なロジックをより小さなステップに分割し、たとえば を使用してファイルをscpローカルホストに転送し、ローカルで比較を行うことが考えられます。

関連情報