Variables locales dans zsh: quel est l'équivalent de «export -n» de bash dans zsh

10

J'essaie de contenir la portée d'une variable dans un shell, et de ne pas voir les enfants, dans zsh. Par exemple, je tape ceci dans .zshrc:

GREP_OPTIONS=--color=always

Mais si je lance un script shell avec ce qui suit:

#!/bin/bash
echo $GREP_OPTIONS

La sortie est:

--color=always

alors que je veux qu'il soit nul (le script shell ci-dessus ne devrait pas du tout voir la variable GREP_OPTIONS).

En bash, on peut dire:, export -n GREP_OPTIONS=--color=alwaysce qui empêchera cela de se produire. Comment puis-je accomplir cela dans zsh?

Oreilles de poney
la source
1
export -njuste exporte une variable exportée.
terdon

Réponses:

11

exportdans zsh est un raccourci pour typeset -gx, où l'attribut gsignifie «global» (par opposition à local à une fonction) et l'attribut xsignifie «exporté» (c'est-à-dire dans l'environnement). Donc:

typeset +x GREP_OPTIONS

Cela fonctionne également dans ksh et bash.

Si vous n'exportez jamais GREP_OPTIONSen premier lieu, vous n'avez pas besoin de la dé-exporter.

Vous pouvez également utiliser la méthode indirecte et portable: la suppression d'une variable la désexporte. Dans ksh / bash / zsh, cela ne fonctionne pas si la variable est en lecture seule.

tmp=$GREP_OPTIONS
unset GREP_OPTIONS
GREP_OPTIONS=$tmp
Gilles 'SO- arrête d'être méchant'
la source
Voir aussi env -u GREP_OPTIONS your-scriptavec quelques envimplémentations (n'importe quel shell). Ou(unset GREP_OPTIONS; exec your-script)
Stéphane Chazelas
J'ai essayé de composer + x, mais cela ne fait aucune différence non plus. Comme indiqué dans ma question, quelque chose exporte toutes les variables que je définis, même si je n'inclus pas "export". J'essaie toujours de savoir pourquoi.
PonyEars
@redstreet Vous avez peut-être accidentellement défini l' option export_all( -a)? Mais même dans typeset +x GREP_OPTIONSce cas, la variable ne serait pas exportée. Si vous ne trouvez pas ce qui ne va pas, essayez la recherche binaire: sauvegardez votre .zshrc, supprimez la seconde moitié, voyez si le problème persiste, puis ajoutez le troisième trimestre ou réduisez au premier trimestre et répétez.
Gilles 'SO- arrête d'être méchant'
@Gilles Merci, je l'ai trouvé: zsh a une option "allexport" que j'avais dans mon .zshrc. 'setopt noallexport' peut le désactiver temporairement s'il aide quelqu'un d'autre. J'accepterai votre réponse car elle est venue le plus près.
PonyEars
Maintenant, j'ai un problème différent, qui est plus proche du problème que j'essaie de résoudre, ici: unix.stackexchange.com/questions/113645/…
PonyEars
6

Vous pouvez utiliser une fonction anonyme pour fournir une portée à 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.

Mais à part cela - si vous n'utilisez pas du tout exportdans votre .zshrc, la variable ne devrait être visible que dans votre session interactive actuelle, et elle ne devrait pas être exportée vers des sous-coquilles.

Comme terdon l'a expliqué dans son commentaire: export -nen fait bashjuste supprimer la propriété "export" de la variable, donc utiliser export -n GREP_OPTIONS=--color=alwayséquivaut à ne pas utiliser du tout l'exportation - GREP_OPTIONS=--color=always.

En d'autres termes, pour obtenir le comportement souhaité, ne l'utilisez pas export. Au lieu de cela, dans votre .zshrc, vous devriez avoir

GREP_OPTIONS=--color=always

Cela rendra la variable disponible pour tous les shells (interactifs, sans connexion) que vous exécutez, tout comme vous le souhaitez, mais elle ne sera pas exportée vers les shells enfants.

Martin von Wittich
la source
Juste avoir GREP_OPTIONS = - color = always "est ce que je fais, comme indiqué dans ma question. Quelque chose d'autre dans zsh entraîne l'exportation automatique de toutes mes variables. Toujours en train de découvrir ce que c'est.
PonyEars