Beispielsweise:
me$ FOO="BAR * BAR"
me$ echo $FOO
BAR file1 file2 file3 file4 BAR
und mit dem \
Escape-Zeichen:
me$ FOO="BAR \* BAR"
me$ echo $FOO
BAR \* BAR
Ich mache offensichtlich etwas Dummes.
Wie bekomme ich die Ausgabe BAR * BAR
?
Zitieren, wenn die Einstellung $FOO
nicht ausreicht. Sie müssen auch die Variablenreferenz angeben:
me$ FOO="BAR * BAR"
me$ echo "$FOO"
BAR * BAR
KURZE ANTWORT
Wie andere gesagt haben - Sie sollten immer die Variablen zitieren, um seltsames Verhalten zu verhindern. Also benutze echo "$ foo" in anstatt nur echo $ foo .
LANGE ANTWORT
Ich denke, dieses Beispiel verdient weitere Erklärung, da mehr los ist, als es auf den ersten Blick erscheinen mag.
Ich kann sehen, wo Ihre Verwirrung ins Spiel kommt, denn nachdem Sie Ihr erstes Beispiel ausgeführt haben, haben Sie sich wahrscheinlich gedacht, dass die Shell offensichtlich Folgendes tut:
Also von Ihrem ersten Beispiel:
Nach Parametererweiterung entspricht:
Und nach Dateinamenerweiterung ist gleichbedeutend mit:
Und wenn Sie nur tippen
echo BAR * BAR
in die Befehlszeile eingeben, werden Sie sehen, dass sie gleichwertig sind.Sie haben sich also wahrscheinlich gedacht: "Wenn ich dem * entkomme, kann ich die Dateinamenerweiterung verhindern."
Also aus Ihrem zweiten Beispiel:
Nach der Parametererweiterung sollte äquivalent sein zu:
Und nach der Dateinamenerweiterung sollte gleichbedeutend sein mit:
Und wenn Sie versuchen, "echo BAR \ * BAR" direkt in die Befehlszeile einzugeben, wird tatsächlich "BAR * BAR" ausgegeben, da die Dateinamenerweiterung durch das Escape verhindert wird.
Warum hat die Verwendung von $ foo nicht funktioniert?
Dies liegt daran, dass eine dritte Erweiterung stattfindet - das Entfernen von Angeboten. Aus der Bash-manuellen Angebotsentfernung geht Folgendes hervor:
Wenn Sie den Befehl direkt in die Befehlszeile eingeben, ist das Escape-Zeichen nicht das Ergebnis einer vorherigen Erweiterung. BASH entfernt es also, bevor es an den Echo-Befehl gesendet wird. Im zweiten Beispiel war das "\ *" das Ergebnis einer vorherigen Parametererweiterung, daher wird es NICHT entfernt. Infolgedessen erhält das Echo "\ *" und druckt es aus.
Beachten Sie den Unterschied zwischen dem ersten Beispiel - "*" ist nicht in den Zeichen enthalten, die durch Entfernen von Anführungszeichen entfernt werden.
Ich hoffe das macht Sinn. Am Ende die Schlussfolgerung in der gleichen - verwenden Sie einfach Anführungszeichen. Ich dachte nur, ich würde erklären, warum Escape, was logischerweise funktionieren sollte, wenn nur die Erweiterung von Parameter und Dateiname im Spiel ist, nicht funktioniert.
Eine vollständige Erläuterung der BASH-Erweiterungen finden Sie unter:
http://www.gnu.org/software/bash/manual/bashref.html#Shell-Expansions
quelle
Ich werde diesem alten Thread etwas hinzufügen.
Normalerweise würden Sie verwenden
Ich hatte jedoch auch mit dieser Syntax Probleme. Betrachten Sie das folgende Skript.
Die
*
müssen wörtlich weitergegeben werdencurl
, aber die gleichen Probleme werden auftreten. Das obige Beispiel funktioniert nicht (es wird auf Dateinamen im aktuellen Verzeichnis erweitert) und auch nicht\*
. Sie können auch nicht zitieren,$curl_opts
da dies als einzelne (ungültige) Option für erkannt wirdcurl
.Daher würde ich die Verwendung der
bash
Variablen empfehlen$GLOBIGNORE
, um die Dateinamenerweiterung insgesamt zu verhindern, wenn sie auf das globale Muster angewendet wird, oder dasset -f
integrierte Flag verwenden.Anwendung auf Ihr ursprüngliches Beispiel:
quelle
SELECT * FROM etc.
, dass dies der einzige Weg ist, der funktioniert.quelle
quelle
Es kann sich lohnen, sich daran zu gewöhnen,
printf
eher alsecho
auf der Kommandozeile zu verwenden.In diesem Beispiel bietet es nicht viel Nutzen, kann aber bei komplexeren Ausgaben nützlicher sein.
quelle