Dışa aktarmalı veya dışa aktarmasız bir değişken tanımlama


955

Ne exportiçin?

Arasındaki fark nedir:

export name=value

ve

name=value

4
Teğetsel olarak export name=valuetaşınabilir olmadığını da not edin . Tam olarak ne istediğinize bağlı olarak, name=value; export nametaşınabilir bir çözüm deneyin .
üçlü

Yanıtlar:


1054

export değişkeni alt işlemler için kullanılabilir hale getirir.

Yani,

export name=value

bu değişken adının o kabuk işleminden çalıştırdığınız herhangi bir işlem için kullanılabilir olduğu anlamına gelir . Bir işlemin bu değişkeni kullanmasını istiyorsanız, işlemi kullanın exportve işlemi bu kabuktan çalıştırın.

name=value

değişken kapsamının kabukla sınırlı olduğunu ve başka bir işlem tarafından kullanılamayacağı anlamına gelir. Bunu döngü değişkenleri, geçici değişkenler vb. İçin kullanabilirsiniz.

Bir değişkeni dışa aktarmanın, onu üst süreçler için kullanılabilir hale getirmediğine dikkat etmek önemlidir. Yani, bir yumurtlanmış süreçte bir değişkenin belirtilmesi ve dışa aktarılması, değişkenin başlatılan süreçte kullanılabilir olmasını sağlamaz.


105
Özellikle dışa aktarma, değişkeni ortam aracılığıyla alt süreçler için kullanılabilir hale getirir.
Beano

15
Ayrıca, dışa aktarma "kaynak" (.filename gibi) bir dosyadaysa, bunu çalışma ortamınıza da aktardığını da ekleyebilirim.
rogerdpack

6
@ rogerdpack bunu dışa aktarmadan yapamaz mısınız? cat> blah \ na = merhaba \ n. vesaire; echo $ a; benim için 'merhaba' çıktılar.
David Winiecki

2
Güzel ihracat olmadan bile çalışır. Bir dosyayı kaynaklarken sanırım, eğer ihracat kullanırsanız çocuk süreçlerine yansıtılacaktır, eğer yapmazsanız sadece yerel bash ortamını etkileyecektir ...
rogerdpack

19
Bunun bir ucu var; name=value command yok alt süreçte değişken kullanılabilir hale command.
Oliver Charlesworth

254

Diğer cevapların söylediklerini göstermek için:

$ foo="Hello, World"
$ echo $foo
Hello, World
$ bar="Goodbye"
$ export foo
$ bash
bash-3.2$ echo $foo
Hello, World
bash-3.2$ echo $bar

bash-3.2$ 

9
Bunun için bir örnek dahaal$ foobar="Whatever" bash
Alun

70

Diğerleri, dışa aktarmanın, değişkeni alt kabuklar için kullanılabilir hale getirdiğini ve bunun doğru olduğunu ancak yalnızca bir yan etkisi olduğunu yanıtladı. Bir değişkeni dışa aktardığınızda, bu değişkeni geçerli kabuğun ortamına koyar (yani kabuk çağırır putenv(3)veya setenv(3)).
Bir işlemin ortamı exec'de devralınır ve bu değişkenin alt kabuklarda görünür olmasını sağlar.

Düzenleme (5 yıllık bakış açısıyla): bu aptalca bir cevap. 'Dışa aktarmanın' amacı, bu komutların alt kabuklar veya alt süreçler olmak üzere değişkenlerin "daha sonra yürütülen komutlar ortamında olmasını" sağlamaktır. Saf bir uygulama, değişkeni kabuğun ortamına koymak olacaktır, ancak bu, uygulamayı imkansız hale getirecektir export -p.


6
Bunun tamamen doğru olmadığını unutmayın. In bash, export gerçekten değişkeni mevcut kabuğun ortamına ekler, ancak durum böyle değildir dash. Bana öyle geliyor ki, değişkeni mevcut kabuğun ortamına eklemenin anlambilimini uygulamanın en basit yolu olduğu export, ancak bu davranış zorunlu değildir.
William Pursell

7
Bununla ne dashyapacağından emin değilim . Orijinal poster özellikle soruyordu bash.
Denizyıldızı

14
Soru etiketlidir, bashancak herhangi bir bourne-kabuk varyantı için eşit olarak geçerlidir. Aşırı spesifik olmak ve sadece geçerli olan cevaplar vermek bashbüyük bir kötülüktür.
William Pursell

12
bashKabuğun jQuery'sidir.
Potherca

2
export makes the variable available to subshells, and that is correctBu, terminolojinin çok kafa karıştırıcı bir kullanımıdır. Alt kabukların exportdeğişkenleri devralması gerekmez . Alt işlemler yapılır.
Amit Naidu

62

Diğerleri tam tersini söylerken, alt kabukları yumurtlarken bash'a ihracatın gerekli olmadığı söylenir. Bu altkabuklarda arasındaki farkı dikkat etmek önemlidir (yarattığı olanlar (), ``, $()veya döngüler) ve subprocesses (örneğin, isim tarafından çağrılan süreçler bir hazır bashSenaryonuzun görünen).

  • Alt kabuklar , dışa aktarıldıkları durumdan bağımsız olarak ana öğeden tüm değişkenlere erişebilir.
  • Alt süreçler olacak sadece ihraç değişkenleri bakın.

Bu iki yapıda ortak olan şey, değişkenlerin ana kabuğa geri aktarılamamasıdır.

$ noexport=noexport; export export=export; (echo subshell: $noexport $export; subshell=subshell); bash -c 'echo subprocess: $noexport $export; subprocess=subprocess'; echo parent: $subshell $subprocess
subshell: noexport export
subprocess: export
parent:

Bir karışıklık daha var: bazıları 'çatallı' alt işlemlerin dışa aktarılmayan değişkenleri görmeyenler olduğunu düşünüyor. Genellikle fork () 'ları hemen exec () s izler ve bu nedenle fork () aranacak bir şey gibi görünürken aslında exec ()' dir. Komutları önce fork () olmadan komutları çalıştırabilirsiniz execve bu yöntemle başlatılan işlemlerin de dışa aktarılan değişkenlere erişimi olmaz:

$ noexport=noexport; export export=export; exec bash -c 'echo execd process: $noexport $export; execd=execd'; echo parent: $execd
execd process: export

parent:Bu kez satırı görmediğimizi unutmayın , çünkü üst kabuğu execkomutla değiştirdik, bu yüzden bu komutu yürütecek hiçbir şey kalmadı.


(Tek başına) bir alt kabuk oluşturan bir döngü görmedim; Bir boru hattı OTOH yapar (kabuğunuza, versiyonunuza ve seçeneklerinize bağlı olarak her zaman sondan farklı parçalar için, bazen sonuncusu için). Backgrounding ( &) ayrıca bir alt kabuk oluşturur.
dave_thompson_085

Peki ya bunlar var=asdf bash -c 'echo $var'ya var=asdf exec bash -c 'echo $var'? Çıktı asdf. ;Değişken tanımından sonra yerleştirilmiş ise farktır. Açıklama ne olurdu? Bir şekilde ortaya çıkan alt süreçlere ilişkin var(hayır ile ;) bir şekilde, kök kabuğunun onunla hiçbir ilgisi olmadığı gibi görünüyor. echo $varikinci satıra yürütülürse hiçbir şey yazdırmaz. Ama bir tane var=asdf bash -c 'echo $var'; echo $varverir asdf\nasdf.
4xy

31

export NAME=value bir alt işlem anlamına gelen ayarlar ve değişkenler için.

NAME=value geçerli kabuk işlemine özel geçici veya döngü değişkenleri için.

Daha ayrıntılı olarak, oluşturulduktan exportsonra ortamdaki bir alt işlemlere ve alt işlemlerine kopyalanan değişken adını işaretler. Alt işlemden hiçbir ad veya değer kopyalanmaz.

  • Yaygın bir hata, eşittir işaretinin etrafına boşluk yerleştirmektir:

    $ export FOO = "bar"  
    bash: export: `=': not a valid identifier
  • BAlt işlem tarafından yalnızca dışa aktarılan değişken ( ) görülür:

    $ A="Alice"; export B="Bob"; echo "echo A is \$A. B is \$B" | bash
    A is . B is Bob
  • Alt işlemdeki değişiklikler ana kabuğu değiştirmez:

    $ export B="Bob"; echo 'B="Banana"' | bash; echo $B
    Bob
  • Dışa aktarma için işaretlenen değişkenler, alt işlem oluşturulduğunda kopyalanır:

    $ export B="Bob"; echo '(sleep 30; echo "Subprocess 1 has B=$B")' | bash &
    [1] 3306
    $ B="Banana"; echo '(sleep 30; echo "Subprocess 2 has B=$B")' | bash 
    Subprocess 1 has B=Bob
    Subprocess 2 has B=Banana
    [1]+  Done         echo '(sleep 30; echo "Subprocess 1 has B=$B")' | bash
  • Yalnızca dışa aktarılan değişkenler ortamın bir parçası olur ( man environ):

     $ ALICE="Alice"; export BOB="Bob"; env | grep "ALICE\|BOB"
     BOB=Bob

Şimdi yaz güneşi kadar açık olmalı! Brain Agnew, alexp ve William Prusell'e teşekkürler.


12

export değişkeni geçerli kabuktan çatallanan tüm kabuklar için kullanılabilir hale getirecektir.


11

Bir değişkeni dışa aktarabileceğiniz ve daha sonra değeri değiştirebileceğiniz not edilmelidir. Değişkenin değiştirilen değeri alt süreçler tarafından kullanılabilir. Bir değişken için dışa aktarma ayarlandıktan export -n <var>sonra özelliği kaldırmak için yapmanız gerekir .

$ K=1
$ export K
$ K=2
$ bash -c 'echo ${K-unset}'
2
$ export -n K
$ bash -c 'echo ${K-unset}'
unset

Teşekkürler, bu tam olarak aradığım bilgidir, çünkü ortam değişkenlerini kullanan bir komut dosyası gördüm ve sonra onları yeni bir değerle "yeniden ihraç ettim" ve gerekli olup olmadığını merak ediyordum.
Mike Lippert

8

Bildiğiniz gibi UNIX, işlemlerin hem anahtar hem de değer dizeleri olan anahtar / değer çiftleri olan bir dizi ortam değişkenine sahip olmasına izin verir. İşletim sistemi, bu çiftlerin her işlem için ayrı ayrı tutulmasından sorumludur.

Program, ortam değişkenlerine bu UNIX API'si üzerinden erişebilir:

  • char *getenv(const char *name);
  • int setenv(const char *name, const char *value, int override);
  • int unsetenv(const char *name);

İşlemler ayrıca ortam değişkenlerini üst süreçlerden devralır. İşletim sistemi, alt süreç oluşturulduğu anda tüm "envarların" bir kopyasını oluşturmaktan sorumludur.

Bash , diğer kabukların yanı sıra, ortam değişkenlerini kullanıcı talebi üzerine ayarlayabilir. Bunun için exportvar olan budur.

exportBash için ortam değişkenini ayarlamak için bir Bash komutudur. Bu komutla ayarlanan tüm değişkenler, bu Bash'in oluşturacağı tüm işlemler tarafından devralınır.

Bash'de Çevre Hakkında Daha Fazla Bilgi

Bash'teki başka bir değişken türü iç değişkendir. Bash sadece etkileşimli kabuk olmadığından, aslında bir komut yorumlayıcısıdır, diğer herhangi bir yorumlayıcı gibi (örneğin Python) kendi değişkenlerini tutabilir. Bash'in (Python'dan farklı olarak) yalnızca dize değişkenlerini desteklediği belirtilmelidir.

Bash değişkenlerini tanımlamak için gösterim name=value. Bu değişkenler Bash içinde kalır ve işletim sistemi tarafından tutulan ortam değişkenleri ile ilgisi yoktur.

Kabuk Parametreleri hakkında daha fazla bilgi (değişkenler dahil)

Ayrıca, Bash referans kılavuzuna göre:

Herhangi bir basit komut veya işlevin ortamı, Kabuk Parametreleri'nde açıklandığı gibi parametre atamalarıyla önek eklenerek geçici olarak artırılabilir . Bu atama ifadeleri yalnızca bu komutun gördüğü ortamı etkiler.


Özetlemek gerekirse:

  • exportişletim sisteminde ortam değişkenini ayarlamak için kullanılır. Bu değişken, şimdiki Bash işlemi tarafından oluşturulan tüm alt süreçler için kullanılabilir.
  • Bash değişkeni gösterimi (name = değer), yalnızca geçerli bash işlemi için kullanılabilir yerel değişkenleri ayarlamak için kullanılır
  • Başka bir komutun önüne gelen Bash değişkeni notasyonu, yalnızca bu komutun kapsamı için ortam değişkeni oluşturur.

1
bash vars, Python kadar türü desteklemez, ancak dize, tamsayı ve iki tür diziye sahiptir (awk dizisine, perl karma veya Python dict'e benzer olan 'dizinli' / geleneksel ve 'ilişkilendirici'). Diğer mermiler değişiklik gösterir; sadece dize taşınabilir .
dave_thompson_085

7

Kabul edilen cevap bunu ima eder, ancak kabuk yuvalarına bağlantıyı açıkça yapmak istiyorum:

Daha önce de belirtildiği gibi, exportbir değişkeni hem kabuk hem de çocuklar için kullanılabilir hale getirecektir. Eğer exportedilir değil kullanılan, değişken sadece kabuk satışa sunulacak ve sadece kabuk yerleşikleri erişebilir.

Yani,

tango=3
env | grep tango # prints nothing, since env is a child process
set | grep tango # prints tango=3 - "type set" shows `set` is a shell builtin

3

İşte başka bir örnek:

VARTEST="value of VARTEST" 
#export VARTEST="value of VARTEST" 
sudo env | grep -i vartest 
sudo echo ${SUDO_USER} ${SUDO_UID}:${SUDO_GID} "${VARTEST}" 
sudo bash -c 'echo ${SUDO_USER} ${SUDO_UID}:${SUDO_GID} "${VARTEST}"'  

Yalnızca VARTEST dışa aktarma kullanılarak VARTEST değeri sudo bash -c '...' de kullanılabilir!

Diğer örnekler için bakınız:


3

UNIX'in yaratıcılarından ikisi, Brian Kernighan ve Rob Pike, bunu "UNIX Programlama Ortamı" başlıklı kitaplarında açıklıyor. Başlık için Google ve kolayca bir pdf sürümü bulacaksınız.

Bölüm 3.6'daki kabuk değişkenlerini ele alırlar ve bölümün exportsonundaki komutun kullanımına odaklanırlar :

Bir değişkenin değerini alt kabuklarda erişilebilir hale getirmek istediğinizde, kabuğun dışa aktarma komutu kullanılmalıdır. (Bir değişkenin değerini neden bir alt kabuktan üst öğesine vermenin bir yolu olmadığını düşünebilirsiniz).


2

Dışa aktarılan bir değişken (env) ile dışa aktarılmamış bir değişkenin ortamda bulunmaması arasındaki farkı göstermek için:

Bunu yaparsam:

$ MYNAME=Fred
$ export OURNAME=Jim

env'de yalnızca $ OURNAME görünür. $ MYNAME değişkeni env'de değil.

$ env | grep NAME
OURNAME=Jim

ancak kabukta $ MYNAME değişkeni var

$ echo $MYNAME
Fred

1

Varsayılan olarak, bir komut dosyası içinde oluşturulan değişkenler yalnızca geçerli kabuk tarafından kullanılabilir; alt işlemlerin (alt kabuklar) ayarlanmış veya değiştirilmiş değerlere erişimi olmaz. Alt işlemlerin değerleri görmesine izin vermek için verme komutunun kullanılması gerekir.


0

Tartışmada açıkça belirtilmemesine rağmen, tüm değişkenler alt sürece kopyalandığından, bash içinden bir alt kabuk üretilirken dışa aktarma kullanılması gerekli DEĞİLDİR.


Lütfen söylediklerinizin yukarıdaki örneklerle verilen cevaplarla doğrudan çeliştiğini açıklayın.
Mike Lippert

Değişkenlerin global olarak dışa aktarılmasını istemiyorsanız, ancak yalnızca alt işlem için kullanılabilir durumdaysa, bu doğru yoldur! Teşekkür ederim.
jtblin
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.