170 votes

Comment puis-je échapper à la générique/astérisque en bash?

par exemple.

me$ FOO="BAR * BAR"
me$ echo $FOO
BAR file1 file2 file3 file4 BAR

et en utilisant le "\" caractère d'échappement:

me$ FOO="BAR \* BAR"
me$ echo $FOO
BAR \* BAR

Je suis évidemment faire quelque chose de stupide.

Comment puis-je obtenir la sortie "BAR * BAR" ?

176voto

finnw Points 24592

Citant lors de la configuration de $FOO n'est pas assez. Vous devrez citer la référence de variable:

me$ FOO="BAR * BAR"
me$ echo "$FOO"
BAR * BAR

126voto

mithu Points 368

RÉPONSE COURTE

Comme d'autres l'ont dit -, vous devez toujours citer les variables afin de prévenir des comportements étranges. Donc, utilisez echo "$foo" , au lieu de simplement echo $foo.

RÉPONSE LONGUE

Je pense que cet exemple mérite une explication, car il ya plus de choses qu'il ne paraît sur le visage de celui-ci.

Je peux voir où votre confusion vient de parce que, après vous avez effectué votre premier exemple, vous avez probablement pensé à vous-même que la coquille est de toute évidence en train de faire:

  1. Paramètre d'extension
  2. Nom du fichier d'extension

Donc, à partir de votre premier exemple:

me$ FOO="BAR * BAR"
me$ echo $FOO

Après le paramètre d'expansion est équivalent à:

me$ echo BAR * BAR

Et après le nom de fichier d'extension est équivalent à:

me$ echo BAR file1 file2 file3 file4 BAR

Et si vous tapez juste *echo * BAR* BAR dans la ligne de commande, vous verrez qu'ils sont équivalents.

Donc, vous avez probablement pensé à vous-même "si je échapper à l' *, je ne peux empêcher le nom du fichier d'extension"

Donc, à partir de votre deuxième exemple:

me$ FOO="BAR \* BAR"
me$ echo $FOO

Paramètre après l'expansion devrait être équivalente à:

me$ echo BAR \* BAR

Et après le nom de fichier d'extension doit être équivalente à:

me$ echo BAR \* BAR

Et si vous essayez de taper "echo BAR \* BAR" directement dans la ligne de commande, il sera en effet l'impression de "BAR * BAR" parce que le nom de fichier d'extension est empêché par la fuite.

Alors, pourquoi à l'aide de $foo pas de travail?

C'est parce qu'il y a une troisième extension qui prend la place de Devis Déménagement. À partir du bash manuel de devis déménagement est:

Après les précédentes extensions, toutes les non cotées occurrences des caractères ‘ \ ', ‘ 'et ‘"' qui n'ont pas abouti à partir de l'une de ces extensions sont à l' supprimé.

Donc ce qui se passe lorsque vous tapez la commande directement dans la ligne de commande, le caractère d'échappement n'est pas le résultat d'une précédente expansion de BASH le supprime avant de l'envoyer à la commande echo, mais dans le 2ème exemple, le "\*" est le résultat d'un Paramètre précédent expansion, de sorte qu'il n'est PAS supprimé. En conséquence, l'echo reçoit "\*" et c'est ce qu'il imprime.

Notez la différence entre le premier exemple - "*" n'est pas inclus dans les caractères qui seront supprimés par Devis de Déménagement.

J'espère que cela a du sens. À la fin de la conclusion, dans le même - il suffit d'utiliser les guillemets. J'ai juste pensé que je voudrais vous expliquer pourquoi s'en échappe, ce qui logiquement devrait fonctionner si seul Paramètre et le nom de fichier d'extension sont en jeu, n'a pas fonctionné.

Pour une explication complète de BASH expansions, reportez-vous à:

http://www.gnu.org/software/bash/manual/bashref.html#Shell-Expansions

68voto

AlexandreH Points 71

Je vais ajouter un peu de ce vieux fil.

Habituellement, vous devez utiliser

$ echo "$FOO"

Cependant, j'ai eu des problèmes avec cette syntaxe. Considérons le script suivant.

#!/bin/bash
curl_opts="-s --noproxy * -O"
curl $curl_opts "$1"

L' * doit être transmis verbatim d' curl, mais les mêmes problèmes vont se poser. L'exemple ci-dessus ne fonctionne pas (il se développera pour les noms de fichiers dans le répertoire courant), ni \*. Vous aussi vous ne pouvez pas citer $curl_opts car il sera reconnu comme un seul (invalides) option d' curl.

curl: option -s --noproxy * -O: is unknown
curl: try 'curl --help' or 'curl --manual' for more information

Par conséquent, je recommande l'utilisation de l' bash variable $GLOBIGNORE pour prévenir l'extension de nom de fichier s'applique à la structure mondiale, ou de l'utilisation de l' set -f intégré dans le pavillon.

#!/bin/bash
GLOBIGNORE="*"
curl_opts="-s --noproxy * -O"
curl $curl_opts "$1"  ## no filename expansion

L'application pour votre exemple d'origine:

me$ FOO="BAR * BAR"

me$ echo $FOO
BAR file1 file2 file3 file4 BAR

me$ set -f
me$ echo $FOO
BAR * BAR

me$ set +f
me$ GLOBIGNORE=*
me$ echo $FOO
BAR * BAR

6voto

tzot Points 32224
FOO='BAR * BAR'
echo "$FOO"

3voto

Rafał Dowgird Points 16600
echo "$FOO"

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X