Questão No bash, como faço para escapar de um ponto de exclamação?


Eu quero fazer algo como bzr commit -m "It works!". Eu posso escapar do ponto de exclamação fazendo bzr commit -m "It works\!". No entanto, minha mensagem de commit inclui a barra invertida. Como faço para escapar do ponto de exclamação, enquanto ainda ignoro a barra invertida?


163


origem


Fazendo bzr commit -m "It works"! funciona também. - kba
Como eu observei antes do comando que você colocou realmente funciona sozinho :) bzr commit -m "It works!" - h4unt3r
Um caso ainda mais esquisito com citações aninhadas: stackoverflow.com/questions/22125658/… - Ciro Santilli 新疆改造中心 六四事件 法轮功
Embora a resposta aceita seja uma boa solução para seus problemas de comprometimento, sinto que não é uma resposta para o problema real: Expansão do histórico de bash. Por favor considere aceitar a resposta de Dennis? - Arjan


Respostas:


Como você não depende do bash para expandir variáveis ​​em sua mensagem de commit, você pode usar aspas simples. Strings entre aspas simples não são expandidas por bash.

bzr commit -m 'This does work!' 

134



Desde que a questão era "Como faço para escapar de um ponto de exclamação?" e não "Como eu não expandir um ponto de exclamação?" Eu não acho que isso seja válido. Há algumas vezes (como ao passar apóstrofos e pontos de exclamação na mesma linha de comando) que isso não funciona. A resposta abaixo funciona muito melhor para fazer o que muitas pessoas precisam. - Jann
@Jann: Você está 100% certo sobre isso, mas acho que a questão aqui é a questão com tantas perguntas sobre o superusuário: respondemos a pergunta ao ponto ou ajudamos as pessoas a resolver seu problema específico. Acho que as duas maneiras podem ser úteis, e isso estava procurando ajuda em um problema específico. - Benjamin Bannier
toque! Este foi um problema específico. Eu só tendem a querer uma resposta às minhas perguntas para poder ser usado em muitas situações. pS: A razão pela qual eu mencionei isso foi que eu estava precisando passar um apóstrofo e um ponto de exclamação para um programa perl e eu precisava da solução abaixo. :) - Jann
Concordo com Benjamin e Jann, mas dei um voto negativo. O título da pergunta é indexado por mecanismos de busca e é assim que eu vim até aqui e provavelmente a maioria dos usuários vem aqui. É por isso que acredito que é importante que a pergunta real reflita sobre o problema por trás dela. Em outros fóruns, as pessoas são aconselhadas (quase forçadas) a perguntar exatamente o que procuram. Responder a perguntas mal expressas suporta desleixo e essa é a razão exata para o meu downvote aqui. Como compromisso / solução, minha sugestão é ajudar a adaptar o cabeçalho para refletir o problema real. - ChristophK


Pergunta antiga que conheço, mas para futuros pesquisadores:

Você também pode usar esse método se quiser aspas duplas, bem como a exclamação:

echo "It's broken"'!'

Isso funciona mesmo se o ! não está no final da linha.

Por exemplo:

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

Bônus: Uma técnica similar pode ser usada para escapar qualquer texto em Sh ou Bash (com a ajuda de sed): veja a primeira opção em esta resposta. Além disso, se você tiver bash-completion instalado, você provavelmente tem a quote() função já está disponível.


139



Boa dica, JWD. Eu não sabia que as strings bash podiam ser concatenadas simplesmente omitindo o espaço em branco entre elas. - Alan H.
Na verdade, se o ponto de exclamação está no final da string, você está no claro echo "Happy birthday!" vai funcionar como esperado, caso contrário, você pode escapar com uma barra invertida, mas a barra invertida será impressa também XD Bash não é para os fracos de coração :) - h4unt3r
@ h4unt3r: Estranho, essa não é a minha experiência. Para mim, echo "Happy Birthday!" produz 2 linhas. O primeiro é echo "Happy birthday" (sem exclamação), e o segundo é "Feliz aniversário" (novamente, sem exclamação). Você tem a expansão do histórico ativada ao fazer este teste? - jwd
@ jwd qual versão do bash você está executando? Eu sempre tenho expansão de hist. Você acidentalmente usou dois !! para o seu teste? - h4unt3r
@ h4unt3r: version 4.1.2(1)-release (x86_64-redhat-linux-gnu), definitivamente apenas um ! sendo usado. eu tenho histexpand presente em $SHELLOPTS. No entanto, eu tentei apenas 4.3.18 (2) - liberar em outra máquina, e ela se comporta como você descreveu. Eu acho que foi um bug que foi corrigido. - jwd


Desligar expansão da história:

set +H

ou

set +o histexpand

63



Obrigado - isso funcionou, mas eu tive que fazer set +o histexpand, não set -o histexpand. Você poderia editar sua resposta para consertar isso? - Matthew
Opa, erro de digitação, desculpe. Fixo. - Dennis Williamson
excelente! estava procurando por isso AGES .... thx vm! como escape não vai funcionar ... Eu não quero usar aspas simples também ... vou acrescentar isso ao meu .bashrc thx !!, nunca usado ! em scripts e por nada !! sempre foi preocupante ... - Aquarius Power
Isso é tão incrível! echo "@AquariusPower!" - joehanna


Use aspas simples (') em vez de aspas duplas ("). As aspas simples desligam todas as interpretações das coisas nelas, enquanto as aspas duplas desativam apenas algumas.

bzr commit -m 'It works!'

9





Acabei de encontrar outro jeito, que pelo menos funcionará com echoseqüências de caracteres (frases) que você deseja pontuar com um ponto de exclamação. Ele faz um funcionamento final, mais ou menos, em torno do histexpand Bash e demora apenas um pouco mais para codificar.

O hexadecimal para um ponto de exclamação, conforme listado http://www.ascii-code.com/, é 21, então se você colocar \x21 no final da sua string, echo -e $foo, faço $foo seu próprio eco expandido [isto é, foo=$(echo -e "$foo")], o que você ganha quando você echo $foo novamente é a string com um ! no fim. E sem trocar histexpand também.

Funciona com certeza no Bash 4+. Versões anteriores, ymmv.


4



Hmmm isso não funciona para mim. - lzap