Этот вопрос не о том, как написать правильно экранированный строковый литерал. Я не смог найти ни одного связанного вопроса, который бы не касался того, как экранировать переменные для непосредственного использования в скрипте или другими программами.
Моя цель - включить скрипт для генерации других скриптов. Это связано с тем, что задачи в сгенерированных сценариях будут выполняться от 0 до n раз на другом компьютере, и данные, из которых они сгенерированы, могут измениться до того, как они будут выполнены (снова), поэтому выполнение операций напрямую по сети приведет к не работает.
Учитывая известную переменную, которая может содержать специальные символы, такие как одинарные кавычки, мне нужно записать это как полностью экранированный строковый литерал, например, foo
содержащая переменная bar'baz
должна появиться в сгенерированном скрипте как:
qux='bar'\''baz'
который будет написан путем добавления "qux=$foo_esc"
к другим строкам сценария. Я сделал это с помощью Perl следующим образом:
foo_esc="'`perl -pe 's/('\'')/\\1\\\\\\1\\1/g' <<<"$foo"`'"
но это кажется излишним.
У меня не было успеха в том, чтобы сделать это только с Bash. Я пробовал много вариантов этих:
foo_esc="'${file//\'/\'\\\'\'}'"
foo_esc="'${file//\'/'\\''}'"
но либо лишние косые черты появляются в выводе (когда я это делаю echo "$foo"
), либо они вызывают синтаксическую ошибку (ожидая дальнейшего ввода, если это сделано из оболочки).
alias
и / илиset
довольно универсальноalias "varname=$varname" varname
илиvar=value set
Ответы:
Bash имеет опцию расширения параметров именно для этого случая :
Итак, в этом случае:
Это поддерживается в Bash 4.4 и выше. Есть также несколько вариантов для других форм расширения, а также для конкретной генерации полных операторов присваивания (
@A
).источник
bad substitution
."${foo:q}"
."${foo@Q}"
работает!Bash предоставляет
printf
встроенный%q
спецификатор формата, который выполняет экранирование оболочки даже в более старых (<4.0) версиях Bash:Этот прием также можно использовать для возврата массивов данных из функции:
Обратите внимание, что
printf
встроенная Bash отличается отprintf
утилиты, которая поставляется в комплекте с большинством Unix-подобных операционных систем. Если по какой-то причинеprintf
команда вызывает встроенную утилиту вместо встроенной, вы всегда можете выполнить ееbuiltin printf
вместо.источник
'Ne'\''er do well'
и т. Д., То есть цитаты, включенные в вывод.[[ 'Ne'\''er do well' == Ne\'er\ do\ well ]] && echo 'equivalent!'
будет эхомequivalent!
'hello'
приводит к неверному значению''\''hello''
, которое имеет ненужную начальную пустую строку (первые две одинарные кавычки) и неподходящую конечную одинарную кавычку.$'escape-these-chars'
это функция цитирования ANSI-C в Bash, которая позволяет экранировать все символы в указанной строке. Таким образом, чтобы легко создать строковый литерал, который содержит новую строку в имени файла (например$'first-line\nsecond-line')
, используйте\n
в этой конструкции.Я думаю, что я не RTFM. Это можно сделать так:
Затем
echo "$foo_esc"
дает ожидаемый'bar'\''baz'
Как я на самом деле использую это с функцией:
Модифицируя это, чтобы использовать
printf
встроенное решение Деджея:источник
Есть несколько решений процитировать значение переменной:
псевдоним
В большинстве оболочек (где псевдоним доступен) (кроме csh, tcsh и, вероятно, других csh, как):
Да, это работает во многих
sh
подобных оболочках, таких как приборная панель или пепел.установить
также в большинстве оболочек (опять же, не csh):
верстать
В некоторых оболочках (КШ, Баш и ЗШ , по крайней мере):
экспорт
сначала сделать:
Затем используйте:
ksh
export -p | grep 'qux='
bashexport -p | grep 'qux='
zsh
export -p qux
цитата
bash
echo "${qux@Q}"
zsh
echo "${(qq)qux}"
# может использоваться от одного до четырех q.источник
grep
сexport
илиset
могут нарушать переменные, содержащие встроенные символы новой строки.