GNU/Linux >> LINUX-Kenntnisse >  >> Linux

In Anführungszeichen gesetzte vs. nicht in Anführungszeichen gesetzte Zeichenfolgenerweiterung?

  1. for i in $(xrandr); do echo "$i" ; done
  2. for i in "$(xrandr)"; do echo "$i"; done
  3. 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, dass xrandr gibt niemals * aus oder ? oder [ Zeichen (die Platzhalter sind, die in Dateinamen-Generierungsmustern verwendet werden)
Verwandt:Db2 – Finden Sie die Verbindungszeichenfolge für eine DB2-Datenbank?

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='
'

Linux
  1. Wie ersetze ich eine Zeichenfolge in einer oder mehreren Dateien?

  2. Bash Brace Erweiterung &Variablen?

  3. String-Ersetzung mit einem Wörterbuch?

  4. Ist `~#` eine Tilde-Erweiterung von Bash?

  5. So teilen Sie eine Zeichenfolge in Bash-Skript auf

Bash Strings verketten

So prüfen Sie, ob eine Zeichenfolge in Bash eine Teilzeichenfolge enthält

Ersetzen von Zeichenfolgen in Bash

Bash-Scripting – String-Manipulation

Edierte Informationen

Wie füge ich diesem Curl-Befehl eine Variable hinzu?