Frage

zB.

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

und mit den "\" Escape-Zeichen:

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

Ich bin natürlich etwas zu tun dumm.

Wie bekomme ich die Ausgabe "BAR * BAR"?

War es hilfreich?

Lösung

Zitiert bei $ FOO Einstellung ist nicht genug. Sie müssen die variablen Referenz auch zitieren:

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

Andere Tipps

SHORT ANTWORT

Wie schon andere gesagt haben - sollten Sie immer die Variablen zitieren seltsame Verhalten zu verhindern. So verwenden echo "$ foo" in anstatt nur echo $ foo .

LONG ANTWORT

Das glaube ich dieses Beispiel weitere Erklärung garantiert, weil es mehr los ist, als es auf den ersten Blick es scheinen mag.

kann ich sehen, wo Ihre Verwirrung in da kommt, nachdem Sie Ihr erstes Beispiel lief Sie wahrscheinlich zu sich selbst dachte, dass die Schale offensichtlich tut:

  1. Parameter Erweiterung
  2. Dateierweiterung

So von Ihrem ersten Beispiel:

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

Nach Parameter Expansion entspricht:

me$ echo BAR * BAR

Und nach Dateinamen Expansion entspricht:

me$ echo BAR file1 file2 file3 file4 BAR

Und wenn Sie nur echo BAR * BAR in die Befehlszeile eingeben, werden Sie sehen, dass sie gleichwertig sind.

So werden Sie wahrscheinlich gedacht, um sich selbst „wenn ich die * entkommen, kann ich den Dateinamen Erweiterung verhindern“

So von Ihrem zweiten Beispiel:

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

Nach Parameter Expansion sollten gleichwertig sein:

me$ echo BAR \* BAR

Und nach Dateinamen Expansion sollten gleichwertig sein:

me$ echo BAR \* BAR

Und wenn Sie versuchen, die Eingabe von „echo BAR \ * BAR“ direkt in die Befehlszeile wird es in der Tat Druck „BAR * BAR“, weil der Dateinamen Erweiterung durch das Entweichen verhindert wird.

Warum also mit $ foo nicht?

Es ist, weil es eine dritte Erweiterung ist, die stattfindet - Quote Removal. Von der bash Entfernung manuell Zitat:

  

Nach den vorangegangenen Erweiterungen, die alle   unquoted Vorkommen der Zeichen   ‚\‘, ‚'‘ Und ‚'‘, das nicht zur Folge hat   aus einem der oben genannten Erweiterungen sind   entfernt.

Also, was passiert, wenn Sie den Befehl direkt in die Befehlszeile eingeben, ist das Escape-Zeichen nicht das Ergebnis einer vorherigen Expansion so BASH es entfernt, bevor es den Echo-Befehl, aber im zweiten Beispiel der „\ Senden *“war das Ergebnis einer vorherigen Parameter Expansion, so ist es nicht entfernt. Als Ergebnis erhält echo „\ *“ und das ist, was es gedruckt wird.

Beachten Sie den Unterschied zwischen dem ersten Beispiel -. „*“ Ist nicht in den Zeichen enthalten, die durch Quote Removal entfernt werden

Ich hoffe, das macht Sinn. Am Ende der Abschluss in der gleichen - nur Anführungszeichen verwenden. Ich dachte, ich würde erklären, warum, zu entkommen, was logisch funktionieren sollte, wenn nur Parameter und Dateierweiterung im Spiel sind, hat nicht funktioniert.

Für eine vollständige Erklärung der BASH-Erweiterungen finden Sie unter:

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

Ich werde ein wenig zu diesem alten Thread hinzufügen.

In der Regel würden Sie verwenden

$ echo "$FOO"

Allerdings habe ich Probleme, auch mit dieser Syntax hatte. Betrachten Sie das folgende Skript.

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

Die * muss wörtlich zu curl weitergegeben werden, aber die gleichen Probleme auftreten werden. Das obige Beispiel wird nicht funktionieren (es Dateinamen im aktuellen Verzeichnis erweitern) und wird weder \*. Sie können auch nicht $curl_opts zitieren, weil sie als einzige (ungültig) Option erkannt wird curl.

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

Deshalb würde ich die Verwendung der bash Variable $GLOBIGNORE empfiehlt Dateinamen Erweiterung gänzlich zu verhindern, wenn auf das globale Muster aufgebracht, oder verwenden Sie die set -f Einbau-Flagge.

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

Die Anwendung auf Ihrem ursprünglichen Beispiel:

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
FOO='BAR * BAR'
echo "$FOO"
echo "$FOO"

Es kann vielmehr mit printf immer in die Gewohnheit wert sein dann auf der Kommandozeile echo.

In diesem Beispiel ist es nicht viel Nutzen geben, aber es kann mit komplexeren Ausgabe nützlicher sein.

FOO="BAR * BAR"
printf %s "$FOO"
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top