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

Muss ich Befehlssubstitutionen in Anführungszeichen setzen, wenn ich ihre Ausgabe einer Variablen zuweise?

Auf diese Frage gibt es hier bereits eine Antwort :Wann sind doppelte Anführungszeichen erforderlich?

(1 Antwort)
Vor 4 Jahren geschlossen.

Ich neige dazu, Befehlsersetzungen wie unten gezeigt zu zitieren, selbst wenn ihre Ausgabe einer Variablen zugewiesen wird:

var="$(command)"

Ist das aber wirklich nötig? Wann bricht es? Die akzeptierte Antwort hier behauptet:

DIRNAME="$(dirname $FILE)" wird nicht das tun, was Sie wollen, wenn $FILE Leerzeichen oder Globbing-Zeichen [?*.

enthält

Der Link verweist auf die großartige Seite von Grey Cat Wiki über das Zitieren, aber diese Seite erwähnt nicht speziell das Zitieren von Befehlssubstitutionen. Und während Sie die Variable zitieren ist eindeutig erforderlich, das Zitieren der Befehlsersetzung selbst scheint nicht erforderlich zu sein.

Derselbe Beitrag endet jedoch mit:

DIRNAME="$(dirname "$FILE")" ist der empfohlene Weg. Sie können DIRNAME=durch einen Befehl und ein Leerzeichen ersetzen, ohne etwas anderes zu ändern, und dirname erhält den richtigen String.

Das habe ich auch immer gedacht und hier oft Beiträge korrigiert, die es nicht zitiert haben. Die oben verlinkte Wiki-Seite behauptet jedoch auch, dass:

Es gibt einige Fälle, in denen doppelte Anführungszeichen getrost weggelassen werden können:

Auf der rechten Seite einer einfachen Aufgabe. Sie können foo=$bar ohne Anführungszeichen schreiben. Dies ist POSIX-kompatibel.

[. . . ]

Während var=$(command) ist keine wirklich „einfache“ Aufgabe, ich konnte trotzdem keinen Fall finden, wo die Anführungszeichen wirklich nötig wären:

$ var=$(echo "foo bar baz")  ## whitespace works
$  echo "$var"
foo bar baz

$ var=$(printf "foonbar * baz") ## so do globbing characters
$ echo "$var"
foo
bar * baz

$ var1="foonbar * baz"
$ var=$(printf "$var1")  ## printing a variable doesn't make any difference
$ echo "$var" 
foo
bar * baz

$ var=$(printf '%sn' "$var1")
$ echo "$var"
foonbar * baz

$ var=$(printf -- '-e %sn' "$var1") ## strings starting with - also work
$ echo "$var"
-e foonbar * baz

Natürlich sind die Anführungszeichen absolut notwendig, wenn die Befehlsersetzung direkt für Dinge wie command1 "$(command2)" verwendet wird , aber das scheint bei der Zuweisung an eine Variable nicht der Fall zu sein.

Also, was verpasse ich? Werden die Anführungszeichen jemals benötigt? Welcher Sonderfall wird das Zitieren einer Befehlsersetzung beim Zuweisen ihres Rückgabewerts zu einer Variablen sein? davor beschützen? Oder ist es immer in Ordnung, eine Befehlsersetzung nicht in Anführungszeichen zu setzen, wenn sie die rechte Seite einer Variablenzuweisungsoperation ist?

Akzeptierte Antwort:

Als eine Referenz ist das Bash-Handbuch diesbezüglich klar:

Eine Variable kann durch eine Anweisung der Form

zugewiesen werden

name=[value]

Wenn kein Wert angegeben ist, wird der Variablen der Null-String zugewiesen. Alle Werte werden einer Tilde-Erweiterung, einer Parameter- und Variablen-Erweiterung, einer Befehlsersetzung, einer arithmetischen Erweiterung und einer Entfernung von Anführungszeichen unterzogen (siehe unten). […] Wortaufteilung wird nicht durchgeführt , mit Ausnahme von „[E-Mail geschützt]“, wie unten erläutert. Dateinamenerweiterung wird nicht durchgeführt.

Keine Worttrennung, keine Dateinamenerweiterung, daher keine Anführungszeichen erforderlich.

Verwandte:PostgreSQL psql-Befehlszeilentool und SET CONSTRAINTS DEFERRED?

Wie bei POSIX, Abschnitt 2.9.1 Einfache Befehle:

2. Die Wörter, die keine variablen Zuweisungen oder Umleitungen sind, werden erweitert. Wenn nach ihrer Erweiterung irgendwelche Felder übrig bleiben. Wenn nach ihrer Erweiterung irgendwelche Felder übrig bleiben, soll das erste Feld als Befehlsname betrachtet werden und die restlichen Felder sind die Argumente für den Befehl.
[…]
4. Jede Variablenzuweisung soll für Tilde-Erweiterung, Parameter-Erweiterung, Befehlsersetzung, arithmetische Erweiterung und Entfernung von Anführungszeichen erweitert werden, bevor der Wert zugewiesen wird.

Ich bin mir nicht sicher, ob das so interpretiert werden soll, dass die Feldaufteilung nur für Erweiterungen erfolgt, die in Schritt 2 durchgeführt wurden? Schritt 4 nicht Erwähnen Sie die Feldaufteilung, obwohl der Abschnitt über die Feldaufteilung ebenfalls keine Variablenzuweisungen als Ausnahme zur Erzeugung mehrerer Felder erwähnt.


Linux
  1. tee-Befehlsbeispiele in Linux

  2. Ausgabe des letzten Befehls automatisch mit Bash in eine Variable erfassen?

  3. Das Umleiten der Befehlsausgabe an eine Variable in Bash schlägt fehl

  4. Wandeln Sie eine Ausgabe in einen String um

  5. Wie werden Zeilenumbrüche beibehalten, wenn die Befehlsausgabe in einer Variablen gespeichert wird?

So weisen Sie einer Variablen die Ausgabe eines Linux-Befehls zu

Ccat – Cat-Befehlsausgabe einfärben

Zwingen Sie Benutzer, das Root-Passwort anstelle ihres eigenen Passworts zu verwenden, wenn Sie den Sudo-Befehl verwenden

Wie verstecke ich die Terminalausgabe beim Ausführen eines Befehls?

Beispiele für Linux-Echo-Befehle

Alle Zeilenumbrüche werden entfernt, wenn die cat-Ausgabe in einer Variablen gespeichert wird