Kann ich Anführungszeichen auf der rechten Seite einer lokalen Zuordnung sicher weglassen?
function foo {
local myvar=${bar}
stuff()
}
Ich interessiere mich hauptsächlich für bash
, aber jede Information über Eckfälle in anderen Schalen ist willkommen.
shell-script
quoting
assignment
rahmu
quelle
quelle
Antworten:
Zitate sind erforderlich in
export foo="$var"
oderlocal foo="$var"
(oderreadonly
,typeset
,declare
und anderen Variablen deklarieren Befehle ) in:dash
sh
von NetBSD (auch basierend auf der Almquist-Shell).sh
von FreeBSD 9.2 oder älter (siehe die Änderung in 9.3 )yash
zsh
mit Versionen vor 5.1 inksh
odersh
Emulation (oder fürexport var="$(cmd)"
wozsh
sonst Wortteilung durchführen würde (nicht Globbing)).Da ansonsten die Variablenerweiterung einer Wortteilung und / oder Dateinamenerzeugung unterworfen wäre, wie bei jedem Argument für einen anderen Befehl.
Und werden nicht benötigt in:
bash
ksh
(alle Implementierungen)sh
von FreeBSD 9.3 oder neuersh
(seit 2005)zsh
In
zsh
wird split + glob nie bei der Parametererweiterung ausgeführt, es sei denn, insh
oderksh
Emulation, aber split (nicht glob) wird bei der Befehlssubstitution ausgeführt. Seit Version 5.1 sindexport
/local
und andere Deklarationsbefehle wie in den anderen oben genannten Shells Dual Keyword / Builtin- Befehle, was bedeutet, dass keine Anführungszeichen erforderlich sind, auch nicht insh
/ksh
emuliert und auch nicht für die Befehlssubstitution.Es gibt spezielle Fälle, in denen ein Zitieren auch in diesen Shells erforderlich ist, obwohl:
Oder allgemeiner, links , wenn etwas von der
=
(einschließlich der=
) notiert wird oder das Ergebnis einer Expansion (wieexport 'foo'="$var"
,export foo\="$var"
oderexport foo$((n+=1))="$var"
(das$((...))
auch tatsächlich zitiert werden sollte) ...). Oder mit anderen Worten, wenn das Argument toexport
keine gültige Variablenzuweisung wäre, wenn es ohne das Argument geschrieben würdeexport
.Wenn die
export
/local
Befehlsnamen selbst zitiert wird (auch auszugsweise wie"export" a="$b"
,'ex'port a="$b"
,\export a="$b"
oder sogar""export a="$b"
), um die Anführungszeichen$b
sind erforderlich , außer in AT & Tksh
undmksh
.Wenn
export
/local
oder ein Teil davon das Ergebnis einer Erweiterung (wie incmd=export; "$cmd" a="$b"
oder sogarexport$(:) a="$b"
) oder in Dingen wiedryrun=; $dryrun export a="$b"
) ist, werden die Anführungszeichen in jeder Shell benötigt.Im Fall von
> /dev/null export a="$b"
werden die Anführungszeichen inpdksh
und einige seiner Ableitungen benötigt.Denn
command export a="$b"
die Anführungszeichen werden in jeder Shell benötigt, abermksh
undksh93
(mit den gleichen Vorbehaltencommand
undexport
nicht das Ergebnis einer gewissen Erweiterung).Sie werden in keiner Shell benötigt, wenn sie geschrieben werden:
(Diese Syntax ist auch mit der Bourne-Shell kompatibel
zsh
, funktioniert jedoch in neueren Versionen von nur insh
/ksh
emulation).(Beachten Sie, dass dies
var=value local var
nicht verwendet werden sollte, da das Verhalten von Shell zu Shell unterschiedlich ist.)Beachten Sie auch, dass die Verwendung
export
mit einer Zuweisung auch bedeutet, dass der Exit-Status voncmd
inexport var="$(cmd)"
verloren geht. Es so zu machen,export var; var=$(cmd)
hat dieses Problem nicht.Beachten Sie diesen Sonderfall auch bei
bash
:Mein Rat wäre, immer zu zitieren.
quelle
zsh
Anführungszeichen sind für erforderlich ,local foo="$(cmd)"
weil wordsplitting (aber nicht Dateinamen Generation) wird für nicht notierte Befehlsersetzungen durchgeführt (jedoch nicht für nicht notierte Parameter Erweiterungen), es sei denn ,KSH_TYPESET
aktiviert ist , wobei in diesem Fall Anführungszeichen sind nicht erforderlich. Sinn ergeben? Nein? Zitieren Sie dann immer alles, es sei denn, Sie wissen genau, was Sie tun.Ich zitiere im Allgemeinen jede Verwendung von Variablen, bei denen Zeichen wie Leerzeichen vorkommen können. Andernfalls treten folgende Probleme auf:
Die Verwendung der Variablen in einer Zuweisung scheint keine Anführungszeichen zu erfordern, aber wenn Sie sie verwenden, wie im Beispiel,
printf
müssen Sie sie dort angeben:HINWEIS: Denken Sie daran, dass die Variable
$IFS
die Trennzeichen bestimmt.Beispiel
Wenn das Debuggen in Bash aktiviert ist, können wir sehen, was hinter den Kulissen passiert.
Oben sehen wir, dass die Variable
$bar
gut an übergeben wurde,$myvar
aber als wir sie verwendeten$myvar
, mussten wir den Inhalt der Variablen kennen,$myvar
als wir sie verwendeten.quelle
bash
undksh
inlocal
/typeset
... speziellen Builtins nicht zutrifft ).