Yanıtlar:
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 export
ve 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.
name=value command
yok alt süreçte değişken kullanılabilir hale command
.
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
.
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.
dash
yapacağından emin değilim . Orijinal poster özellikle soruyordu bash
.
bash
ancak herhangi bir bourne-kabuk varyantı için eşit olarak geçerlidir. Aşırı spesifik olmak ve sadece geçerli olan cevaplar vermek bash
büyük bir kötülüktür.
bash
Kabuğun jQuery'sidir.
export makes the variable available to subshells, and that is correct
Bu, terminolojinin çok kafa karıştırıcı bir kullanımıdır. Alt kabukların export
değişkenleri devralması gerekmez . Alt işlemler yapılır.
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 bash
Senaryonuzun görünen).
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 exec
ve 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 exec
komutla değiştirdik, bu yüzden bu komutu yürütecek hiçbir şey kalmadı.
&
) ayrıca bir alt kabuk oluşturur.
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 $var
ikinci satıra yürütülürse hiçbir şey yazdırmaz. Ama bir tane var=asdf bash -c 'echo $var'; echo $var
verir asdf\nasdf
.
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 export
sonra 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
B
Alt 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.
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
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 export
var olan budur.
export
Bash 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:
export
iş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.Kabul edilen cevap bunu ima eder, ancak kabuk yuvalarına bağlantıyı açıkça yapmak istiyorum:
Daha önce de belirtildiği gibi, export
bir değişkeni hem kabuk hem de çocuklar için kullanılabilir hale getirecektir. Eğer export
edilir 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
İş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:
bash-hackers.org/wiki/doku.php/scripting/processtree
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 export
sonundaki 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).
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
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.
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.
export name=value
taşınabilir olmadığını da not edin . Tam olarak ne istediğinize bağlı olarak,name=value; export name
taşınabilir bir çözüm deneyin .