POSIX-Konforme Weise auf den Geltungsbereich von Variablen an eine Funktion in einem Shell-Skript
Gibt es ein POSIX-Konformer Weise zu beschränken den Geltungsbereich einer Variablen auf die Funktion in der Sie deklariert ist? also:
Testing()
{
TEST="testing"
}
Testing
echo "Test is: $TEST"
sollte print "Test:". Ich habe gelesen die erklären, die lokalen und Platzierten keywords, aber es sieht nicht wie Sie erforderlich sind POSIX-gebaut-ins.
- BTW kann man "annehmen" eine der gegebenen Antworten, wenn es Ihr problem löst.
- Positionsparameter, die lokal in der aktuellen Funktion, verwenden
set -- "$@" value1 value2
am Anfang der Funktion zum Anhängen von Werten an die parameter-Liste. Aber es gibt keine einfache Möglichkeit zum ändern der einzelnen Werte, die Sie haben, immer angeben alle Parameter, wie:set -- "$1" "$2" ... valuex ...
Du musst angemeldet sein, um einen Kommentar abzugeben.
Es erfolgt in der Regel mit der
local
Stichwort, die ist, wie Sie zu wissen scheinen, nicht POSIX definiert. Hier ist eine informative Diskussion über das hinzufügen von 'local' nach POSIX.Aber auch die meisten primitiven POSIX-konforme shell, die ich kenne, die von einigen GNU/Linux-Distributionen sowie die
/bin/sh
Standard,dash
(Debian Almquist Shell), die es unterstützt. FreeBSD und NetBSD benutzenash
die original-Almquist-Shell, die auch unterstützt es. OpenBSD benutzt eineksh
Umsetzung für/bin/sh
die auch unterstützt es. So, es sei denn, Sie sind mit dem Ziel, die Unterstützung von nicht-GNU-nicht-BSD-Systeme wie Solaris, oder diejenigen, die sich mit standard-ksh, etc., Sie könnten Weg mit Hilfelocal
. (Vielleicht möchten Sie einige Kommentar direkt am Anfang des Scriptes unter der shebang-Zeile, sagen, dass es sich streng genommen nicht um eine POSIX-sh-Skript. Nur nicht böse sein.) Nachdem alles gesagt, dass, möchten Sie vielleicht zu prüfen, die jeweiligen man-pages von all diesensh
Implementierungen unterstützenlocal
, da Sie möglicherweise subtile Unterschiede darin, wie genau Sie arbeiten. Oder einfach nicht mitlocal
:Wenn Sie wirklich wollen, zu entsprechen, vollständig POSIX, oder nicht wollen, um Chaos mit möglichen Problemen und so nicht verwenden
local
, dann haben Sie ein paar Optionen. Die Antwort von Lars Brinkhoff ist solide, Sie können einfach wickeln Sie die Funktion in eine sub-shell. Diese haben möglicherweise andere unerwünschte Wirkungen, obwohl. Übrigens shell-Grammatik (pro POSIX) ermöglicht die folgenden:Obwohl vielleicht vermeiden, dass sein super-portable, einige alte Bourne-shells können auch nicht-POSIX-konform. Wollte nur erwähnen, dass POSIX erlaubt es.
Eine andere option wäre
unset
Variablen am Ende der Funktion Körper, aber das ist nicht wiederherstellen würde der alte Wert natürlich so nicht wirklich, was Sie wollen, ich Schätze, es wird lediglich verhindern, dass die variable s in der Funktion Wert-Leck außerhalb. Nicht sehr hilfreich, denke ich.Einen letzten, und verrückt, die Idee, die ich denken kann, ist die Umsetzung
local
selbst. Die Schale hateval
, die aber das böse, die Erträge Weg, um einige wahnsinnige Möglichkeiten. Die folgenden grundsätzlich führt dynamisches scoping a la alte Lisps, ich verwende das Schlüsselwortlet
stattlocal
für weitere kühl-Punkte, obwohl Sie mit der so genanntenunlet
am Ende:Nun können Sie:
(Übrigens
unlet
gegeben werden kann eine beliebige Anzahl von Variablen auf einmal (als verschiedene Argumente), für die Bequemlichkeit, nicht präsentiert oben).Versuchen Sie nicht dieses zu Hause, nicht zu Kindern, nicht zeigen Sie Ihre Mitarbeiter, zeigen Sie nicht, es zu
#bash
auf Freenode, nicht zu zeigen es, um Mitglieder der POSIX-Ausschuss, nicht, zeigen Sie es Mr. Bourne, vielleicht zeigen Sie es Vater McCarthy ' s ghost, ihm ein lachen. Sie wurden gewarnt, und Sie wusste nicht, erfahren es von mir.EDIT:
Anscheinend habe ich geschlagen wurde, sendet der IRC-bot
greybot
auf Freenode (gehört zu#bash
) den Befehl "posixlocal" wird es geben einige obskure code, der veranschaulicht, eine Möglichkeit zu erreichen, lokale Variablen, die in POSIX-sh. Hier ist ein etwas aufgeräumt-version, weil das original war schwer zu entziffern:Diese Transkript veranschaulicht Verwendung:
Also lässt man die Variablen
x
undy
wie die einheimischen in derthen
- Zweigs der if-form. Weitere Variablen Hinzugefügt werden können, an derelse
Zweig; beachten Sie, dass man hinzufügen muss zweimal, einmal wievariable=
in der ersten Liste, und einmal als argument übergebentypeset
. Beachten Sie, dass keineunlet
oder so benötigt wird (es ist eine "transparente" Implementierung), und no-name-mangling und übermäßigeeval
ist getan. So scheint es zu sein, eine viel sauberere Umsetzung insgesamt.EDIT 2:
Kommt
typeset
ist nicht POSIX definiert, und Implementierungen die Almquist-Shell (FreeBSD, NetBSD, Debian) nicht unterstützen. Also die oben genannten hack funktioniert nicht auf diese Plattformen.let
/unlet
Lösung Konstrukte eine variable name auf den Wert der global, während die lokale im Einsatz ist, aber nicht sicher, dass das - name nicht bereits im Einsatz, wie eine Globale. Solche Kollisionen sind unwahrscheinlich, aber man sollte sich bewusst sein die Möglichkeit.typeset
funktioniert wielocal
innerhalb einer Funktion, aberfunction name
syntax statt dername()
syntax.local
Unterstützung für Debian, obwohl es nicht POSIX. War es das, was Sie sich beziehen?local
austingroupbugs.net/view.php?id=767"$@"
vs"$*"
), also habe ich aktualisiert, der link in dieser Antwort auf gehen Sie direkt.Ich glaube, die nächste Sache wäre die Funktion Körper in einer subshell.
E. g. versuchen Sie, diese
Hier ist eine Funktion, mit der Festlegung des lösungsumfangs:
Beispiel-Skript:
Ergebnis:
Wenn Sie möchten, begeben Sie sich hinab in die Hölle mit mir, habe ich eine mehr ausgearbeitete Umsetzung der
eval
Konzept.Dieser automatisch hält ein Konto Ihrer quasi-scoped Variablen aufgerufen werden kann, mit einer vertrauten syntax und ordnungsgemäß deaktiviert (im Gegensatz zu bloß nulling -) Variablen beim verlassen einer geschachtelten scopes.
Nutzung
Wie Sie sehen können, Sie
push_scope
eingeben eines Bereichs_local
zu erklären, Ihre quasi-lokale Variablen undpop_scope
zu verlassen Anwendungsbereich. Verwenden_unset
zu unset variable, undpop_scope
wird wieder ausgeschaltet, wenn Sie wieder draußen in diesem Bereich wieder.Code
All die nichtssagenden Variablen-Namen-Endungen sind extra sicher gegen Kollisionen mit Namen, die.
Definieren Sie die Funktionen über die
function myfunc {
syntax und Verwendungtypeset myvar
definieren Sie Ihre Variablen. Wenn Sie Funktionen definieren, die Art und Weise, anstatt mit denmyfunc(){
syntax, die alle das gemeinsame Bourne-shells (bash, zsh, ksh '88 und '93) lokalisiert definierten Variablen mittypeset
(und Aliase gesetzt wieinteger
).Oder das Rad neu erfinden. Je nachdem, was schwimmt Ihr Boot. 😉
EDIT: während die Frage fragt nach POSIX, und dies ist keine POSIX-konforme function definition syntax, die person, die gefragt gibt an, in einem späteren Kommentar, dass er die bash benutzen. Die Verwendung von "typset" in Kombination mit dem alternativen function definition syntax ist die beste Lösung gibt, als den wahren POSIX-Mechanismus erfordert der zusätzliche overhead der Gabelung einer neuen subshell.
function
syntax funktioniert nicht auf Implementierungen der Almquist Shell: NetBSD, FreeBSD, Debian. Sie können suchen, für den man-pages von denen, mit Ihrer Lieblings-Suchmaschine.