Ortam değişkenlerini ayarlamanın en iyi dağıtım / kabuk agnostik yolu nedir?


31

Soru her şeyi söylüyor. Şu anda Arch Linux ve zsh kullanıyorum, ancak dağıtımları veya mermileri değiştirdiğimde (en azından) hem VT'lerde hem de xterms'de çalışan ve aynı zamanda (umarım, tercihen) çalışmaya devam edecek bir çözüm istiyorum.

Farklı soruların farklı dokümanlarındaki bu soruya çılgınca farklı cevaplar duydum. Ubuntu, "use .pam_environment" diyor. Bence Arch'ta önerdikleri şey kabuğuna bağlı. Şu anda her şeyi .profile 'e koyuyorum ve eğer bir kabuk bir nedenden dolayı kaynak göstermiyorsa (örneğin .bash_profile varsa bash), elle kaynak yaparak bunu geçersiz kılıyorum. Fakat daha iyi bir yol olmalı gibi görünüyor.


2
Bunun dağıtımla ve kabukla ilgisi yok. Ancak, bunu yapmanın taşınabilir bir yolu olduğundan emin değilim.
Joseph R.

Hmm. Harika .
Strugee

Yanıtlar:


29

Ortam değişkenlerini ayarlamak için maalesef tamamen taşınabilir bir yer yok. En yakın gelen iki dosya ~/.profile, geleneksel kurulum olan ve birçok kurulumda kutudan çıkan ve ~/.pam_environmentmodern, sıradan fakat sınırlı bir alternatif.

Ne koymak ~/.pam_environment

Dosya ~/.pam_environment, PAM kullanan ve bu dosyayı etkinleştiren tüm giriş yöntemleriyle okunur . Bu, günümüzde çoğu Linux sistemini kapsamaktadır.

En büyük avantajı ~/.pam_environment(etkinleştirildiğinde) kullanıcının kabuğu başlamadan önce okunmasıdır, bu nedenle oturum türü, oturum açma kabuğu ve diğer karmaşıklıklardan bağımsız olarak çalışır. Hatta su -c somecommandve gibi etkileşimli olmayan girişler için bile çalışır ssh somecommand.

Bunun ana sınırlaması, ~/.pam_environmentkarmaşık kabuk sözdizimini değil, yalnızca basit atamaları koyabileceğinizdir. Bu dosyanın sözdizimi aşağıdaki gibidir.

  • Dosyalar satır satır ayrıştırılır.
  • Önde gelen beyaz boşluk yoksayılır.
  • İsteğe bağlı olarak satırları exporttek bir boşlukla başlatabilirsiniz (sekme değil, şekil git).
  • Bundan sonra, her satır VAR=VALUEVAR'ın harflerden, rakamlardan ve alt çizgilerden oluştuğu forma sahip olmalıdır .
  • # bir yorum başlatır, bir değerde görünemez.
  • VALUE 'veya ile başlıyorsa "ve aynı bir fiyat teklifi içeriyorsa, VAR, tırnak işaretleri arasındaki dizeye ayarlanır (ikinci tekliften sonra gelen her şey yoksayılır). Aksi halde, VAR, =işaretten sonra dizeye ayarlanır .
  • Hayır =ise, değişken ortamdan kaldırılır.

Dolayısıyla, tersine, ~/.pam_environmentçok çeşitli koşullarda çalışır. Aşağı yönde, bir değişkenin değerini başka bir değişkene (örneğin PATH'ye bir dizin ekleyerek) temel almak veya bir komutun çıktısını kullanmak (örneğin, bir dizin veya program varsa test etmek) gibi bazı dinamik ayarlara sahip olamazsınız. karakterleri ( #'", newline) değeri koymak imkansız veya zahmetli.

Ne koymak ~/.profile

Bu dosya taşınabilir (POSIX) sh sözdizimine sahip olmalıdır. [[ … ]]Sisteminizde bu kabukları bulunduğunu biliyorsanız, yalnızca ksh veya bash uzantılarını (diziler, vb.) Kullanın /bin/sh.

Bu dosya otomatik uygulamalardaki komut dosyaları tarafından okunabilir, bu nedenle herhangi bir çıktı ya da çağrı üreten programları çağırmamalıdır exec. Bunu metin modu oturum açmalarında yapmak istiyorsanız, yalnızca etkileşimli kabukları için yapın. Örnek:

case $- in *i*)
  # Display a message if I have new mail
  if mail -e; then echo 'You have new mail'; fi
  # If zsh is available, and this looks like a text-mode login, run zsh
  case "`ps $PPID` " in
    *" login "*)
      if type zsh >/dev/null 2>/dev/null; then exec zsh; fi;;
  esac
esac

Bu, /bin/shgiriş kabuğunuz olarak kullanmanın ve en sevdiğiniz kabuğunuza geçmenin bir örneğidir . Ayrıca sysadmin değiştirmeme izin vermediğinde, bash'ı giriş kabuğum olarak nasıl kullanabilirim

~/.profileGrafiksel olmayan giriş bilgileri ne zaman okunmaz?

Farklı giriş kabukları, farklı dosyaları okur.

Giriş kabuğunuz bash ise

Bash okuyor ~/.bash_loginya da ~/.bash_profilevarsa onlar var ~/.profile. Ayrıca bash ~/.bashrc, etkileşimli olsa bile bir giriş kabuğunda okunmaz . Bu tuhaflıkları bir daha asla hatırlamak zorunda kalmamak ~/.bash_profileiçin aşağıdaki iki satırdan oluşan bir a oluşturun :

. ~/.profile
case $- in *i*) . ~/.bashrc;; esac

Ayrıca bakınız bash ile ortam değişkenlerini ayarlamak için hangi kurulum dosyaları kullanılmalıdır?

Giriş kabuğunuz zsh ise

Zsh okur ~/.zprofileve ~/.zloginancak ~/.profile. Zsh, sh'den farklı bir sözdizimine sahiptir, ancak ~/.profilesh emülasyon modunda okuyabilir . Bunu sizin için kullanabilirsiniz ~/.zprofile:

emulate sh -c '. ~/.profile'

Ayrıca bkz. Zsh ~ / .profile

Giriş kabuğunuz başka bir kabuksa

Orada yapabileceğiniz pek bir şey yok, /bin/shgiriş kabuğunuz olarak ve en sevdiğiniz kabuğunuzu (balık gibi) yalnızca etkileşimli bir kabuk olarak kullanmanız çok kısa . Zsh ile yaptığım şey bu. 'Den başka bir kabuk çağırma örneği için yukarıya bakın ~/.profile.

Uzaktan komutlar

Etkileşimli bir kabuktan geçmeden bir uzak komutu çağırırken, tüm kabukları başlangıç ​​dosyasını okumaz.

Ksh, değişmeyi ENVbaşarırsanız , değişken tarafından belirtilen dosyayı okur .

Bash okur ~/.bashrcÇünkü eğer interaktif değil (!) Ve üst süreç denir rshdya sshd. Böylece ~/.bashrcile başlayabilirsiniz

if [[ $- != *i* ]]; then
  . ~/.profile
  return
fi

Zsh ~/.zshenv, başladığında her zaman okur . Dikkat edin, çünkü bu, diğer değişkenleri ayarladığınız bir alt kabuk olsa bile, her zsh örneği tarafından okunur. Eğer zsh giriş kabuğunuzsa ve sadece uzak komutlar için değişkenleri ayarlamak için kullanmak istiyorsanız, bir koruyucu kullanın: ~/.profilegibi bir değişken ayarlayın MY_ENVIRONMENT_HAS_BEEN_SET=yesve okumadan önce bu korumayı kontrol edin ~/.profile.

if [[ -z $MY_ENVIRONMENT_HAS_BEEN_SET ]]; then emulate sh -c '~/.profile'; fi

Grafiksel oturum açma durumu

Pek çok dağıtım, ekran yöneticisi ve masaüstü ortamı, çalıştırma ~/.profilekomutlarını açık bir şekilde başlangıç ​​komut dosyalarından alarak veya bir giriş kabuğu çalıştırarak düzenler .

Ne yazık ki, ~/.profileokunamayan distro / DM / DE kombinasyonlarını işlemek için genel bir yöntem yoktur .

Başladığınız geleneksel bir oturum kullanıyorsanız ~/.xsession, ortam değişkenlerinizi ayarlamanız gereken yer burasıdır; kaynak yaparak ~/.profile(yani . ~/.profile) yapın. Bazı kurulumlarda, masaüstü ortamı başlangıç ​​komut dosyalarının yeniden kaynaklanacağını unutmayın ~/.profile.


ne gelmez case $- in *i*)mi?
qodeninja

2
@qodeninja çalıştırır (eşleme kadar aşağıdaki talimatlar ;;veya esac) eğer $-maçları deseni *i*ise, yani $-içeren i, kabuk etkileşimli yani eğer.
Gilles 'SO- kötülük yapmayı bırak' 05

$-şu anda ayarlanan kabuk seçeneklerinin bir dizesidir. (gibi set -x). ietkileşimli kabuk anlamına gelir.
Peter Cordes

Öyleyse, ortak bir dosyaya, yani ~/.config/envöykünme olmadan bile kaynak olamaz mı ?
Kevin Suttle,

1
@ StéphaneChazelas Bu saf bir görünüm. Benim tutmak .profileoldukça eski Bourne kabukları ile sürekli uyumluluk, ama bazı insanlar sadece ilgilendirmiyor biliyoruz. İnsanların sh = bash'ı kendi dosyaları için varsayarak hiçbir şeyim yok, sadece #!/bin/shbash özelliklerini kullanan bir betik yayınlamaları umrumda .
Gilles 'SO- kötülük' stop

4

Bildiğim kadarıyla, ortam değişkenlerinin nasıl ayarlanacağına dair bir dağıtım ve kabuk agnostik standart yok.

En yaygın ve fiili standart olarak görünüyor /etc/profileve ~/.profile. İkinci en yaygın olarak görünüyor /etc/environmentve ~/.pam_environment.

Bana bulduğum tüm dökümanları da zaten buldum. Zaten diğer okuyucular için onları burada listeliyorum.

  • Debian önerir /etc/profileve ~/.profile( link ).
  • Ubuntu önerir /etc/environmentve ~/.pam_environment( link ).
  • Arch Linux, diğerleri arasında /etc/profileve /etc/environment( link ) bahseder .

Bonus: /etc/environmentdebian'da kullanımı ve / veya kötüye kullanımını sorgulayan bir metin ( bağlantı , son güncelleme 2008).


Kullandığınız dosyadan bağımsız olarak, farklı mermiler arasında uyumsuz sözdizimine rastlarsınız.
Joseph R.

1
@JosephR. Çoğu kabuk geriye dönük uyumluluk sağlamaz shmı?
POSIX'e bağlı kaldığın

1
AFAIK csh, POSIX yönteminde değişkenler ve arkadaşlar atayamazsınız ( setya da benzeri bir şeye ihtiyacınız vardır setenv)
Joseph R.

0

Aşağıdaki komut dosyasını ~ / bin / agnostic_setenv ekledim:

#!/bin/csh -f
set args = ($*)
if ($#args == 1) then
   echo "export $args[1]="
   exit 0
endif

if ($#args == 2) then
   if ("$args[1]" =~ *csh*) then 
      echo "setenv $args[2]"
      exit 0
   else
      echo "export $args[1]=$args[2]"
      exit 0
   endif
endif

echo "setenv $args[2] $args[3]"

Ve ~ / .perl-homedir'de kullanıyorum:

eval `${HOME}/bin/agnostic_setenv $shell PERL_HOMEDIR 0`

Agnostic_unsetenv için benzer bir komut dosyası:

#!/bin/csh -f
set args = ($*)
if ($#args == 1) then
   echo "export $args[1]"
   exit 0
endif

echo "unsetenv $args[2]"
exit 0
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.