В bash, как мне избежать восклицательного знака?

85891
Matthew

Я хочу сделать что-то вроде bzr commit -m "It works!". Я могу как-то избежать восклицательного знака bzr commit -m "It works\!". Тем не менее, мое сообщение о фиксации содержит обратную косую черту. Как мне избежать восклицательного знака, игнорируя при этом обратную косую черту?

169
Выполнение `bzr commit -m" Это работает "!` Тоже работает. kba 11 лет назад 1
Как я уже отмечал ранее, команда, которую вы вводите, на самом деле работает сама по себе :) `bzr commit -m" Это работает! " h4unt3r 10 лет назад 1
Еще более странный случай с вложенными кавычками: http://stackoverflow.com/questions/22125658/how-to-escape-history-expansion-exclamation-mark-inside-a-double-quoted-comm Ciro Santilli 新疆改造中心 六四事件 法轮功 9 лет назад 0
Хотя принятый ответ является хорошим решением для ваших проблем с фиксацией, я чувствую, что это не ответ на актуальную проблему: [Расширение истории Bash] (https://www.gnu.org/software/bash/manual/bashref.html# История взаимодействия). Пожалуйста, подумайте о том, чтобы принять ответ Дениса? Arjan 8 лет назад 0

5 ответов на вопрос

141
Benjamin Bannier

Поскольку вы не зависите от bash для расширения переменных в сообщении фиксации, вы можете вместо этого использовать одинарные кавычки. Строки в одинарных кавычках не раскрываются с помощью bash.

bzr commit -m 'This does work!' 
Поскольку вопрос был «Как мне избежать восклицательного знака?» а не "Как не развернуть восклицательный знак?" Я не думаю, что это действительно. В некоторых случаях (например, при передаче апострофов и восклицательных знаков в одной командной строке) это не работает. Ответ ниже работает намного лучше, чтобы делать то, что нужно многим людям. Jann 13 лет назад 23
@Jann: Вы на 100% правы в этом, но я думаю, что проблема заключается в том, что у нас так много вопросов о суперпользователе: отвечаем ли мы на вопрос по существу, или мы помогаем людям решить их конкретную проблему. Я думаю, что оба способа могут быть полезны, и здесь нужно было получить помощь по конкретному вопросу. Benjamin Bannier 13 лет назад 7
туш! Это была конкретная проблема. Я просто хочу, чтобы ответ на мои вопросы можно было использовать во многих ситуациях. pS: причина, по которой я даже упомянул это, была в том, что мне нужно было передать апостроф и восклицательный знак в программу Perl, и мне нужно следующее решение. :) Jann 13 лет назад 0
Я согласен и с Бенджамином, и с Янном, но дал отрицательный ответ. Название вопроса индексируется поисковыми системами, и вот как я сюда попал, и, вероятно, большинство пользователей приходят сюда. Вот почему я считаю, что важно, чтобы фактический вопрос отражал проблему. На других форумах людям советуют (почти вынуждены) спрашивать, что именно они ищут. Ответы на плохо сформулированные вопросы поддерживают неряшливость, и именно в этом причина моего отрицательного ответа здесь. В качестве компромисса / решения я предлагаю адаптировать заголовок, чтобы он отражал реальную проблему. ChristophK 6 лет назад 0
141
jwd

Старый вопрос я знаю, но для будущих искателей:

Вы также можете использовать этот метод, если вы хотите двойные кавычки, а также восклицательный знак:

echo "It's broken"'!' 

Это работает, даже если !это не в конце строки.

Например:

echo "hello there"'!'" and goodbye" 

Бонус: аналогичная техника может быть использована для экранирования любого текста в Sh или Bash (с помощью sed): см. Первый вариант в этом ответе . Кроме того, если вы bash-completionустановили, скорее всего, эта quote()функция уже доступна.

Хороший совет, JWD. Я не понимал, что строки bash можно объединять, просто пропуская пробелы между ними. Alan H. 13 лет назад 4
На самом деле, если восклицательный знак находится в конце строки, вы находитесь в чистом `echo" С днём рождения! "` Будет работать так, как ожидалось, иначе вы можете избежать его с помощью обратной косой черты, но обратная косая черта также будет напечатана. XD Bash Не для слабонервных :) h4unt3r 10 лет назад 0
@ h4unt3r: Странно, это не мой опыт. Для меня `echo" Happy Birthday! "` Выводит 2 строки. Первый - `echo" Happy birthday "(без восклицания), а второй -" Happy birthday "(опять же без восклицания). У вас включено расширение истории при выполнении этого теста? jwd 10 лет назад 0
@jwd, какую версию bash вы используете? У меня всегда есть расширение истории. Вы случайно использовали два !! для вашего теста? h4unt3r 10 лет назад 0
@ h4unt3r: `версия 4.1.2 (1) -релиз (x86_64-redhat-linux-gnu)`, определенно используется только один `!`. У меня есть «Histexpand» в «$ SHELLOPTS». Тем не менее, я просто попробовал 4.3.18 (2) -релиз на другой машине, и он ведет себя так, как вы описали. Я думаю, это была ошибка, которая была исправлена. jwd 10 лет назад 0
64
Dennis Williamson

Отключить расширение истории :

set +H 

или же

set +o histexpand 
Спасибо - это сработало, но я должен был сделать `set + o histexpand`, а не` set -o histexpand`. Не могли бы вы отредактировать свой ответ, чтобы это исправить? Matthew 14 лет назад 0
Ой, опечатка, извините. Исправлена. Dennis Williamson 14 лет назад 0
свободно! искал это для AGES .... THX VM! как escape не будет работать ... Я тоже не хочу использовать одинарные кавычки ... Я добавлю это в мой `.bashrc` thx !!, никогда не использовал`! `в скриптах и ​​ни за что !! это всегда беспокоило ... Aquarius Power 11 лет назад 0
Это так круто! `` `echo" @AquariusPower! "` `` joehanna 8 лет назад 0
9
KeithB

Используйте одинарные кавычки (') вместо двойных кавычек ("). Одинарные кавычки отключают всю интерпретацию содержимого в них, в то время как двойные кавычки отключают только некоторые.

bzr commit -m 'It works!' 
4
SilversleevesX

Я только что нашел другой способ, который по крайней мере будет работать со echoстроками (предложениями), которые вы хотите акцентировать с восклицательным знаком. Он выполняет более или менее конечный прогон вокруг своей вершины Bash и занимает чуть больше времени для кодирования.

Гекс для восклицательного знака, как указано на http://www.ascii-code.com/, равен 21, поэтому, если вы поместите \x21в конец своей строки echo -e $foo, сделайте $fooсвое собственное расширенное эхо [то есть, foo=$(echo -e "$foo")] то, что вы получить, когда вы echo $fooснова это строка с !в конце. И никакого переключения его оси тоже нет.

Работает наверняка в Bash 4+. Более ранние версии, ymmv.

Хм, это не работает для меня. lzap 10 лет назад 0