web-dev-qa-db-fra.com

En bash, comment puis-je é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 inversée. Comment puis-je échapper au point d'exclamation tout en ignorant la barre oblique inverse?

178
Matthew

Puisque vous ne comptez pas sur bash pour développer les 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!' 
149
Benjamin Bannier

Voici une autre méthode si vous voulez des guillemets doubles ainsi que l'exclamation:

echo "It's broken"'!'

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

Par exemple:

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

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

151
jwd

Désactiver expansion de l'historique :

set +H

ou

set +o histexpand

Vous pouvez ajouter l'une de ces commandes à votre ~/.bashrc si vous n'utilisez généralement pas le développement de l'historique.

Bash 4.3 a ajouté un cas spécial :

le caractère d'expansion de l'historique est également traité comme cité s'il précède immédiatement la double guillemet fermante dans une chaîne entre guillemets

65
Dennis Williamson

Utilisez des guillemets simples (') au lieu de guillemets doubles ("). Les guillemets simples désactivent toute interprétation des éléments qu’ils contiennent, alors que les guillemets n'en désactivent que certaines.

bzr commit -m 'It works!'
12
KeithB

Je viens tout juste de trouver un autre moyen, qui fonctionnera au moins avec les chaînes echoing que vous voulez ponctuer avec un point d’exclamation. Il effectue plus ou moins une analyse finale autour de Bash histexpand et ne prend qu'un peu plus de temps à coder.

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

Fonctionne à coup sûr dans Bash 4+. Les versions précédentes, ymmv.

4
SilversleevesX