Eine nicht zitierte Variable (wie in $var
) oder Befehlssubstitution (wie in $(cmd)
oder `cmd`
) ist der Operator split + glob in Bourne-ähnlichen Shells.
Das heißt, ihr Inhalt wird gemäß dem aktuellen Wert der $IFS
Sondervariablen aufgeteilt (die standardmäßig die Zeichen für Leerzeichen, Tabulatoren und Zeilenumbrüche enthält).
Und dann unterliegt jedes Wort, das sich aus dieser Aufteilung ergibt, der Dateinamengenerierung (auch als Globbing oder Dateinamenerweiterung bezeichnet ), dh sie werden als Muster betrachtet und auf die Liste der Dateien erweitert, die diesem Muster entsprechen.
Also for i in $(xrandr)
, die $(xrandr)
, weil sie nicht in Anführungszeichen sind, wird aufgeteilt auf Sequenzen von Raum, Tab und Zeilenumbrüchen. Und jedes Wort, das sich aus dieser Aufteilung ergibt, wird auf übereinstimmende Dateinamen überprüft (oder so belassen, als ob sie keiner Datei entsprechen) und for
alle durchlaufen.
In for i in "$(xrandr)"
wird der Operator split + glob nicht verwendet, da die Befehlssubstitution in Anführungszeichen gesetzt wird. Daher gibt es in der Schleife einen Durchgang für einen Wert: die Ausgabe von xrandr
(ohne die nachgestellten Zeilenumbruchzeichen, die Substitutionsstreifen befehlen ).
Jedoch in echo $i
, $i
wieder unquoted, also wieder der Inhalt der $i
geteilt ist und je nach Dateinamen Generation und diese werden als getrennte Argumente an den übergebenen echo
Befehl (und echo
gibt seine Argumente durch Leerzeichen getrennt sind).
So gelernt Lektion:
- Wenn Sie keine Wortteilung oder Dateinamengenerierung wünschen , geben Sie immer Variablenerweiterungen und Befehlsersetzungen an
- Wenn Sie eine Wortaufteilung oder Dateinamengenerierung wünschen , lassen Sie sie nicht in Anführungszeichen, sondern stellen Sie sie
$IFS
entsprechend ein und / oder aktivieren oder deaktivieren Sie die Dateinamengenerierung, falls erforderlich ( set -f
, set +f
).
Wenn Sie in Ihrem obigen Beispiel die leere, getrennte Liste von Wörtern in der Ausgabe von xrandr
durchlaufen möchten , müssen Sie normalerweise Folgendes tun:
- verlassen
$IFS
auf seinem Standardwert (oder löschen) zu Split auf Zuschnitte
- Verwenden Sie
set -f
diese Option, um die Dateinamengenerierung zu deaktivieren, es sei denn, Sie sind sicher, dass xrandr
niemals ein *
oder ?
mehrere [
Zeichen ausgegeben werden (dies sind Platzhalter, die in Dateinamengenerierungsmustern verwendet werden).
Verwenden Sie dann nur den Operator split + glob (lassen Sie die Befehlssubstitution oder die Variablenerweiterung nur ohne Anführungszeichen) im in
Teil der for
Schleife:
set -f; unset -v IFS
for i in $(xrandr); do whatever with "$i"; done
Wenn Sie die (nicht leeren) Zeilen der xrandr
Ausgabe $IFS
durchlaufen möchten , müssen Sie das Zeilenumbruchzeichen festlegen:
IFS='
'