Question En bash, comment échapper à un point d'exclamation?


Je veux faire quelque chose comme bzr commit -m "It works!". Je peux en quelque sorte échapper au point d'exclamation en faisant bzr commit -m "It works\!". Cependant, mon message de validation inclut la barre oblique inverse. Comment échapper au point d'exclamation, tout en ignorant la barre oblique inverse?


163
2018-04-22 18:53


origine


Faire bzr commit -m "It works"! travaille aussi. - kba
Comme je l'ai noté avant que la commande que vous mettez ne fonctionne réellement sur elle-même :) bzr commit -m "It works!" - h4unt3r
Un cas encore plus étrange avec des guillemets imbriqués: stackoverflow.com/questions/22125658/ ... - Ciro Santilli 新疆改造中心 六四事件 法轮功
Bien que la réponse acceptée soit une bonne solution pour résoudre vos problèmes d’engagement, j’ai le sentiment que ce n’est pas une réponse au problème actuel: Expansion de l'histoire de Bash. S'il vous plaît envisager d'accepter la réponse de Dennis? - Arjan


Réponses:


Comme vous ne dépendez pas de bash pour développer des variables dans votre message de validation, vous pouvez utiliser des guillemets simples. Les chaînes entre guillemets simples ne sont pas développées par bash.

bzr commit -m 'This does work!' 

134
2018-04-22 19:31



Puisque la question était "Comment échapper à un point d'exclamation?" et non "Comment ne pas développer un point d'exclamation?" Je ne pense pas que cela soit valable. Il y a quelques fois (comme lors du passage des apostrophes et des points d'exclamation dans la même ligne de commande) que cela ne fonctionne pas. La réponse ci-dessous fonctionne beaucoup mieux pour faire ce que beaucoup de gens ont besoin. - Jann
@Jann: Vous avez raison à 100% là-dessus, mais je pense que le problème est ici celui qui comporte tellement de questions sur le super-utilisateur: répondons-nous à la question ou aidons-nous les gens à résoudre leur problème spécifique? Je pense que les deux manières peuvent être utiles, et cela cherchait de l'aide sur un problème spécifique. - Benjamin Bannier
touché! C'était un problème spécifique. J'ai juste tendance à vouloir une réponse à mes questions pour pouvoir l'utiliser dans de nombreuses situations. PS: La raison pour laquelle j'ai même mentionné cela était que je devais passer à la fois une apostrophe et un point d'exclamation à un programme Perl et j'avais besoin de la solution ci-dessous. :) - Jann
Je suis d'accord avec Benjamin et Jann, mais j'ai donné une note. Le titre de la question est indexé par les moteurs de recherche et c'est ainsi que je suis venu ici et que la plupart des utilisateurs viennent probablement ici. C'est pourquoi j'estime qu'il est important que la question présente reflète le problème. Dans d'autres forums, les gens sont invités (presque obligés) à demander précisément ce qu'ils recherchent. Répondre à des questions mal exprimées supporte la négligence et c'est la raison exacte de ma défaite ici. À titre de compromis / solution, je suggère d’aider à adapter l’en-tête afin qu’il reflète le problème réel. - ChristophK


Ancienne question que je connais, mais pour les futurs chercheurs:

Vous pouvez également utiliser cette méthode si vous souhaitez des guillemets doubles ainsi que l'exclamation:

echo "It's broken"'!'

Cela fonctionne même si le ! n'est pas au bout de la ligne.

Par exemple:

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

Bonus: Une technique similaire peut être utilisée pour échapper à tout texte dans Sh ou Bash (avec l'aide de sed): voir la première option dans cette réponse. De plus, si vous avez bash-completion installé, vous avez probablement la quote() fonction disponible déjà.


139
2018-06-23 19:16



Bon conseil, JWD. Je n'ai pas réalisé que les chaînes de bash pouvaient être concaténées simplement en omettant les espaces entre elles. - Alan H.
En fait, si le point d'exclamation est à la fin de la chaîne, vous êtes en clair echo "Happy birthday!" fonctionnera comme prévu sinon vous pouvez y échapper avec une barre oblique inverse, mais la barre oblique inverse sera également imprimée XD Bash n'est pas pour les faibles de cœur :) - h4unt3r
@ h4unt3r: Etrange, ce n'est pas mon expérience. Pour moi, echo "Happy Birthday!" sorties 2 lignes. Le premier est echo "Happy birthday" (pas d'exclamation), et la seconde est "Joyeux anniversaire" (encore une fois, pas d'exclamation). Avez-vous l'expansion de l'historique activée lorsque vous effectuez ce test? - jwd
@jwd quelle version de bash exécutez-vous? J'ai toujours une expansion hist. Avez-vous accidentellement utilisé deux !! pour votre test? - h4unt3r
@ h4unt3r: version 4.1.2(1)-release (x86_64-redhat-linux-gnu), certainement un seul ! utilisé. j'ai histexpand présenter à $SHELLOPTS. Cependant, j'ai juste essayé 4.3.18 (2) -release sur une autre machine, et il se comporte comme vous l'avez décrit. Je suppose que c'était un bug qui a été corrigé. - jwd


Éteindre expansion de l'histoire:

set +H

ou

set +o histexpand

63
2018-04-22 18:58



Merci - cela a fonctionné, mais je devais faire set +o histexpand, ne pas set -o histexpand. Pourriez-vous modifier votre réponse pour résoudre ce problème? - Matthew
Oups, typo, désolé. Fixé. - Dennis Williamson
excelent! cherchait ceci pour AGES .... thx vm! comme évasion ne fonctionnera pas ... Je ne veux pas utiliser des citations simples aussi ... Je vais ajouter ceci à mon .bashrc merci !!, jamais utilisé ! dans les scripts et pour rien !! c'était toujours troublant ... - Aquarius Power
C'est tellement génial! echo "@AquariusPower!" - joehanna


Utilisez des guillemets simples (') au lieu de guillemets ("). Les guillemets simples désactivent toutes les interprétations du contenu, tandis que les guillemets doubles en désactivent certains.

bzr commit -m 'It works!'

9
2018-04-22 19:32





Je viens juste de trouver un autre moyen, qui au moins fonctionnera avec echochaînes de caractères (phrases) que vous souhaitez ponctuer avec un point d’exclamation. Il effectue une analyse, plus ou moins, autour de Bex histexpand et ne prend qu'un peu plus de temps à coder.

L'hexagone pour un point d'exclamation, comme indiqué sur http://www.ascii-code.com/, a 21 ans, donc si vous mettez \x21 à la fin de votre chaîne, echo -e $foo, faire $foo son propre écho élargi [c.-à-d. foo=$(echo -e "$foo")], ce que vous obtenez quand vous echo $foo est encore la chaîne avec un ! à la fin. Et pas de changement d'histexpand non plus.

Fonctionne à coup sûr dans Bash 4+. Versions antérieures, ymmv.


4
2017-11-23 04:28



Hmmm ça ne marche pas pour moi. - lzap