web-dev-qa-db-fra.com

Qu'est-ce que "-bash:!": Événement introuvable "

Essayez d'exécuter ce qui suit sous un shell bash echo "Reboot your instance!"

Sur mon installation:

root@domU-12-31-39-04-11-83:/usr/local/bin# bash --version
GNU bash, version 4.1.5(1)-release (i686-pc-linux-gnu)
Copyright (C) 2009 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
root@domU-12-31-39-04-11-83:/usr/local/bin# uname -a
Linux domU-12-31-39-04-11-83 2.6.35-22-virtual #35-Ubuntu SMP Sat Oct 16 23:57:40 UTC 2010 i686 GNU/Linux
root@domU-12-31-39-04-11-83:/usr/local/bin# echo "Reboot your instance!"
-bash: !": event not found

Quelqu'un peut-il expliquer ce que sont les "événements bash"? Je n'avais jamais entendu ce concept auparavant. Aussi, comment dois-je produire "!" à la fin de la phrase?

123
Maxim Veksler

Vous pouvez désactiver la substitution d'historique à l'aide de set +H.

! est un caractère spécial à bash, il est utilisé pour faire référence aux commandes précédentes; par exemple,

!rm

se souviendra et exécutera la dernière commande commençant par la chaîne "rm", et

!rm:p

se rappellera mais n'exécutera pas la dernière commande commençant par la chaîne "rm". bash interprète le point d'exclamation dans echo "reboot your instance!" comme "remplacez ici la dernière commande qui a commencé par le (s) caractère (s) suivant immédiatement le point d'exclamation", et vous grogne qu'il ne peut pas trouver un événement (commande) dans votre histoire qui a commencé par un guillemet simple.

Essayer

echo reboot your instance\!

pour protéger (échapper) le point d'exclamation de bash.

111
MadHatter

Pour résoudre votre problème d'origine, essayez d'utiliser des guillemets simples plutôt que des guillemets doubles. Avec ce dernier, bash tentera de développer certains caractères avant de passer le résultat à la commande (echo dans ce cas). Avec des guillemets simples, bash transmet la chaîne entière, inchangée.

! est utilisé dans les commandes pour faire référence à l'historique de la ligne de commande. Voir: http://tldp.org/LDP/abs/html/abs-guide.html#HISTCOMMANDS pour un ensemble complet. Avec l'exemple ci-dessus, bash essaie de développer !" comme référence à un événement avant que l'écho n'intervienne, d'où l'erreur.

Notez que dans les scripts, toutes les commandes d'historique sont désactivées, car elles n'ont de sens que dans un shell interactif.

Le seul que j'utilise régulièrement est !$. Il se développe jusqu'au dernier argument de la commande précédente. C'est un raccourci utile par endroits.

27
SmallClanger

Mettez juste un espace entre! et "que cela fonctionnera.

À votre santé.

6
Isik Mater

Oui, ! est un caractère spécial à bash, il est utilisé pour faire référence aux commandes précédentes.

Peu de façons de gérer la situation

Ce qui suit affichera la chaîne telle qu'elle est

echo 'Reboot your instance!'

Ce qui suit exécutera la commande et concaténera la chaîne

echo 'escaping #'" adding `which python` to the string"
echo '#!'`which python`
2
Syed Qaiser

Vous pouvez également utiliser un heredoc :

cat <<EOF
Reboot your instance!
EOF

C'est ennuyeux dans ce cas car ce n'est pas une ligne mais pour les commandes plus longues (comme l'écriture d'un script bash), cela fonctionne très bien.

0
Tom Saleeba

Vous pouvez également ajouter

histchars=  

Dans ./bash_profile (ou utilisez-le comme unique sur la ligne de commande)

Pour désactiver ! d'être un "caractère d'histoire spécial", ou de le définir sur autre chose.

Avertissement; certaines choses peuvent se casser lorsque vous le définissez par exemple sur ~ et éventuellement d'autres chaînes.

Regardez:

$ echo "!test"
-bash: !test: event not found
$ histchars=
$ echo "!test"
!test
$ histchars=7
$ echo "7test"
-bash: 7test: event not found
$ histchars=
$ histchars=~
$ histchars=
hars=hars=~     # odd output
$ ~/test
-bash: /test: event not found
0
Roel Van de Paar

Dans bash 4.3 il semble que vous n'ayez plus besoin d'utiliser des guillemets simples ou set +H:

$ bash --version
GNU bash, version 4.3.46(1)-release (x86_64-unknown-linux-gnu)
[...]
$ echo "Reboot your instance!"
Reboot your instance!
0
Eugene Yarmash