Ich weiß, dass Bash und Zsh local
unterstützen Variablen, aber es gibt Systeme, die nur POSIX-kompatible Shells haben. Und local
ist in POSIX-Shells undefiniert.
Also möchte ich fragen, welche Shells local
unterstützen Schlüsselwort zum Definieren lokaler Variablen?
Bearbeiten :Über Shells meine ich den Standard /bin/sh
Schale.
Akzeptierte Antwort:
Es ist nicht so einfach, local
zu unterstützen oder nicht. Es gibt viele Variationen in der Syntax und wie es zwischen Shells gemacht wird, die die eine oder andere Form von lokalem Gültigkeitsbereich haben.
Deshalb ist es sehr schwierig, einen Standard zu finden, der mit allen übereinstimmt. Siehe http://austingroupbugs.net/bug_view_page.php?bug_id=767 für die POSIX-Bemühungen an dieser Front.
Der lokale Geltungsbereich wurde zuerst in den frühen 80er Jahren in ksh hinzugefügt.
Die Syntax zum Deklarieren einer lokalen Variablen in einer Funktion war mit typeset
:
function f {
typeset var=value
set -o noglob # also local to the function
...
}
(Funktionsunterstützung wurde später zur Bourne-Shell hinzugefügt, aber mit einer anderen Syntax (f() command
) und ksh
später auch Unterstützung für diesen hinzugefügt; die Bourne-Shell hatte nie einen lokalen Gültigkeitsbereich (außer natürlich über Subshells))
Die local
builtin AFAIK wurde 1989 zuerst zur Almquist-Shell hinzugefügt (verwendet in BSDs, dash, busybox sh), funktioniert aber deutlich anders als ksh
’s typeset
. ash
Derivate unterstützen typeset
nicht als Alias für local
, aber Sie können immer einen von Hand definieren.
bash und zsh haben typeset
hinzugefügt Alias zu local
1989 bzw. 1991.
ksh88 hat local
hinzugefügt als undokumentierter Alias für typeset
ca. 1990 und pdksh und seine Derivate im Jahr 1994. posh
(basierend auf pdksh
) typeset
entfernt (zur strikten Einhaltung der Debian-Richtlinie, die local
erfordert , aber nicht typeset
).
POSIX lehnte zunächst die Angabe von typeset
ab mit der Begründung, dass es dynamisch war Umfang. Also wechselte ksh93 (eine Neufassung von ksh 1993 von David Korn) zu statisch Bereich statt. Auch in ksh93, im Gegensatz zu ksh88, wird lokales Scoping nur für Funktionen durchgeführt, die mit ksh
deklariert sind Syntax (function f {...}
), nicht die Bourne-Syntax (f() {...}
) und die local
Alias wurde entfernt.
Die ksh93v-Beta und die endgültige Version von AT&T können jedoch mit einem experimentellen „Bash“-Modus (eigentlich standardmäßig aktiviert) kompiliert werden, der dynamisches Scoping durchführt (in störenden Formen von Funktionen, einschließlich mit local
). und typeset
) wenn ksh93
wird als bash
aufgerufen . local
unterscheidet sich von typeset
in diesem Fall, da es nur innerhalb einer Funktion aufgerufen werden kann. Dieser bash
-Modus wird in ksh2020 standardmäßig deaktiviert, obwohl der local
/declare
Aliase zu typeset
wird beibehalten, auch wenn der Bash-Modus nicht einkompiliert ist (allerdings immer noch mit statischem Scoping).
yash
(viel später geschrieben), hat typeset
(à la ksh88), hatte aber nur local
als Alias seit Version 2.48 (Dezember 2018).
@Schily unterhält einen Nachkommen der Bourne-Shell, der kürzlich weitgehend POSIX-kompatibel gemacht wurde, namens bosh
die den lokalen Geltungsbereich seit Version 2016-07-06 unterstützt (mit local
, ähnlich wie ash
).
Die Bourne-ähnlichen Shells, die heute irgendeine Art von lokalem Geltungsbereich für Variablen haben, sind also:
- ksh, alle Implementierungen und ihre Derivate (ksh88, ksh93, pdksh und Derivate wie posh, mksh, OpenBSD sh).
- ash und alle seine Derivate (NetBSD sh, FreeBSD sh, dash, busybox sh)
- Bash
- zsch
- yash
- Schwach
Soweit zum sh
von verschiedenen Systemen gehen, beachten Sie, dass es Systeme gibt, bei denen der POSIX sh
befindet sich in /bin
(die meisten) und andere, wo es nicht ist (wie Solaris, wo es in /usr/xpg4/bin
ist ). Für sh
Implementierung auf verschiedenen Systemen, die wir haben:
- ksh88:die meisten von SysV abgeleiteten kommerziellen Unices (AIX, HP/UX, Solaris¹…)
- bash:die meisten GNU/Linux-Systeme, Cygwin, macOS
- ash:standardmäßig auf Debian und den meisten Derivaten (einschließlich Ubuntu, Linux/Mint), kann aber vom Administrator auf bash oder mksh geändert werden. NetBSD, FreeBSD und einige ihrer Derivate (nicht macOS).
- busybox sh:viele, wenn nicht die meisten eingebetteten Linux-Systeme
- pdksh oder Derivate:OpenBSD, MirOS
Nun, wo sie sich unterscheiden:
typeset
(ksh, pdksh, bash, zsh, yash) vs.local
(ksh88, pdksh, bash, zsh, ash, yash 2.48+).- statisch (ksh93, in
function f {...}
Funktion) vs. dynamisches Scoping (alle anderen Shells). Ob beispielsweisefunction f { typeset v=1; g; echo "$v"; }; function g { v=2; }; f
gibt1
aus oder2
. Siehe auch wie derexport
-Attribut wirkt sich auf den Geltungsbereich inksh93
aus . - ob
local
/typeset
macht die Variable einfach lokal (ash
,bosh
) oder erstellt eine neue Instanz der Variablen (andere Shells). Ob beispielsweisev=1; f() { local v; echo "${v:-empty}"; }; f
gibt1
aus oderempty
(siehe auchlocalvar_inherit
Option in bash 5.0 und höher). - bei denen, die eine neue Variable erstellen, ob die neue die Attribute erbt (wie
export
) und/oder Typ und welche aus der Variablen im übergeordneten Gültigkeitsbereich. Ob beispielsweiseexport V=1; f() { local V=2; printenv V; }; f
gibt1
aus ,2
oder nichts. - ob diese neue Variable einen Anfangswert hat (leer, 0, leere Liste, je nach Typ,
zsh
) oder ist anfänglich nicht gesetzt. - ob
unset V
auf eine Variable in einem lokalen Geltungsbereich lässt die Variableunset
, oder nur Schalen eine Scoping-Ebene (mksh
,yash
,bash
unter Umständen). Ob beispielsweisev=1; f() { local v=2; unset v; echo "$v"; }
gibt1
aus oder nichts (siehe auchlocalvar_unset
Option in bash 5.0 und höher) - wie für
export
, ob es sich um ein Keyword oder nur um einen eingebauten Begriff oder beides handelt und unter welchen Bedingungen es als Keyword betrachtet wird. - wie für
export
, ob die Argumente als normale Befehlsargumente oder als Zuweisungen geparst werden (und unter welchen Bedingungen). - ob Sie lokal deklarieren können eine Variable, die im übergeordneten Geltungsbereich schreibgeschützt war.
- die Interaktionen mit
v=value myfunction
womyfunction
selbst deklariertv
als lokal oder nicht.
Das sind die, an die ich gerade denke. Weitere Einzelheiten finden Sie im Fehler der Austin-Gruppe oben.
Was den lokalen Geltungsbereich für Shell-Optionen betrifft (im Gegensatz zu Variablen ), Shells, die es unterstützen, sind:
ksh88
(mit beiden Funktionsdefinitionssyntaxen):standardmäßig ausgeführt, mir ist keine Möglichkeit bekannt, sie zu deaktivieren.ash
(seit 1989):mitlocal -
. Es macht den$-
Parameter (der die Liste der Optionen speichert) local.ksh93
:jetzt nur noch fürfunction f {...}
erledigt Funktionen.zsh
(seit 1995). Mitsetopt localoptions
. Auch mitemulate -L
für den Emulationsmodus (und seinen Satz von Optionen), der für die Funktion lokal gemacht werden soll.bash
(seit 2016) mitlocal -
wie inash
.
Verwandte:Md5sum-Befehl Binär- und Textmodus?