Lokale Variablen in zsh: Was entspricht dem "export -n" von bash in zsh?

10

Ich versuche, den Gültigkeitsbereich einer Variablen in einer Shell einzuschließen, ohne dass Kinder ihn in zsh sehen. Zum Beispiel tippe ich dies in .zshrc:

GREP_OPTIONS=--color=always

Aber wenn ich ein Shell-Skript mit folgendem ausführe:

#!/bin/bash
echo $GREP_OPTIONS

Die Ausgabe ist:

--color=always

während ich möchte, dass es null ist (das obige Shell-Skript sollte die Variable GREP_OPTIONS überhaupt nicht sehen).

In Bash kann man sagen : export -n GREP_OPTIONS=--color=always, was dies verhindern wird. Wie schaffe ich das in zsh?

PonyEars
quelle
1
export -nexportiert einfach eine exportierte Variable.
Terdon

Antworten:

11

exportin zsh ist eine Abkürzung für typeset -gx, wobei das Attribut g"global" bedeutet (im Gegensatz zu lokal für eine Funktion) und das Attribut x"exportiert" bedeutet (dh in der Umgebung). Somit:

typeset +x GREP_OPTIONS

Dies funktioniert auch in ksh und bash.

Wenn Sie nie exportieren GREP_OPTIONS, müssen Sie es nicht deportieren.

Sie können auch die indirekte, tragbare Methode verwenden: Wenn Sie eine Variable deaktivieren, wird sie nicht exportiert. In ksh / bash / zsh funktioniert dies nicht, wenn die Variable schreibgeschützt ist.

tmp=$GREP_OPTIONS
unset GREP_OPTIONS
GREP_OPTIONS=$tmp
Gilles 'SO - hör auf böse zu sein'
quelle
Siehe auch env -u GREP_OPTIONS your-scriptbei einigen envImplementierungen (beliebige Shell). Oder(unset GREP_OPTIONS; exec your-script)
Stéphane Chazelas
Ich habe Satz + x ausprobiert, aber das macht auch keinen Unterschied. Wie in meiner Frage gezeigt, exportiert etwas alle von mir definierten Variablen, auch wenn ich "export" nicht einbeziehe. Ich versuche immer noch herauszufinden warum.
PonyEars
@redstreet Vielleicht hast du versehentlich die Option export_all( -a) gesetzt? Aber selbst dann typeset +x GREP_OPTIONSwürde die Variable nicht exportiert. Wenn Sie nicht finden können, was falsch ist, versuchen Sie es mit der binären Suche: Sichern Sie Ihre .zshrc, entfernen Sie die zweite Hälfte, prüfen Sie, ob das Problem weiterhin besteht, hängen Sie entweder das dritte Quartal an oder reduzieren Sie es auf das erste Quartal und wiederholen Sie den Vorgang.
Gilles 'SO - hör auf böse zu sein'
@ Gilles Danke, ich habe es gefunden: zsh hat eine "allexport" -Option, die ich in meiner .zshrc hatte. 'setopt noallexport' kann es vorübergehend ausschalten, wenn es jemand anderem hilft. Ich werde Ihre Antwort akzeptieren, da sie am nächsten kam.
PonyEars
Jetzt habe ich ein anderes Problem, das näher an dem Problem liegt, das ich zu lösen versuche, hier: unix.stackexchange.com/questions/113645/…
PonyEars
6

Sie können eine anonyme Funktion verwenden, um einen Bereich für die Variable bereitzustellen. Von man zshall:

ANONYMOUS FUNCTIONS
       If no name is given for a function, it is `anonymous'  and  is  handled
       specially.  Either form of function definition may be used: a `()' with
       no preceding name, or a `function' with an immediately  following  open
       brace.  The function is executed immediately at the point of definition
       and is not stored  for  future  use.   The  function  name  is  set  to
       `(anon)'.

       Arguments to the function may be specified as words following the clos‐
       ing brace defining the function, hence if there are none  no  arguments
       (other than $0) are set.  This is a difference from the way other func‐
       tions are parsed: normal function definitions may be followed  by  cer‐
       tain  keywords  such  as `else' or `fi', which will be treated as argu
       ments to anonymous functions, so that a newline or semicolon is  needed
       to force keyword interpretation.

       Note also that the argument list of any enclosing script or function is
       hidden (as would be the case for any  other  function  called  at  this
       point).

       Redirections  may be applied to the anonymous function in the same man
       ner as to a current-shell structure enclosed in braces.  The  main  use
       of anonymous functions is to provide a scope for local variables.  This
       is particularly convenient in start-up files as these  do  not  provide
       their own local variable scope.

       For example,

              variable=outside
              function {
                local variable=inside
                print "I am $variable with arguments $*"
              } this and that
              print "I am $variable"

       outputs the following:

              I am inside with arguments this and that
              I am outside

       Note  that  function definitions with arguments that expand to nothing,
       for example `name=; function $name { ... }', are not treated as  anony‐
       mous  functions.   Instead, they are treated as normal function defini‐
       tions where the definition is silently discarded.

Aber abgesehen davon , dass - wenn Sie nicht mit exportIhrem .zshrcüberhaupt, sollte die Variable nur sichtbar, in der aktuellen interaktiven Sitzung, und es soll nicht zu Subshells exportiert werden.

Wie Terdon in seinem Kommentar erklärte: export -nIn bashbewirkt nur, dass die Eigenschaft "export" aus der Variablen entfernt wird. Die Verwendung von export -n GREP_OPTIONS=--color=alwaysist also gleichbedeutend damit, dass export überhaupt nicht verwendet wird GREP_OPTIONS=--color=always.

Mit anderen Worten, um das gewünschte Verhalten zu erzielen, verwenden Sie es einfach nicht export. Stattdessen sollten Sie in Ihrem .zshrchaben

GREP_OPTIONS=--color=always

Dadurch wird die Variable für alle von Ihnen ausgeführten (interaktiven, nicht angemeldeten) Shells verfügbar, so wie Sie es möchten, sie wird jedoch nicht in untergeordnete Shells exportiert.

Martin von Wittich
quelle
Nur GREP_OPTIONS = - color = always "zu haben, ist das, was ich tue, wie in meiner Frage gezeigt. Etwas anderes in zsh bewirkt, dass alle meine Variablen automatisch exportiert werden.
Ich