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 fais évidemment quelque chose de stupide.
Comment obtenir la sortie BAR * BAR
?
RÉPONSE COURTE
Comme d'autres l'ont dit, vous devez toujours citer les variables pour éviter un comportement étrange. Utilisez donc echo "$ foo" au lieu de simplement echo $ foo .
LONGUE RÉPONSE
Je pense que cet exemple mérite des explications supplémentaires, car il se passe plus qu'il n'y paraît à première vue.
Je peux voir d'où vient votre confusion, car après avoir exécuté votre premier exemple, vous vous êtes probablement dit que le shell faisait évidemment:
Donc à partir de votre premier exemple:
Après l'expansion des paramètres équivaut à:
Et après l'extension du nom de fichier, cela équivaut à:
Et si vous tapez simplement
echo BAR * BAR
dans la ligne de commande, vous verrez qu'ils sont équivalents.Alors vous vous êtes probablement dit "si j'échappe au *, je peux empêcher l'expansion du nom de fichier"
Donc, à partir de votre deuxième exemple:
Après l'expansion des paramètres doit être équivalent à:
Et après l'expansion du nom de fichier devrait être équivalent à:
Et si vous essayez de taper "echo BAR \ * BAR" directement dans la ligne de commande, cela affichera en effet "BAR * BAR" car l'expansion du nom de fichier est empêchée par l'échappement.
Alors pourquoi l'utilisation de $ foo n'a-t-elle pas fonctionné?
C'est parce qu'il y a une troisième extension qui a lieu - Quote Removal. De la suppression manuelle des devis bash est:
Donc ce qui se passe, c'est que lorsque vous tapez la commande directement dans la ligne de commande, le caractère d'échappement n'est pas le résultat d'une expansion précédente donc BASH le supprime avant de l'envoyer à la commande echo, mais dans le 2ème exemple, le "\ *" était le résultat d'une expansion de paramètre précédente, il n'est donc PAS supprimé. En conséquence, 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 la suppression de devis.
J'espère que cela a du sens. En fin de compte, la conclusion est la même - utilisez simplement des guillemets. J'ai juste pensé expliquer pourquoi échapper, ce qui devrait logiquement fonctionner si seules les extensions de paramètres et de noms de fichiers sont en jeu, ne fonctionnait pas.
Pour une explication complète des extensions BASH, reportez-vous à:
http://www.gnu.org/software/bash/manual/bashref.html#Shell-Expansions
la source
Je vais ajouter un peu à ce vieux fil.
Habituellement, vous utiliseriez
Cependant, j'ai eu des problèmes même avec cette syntaxe. Considérez le script suivant.
Les
*
besoins doivent être transmis mot pour motcurl
, mais les mêmes problèmes se poseront. L'exemple ci-dessus ne fonctionnera pas (il s'étendra aux noms de fichiers dans le répertoire actuel) et ni l'un ni l'autre\*
. Vous ne pouvez pas non plus citer$curl_opts
car il sera reconnu comme une option unique (non valide) decurl
.Par conséquent, je recommanderais l'utilisation de la
bash
variable$GLOBIGNORE
pour empêcher complètement l'expansion du nom de fichier si elle est appliquée au modèle global, ou utilisez l'set -f
indicateur intégré.S'appliquant à votre exemple d'origine:
la source
SELECT * FROM etc.
c'est la seule façon qui fonctionne.la source
la source
Il vaut peut-être la peine de prendre l'habitude d'utiliser
printf
plutôt queecho
sur la ligne de commande.Dans cet exemple, cela ne donne pas beaucoup d'avantages, mais cela peut être plus utile avec une sortie plus complexe.
la source