Variables locales en zsh: ¿cuál es el equivalente de bash "export -n" en zsh

10

Estoy tratando de contener el alcance de una variable a un shell, y no hacer que los niños lo vean, en zsh. Por ejemplo, escribo esto en .zshrc:

GREP_OPTIONS=--color=always

Pero si ejecuto un script de shell con lo siguiente:

#!/bin/bash
echo $GREP_OPTIONS

El resultado es:

--color=always

mientras quiero que sea nulo (el script de shell anterior no debería ver la variable GREP_OPTIONS en absoluto).

En bash, se puede decir:, export -n GREP_OPTIONS=--color=alwayslo que evitará que esto suceda. ¿Cómo logro esto en zsh?

Orejas De Poni
fuente
1
export -nsimplemente exporta una variable exportada.
terdon

Respuestas:

11

exporten zsh es la abreviatura de typeset -gx, donde el atributo gsignifica "global" (en oposición a local a una función) y el atributo xsignifica "exportado" (es decir, en el entorno). Así:

typeset +x GREP_OPTIONS

Esto también funciona en ksh y bash.

Si nunca exporta GREP_OPTIONSen primer lugar, no necesita exportarlo.

También puede usar la forma indirecta y portátil: desarmar una variable no la exporta. En ksh / bash / zsh, esto no funciona si la variable es de solo lectura.

tmp=$GREP_OPTIONS
unset GREP_OPTIONS
GREP_OPTIONS=$tmp
Gilles 'SO- deja de ser malvado'
fuente
Ver también env -u GREP_OPTIONS your-scriptcon algunas envimplementaciones (cualquier shell). O(unset GREP_OPTIONS; exec your-script)
Stéphane Chazelas
Intenté typeset + x, pero eso tampoco hace la diferencia. Como se muestra en mi pregunta, algo está exportando todas las variables que defino, incluso si no incluyo "exportar". Todavía estoy tratando de averiguar por qué.
PonyEars
@redstreet ¿Quizás configuró accidentalmente la opción export_all( -a)? Pero incluso entonces typeset +x GREP_OPTIONSno exportaría la variable. Si no puede encontrar lo que está mal, intente la búsqueda binaria: haga una copia de seguridad de su .zshrc, elimine la segunda mitad, vea si el problema aún surge, luego agregue el tercer trimestre o reduzca al primer trimestre y repita.
Gilles 'SO- deja de ser malvado'
@Gilles Gracias, lo encontré: zsh tiene una opción de "allexport" que tenía en mi .zshrc. 'setopt noallexport' puede desactivarlo temporalmente si ayuda a alguien más. Aceptaré tu respuesta ya que fue la más cercana.
PonyEars
Ahora tengo un problema diferente, que está más cerca del problema que estoy tratando de resolver, aquí: unix.stackexchange.com/questions/113645/…
PonyEars
6

Puede usar una función anónima para proporcionar un alcance para la variable. De 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.

Pero aparte de eso, si no está usando exporten .zshrcabsoluto, la variable solo debería ser visible en su sesión interactiva actual, y no debería exportarse a subcapas.

Como terdon explicó en su comentario: export -nen bashsolo hace que la propiedad "exportar" se elimine de la variable, por lo que usar export -n GREP_OPTIONS=--color=alwayses equivalente a no usar la exportación en absoluto - GREP_OPTIONS=--color=always.

En otras palabras, para obtener el comportamiento deseado, simplemente no lo use export. En cambio, en tu .zshrc, deberías tener

GREP_OPTIONS=--color=always

Eso hará que la variable esté disponible para todos los shells (interactivos, sin inicio de sesión) que ejecute, tal como lo desea, pero no se exportará a shells secundarios.

Martin von Wittich
fuente
Simplemente tener GREP_OPTIONS = - color = siempre "es lo que estoy haciendo, como se muestra en mi pregunta. Algo más en zsh está causando que todas mis variables se exporten automáticamente. Todavía estoy tratando de averiguar qué es eso.
PonyEars