прерывающий звук терминального звонка

прерывающий звук терминального звонка
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"

В вашем конкретном случае он не catредактируется, а отправляется на удаленный хост для выполнения.

Уровень экранирования явно недостаточен. Я считаю, что это причина странного поведения, которое вы испытываете, хотя я не уверен, на каких специальных символах он не срабатывает в вашем случае.

Одним из возможных подходов является экранирование значения, чтобы последующее присваивание в 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, возможно, даже на локальный хост и выполнение сравнения локально.

Связанный контент