for i in $(xrandr); do echo "$i" ; done
for i in "$(xrandr)"; do echo "$i"; done
for i in "$(xrandr)"; do echo $i; done
Ich verstehe, warum sich 1 von 2 unterscheidet. Aber warum gibt 3 eine andere Ausgabe als 2? Bitte erläutern Sie auch die Ausgabe. Wie funktionieren Anführungszeichen bei Zeilenumbrüchen?
Akzeptierte Antwort:
Eine Variable ohne Anführungszeichen (wie in $var
) oder Befehlsersetzung (wie in $(cmd)
oder `cmd`
) ist split+glob Operator in Bourne-ähnlichen Shells.
Das heißt, ihr Inhalt wird gemäß dem aktuellen Wert von $IFS
aufgeteilt Sondervariable (die standardmäßig Leerzeichen, Tabulatoren und Zeilenumbrüche enthält)
Und dann wird jedes aus dieser Teilung resultierende Wort einer Dateinamengenerierung unterzogen (auch bekannt als Globbing oder Dateinamenerweiterung ), das heißt, sie werden als Muster betrachtet und auf die Liste der Dateien erweitert, die diesem Muster entsprechen.
Also in for i in $(xrandr)
, der $(xrandr)
, da es nicht in Anführungszeichen steht, wird auf Sequenzen von Leerzeichen, Tabulatoren und Zeilenumbrüchen aufgeteilt. Und jedes Wort, das sich aus dieser Aufteilung ergibt, wird auf übereinstimmende Dateinamen geprüft (oder unverändert gelassen, wenn sie mit keiner Datei übereinstimmen) und for
Schleifen über sie alle.
In for i in "$(xrandr)"
verwenden wir den split+glob-Operator nicht als Befehlsersetzung wird in Anführungszeichen gesetzt, also gibt es einen Durchlauf in der Schleife auf eins value:die Ausgabe von xrandr
(ohne die abschließenden Newline-Zeichen, die Ersetzungen befehlen Streifen).
Allerdings in echo $i
, $i
wird wieder nicht in Anführungszeichen gesetzt, also wieder der Inhalt von $i
wird geteilt und unterliegt der Dateinamengenerierung und diese werden als separate Argumente an echo
übergeben Befehl (und echo
gibt seine Argumente getrennt durch Leerzeichen aus).
Also Lektion gelernt:
- wenn Sie keine Wortaufteilung möchten oder Dateinamengenerierung , Variablenerweiterungen und Befehlsersetzungen immer in Anführungszeichen setzen
- wenn Sie eine Wortaufteilung wünschen oder Dateinamengenerierung , lassen Sie sie ohne Anführungszeichen, aber setzen Sie
$IFS
entsprechend und/oder aktivieren oder deaktivieren Sie die Generierung von Dateinamen, falls erforderlich (set -f
,set +f
).
Typischerweise in Ihrem obigen Beispiel, wenn Sie die leere getrennte Liste von Wörtern in der Ausgabe von xrandr
durchlaufen möchten , müssten Sie:
$IFS
verlassen bei seinem Standardwert (oder setzen Sie ihn nicht), um bei Leerzeichen aufzuteilen- Verwenden Sie
set -f
um die Generierung von Dateinamen zu deaktivieren, es sei denn, Sie sind sicher, dassxrandr
gibt niemals*
aus oder?
oder[
Zeichen (die Platzhalter sind, die in Dateinamen-Generierungsmustern verwendet werden)
Und verwenden Sie dann nur den Split+Glob-Operator (lassen Sie nur die Befehlsersetzung oder die Variablenerweiterung ohne Anführungszeichen) im in
Teil des for
Schleife:
set -f; unset -v IFS
for i in $(xrandr); do whatever with "$i"; done
Wenn Sie die (nicht leeren) Zeilen durchlaufen möchten des xrandr
Ausgabe müssen Sie $IFS
setzen zum Newline-Zeichen:
IFS='
'