@ jw013 Хороший вопрос и отличные статьи. Мне нравится цитата «Переменные содержат данные, функции содержат код». из первой ссылки, но для моего использования данные, которые передаются функции (в данном случае at), являются кодом. Какие-нибудь советы по безопасному способу организации / сбора кода, который будет дан at?
Кори Кляйн
atпринимает shсинтаксис в качестве входных данных. Таким образом, генерирование входных данных atозначает создание правильного shсинтаксиса с правильными кавычками из произвольного ввода, что не является тривиальным, поэтому я постараюсь избежать этого, если это вообще возможно. Было бы очень полезно, если бы вы могли немного подробнее рассказать о том, что вы пытаетесь достичь.
jw013
Извините, я не хотел отвлекаться на слишком много деталей, но то, что я делаю, не очень сложно, ИМО. Я создаю сценарий, который занимает «время» и «сообщение». Затем он запускается в atтечение заданного «времени» и говорит atвыполнить команду dzen2. dzen2принимает "сообщение" из стандартного ввода, а также использует некоторые другие статические параметры. Сложность в том, что мне нужно передать параметр «message» от пользователя в dzen2команду, но я на самом деле не запускаю dzen2сам, я говорю atэто делать.
Также важно отметить, что кавычки оцениваются по-разному; двойные кавычки (") позволяют вычислять вложенную строку, одинарные кавычки (') печатают строку как литерал. Пример: "$(ls)"и '$(ls)'. Это причина, по которой кавычки появляются в исходных примерах вопросов.
Джозеф Керн,
Массив также является источником проблем. Код принадлежит функциям, данные - переменным. Представленный вами пример работает только потому, что кавычки удаляются в разбиении массива. А printf '<%s> ' "${VAR[@]}"покажет, что цитаты уже удалены. Если вы установите VAR так, VAR=(echo \"hi\")чтобы на самом деле были кавычки, та же проблема появится снова, $ ${VAR[@]}будет напечатано"hi"
9
Удаление кавычек происходит только в исходных словах ввода, а не в результате расширений. Кавычки, которые являются частью расширенных переменных, остаются нетронутыми.
Если вы отступите немного назад, вы поймете, почему подстановка переменных должна сохранять кавычки.
Смысл кавычек в оболочке Unix / Linux / BSD состоит в том, чтобы объединить части строки, которые в противном случае были бы проанализированы как несколько строк. Поскольку по умолчанию оболочка использует пробел в качестве разделителя токенов, строка с пробелами (например, «один два три»), если она не заключена в кавычки или не экранирована каким-либо образом, будет проанализирована как 3 строки: «одна», «два» и «три».
Если программист хочет получить строку со значением некоторой переменной, интерполированной:
VAR=two
STRING="one $VAR three"
оболочка абсолютно не должна удалять кавычки: строка, содержащая пробелы, будет проанализирована как 3 меньшие строки.
eval
это минное поле потенциальных дыр в безопасности, которые вы должны очень осторожноat
), являются кодом. Какие-нибудь советы по безопасному способу организации / сбора кода, который будет данat
?at
принимаетsh
синтаксис в качестве входных данных. Таким образом, генерирование входных данныхat
означает создание правильногоsh
синтаксиса с правильными кавычками из произвольного ввода, что не является тривиальным, поэтому я постараюсь избежать этого, если это вообще возможно. Было бы очень полезно, если бы вы могли немного подробнее рассказать о том, что вы пытаетесь достичь.at
течение заданного «времени» и говоритat
выполнить командуdzen2
.dzen2
принимает "сообщение" из стандартного ввода, а также использует некоторые другие статические параметры. Сложность в том, что мне нужно передать параметр «message» от пользователя вdzen2
команду, но я на самом деле не запускаюdzen2
сам, я говорюat
это делать.Ответы:
Дополнительная пара цитат будет потребляться только на дополнительном шаге оценки. Например, принудительно
eval
:Но, как правило, плохая идея помещать команды с параметрами в одну строку. Вместо этого используйте массив:
источник
"$(ls)"
и'$(ls)'
. Это причина, по которой кавычки появляются в исходных примерах вопросов.printf '<%s> ' "${VAR[@]}"
покажет, что цитаты уже удалены. Если вы установите VAR так,VAR=(echo \"hi\")
чтобы на самом деле были кавычки, та же проблема появится снова,$ ${VAR[@]}
будет напечатано"hi"
Удаление кавычек происходит только в исходных словах ввода, а не в результате расширений. Кавычки, которые являются частью расширенных переменных, остаются нетронутыми.
источник
Если вы отступите немного назад, вы поймете, почему подстановка переменных должна сохранять кавычки.
Смысл кавычек в оболочке Unix / Linux / BSD состоит в том, чтобы объединить части строки, которые в противном случае были бы проанализированы как несколько строк. Поскольку по умолчанию оболочка использует пробел в качестве разделителя токенов, строка с пробелами (например, «один два три»), если она не заключена в кавычки или не экранирована каким-либо образом, будет проанализирована как 3 строки: «одна», «два» и «три».
Если программист хочет получить строку со значением некоторой переменной, интерполированной:
оболочка абсолютно не должна удалять кавычки: строка, содержащая пробелы, будет проанализирована как 3 меньшие строки.
источник