Учебное пособие Брюса Барнетта по UNIX Shell по цитате потрясающе, а Bash FAQ / подводные камни / разбиение слов статьи имеют массу полезного чаевые. Краткое резюме:
Строки без кавычек могут содержать большинство символов, но не все (например, новые строки), и многие из них (включая пробел) должны быть экранированы. Только не используйте их - если вы впадаете в искушение, вы можете обнаружить, что тот, кто изменил сценарий, забыл включить кавычки, когда они стали необходимыми.
Строки в одинарных кавычках могут содержать большинство символов, включая NUL и символы новой строки, но не одинарные кавычки, поэтому они также полезны только для простых значений.
Обратные пометки предназначены для команд. Они должны использоваться только в том случае, если ваша оболочка не поддерживает $()
. Пример: * +1022 *
current_dir=`pwd` # BAD! Don't do this!
Эта команда плохая, потому что, когда правая часть назначения не заключена в кавычки, оболочка выполняет разбиение слов над ней. Это часто приводит к трудным для воспроизведения ошибкам, потому что пробел трудно проверить визуально. Чтобы заключить в кавычки команды вы должны использовать двойные кавычки :
current_dir="$(pwd)" # OK, but loses newlines at EOF
Новые строки в EOF особенно хитры. Вы можете добавить один символ и удалить его, используя, например,
# Works for some commands, but not pwd
current_dirx="$(pwd; echo x)"
current_dir="${current_dirx%x}"
printf %s "$current_dir"
, но есть дополнительная трудность, потому что некоторые команды (например, pwd
) добавят символ новой строки в конце своего вывода в любом случае , поэтому вам, возможно, придется удалить это:
# Works for some commands, including pwd
current_dirx="$(pwd; echo x)"
current_dir="${current_dirx%$'\nx'}"
printf %s "$current_dir"
Двойные кавычки могут содержать любой символ (Попробуйте echo -ne "\0" | wc -c
), но обратите внимание, что переменные не могут содержать символ NUL.
Цитаты ANSI-C могут содержать любые символы , кроме NUL (Попробуйте echo -ne $'\0' | wc -c
), и предоставляют удобные коды перехода, облегчающие работу с ними. специальные символы:
printf %s $'--$`!*@\a\b\E\f\r\t\v\\\'"\360\240\202\211 \n'
printf %q $'--$`!*@\a\b\E\f\r\t\v\\\'"\360\240\202\211 \n'
touch -- $'--$`!*@\a\b\E\f\r\t\v\\\'"\360\240\202\211 \n'
rm -- $'--$`!*@\a\b\E\f\r\t\v\\\'"\360\240\202\211 \n'