ich kann schreiben
VAR=$VAR1
VAR=${VAR1}
VAR="$VAR1"
VAR="${VAR1}"
Das Endergebnis scheint mir alle ungefähr gleich zu sein. Warum soll ich den einen oder anderen schreiben? Sind einige davon nicht portabel / POSIX?
quelle
ich kann schreiben
VAR=$VAR1
VAR=${VAR1}
VAR="$VAR1"
VAR="${VAR1}"
Das Endergebnis scheint mir alle ungefähr gleich zu sein. Warum soll ich den einen oder anderen schreiben? Sind einige davon nicht portabel / POSIX?
VAR=$VAR1
ist eine vereinfachte Version von VAR=${VAR1}
. Es gibt Dinge, die der zweite tun kann, die der erste nicht kann, zum Beispiel einen Array-Index referenzieren (nicht portierbar) oder eine Teilzeichenfolge entfernen (POSIX-portierbar). Siehe die Mehr zu Variablen Abschnitt des Bash Leitfaden für Anfänger und Parameter Expansion in der POSIX - Spezifikation.
Die Verwendung von Anführungszeichen um eine Variable wie in rm -- "$VAR1"
oder rm -- "${VAR}"
ist eine gute Idee. Dies macht den Inhalt der Variablen zu einer atomaren Einheit. Wenn der Variablenwert Leerzeichen (also Zeichen in der $IFS
Sondervariable, standardmäßig Leerzeichen) oder Globenzeichen enthält und Sie ihn nicht in Anführungszeichen setzen, wird jedes Wort für die Generierung von Dateinamen (Globenzeichen) in Betracht gezogen, dessen Erweiterung beliebig viele Argumente liefert mache.
$ find .
.
./*r*
./-rf
./another
./filename
./spaced filename
./another spaced filename
./another spaced filename/x
$ var='spaced filename'
# usually, 'spaced filename' would come from the output of some command and you weren't expecting it
$ rm $var
rm: cannot remove 'spaced': No such file or directory
# oops! I just ran 'rm spaced filename'
$ var='*r*'
$ rm $var
# expands to: 'rm' '-rf' '*r*' 'another spaced filename'
$ find .
.
./another
./spaced filename
./another spaced filename
$ var='another spaced filename'
$ rm -- "$var"
$ find .
.
./another
./spaced filename
Zur Portabilität: Gemäß POSIX.1-2008 Abschnitt 2.6.2 sind die geschweiften Klammern optional.
var1=$var
Erweiterung einen Fehler verursacht?export VAR=$VAR1
. Die geschweiften Klammern sind optional (siehe den vierten Absatz des Abschnitts, den Sie zitiert haben; dies ist bei allen Schalen vor POSIX und POSIX der Fall).${VAR}
und$VAR
sind genau gleichwertig. Für eine einfache Variablenerweiterung ist der einzige Grund zu verwenden,${VAR}
wenn beim Parsen ansonsten zu viele Zeichen in den Variablennamen${VAR1}_$VAR2
eingehen würden , wie in (was ohne geschweifte Klammern äquivalent wäre${VAR1_}$VAR2
). Die meisten geschmückt Erweiterungen (${VAR:=default}
,${VAR#prefix}
, ...) erfordern Klammern.In einer Variablenzuweisung, Feldaufspaltung (dh Spaltung bei Leerraum im Wert) und Pfadnamenerweiterung (dh Globbing) ausgeschaltet sind, so
VAR=$VAR1
genau entsprichtVAR="$VAR1"
, in allen POSIX Muscheln und in alle pre-POSIX sh , die ich habe gehört , von . (POSIX ref: einfache Befehle ). Legt aus demselben GrundVAR=*
zuverlässigVAR
die Literalzeichenfolge fest*
. NatürlichVAR=a b
setztVAR
auf ,a
da dasb
ist ein separates Wort an erster Stelle. Im Allgemeinen sind doppelte Anführungszeichen nicht erforderlich, wenn die Shell-Syntax ein einzelnes Wort erwartet, zum Beispiel incase … in
(aber nicht im Muster), aber auch dort müssen Sie vorsichtig sein: POSIX gibt dies zum Beispiel anUmleitungsziele (>$filename
) erfordern keine Anführungszeichen in Skripten, aber einige Shells, einschließlich Bash, erfordern die doppelten Anführungszeichen sogar in Skripten. Siehe Wann sind doppelte Anführungszeichen erforderlich? für eine gründlichere Analyse.Sie benötigen die doppelten Anführungszeichen in anderen Fällen, insbesondere in
export VAR="${VAR1}"
(was äquivalent geschrieben werden kannexport "VAR=${VAR1}"
) in vielen Shells (POSIX lässt diesen Fall offen). Aufgrund der Ähnlichkeit dieses Falls mit einfachen Zuweisungen und der Streuung der Liste der Fälle, in denen Sie keine doppelten Anführungszeichen benötigen, empfehle ich, nur doppelte Anführungszeichen zu verwenden, es sei denn, Sie möchten splitten und globieren.quelle
IFS
Zeichen enthält, weil ich es mir zur Gewohnheit machen möchte. Die einzige Ausnahme ist, dass ich den Wert bei einer Variablenzuweisung nicht zitiere (sofern nicht erforderlich, z. B. wenn der Wert ein Leerzeichen enthält). Dies macht die Hervorhebung der Editor-Syntax nützlicher, wenn Befehlssubstitutionen wie zFOO=$(BAR=$(BAZ=blah; printf %s "${BAZ}"); printf %s "${BAR}")
. Anstatt alles in der "String" -Farbe zu färben, erhalte ich eine Syntaxhervorhebung des verschachtelten Codes. Deshalb vermeide ich auch Backticks.>$file
in POSIX - Skripte in Ordnung ist, ist es in der Bash nicht einmal , wenn nicht-interaktive (es sei denn , POSIX Einhaltung erzwungen wird$POSIXLY_CORRECT
oder--posix
...).VAR=$VAR1
, aber ich war manchmal überraschtlocal VAR=$VAR1
, weil ich mich erinnere, dass ich in mancher Hinsicht anders gearbeitet habe, zumindest in einigen Shells. Aber atm, ich kann die Divergenz nicht reproduzieren.local VAR=$VAR1
ist wieexport VAR=$VAR1
, es kommt auf die Shell an.Zitat
Bedenken Sie, dass für die variable Erweiterung das doppelte Anführungszeichen und für die starke Anführungszeichen, dh ohne Erweiterung, das einfache Anführungszeichen verwendet wird.
Erweiterung:
Ausgabe:
Es kann sinnvoll sein, zu erwähnen, dass Sie aus verschiedenen Gründen, wo immer möglich, Zitate verwenden sollten, von denen die besten sind, dass sie als Best Practice gelten, und aus Gründen der Lesbarkeit. Auch, weil Bash zuweilen skurril ist und häufig für unlogisch oder unvernünftig / unerwartet erscheinende Wege und das Ändern von impliziten Erwartungen zu explizit, was diese Fehlerfläche (oder das Potenzial dafür) reduziert.
Und obwohl es völlig legal ist, nicht zu zitieren, und in den meisten Fällen funktioniert, wird diese Funktionalität aus Bequemlichkeitsgründen bereitgestellt und ist wahrscheinlich weniger portabel. Die vollständig formale Praxis, die die Absicht und Erwartung widerspiegelt, ist das Zitieren.
Auswechslung
Bedenken Sie nun auch, dass das Konstrukt
"${somevar}"
für Substitutionsoperationen verwendet wird. Mehrere Anwendungsfälle, z. B. Ersatz und Arrays.Ersatz (Abisolieren):
Ersatz (Ersatz):
Arrays:
All dies kratzt kaum an der Oberfläche des
"${var}"
Substitutionskonstrukts. Die endgültige Referenz für Bash-Shell-Skripte ist die libre-Online-Referenz TLDP The Linux Documentation Projecthttps://www.tldp.org/LDP/abs/html/parameter-substitution.html
quelle
ende dann:
Erwähnenswert als klareres Beispiel für die Verwendung von Locken
quelle