Tüm alt kabuklarda kullanılabilen ve değiştirilebilecek bir env değişkenini dışa aktarın?


22

Varsayalım ki

export MY_VAR=0

içinde ~/.bashrc.

Açılmış bir gnome terminalim var ve bu terminalde $MY_VARdeğeri değiştiriyorum 200. Eğer yaparsam

echo $MY_VAR

Bu terminalde 200gösterilmiştir.

Şimdi, GNOME terminalimde başka bir sekme açtım ve

echo $MY_VAR

... ve yerine 200, var 0.

Bir terminal bir ortam değişkenini değiştirdiğinde, bu modifikasyonu (200'e ayarlayarak) sonraki tüm alt kabuklarda kullanılabilir hale getirdiğinde 200 değerini sürdürmek için ne yapmalıyım? Mümkün mü?

Yanıtlar:


23

Ortamın bir kopyası alt kabuklara yayılır, bu nedenle işe yarar:

$ export MY_VAR=200
$ bash
$ echo $MY_VAR
200

ancak bu bir kopya olduğundan, bu değeri ana kabuğa kadar elde edemezsiniz - en azından çevreyi değiştirerek değil.

Aslında Gnome Terminali'ndeki yeni sekmenizde olduğu gibi, ebeveynden ayrı olarak başlatılan "kardeş" mermileriyle paylaşılan, global bir değişken gibi davranan bir şey yapmak için gerçekten bir adım daha ileri gitmek istediğiniz gibi geliyor.

Çoğunlukla, cevap "yapamazsınız, çünkü ortam değişkenleri bu şekilde çalışmaz" dır. Ancak, başka bir cevap var ki, bir şeyleri her zaman kesebilirsin. Bir yaklaşım değişkenin değerini bir dosyaya yazmak gibi bir şey olur ~/.myvarve sonra bunu da içine alır ~/.bashrc. Ardından, her yeni kabuk bu dosyadan okunan değerle başlayacaktır .

Bir adım daha ileri gidebilirsiniz - ~/.myvarformatta olun MYVAR=200ve ardından PROMPT_COMMAND=source ~/.myvarher yeni komut isteminde değerin yeniden okunmasına neden olacak şekilde ayarlayın . Hala oldukça paylaşılan bir global değişken değil, ancak böyle davranmaya başlıyor. Yine de, bir geri dönüş yapılıncaya kadar aktif olmayacaktır, ki bu ne yapmaya çalıştığınıza bağlı olarak ciddi bir sınırlama olabilir.

Ve sonra, elbette, sonraki şey otomatik olarak değişiklikler yazmaktır~/.myvar . Bu biraz daha karmaşık bir hal alıyor ve bu noktada duracağım, çünkü gerçekten, çevre değişkenleri kabuklar arası bir iletişim mekanizması olmak zorunda değildi ve bunu yapmanın başka bir yolunu bulmak daha iyi.


10
İşkencenin altında kabuk

Evet üzgünüm. Bu yüzden durdum. :)
mattdm

“Bu, küresel bir değişken gibi davranan bir şey yapmaktır” - Eh, aslında, yapmaya çalıştığım şey buydu. ~ / .Myvar hoş değil, ama işe yarıyor. Başka bir önerin var mı?
Birisi hala sizi MS-DOS kullanıyor

2
Peki, biraz geri çekilelim. Neden global bir değişken istiyorsun?
mattdm

1
@ mattdm: Uymam gereken bazı "bürokrasiler" var. Bunlardan biri, bir yorumla birlikte yapmam gereken bir sürü kod. Bu kodlar şimdi, bir klasör hiyerarşisindedir (ev / kullanıcı / projeler / proje kodu / kod1 / kod2). Env değişkenlerine code1 ve code2 ayıklayan bir işlev yaptım (bu nedenle bir etkinlik yapmam gerektiğinde, yalnızca dir içindeki içini kodlar ile çağırırım), ve bunları yaparken, vim kullanıyorum ve bazı işlevler var. bu değişkenleri oku ve otomatik olarak yorum yap. Bunun için dosyaları kullanarak bir çözüm olabilir düşünüyorum.
Birisi hala sizi MS-DOS kullanıyor,

13

Ben olduğunu varsayalım export MY_VAR=0içinde ~/.bashrc.

İşte senin hatan. Ortam değişkenlerinizi ~/.profile, giriş yaptığınız zaman ~/.bashrcokunan bir kabuk tanımlamanız gerekir . iç kabuğu başlattığınızda geçersiz kılınır MY_VAR. Bunu yapmamış olsaydınız, ortam değişkeniniz aşağıya doğru yayılırdı.

~/.bashrcVs hakkında daha fazla bilgi için , bu konuyla ilgili önceki yayınlarıma~/.profile bakın .

Not yukarı doğru (otomatik ana kabuğu yansıyan alt kabuğa modifiye edilmiş bir değer elde) yayılımı, nokta mümkün değildir.



3

Ortam değişkenlerini hiç kullanmayın. Dosyaları kullanın.

Dosyayı güncellerken / okurken işlemlerin birbirine geçmesini önlemek için, amacı kilitli değilse 1 $ olan bir dosyayı güncellemek olan kilit dosyalarını ve küçük ön uç güncelleyici komut dosyalarını kullanın. Lockfiles, belirli bir dosyanın var olup olmadığını (/var/run/yourscript.lck) olup olmadığını kontrol ederek uygulanır ve eğer varsa, dosyanın bir süre kaybolmasını bekleyin, yoksa kaybolursa başarısız olur. Ayrıca dosyayı güncellemeyi tamamladığınızda kilit dosyasını silmelisiniz.

Dosya meşgul olduğu için bir komut dosyasının bir dosyayı güncelleyemediği bir durumu ele almaya hazır olun.


8
Bir hile: mkdirAtomik bir test et ve oluştur olarak çalıştığından , kilitleme için dosyalar yerine dizinleri kullanın .
mattdm

1
Kilitleme hakkında konuşmak istiyorsanız, kullanıyor olabilirsinizflock(2)
Ehtesh Choudhury

@ mattdm Bir linkin ln -s dummy lockfile(kopmuş olsa bile), link zaten mevcutsa başarısız olacağından çalışabileceğini de buldum . Bunun% 100 güvenli olup olmadığını test etmenin bir yolunu merak ediyorum.
Kova Gücü

1

Bu soruyu daha önce google çıktığımda, durum güncellemesi sorununu (örneğin kabuk değişkenleri) alt kabuklardan çözmeye çalışıyordum. Böylece, biri bir boru hattının içinde değişkenler atayabilir - ve atama ebeveyn tarafından şeffaf bir şekilde görülebilir.

Tabii ki, bu basit bir şekilde mümkün değildir, çünkü bir boru hattının bireysel bölümleri fork, üst kabuktan alt kabuklarda yürütülür ve bu nedenle ebeveynin hafızasına yazma üzerine kopyalanan bir belleğe sahiptir. Ancak, " paylaşılan hafıza " türündeki IPC'lere dayanarak ince ve şeffaf bir çözümün mümkün olabileceğini düşünmüştüm .

Ve tam olarak bu tasarımın bir uygulamasını bile buldum ... ama Perl'de.

Yine de bu cevabı olası bir çözüm olarak eklemek.

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.