Я хочу запустить команду из скрипта bash, который содержит одинарные кавычки и некоторые другие команды внутри одинарных кавычек и переменную.
например repo forall -c '....$variable'
В этом формате $
экранируется, а переменная не раскрывается.
Я попробовал следующие варианты, но они были отклонены:
repo forall -c '...."$variable" '
repo forall -c " '....$variable' "
" repo forall -c '....$variable' "
repo forall -c "'" ....$variable "'"
Если я подставляю значение вместо переменной, команда выполняется просто отлично.
Пожалуйста, скажите мне, где я иду не так.
repo forall -c ' ...before... '"$variable"' ...after...'
bash
ест одинарные кавычки. Либо вы не вbash
, либо одинарные кавычки не являются частьюrepo
команды.Ответы:
Внутри одинарных кавычек все сохранилось буквально без исключения.
Это означает, что вы должны закрыть кавычки, вставить что-то, а затем снова войти.
Конкатенация слов просто делается путем сопоставления. Как вы можете убедиться, каждая из приведенных выше строк является одним словом в оболочке. Кавычки (одинарные или двойные, в зависимости от ситуации) не изолируют слова. Они используются только для отключения интерпретации различных специальных символов, таких как пробелы
$
,;
... Хороший учебник по цитированию см. В ответе Марка Рида. Также актуально: Какие символы нужно экранировать в bash?Не объединять строки, интерпретируемые оболочкой
Вы должны абсолютно избегать создания команд оболочки путем объединения переменных. Это плохая идея, похожая на конкатенацию фрагментов SQL (инъекция SQL!).
Обычно в команде можно использовать заполнители и предоставлять команду вместе с переменными, чтобы вызываемый абонент мог получить их из списка аргументов вызова.
Например, следующее очень небезопасно. НЕ ДЕЛАЙТЕ ЭТОГО
Если содержимое
$myvar
не заслуживает доверия, вот эксплойт:Вместо приведенного выше вызова используйте позиционные аргументы. Следующий вызов лучше - он не пригоден для использования:
Обратите внимание на использование одиночных тиков в присваивании
script
, что означает, что оно взято буквально, без расширения переменных или любой другой формы интерпретации.источник
"some"thing' like'this
это все одно слово в оболочке. Кавычки ничего не прекращаются, насколько синтаксический обеспокоен, и нет никакого способа для команды под названием от оболочки , чтобы сказать , что было процитировано как.repo
Команда не может заботиться , какие цитаты он получает. Если вам нужно расширение параметров, используйте двойные кавычки. Если это означает, что вам приходится сталкиваться с большим количеством вещей, используйте большую часть одинарных кавычек, а затем вырывайтесь из них и переходите в двойные числа для той части, где вам нужно расширение.Объяснение следует, если вам интересно.
Когда вы запускаете команду из оболочки, эта команда получает в качестве аргументов массив строк с нулевым символом в конце. Эти строки могут содержать абсолютно любой ненулевой символ.
Но когда оболочка создает этот массив строк из командной строки, она интерпретирует некоторые символы специально; это сделано для того, чтобы упростить (возможно, сделать) команды для ввода. Например, пробелы обычно указывают границу между строками в массиве; по этой причине отдельные аргументы иногда называют «словами». Но аргумент, тем не менее, может содержать пробелы; вам просто нужен какой-то способ сказать оболочке, что вы хотите.
Вы можете использовать обратную косую черту перед любым символом (включая пробел или другую обратную косую черту), чтобы указать оболочке обрабатывать этот символ буквально. Но пока вы можете сделать что-то вроде этого:
echo \"Thank\ you.\ \ That\'ll\ be\ \$4.96,\ please,\"\ said\ the\ cashier
... это может стать утомительным. Таким образом, оболочка предлагает альтернативу: кавычки. Они бывают двух основных разновидностей.
Двойные кавычки называются «группирующими кавычками». Они препятствуют расширению подстановочных знаков и псевдонимов, но в основном они включают пробелы в слове. Другие вещи, такие как расширение параметров и команд (виды, обозначенные как a
$
), все еще происходят. И, конечно, если вы хотите, чтобы буквальные двойные кавычки были в двойных кавычках, вы должны использовать обратную косую черту:echo "\"Thank you. That'll be \$4.96, please,\" said the cashier"
Одиночные кавычки более драконовские. Все между ними воспринимается буквально, включая обратную косую черту. Нет абсолютно никакого способа получить буквальную одинарную кавычку внутри одинарных кавычек.
К счастью, кавычки в оболочке не являются разделителями слов ; сами по себе они не заканчивают слово. Вы можете входить и выходить из кавычек, в том числе между разными типами кавычек, в пределах одного и того же слова, чтобы получить желаемый результат:
echo '"Thank you. That'\''ll be $4.96, please," said the cashier'
Так что это проще - намного меньше обратной косой черты, хотя последовательность «закрывающая одинарная кавычка», «обратная косая черта», буквальная одинарная кавычка, открытая одинарная кавычка требует некоторого привыкания.
Современные оболочки добавили еще один стиль цитирования, не указанный в стандарте POSIX, в котором перед одинарной кавычкой стоит начальный знак доллара. Строки так цитируемые следуют аналогичным соглашениям в строковые литералы в языке программирования ANSI C, и поэтому иногда называют «ANSI строкой» и
$'
...'
пара «ANSI кавычки». Внутри таких строк приведенный выше совет о том, что обратная косая черта воспринимается буквально, больше не применяется. Вместо этого они снова становятся особенными - вы можете не только включить буквальную одинарную кавычку или обратную косую черту, добавив к ней обратную косую черту, но и оболочка также расширяет экранирование символов ANSI C (например,\n
для новой строки,\t
для табуляции и\xHH
для символа с шестнадцатеричный кодHH
). В противном случае, однако, они ведут себя как строки в одинарных кавычках: подстановка параметров или команд не происходит:Важно отметить, что единственная строка, полученная в качестве аргумента
echo
команды , одинакова во всех этих примерах. После того, как оболочка выполнила синтаксический анализ командной строки, команда не может сказать, что и как было указано. Даже если бы захотел.источник
$'string'
Соответствует ли формат POSIX? Кроме того, есть ли название для этого?$'string'
- это расширение, отличное от POSIX, которое я видел как «строки ANSI»; Я включил эти факты в ответ. Такие строки работают в большинстве современных Bourne-совместимых оболочек: bash, dash, ksh (как AT & T, так и PD), и zsh поддерживают их.Вот что сработало для меня -
источник
QUOTE
в отдельную переменную совершенно излишне; одинарные кавычки внутри двойных кавычек являются обычным символом. (Кроме того, не используйте верхний регистр для ваших личных переменных.)РЕДАКТИРОВАТЬ: (Согласно комментариям в вопросе :)
Я смотрю на это с тех пор. Мне повезло, что у меня было репо. Тем не менее, мне не ясно, нужно ли вам заключать команды в одинарные кавычки принудительно. Я изучил синтаксис репо и не думаю, что вам это нужно. Вы можете использовать двойные кавычки вокруг вашей команды, а затем использовать любые одинарные и двойные кавычки, которые вам нужны, если вы избегаете двойных.
источник
просто используйте printf
вместо
используйте printf для замены токена переменной на расширенную переменную.
Например:
источник
printf
на самом деле ничего вам здесь не покупается, и неспособность процитировать командную замену вызывает новые проблемы с цитированием.Переменные могут содержать одинарные кавычки.
источник
"$myvar"
в двойные кавычки.Это работает для вас?
источник