web-dev-qa-db-fra.com

Vous ne pouvez pas utiliser le point d'exclamation (!) Dans bash?

J'essaie d'utiliser la commande curl pour accéder à une URL http avec un point d'exclamation (!) sur son chemin. par exemple:

curl -v "http://example.org/!287s87asdjh2/somepath/someresource"

la console répond par bash: ... event not found.

Qu'est-ce qui se passe ici? et quelle serait la syntaxe appropriée pour échapper au point d'exclamation?

103
netbrain

Le point d'exclamation fait partie de l'expansion de l'histoire dans bash. Pour l'utiliser, vous devez le mettre entre guillemets simples (par exemple: 'http://example.org/!132') ou pour y échapper directement avec une barre oblique inverse (\) avant le caractère (par exemple: "http://example.org/\!132").

Notez que dans les guillemets doubles, une barre oblique inverse avant l'exclam empêche l'expansion de l'historique, MAIS la barre oblique inverse n'est pas supprimée dans un tel cas. Il est donc préférable d'utiliser des guillemets simples, donc vous ne passez pas une barre oblique inverse littérale à curl dans le cadre de l'URL.

111
Daniel Pittman

En plus de la réponse donnée par Daniel, vous pouvez également désactiver complètement l'expansion de l'historique si vous ne l'utilisez pas avec set +H.

68
Chris Down

Je ferais personnellement des guillemets simples, mais pour être complet, je noterai également qu'il s'agit d'une URL, vous pouvez encoder le ! comme %21, par exemple. curl -v http://example.org/%21132.

18
Aaron D. Marasco

Cela peut aussi faire

curl -v "http://example.org/"'!'"287s87asdjh2/somepath/someresource"
ou
curl -v "http://example.org/"\!"287s87asdjh2/somepath/someresource"

Ce qui fonctionne car bash concatène les chaînes adjacentes. Cette approche est particulièrement utile lorsque vous avez d'autres choses qui nécessitent une expansion de Shell, vous ne pouvez donc pas utiliser de guillemets simples pour la chaîne entière:

curl -v 'http://example.org/!'"287s87asdjh2/${basepath}/someresource"

Le caractère ! Est utilisé pour les extensions d'historique dans l'invite de ligne de commande.
cela peut donc être un problème dans Invite mais pas dans les fichiers de script Shell.
comme vous pouvez le voir, les extensions d'historique fonctionnent même entre guillemets.

13
mug896

J'ai rencontré le même problème, et ma solution simple a été d'utiliser une variable:

E=!  
curl -v "http://example.org/${E}287s87asdjh2/somepath/someresource"

Ici, la simplicité est que (1) Il est portable à travers les shells et les commandes (2) Ne nécessite pas de connaître la syntaxe d'échappement et les codes ASCII.

9
Prem

Depuis Bash 4.3, vous pouvez désormais utiliser des guillemets doubles pour citer le caractère d'extension de l'historique:

$ bash --version
GNU bash, version 4.3...
[...]
$ echo "Hello World!"
Hello World!
3
Flimm

Pour ceux qui utilisent git bash dans Windows, la réponse acceptée de @DanielPittman fonctionne. Cependant, vous devez remplacer la barre oblique inverse (\) par une barre oblique (/).

Par exemple, sous unix, cela ressemblerait à quelque chose comme ceci:

curl https://abc.com/services -H 'Authorization: Bearer 111A80BBZZCnS\!ZR412543s'

Pour Windows, ce serait quelque chose comme ça (se concentrer sur la barre oblique dans la partie en-tête d'autorisation)

curl https://abc.com/services -H 'Authorization: Bearer 111A80BBZZCnS/!ZR412543s'

0
SamuelDev