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

Zitieren innerhalb von $ (command Substitution) in Bash?

In meiner Bash-Umgebung verwende ich Variablen, die Leerzeichen enthalten, und ich verwende diese Variablen innerhalb der Befehlsersetzung.

Wie zitiere ich meine Variablen richtig? Und wie soll ich das machen, wenn diese verschachtelt sind?

DIRNAME=$(dirname "$FILE")

oder zitiere ich außerhalb der Ersetzung?

DIRNAME="$(dirname $FILE)"

oder beides?

DIRNAME="$(dirname "$FILE")"

oder verwende ich Backticks?

DIRNAME=`dirname "$FILE"`

Was ist der richtige Weg, dies zu tun? Und wie kann ich einfach überprüfen, ob die Anführungszeichen richtig gesetzt sind?

Akzeptierte Antwort:

In der Reihenfolge vom Schlechtesten zum Besten:

  • DIRNAME="$(dirname $FILE)" wird nicht das tun, was Sie wollen, wenn $FILE enthält Leerzeichen (oder beliebige Zeichen $IFS enthält derzeit) oder Globbing-Zeichen [?* .
  • DIRNAME=`dirname "$FILE"` ist technisch korrekt, aber Backticks werden wegen der zusätzlichen Komplexität beim Verschachteln und der zusätzlichen Backslash-Verarbeitung, die darin stattfindet, nicht für die Befehlserweiterung empfohlen.
  • DIRNAME=$(dirname "$FILE") ist korrekt, aber nur, weil dies eine Zuweisung an eine skalare (nicht Array-) Variable ist. Wenn Sie die Befehlsersetzung in einem anderen Kontext verwenden, z. B. export DIRNAME=$(dirname "$FILE") oder du $(dirname -- "$FILE") , führt das Fehlen von Anführungszeichen zu Problemen, wenn das Ergebnis der Erweiterung Leerzeichen oder Globbing-Zeichen enthält.
  • DIRNAME="$(dirname "$FILE")" (mit Ausnahme des fehlenden -- , siehe unten) ist der empfohlene Weg. Sie können DIRNAME= ersetzen mit einem Befehl und einem Leerzeichen, ohne etwas anderes zu ändern, und dirname erhält den richtigen String.

Noch weiter verbessern:

  • DIRNAME="$(dirname -- "$FILE")" funktioniert wenn $FILE beginnt mit einem Bindestrich.
  • DIRNAME="$(dirname -- "$FILE" && printf x)" && DIRNAME="${DIRNAME%?x}" || exit funktioniert auch wenn $FILE Der Dirname endet mit einem Zeilenumbruch, da $() schneidet Zeilenumbrüche am Ende der Ausgabe ab, sowohl die von dirname hinzugefügten und diejenigen, die Teil der eigentlichen Daten sein können.

Sie können Befehlserweiterungen beliebig verschachteln. Mit $() Sie erstellen immer einen neuen Zitierkontext, sodass Sie beispielsweise Folgendes tun können:

foo "$(bar "$(baz "$(ban "bla")")")"

Du nicht möchte das mit Backticks versuchen.


Linux
  1. Der „eval“-Befehl in Bash?

  2. apachectl von bash starten

  3. Bash-Exportbefehl

  4. Exit-Code der Variablenzuweisung zur Befehlsersetzung in Bash

  5. Führen Sie den Bash-Befehl auf der Jenkins-Pipeline aus

Verlaufsbefehl in Linux (Bash-Verlauf)

Bash Exit-Befehl und Exit-Codes

Bash-printf-Befehl

Bash-Skripting (II)

Bash-Scripting(III)

Verwenden des Linux-Dirname-Befehls in Bash-Skripten