Variabel lokal di zsh: apa yang setara dengan "ekspor-n" bash di zsh

10

Saya mencoba memuat ruang lingkup variabel ke shell, dan tidak membuat anak melihatnya, di zsh. Misalnya, saya mengetik ini dalam .zshrc:

GREP_OPTIONS=--color=always

Tetapi jika saya menjalankan skrip shell dengan yang berikut:

#!/bin/bash
echo $GREP_OPTIONS

Outputnya adalah:

--color=always

sementara saya ingin menjadi nol (skrip shell di atas seharusnya tidak melihat variabel GREP_OPTIONS sama sekali).

Dalam bash, dapat dikatakan:, export -n GREP_OPTIONS=--color=alwaysyang akan mencegah hal ini terjadi. Bagaimana saya melakukannya di zsh?

PonyEars
sumber
1
export -ncukup hapus ekspor variabel yang diekspor.
terdon

Jawaban:

11

exportdi zsh adalah singkatan untuk typeset -gx, di mana atribut gberarti "global" (sebagai lawan dari fungsi lokal) dan atribut xberarti "diekspor" (yaitu di lingkungan). Jadi:

typeset +x GREP_OPTIONS

Ini juga berfungsi di ksh dan bash.

Jika Anda tidak pernah mengekspor GREP_OPTIONS, Anda tidak perlu mengekspornya.

Anda juga dapat menggunakan cara tidak langsung dan portabel: membatalkan pengaturan suatu variabel akan menghapusnya. Di ksh / bash / zsh, ini tidak berfungsi jika variabel hanya-baca.

tmp=$GREP_OPTIONS
unset GREP_OPTIONS
GREP_OPTIONS=$tmp
Gilles 'SANGAT berhenti menjadi jahat'
sumber
Lihat juga env -u GREP_OPTIONS your-scriptdengan beberapa envimplementasi (shell apa saja). Atau(unset GREP_OPTIONS; exec your-script)
Stéphane Chazelas
Saya mencoba mengeset + x, tetapi itu tidak membuat perbedaan juga. Seperti ditunjukkan dalam pertanyaan saya, ada sesuatu yang mengekspor semua variabel yang saya definisikan, bahkan jika saya tidak memasukkan "ekspor". Masih berusaha mencari tahu kenapa.
PonyEars
@redstreet Mungkin Anda tidak sengaja mengatur opsi export_all( -a)? Tetapi bahkan kemudian tidak typeset +x GREP_OPTIONSakan mengekspor variabel. Jika Anda tidak dapat menemukan apa yang salah, coba pencarian biner: buat cadangan Anda .zshrc, hapus paruh kedua, lihat apakah masalahnya masih muncul, lalu tambahkan kuartal ketiga atau kurangi ke kuartal pertama dan ulangi.
Gilles 'SO- stop being evil'
@Gilles Terima kasih, saya menemukannya: zsh memiliki opsi "allexport" yang saya miliki di .zshrc saya. 'setopt noallexport' dapat mematikannya sementara jika membantu orang lain. Saya akan menerima jawaban Anda karena paling dekat.
PonyEars
Sekarang saya memiliki masalah yang berbeda, yang lebih dekat dengan masalah yang saya coba selesaikan, di sini: unix.stackexchange.com/questions/113645/…
PonyEars
6

Anda bisa menggunakan fungsi anonim untuk memberikan cakupan variabel. Dari 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.

Tapi selain itu - jika Anda tidak menggunakan exportdi Anda .zshrcsama sekali, variabel hanya harus terlihat dalam sesi interaktif Anda saat ini, dan itu tidak boleh diekspor ke subkulit.

Seperti Terdon dijelaskan dalam komentarnya: export -ndi bashhanya menyebabkan "ekspor" properti untuk dihapus dari variabel, sehingga menggunakan export -n GREP_OPTIONS=--color=alwayssetara dengan tidak menggunakan ekspor sama sekali - GREP_OPTIONS=--color=always.

Dengan kata lain, untuk mendapatkan perilaku yang diinginkan, jangan gunakan export. Sebaliknya, dalam diri Anda .zshrc, Anda seharusnya memilikinya

GREP_OPTIONS=--color=always

Itu akan membuat variabel tersedia untuk semua shell (interaktif, non-login) yang Anda jalankan, seperti yang Anda inginkan, tetapi tidak akan diekspor ke shell anak.

Martin von Wittich
sumber
Hanya memiliki GREP_OPTIONS = - color = selalu "adalah apa yang saya lakukan, seperti yang ditunjukkan dalam pertanyaan saya. Sesuatu yang lain di zsh menyebabkan semua variabel saya diekspor secara otomatis. Masih berusaha mencari tahu apa itu.
PonyEars