Variabili locali in zsh: qual è l'equivalente di "export -n" di bash in zsh


10

Sto cercando di contenere l'ambito di una variabile in una shell e non far vedere ai bambini, in zsh. Ad esempio, lo scrivo in .zshrc:

GREP_OPTIONS=--color=always

Ma se eseguo uno script di shell con il seguente:

#!/bin/bash
echo $GREP_OPTIONS

L'output è:

--color=always

mentre voglio che sia nullo (lo script di shell sopra non dovrebbe vedere affatto la variabile GREP_OPTIONS).

In bash, si può dire:, export -n GREP_OPTIONS=--color=alwaysche impedirà che ciò accada. Come posso farlo in zsh?


1
export -nnon esporta solo una variabile esportata.
terdon

Risposte:


11

exportin zsh è una scorciatoia per typeset -gx, dove l'attributo gsignifica "globale" (al contrario di locale a una funzione) e l'attributo xsignifica "esportato" (cioè nell'ambiente). Così:

typeset +x GREP_OPTIONS

Questo funziona anche in ksh e bash.

Se non esporti mai GREP_OPTIONSin primo luogo, non è necessario esportarlo.

Puoi anche usare il modo indiretto e portatile: annullare l'impostazione di una variabile non esportarla. In ksh / bash / zsh, questo non funziona se la variabile è di sola lettura.

tmp=$GREP_OPTIONS
unset GREP_OPTIONS
GREP_OPTIONS=$tmp

Vedi anche env -u GREP_OPTIONS your-scriptcon alcune envimplementazioni (qualsiasi shell). Oppure(unset GREP_OPTIONS; exec your-script)
Stéphane Chazelas,

Ho provato a digitare + x, ma neanche quello fa differenza. Come mostrato nella mia domanda, qualcosa sta esportando tutte le variabili che definisco, anche se non includo "export". Sto ancora cercando di scoprire perché.
PonyEars,

@redstreet Forse hai impostato accidentalmente l' opzione export_all( -a)? Ma anche allora typeset +x GREP_OPTIONSnon esporterebbe la variabile. Se non riesci a trovare ciò che non va, prova la ricerca binaria: esegui il backup .zshrc, rimuovi la seconda metà, vedi se il problema persiste, quindi aggiungi il terzo trimestre o riduci al primo e ripeti.
Gilles 'SO- smetti di essere malvagio' il

@Gilles Grazie, l'ho trovato: zsh ha un'opzione "allexport" che avevo nel mio .zshrc. 'setopt noallexport' può disattivarlo temporaneamente se aiuta qualcun altro. Accetterò la tua risposta poiché è arrivata la più vicina.
PonyEars,

Ora ho un problema diverso, che è più vicino al problema che sto cercando di risolvere, qui: unix.stackexchange.com/questions/113645/…
PonyEars

6

È possibile utilizzare una funzione anonima per fornire un ambito per la variabile. Da 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.

Ma a parte questo - se non si sta usando exportnel vostro .zshrca tutti, la variabile dovrebbe essere solo visibile nella vostra sessione interattiva corrente, e non dovrebbe essere esportato in sottoshell.

Come terdon spiegato nel suo commento: export -nnel bashsolo fa sì che la proprietà "esportazione" di essere rimosso dalla variabile, in modo da utilizzare export -n GREP_OPTIONS=--color=alwaysequivale a non usare l'esportazione a tutti - GREP_OPTIONS=--color=always.

In altre parole, per ottenere il comportamento desiderato, non usare export. Invece, nel tuo .zshrc, dovresti avere

GREP_OPTIONS=--color=always

Ciò renderà la variabile disponibile per tutte le shell (interattive, non di accesso) che si esegue, proprio come si desidera che sia, ma non verrà esportata in shell secondarie.


Avere GREP_OPTIONS = - color = always "è quello che sto facendo, come mostrato nella mia domanda. Qualcos'altro in zsh sta causando l'esportazione automatica di tutte le mie variabili.
Sto
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.