Bir ortam değişkenini nereden dışa aktarmalıyım ki bash / dash, etkileşimli / etkileşimli olmayan, oturum açma / oturum açma dışındaki tüm kombinasyonlar onu alacaktır?


11

Soru için motivasyon:

Unity masaüstü ile Ubuntu 12.04 LTS 2 kullanıyorum. .Bashrc dosyamda PATH değişkenime birkaç dizin ekliyorum ve JAVA_HOME gibi birkaç ortam değişkeni tanımlıyorum. Uygulamaları bir terminalden başlattığımda (çalışan bash, varsayılan kabuğum) bu harika çalışıyor, ancak Unity başlatıcıyı kullanan kısayolların birçoğu için #! / Bin / sh kullanmak için tanımlanmış gibi görünen uygulamaları çalıştırıyorlar. / bin / tire olarak adlandırılır ve ~ / .bashrc veya ~ / .profile öğelerinin içeriğini almazlar.

Sanırım .bashrc değişikliklerini almaya zorlamak için / bin / sh yerine / bin / bash kullanmak için bu kısayolları değiştirebilirim, ancak bu gerçekten acayip görünüyor.

Ubuntu 12.04'ün (varsayılan olarak) / bin / sh - / bin / dash olduğu ve varsayılan kabuğumun / bin / bash olduğu düşünüldüğünde, PATH'ı değiştirmeyi ve istersem ortam değişkenlerini tanımlamayı seçebileceğim tek bir yer var tüm bu koşullar altında mevcut olmak :

  1. Ne zaman bir oturum açma olmayan bash kabuğu (birlik içinde terminal kullanarak) oluşturmak
  2. Ne zaman bir giriş bash kabuğu oluşturduğumda (örneğin, ssh üzerinden uzaktan oturum açma)
  3. Ne zaman bir Unity uygulama başlatıcısı kullanırsam (başlatıcı / bin / sh kullanıyorsa).
  4. Bir cron işi yürütüldüğünde (/ etc / crontab içinde SHELL = / bin / sh verildiğinde).

Doğru anlarsam, tahmin ediyorum:

  • (1) / (2) ve (3) / (4) farklıdır, çünkü (1) / (2) bash ve (3) / (4) kesiktir.
  • (1) ve (2) farklıdır çünkü bash'ın yüklemeyi seçtiği dosyalar, bir giriş kabuğu olup olmamasına bağlı olarak değişir.
  • (3) ve (4) farklıdır, çünkü (3) giriş yaptıktan sonra bir noktada gelecek (ve bu nedenle ~ / .profile üst süreçlerinden biri tarafından kaynaklanmış olacakken (4) Ben değilim nokta değil kaydedilir ve dolayısıyla ~ / .profile okuma gitmiş olmayacak.

(Kabuğun etkileşimli olup olmadığı gibi diğer faktörlerin de önemi varsa şaşırmazdım, bu yüzden muhtemelen tahmin etmediğim daha fazla kombinasyon var ... Sorumu geliştirmekten memnunum " " bu durumda.)

Bir noktada, birisinin ortam değişkenlerini kabuktan bağımsız bir şekilde (veya en azından tire / bash uyumlu bir şekilde) nasıl / nerede değiştireceğinizi söyleyen bir tür rehber yapması beklenirdi ... Böyle bir rehber bulmak için doğru arama terimlerini bulmak gibi görünüyor.

Çözümler veya çözüm önerileri büyük beğeni topluyor!

Güncellenmiş:

  • Açıklama: Bu, 12.04 yükleme işlemi tarafından oluşturulan varsayılan Ubuntu kullanıcısıdır, bu nedenle fantezi değildir. Bu mu var bir ~ / .profile (açıkça kaynaklar ~ / .bashrc) ve sadece ~ / .bash * dosyaları Bashrc, .bash_history ve .bash_logout ... öylesine hayır hayır .bash_profile var olan sunuyoruz.
  • Kapsam vurgu: Gerçekten varsayılan interaktif kabuk (bash) ve (tire diğer adı) kullanımı / bin / sh olur herhangi komut dışında herhangi kabukları umurumda değil, bu yüzden her şey bu zorlaştırmak için gerek yoktur ekstra için tcsh / ksh / zsh / vb. destek.

2
Bir dosyaya yerleştirin ve diğer rc dosyalarının kaynak yapmasına izin verin.
konsolebox

Burada var çizgi adam sayfasına göre giriş kabukları için $ HOME / .profile okumak olmalıdır.
Etan Reisner

@konsolebox Hangi rc dosyaları? AFAICT, dash'in bir rc dosyası yok. Ve belirttiğim gibi, tire ~ / .profile içeriğini alıyor gibi görünmüyor.

@EtanReisner Evet ve sorunun konusu bu. Kısa çizgi bir giriş kabuğu olarak çalışmadığında (ve dolayısıyla ~ / .profile kaynaklanmıyorsa), ne olacak?

@Mickalot Etkileşimli olarak çizgi çalıştırıyor musunuz? Değilse, -l seçeneğini eklemeyi deneyin.
konsolebox

Yanıtlar:


9

Kabuk çağırma biraz karmaşık bir şeydir. Bash ve tire man sayfalarının bununla ilgili INVOCATIONbölümleri vardır .

Özetle diyorlar (kılavuz sayfasında daha fazla ayrıntı var, okumalısınız):

When bash is                   | it reads
-------------------------------|----------
login shell                    | /etc/profile and then the first of ~/.bash_profile, ~/.bash_login or ~/.profile that exists.
                               |
interactive non-login shell    | /etc/bash.bashrc then ~/.bashrc
                               |
non-interactive shell          | The contents of $BASH_ENV (if it exists)
                               |
interactive (as "sh")          | The contents of $ENV (if it exists)

-

When dash is                   | it reads
-------------------------------|---------
login shell                    | /etc/profile then .profile
                               |
interactive shell              | The contents of ENV (it it exists, can be set in .profile as well as in initial environment)

Hiçbirini kullanmadığım için başka mermileri elden bilmiyorum. En iyi seçeneğiniz, ortak konum komut dosyasına işaret etmek için birkaç ortam değişkeni ayarlamak ve kapsamı olmayan birkaç durumda (uygun olduğunda) manuel olarak kaynak oluşturmak olabilir.


Ne yazık ki, bu sorunun temel noktası çizgi tablonuzda eksik olanıdır. Unity masaüstü, #! / Bin / sh ile başlayan herhangi bir komut dosyasını çağırdığında, giriş yapmayan, etkileşimli olmayan bir çizgi kabuğu başlatır (varsaydığım şey). Soru yani: nasıl aynı ortam değişkenleri kullanılabilir yapabilirim orada matris içinde başka her yerde mevcut olduğu?

Sağ. Bu yüzden bash'ın bu alan için BASH_ENV eklediğini hayal ediyorum. Dash'in o yuvada çalışan hiçbir şeye sahip olmadığı göz önüne alındığında, dash'i başlatan uygulama ortamındaki değişikliği etkilemeden (dash'i devralacak şekilde) bu sorunu çözebileceğinizden emin değilim. Bu, X ortamınızda @Mickalot'tan .xsession (rc) yorumunun devreye girdiği ortam değişkenlerinin ayarlanmasını gerektirir. Bu hala belirttiği gibi, dördüncü maddeyi dışarıda bırakıyor (ama bunun aslında biraz kasıtlı olduğuna inanıyorum).
Etan Reisner

Ubuntu 12.04 LTS'de olduğumdan, cron aslında pixie-cron, bu yüzden crontab dosyamdaki env değişkenlerini tanımlayabilirim ... SHELL = / bin / bash ve BASH_ENV = ~ / .bashrc yapmalı mı?

3

Yani, buna yaklaşmanın birkaç yolu var. Birçok kişi ya:

a. Tüm sh tarzı mermilerinizde ortak olan bir dosyaya sahip olun, diyelim .shcommonve her .profile .bashrc .kshrcet cetra'da bunu sadece. .shcommon

b. Her şeyi koyun .profileve bunu diğer dosyalardan kaynaklayın.

Belirli kabuklar veya etkileşimli ve etkileşimli olmayan kabuklar için gereken şeyler, kaynak yapmadan önce uygun dosyaya girebilir .shcommon

Şahsen, birden fazla dosyayı yönetmekten hoşlanmıyorum. Bu yüzden, aşağıdaki yaklaşımı kullanıyorum:

İlk olarak, ihtiyacım olan her şey girer .profile Bazı bash ve ksh'a özgü şeylerim olduğundan, şu anki kabuk adını aşağıdakileri kullanarak belirlerim:

# get name of current shell
# strip leading - from login shell
export SHELLNAME="${0#-}"

ve aşağıdaki gibi bir şeyde belirli mermiler için komutları var (bazıları bir vaka ifadesini tercih eder).

if [ "$SHELLNAME" = 'bash' ]
then
    shopt -s checkwinsize

elif [ "$SHELLNAME" = 'ksh' ]
then
    stty erase ^?
fi

Yalnızca etkileşimli kabuklarda çalışması gereken komutlarım varsa, aşağıdakileri kullanırım:

# check for interactive flag i in shell options $-
# in bash and ksh you could use the following, but breaks in dash
# if [[ $- == *i* ]]
if [ "$(echo $- | grep i)" != "" ]
then
  fortune
fi

Tüm sh tarzı mermilerde yaygın olan şeyler, örneğin, PATHen üste gidebilir.

Sonra, aynı dosya tüm sh tarzı kabukları yüklemek için sembolik kullanın:

ln -s .profile .bashrc
ln -s .profile .kshrc

Birkaç yan not, eğer varsa .bash_profile, o zaman bash bunu yerine yükleyecektir .profileancak tire ve ksh yine de yüklenecektir .profile Bu, sorunun bir parçası olabilir.

Ayrıca, gerçekten POSIX uyumlu komut dosyaları istemiyorsanız #!/bin/bash, komut dosyalarınızda kullanmayı düşünebilirsiniz #!/bin/dash. bash çok güzel ekstra özelliklere sahiptir ve sh bu özelliklerin çoğunu devre dışı bırakacağı için tire veya bash çağrılır.

Ayrıca, bash man sayfası yüklendiğinde ne zaman .profileaçıklandığını açıklamak için iyi bir iş .bashrcçıkarır. Benzer kurallar ksh için de geçerlidir. tire .profile, oturum açıldığında yüklenir ve içindeki ENVortam değişkeni kullanılarak belirtilen etkileşimli kabukların başlangıcında bir dosya yüklemenizi sağlar .profile(kısa çizgi sayfasını da kontrol edin ve .profile öğesini arayın).


Kabuk adı için yalnızca 0 TL test etmekle kalmaz mıydınız? Bunun işe yaramadığı mermiler / kasalar var mı?
Etan Reisner

Benzer şekilde, $ i için kontrol - etkileşimli kabuk testi için yeterli değil mi? (Verdiğim tty olmadan etkileşimli mermileri tetikleyecektir, ancak bu istenmeyen bir yan etki olabilir veya olmayabilir.)
Etan Reisner

@Etan: Hrm, ilk önce denediğimi $0ve problemlerle karşılaştığımı biliyorum ... Tam olarak ne olduklarını hatırlayamıyorum. Konsola doğrudan Yapma neleri gösterir $0şekilde -bashyerine bashama bu çözüme kavuşturulabilir.

@Etan: Evet, i'yi kontrol etmek $-de işe yarayacaktı. Ne zaman bir tty olmadan interaktif bir kabuk olurdu düşünmek gerekir? Çözümünüzün bir sebepten ötürü daha iyi bir "hissi" var, bunu değiştirebilirim.

-İçinde -basharaçlar "giriş kabuğu" ama evet, o değeri test etmek veya başkasına görüntülemek istediğiniz yerlerde bunun için hesaba gerekir.
Etan Reisner

0

Vakalar (1) ve (2), ortam değişkenlerimi .bashrc ve .profile kaynaklarından sağlayarak çözüldüğünden, asıl soru "(3) ve (4) için aynı değişkenleri kaynakladığım dosyanın adı nedir.

Askubuntu'da sorunun (3) kısmına (Unity masaüstüne aktarılacak çevre değişkenini nasıl alabilirim) bir yanıt var gibi görünüyor . Buradaki öneri, / etc / X11 / Xsession kaynaklı bir ~ / .xsessionrc dosyası oluşturmaktır. (Bunu denedim ve işe yarıyor gibi görünüyor ... yay!)

Hala ne yapacağım karşısında şaşkına dönüyorum (4). Elbette, eğer ben bir cron işi (veya sunucu programı) oluşturmak, ben 'bash -i -c / bin / foo' doğru ortam değişkenleri yüklemek için bash kullanarak zorlamak için böyle bir şeyle '/ bin / foo' yerine, ancak bu da benim adımda daemon görevleri veya cron işi yükleyebilecek üçüncü taraf araçlarla uğraşmak zorunda kalacağım anlamına geliyor. Yuk.

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.