Экранирование '!' в двойных кавычках

Возможно, у вас есть какие-то файлы, спрятанные под точкой монтирования. Я бы попытался остановить httpd и выполнить umount /applis/apache, а затем посмотреть в каталоге /applis/apache, чтобы увидеть, есть ли там что-то еще.

3
01.02.2020, 01:27
2 ответа

Печать строки с !не является не проблемой, когда она не заключена в кавычки, заключена в одинарные кавычки, внутри строки C -или внутри скрипта.

$ echo hello\!world 'hello!world' $'hello!world'
hello!world hello!world hello!world

$ echo 'echo "hello!world"' >file
$ bash file
hello!world

Пример скрипта представляет собой особый случай, в котором по умолчанию не задано значение (по умолчанию ). Таким образом, отключение histexpand (set +o histexpand, аналогично shopt -ou histexpandили простоset +H)будет иметь тот же эффект и позволит избежать расширения истории.

Однако вы запрашиваете строку в двойных кавычках в интерактивной оболочке (по умолчанию ), не разбивая строку на части. Хорошо, а как насчет этого:

$ a='!'
$ echo "hello${a}world"
hello!world

Об историческом Почему? .

Why is there a special case made for !?

Поскольку большинство символов ascii являются не специальными (внутри"):

$ printf '%s\n' "\a\b\c\d\e\f...\z \!\@\#\%     \$a \`date\` \\"

\a\b\c\d\e\f...\z \!\@\#\%     $a `date` \

Соответствующий текст изman bash:Заключение символов в двойные кавычки сохраняет буквальное значение всех символов в кавычках, за исключением $, `, \ и, когда расширение истории включено, !.

Именно так работает обратная косая черта внутри двойных кавычек в старых оболочках, и спецификация POSIX отражает это:

The <backslash> shall retain its special meaning as an escape character (see Escape Character (Backslash)) only when followed by one of the following characters when considered special:

$ ` " \ <newline>

4
28.04.2021, 23:25

По-видимому, Bash не удаляет обратную косую черту, используемую для экранирования !, появляющуюся в двойных кавычках (для предотвращения расширения истории ), несколько раз сообщалось об ошибке в ошибка -bash список рассылки.

Историческая причина такого поведения, упомянутая в ответе, который у вас уже есть , действительно является объяснением, данным разработчиком и сопровождающим Bash. Цитирование сообщения об ошибке -bash от Чета Рэми:

As documented, the `!' may be escaped only with single quotes or a backslash. Double quotes don't work because `!' is not one of the characters that are treated specially within double quotes, according to the POSIX.2 spec and traditional sh behavior.

Из того же источника, о том, как обрабатывать !в двойных кавычках:

You can either turn off history expansion with `set +o histexpand' or use backslash outside double quotes. Note that history expansion is not normally enabled when the shell is not interactive, so removing the backslash within a script should not be a problem.

(В этом списке рассылки можно найти несколько вариантов одних и тех же утверждений, например. 1 и 2 , в которых также упоминается связь с оболочкой C ).

Если вы не можете использовать ни одно из этих решений, :в ответах на How to echo a bang! показаны различные обходные пути! , например установка первого символа histcharsна маловероятно используемый символ или использование третьего символа той же переменной для запуска команд, к которым вы не хотите применять расширение истории.

0
28.04.2021, 23:25

Теги

Похожие вопросы