Bir ortam değişkeni tam olarak nedir?


42

Bunun VARIABLE=valuebir ortam değişkeni export VARIABLE=valueyarattığını ve mevcut kabuk tarafından oluşturulan işlemlerde kullanılabilir olduğunu biliyorum . envmevcut çevre değişkenlerini gösterir, fakat nerede yaşıyorlar? Ne (veya bir çevre değişkeni içeren ortamı bu konuda,)?

Yanıtlar:


29

Bir çevre göründüğü kadar büyülü değildir. Kabuk hafızada saklar ve execve()sistem çağrısına geçer . Alt işlem, adlı bir dizi işaretçisi olarak miras alır environ. Gönderen execveman:

ÖZET

   #include <unistd.h>

   int execve(const char *filename, char *const argv[],
              char *const envp[]);

argvYeni programa geçirilen argüman dizelerinin bir dizisidir.
Kurallara göre, bu dizelerin ilki, yürütülen dosyayla ilişkili dosya adını içermelidir. envpgeleneksel olarak yeni programa ortam olarak geçirilen, key = value formundaki geleneksel bir dizge dizisidir.

environ(7)Manpage de bazı fikir veriyor:

ÖZET

   extern char **environ;

AÇIKLAMA

Değişken environ, "çevre" olarak adlandırılan dizelere bir işaretçi dizisini gösterir. Bu dizideki son işaretçi değeri var NULL. (Bu değişken kullanıcı programında bildirilmelidir, ancak <unistd.h>başlık dosyalarının libc4 veya libc5'ten gelmesi durumunda başlık dosyasında bildirilmesi ve glibc ve _GNU_SOURCE öğelerinin gelmesi durumunda tanımlanması gerekir.) Bu dizgiler, İşlemi başlatan exec (3) çağrısı ile yapılan işlem.

Bu GNU man sayfalarının her ikisi de POSIX belirtimiyle eşleşiyor


4
+1 muhtemelen exec(3)ailenin bazı üyelerinin (ör. Exec * v ile eşleşmeyenlerin) örtülerin altındaki ortamlardan geçtiğini belirtmeye değer .
msw

5
Bunun alt süreçlerle ilgili olmadığını (alt süreçler ebeveynlerinin tüm hafızasını devralır) değil, çalıştırılan programlar (aynı süreçte) olduğunu, bu nedenle bir execve () sistem çağrısında (aksi takdirde hafızayı silen) veri iletmenin başka bir yolunun olduğunu unutmayın. sürecin).
Stéphane Chazelas

@ msw: Bu exec*e, environgenel değişkeni dolaylı olarak kullanmak yerine açıkça bir env ileten değişkenlerdir. vAracı "vektör" ve bir dizi (yerine bir "listesinde" (değişken uzunluklu fonksiyonu)) olarak geçirilen komut satırı bağımsız değişkenleri ifade eder execve, bir sistem çağrı ve diğer tüm exec*fonksiyonları bunun için libc sarma bulunmaktadır.
Peter Cordes

19

Sadece biraz yanlış anladınız: SOME_NAME=valuebir kabuk değişkeni yaratır (çoğu kabukta). export SOME_NAME=valuebir ortam değişkeni yaratır. Daha kötüsü için daha iyisi için, çoğu Unix / Linux / * BSD mermi, ortam değişkenlerine ve kabuk değişkenlerine erişimde aynı sözdizimini kullanır.

Bazı daha geniş anlamda, bir "çevre" sadece programın yürütülmesiyle birlikte gelen bilgilerdir. C programlarda, bir ile işlem kimliğini bulabilir getpid()bir kabuk programında bir değişken erişimini kullanmak istiyorsunuz, çağrı: $$. İşlem kimliği, program ortamının sadece bir parçasıdır. "Çevre" teriminin, program yürütme modellemesi gibi bazı teorik bilgisayar bilimi konularından geldiğine inanıyorum. Program yürütme modellerinin "değişkenler ve değerleri arasındaki ilişkileri içeren bir ortamı var ".

Ve sonuncusu, daha güçlü olan tanım Unix / Linux / * BSD mermileri için bir "ortam" ın ne olduğudur: isimler ("değişkenler") ve değerleri arasındaki ilişki. Çoğu Unix tarzı kabuk için, değerlerin tümü karakter dizeleridir, ancak eskisi gibi kesin değildir. Ksh, Zsh ve Bash bugünlerde değişkenler yazdılar. Hatta kabuk işlevi tanımları bile dışa aktarılabilir.

Düz kabuk değişkenlerinden ayrı bir ortam kullanımı, fork/exectüm Unix'lerin kullandığı yeni bir işleme başlama yöntemini içerir. Bir exportad / değer çifti olduğunuzda, bu ad / değer çifti, kabuk tarafından bir execve(2)sistem çağrısı ile başlatılan yeni çalıştırılabilir ortamlarda bulunacaktır ( kabuk komutunun kullanıldığı fork(2)durumlar hariç, genellikle execa'yı izler).

Bir takiben execve(), main()yeni ikili işlevi (göstergelerinden bir BOş sonlandırılmış dizisi olarak saklanan kendi komut satırı argümanları, ortama sahiptir var=value, dizeleri bakın environ(7)adam sayfası). Miras alınan diğer durum, ulimitayarları, geçerli çalışma dizinini ve execve()arayanın FD_CLOEXEC için ayarlanmadığı açık dosya tanımlayıcılarını içerir . Tty'nin şu andaki durumu (echo etkin, ham mod vb.), Yeni bir execişlem tarafından miras alınan yürütme durumunun bir parçası olarak kabul edilebilir .

Basit komutlar için (yerleşik veya kabuk işlevleri hariç) bashkılavuzun çalıştırma ortamı tanımına bakın .

Unix ortamı, en azından bazı işletim sistemlerinden farklıdır: VMS "lexicals", bir alt işlem tarafından değiştirilebilir ve bu değişiklik ebeveynde görülebilir. Bir cdçocuk işlemindeki bir VMS , ebeveynin çalışma dizinini etkiler. En azından bazı durumlarda ve hafızam başarısız oluyor olabilir.

Bazı ortam değişkenleri de, bilinen $HOME, $PATH, $LD_LIBRARY_PATHve diğerleri. Bazıları belirli bir programlama sistemine göre gelenekseldir, böylece bir ana kabuk belirli bir geçici dizin veya gösterilmeyen bir kullanıcı kimliği ve şifresi gibi bazı programlara çok ve çok özel amaçlı bilgi aktarabilir ps -ef. Basit CGI programları, örneğin web değişkenlerinden ortam değişkenleri aracılığıyla birçok bilgiyi devralır.


1
Hala biraz daha karmaşık görünüyor. En azından bash, SOME_NAME=value commandbu komut çağrısı için en azından SOME_NAME ortam değişkenini ayarlayacaktır. Kafa karıştırıcı bir şekilde, aynı ismin kabuk değişkenini ayarlamış gibi görünmüyor.
Samuel Edwin Ward

2
Daha kesin olmak gerekirse, ortam değişkenleri miras alınmaz, ancak açıkça bir kabuktan ortaya çıkardığı programlara aktarılır.
msw

2
@SamuelEdwinBu SOME_NAME=value commandbeklentinize aykırı davranmanızın nedeni, "SOME_NAME komutunu iletilen ortama ekleyerek bu kabuğun değişkenlerini değiştirmeyin" anlamına gelen özel bir sözdizimi olmasıdır.
msw

1
Büyüleyici, lambda matematiği / fonksiyonel programlama. Bu çok anlamlı olan ilginç bir bağlantı.
Matt,

1
Bunlardan bazıları doğru değil. Örneğin, altkabuklarda alt prosesleri ve gereken fork()ed, ancak ne (kopyalarını) kabuk değişkenleri alır.
ruakh

7

Rawest formundaki ortam değişkenleri yalnızca bir ad / değer çifti kümesidir. man 1 bashÇEVRE bölümünün altındaki bash adam sayfasında ( ) açıklandığı gibi :

   When  a  program  is invoked it is given an array of strings called the
   environment.   This  is  a  list  of  name-value  pairs,  of  the  form
   name=value.

   The  shell  provides  several  ways  to manipulate the environment.  On
   invocation, the shell scans its own environment and creates a parameter
   for  each name found, automatically marking it for export to child pro-
   cesses.  Executed commands inherit the  environment.

Pratik açıdan, mevcut kabuktan çağrılan programlarla paylaşılan veya benzersiz davranışı tanımlamanıza izin verir. Örneğin, kullanırken crontabveya sisteminizin varsayılan olarak kullanacağından başka bir düzenleyici visudotanımlamak için EDITORortam değişkenini tanımlayabilirsiniz. Aynısı, man sayfasının çıktısını görüntülemek için hangi çağrı programının kullanılması gerektiğine karar vermek maniçin PAGERortamınıza bakan komut gibi şeyler için de geçerli olabilir .

Oldukça fazla sayıda unix komutu çevreyi okur ve orada neyin olduğuna bağlı olarak bunlara bağlı olarak çıkış / işleme / eylemlerini değiştirir. Bazıları paylaşılır, bazıları programa özeldir. Çoğu man sayfası, ortam değişkeninin açıklanan program üzerinde nasıl bir etkisi olduğu hakkında bilgiler içerir.

Diğer pratik resimler, aynı platformda birden fazla Oracle kurulumu olan sistemler içindir. Ayarlayarak ORACLE_HOMEtüm oracle komutları takımı ( PATHortam değişkeninizden yüklenen şekilde ) sonra ayarları, tanımları, eşlemeleri ve kitaplıkları o üst düzey dizinin altından çeker. Aynı durum, java gibi JAVA_HOMEçevre değişkenleriyle birlikte diğer programlar için de geçerlidir .

bash, geçmiş ( HISTSIZE, HISTFILEvb), ekran boyutu ( COLUMNS), sekme tamamlama ( FIGNORE, GLOBIGNORE) yerel ayarlarından ve karakter kodlama / kod çözme ( LANG, LC_*), bilgi istemi ( PS1.. PS4) ' den bir dizi şeyin davranışını değiştirebilen birçok ortam değişkenine sahiptir ve öyleyse (tekrar bash man sayfasından bilgi arayınız).

Ayrıca, kendi özel ortam değişkenlerinizi kullanan komut dosyaları / programlar yazabilirsiniz (ayarları geçmek veya işlevleri değiştirmek için).


0

"Ortam Değişkenleri" , çalışan işlemlerin bir bilgisayarda nasıl davranacağını etkileyebilecek dinamik bir adlandırılmış değerler kümesidir.

Bunlar bir sürecin çalıştığı işletim ortamının bir parçasıdır. Örneğin, çalışan bir işlem, geçici dosyaları depolamak için uygun bir konum bulmak için TEMP ortam değişkeninin değerini veya işlemi çalıştıran kullanıcının sahip olduğu dizin yapısını bulmak için HOME veya USERPROFILE değişkenini sorgulayabilir.

Burada daha fazla bilgi → http://en.wikipedia.org/wiki/Environment_variable .

Çevre Değişkenleri hakkında bilmek istediğiniz her şey ... ↑


1
Bu bağlantıların kaybolması pek mümkün olmamakla birlikte, buradaki soruyu ilgili metinle cevaplamak ve bağlantıyı yedekleme bilgileri için bir ek olarak sunmak daha iyidir .
Anthon

@Anthon Doğru olduğuna inanıyorum ve elimden geldiğince değişiklikleri yapacağım ... Tavsiyen için teşekkürler ...
SoCalDiegoRob

-1

Bu cevap değişken, değer, değişken ikame, istemi, yankı, çekirdek, kabuk, fayda, oturum ve işlem terimleriyle ilgili bazı kabuk komut dosyası deneyimi ve bilgisi gerektirir.

Bir ortam değişkeni (envar), verilen işlemlerin bilgisayarın işletim sisteminde nasıl davranacağını etkileyebilecek bir dizi küresel tanımlanmış değişkendir.

1. Örnek bir giriş:

Envarları büyük$ ve küçük harflerle değiştiririz . Örneğin: $PS1.

Bu şekilde bir envar yazdırabiliriz:

echo $PS1

$PS1Unix isteminin değerini tutar. Yerel değerlerini söyle \u \w $.

  • \u (mevcut) kullanıcı anlamına gelir,
  • \w çalışma dizini için
  • $ istemi sınırlamaktır.

Yaptığımız Yani,: echo $PS1, biz değerlerinin görülmesi \u, \wartı sonunda dolar işareti.

Bu envarın değerlerini değiştirirsek, Unix davranışını bu bağlamda değiştirebiliriz. Örneğin:

PS1="\w >"

Şimdi bilgi istemi şöyle gözüküyor (çalışma dizininin "John" olduğunu varsayarsak):

John >

Yapabileceğimiz Aynı şekilde PS1="Hello, I'm your prompt >", bu yüzden echo $PS1getirecektir:

Hello, I'm your prompt >

Bash 4.xx'te, sistemdeki ALL envar'larını envkomut ile yazdırabiliriz . envTerminalde çalıştırmayı öneririm ve çıkışa bir göz atın.

2. Bu veriler nasıl gösteriliyor ve değiştiriliyor:

Bir oturumun terminali, Bash ile gelen envarları özelleştirmemize izin verir.

Yukarıda belirtilen değişiklikler genellikle geçicidir ve işte neden:

Her bir oturum (bir alt oturum olmayan) benzersizdir ve birkaç işlem aynı anda (her biri kendi envar kümesiyle) benzersiz şekilde çalışabilir, ancak genellikle oturum 0'dan oturum 1'e ve yukarı doğru miras vardır.

Bir işlemde yaptığımız değişiklikler buna özgüdür ve bir şekilde kaydetmeden kapatırsak sona erer.

Peki bu değişiklikleri nasıl kaydedebiliriz:

Seçtiğimiz kapsama bağlı olarak, envar değişiklikleri saklamanın çeşitli yolları vardır. İşte bu tür değişiklikler için farklı kapsamlar (seviyeler):

  • İşlem seviyesi: Envarlar sadece mevcut oturumdaki programlar için geçerlidir.
  • İhracat seviyesi: envars geçerli oturumda programları veya tümünde kullanılabilen onun alt seans.
  • Global seviye: Değişiklikler ne olursa olsun tüm oturumlar için saklanacaktır (birincil ve tüm alt gruplar).

Envar verileri nerede depolanır:

Unix 3 ana katmandan oluşur: Çekirdek, kabuk ve yardımcı programlar. AFAIK her kabuğun kendine ait envarları vardır ve bunlar öncelikle veya sadece kabuğun içine inşa edilir.

Bunları küresel olarak değiştirmenin belirli bir yeri genellikle elbette /etc/profilebunu yapabilmemize rağmen .bashrc.

3. Yeni envarlar oluşturmak:

Yeni envarlar yaratabiliriz ve işte bir yol; Bash 4.xx'ten itibaren adında yerli bir enavar yoktur MESSAGE(söylendiği gibi, envarlar genellikle büyük harflidir).

MESSAGE="Hello world!"

bizim için yaratacağız ve şimdi yankı yazarsak $MESSAGEanlıyoruz hello world!.

Biz idam ettirmekle Eğer bashmevcut çalışma oturumunda (pencere) içinde, yeni bir bash alt oturumu başlatmak istiyorum ve orijinal süreçte artık çalışmaz, biz çalıştırır sürece exit.

Not: Terminal emülatörlü işletim sistemlerinde (Ubuntu masaüstünde olduğu gibi), genellikle bir alt oturum aynı pencerede çalışır, ancak başka bir penceredeki yeni bir oturum mevcut olanın alt oturumu değildir ( bitişik bir işlemdir) .

Not: Envar değerlerinde özel işaretler kullanmayın! yoksa kurtarılmayacaklar.

Envar'ı orijinal oturumdan tüm alt oturumlara dışa aktarma:

İlk oturumda yarattığımız envariyi, ikincisinde de kullanıcı veya genel düzeydeki conf dosyalarına kaydetmeden kullanabiliriz (aşağıdaki verilere bakınız). İşte bunun nasıl yapılacağı:

Orijinal oturuma gidin (geçerli pencerede veya başka bir pencerede olsun) ve yürütün:

export MESSAGE

dışa aktarırken, bir $işaret kullanmayın .

Şimdi tüm alt oturumlara verilir. Eğer yapacağım Eğer echo $MESSAGEbir alt oturumuna, sizin kullanıcı veya diğerinden olsun, o zaman basılacak.

Shell gibi iç değişkenlerin PS1dışa aktarılmaması gerektiğine dikkat edin, ancak bunları ne nedenle olursa olsun dışa aktarmak istiyorsanız ve görünmüyorlarsa, bashsonra çalıştırmayın export, aksine bash –norc.

4. $ PATH envar:

$PATH Kullanıcıların genellikle en çok değiştirecekleri envardır.

Eğer biz echo $PATH, bu akışı göreceğiz:

/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games

Bu envarın basılan değerleri iki nokta üst üste (:) ile ayrılmıştır, fakat işte potansiyel olarak daha rahat bir yol (bunlar aynı değerlerdir):

/usr/local/bin
/usr/bin
/bin
/usr/local/games
/usr/games

Bir yardımcı program çalıştırdığımızda aramamız gereken terbiyesizler.

Çalıştırarak which echodosya konumunu bulacağız - örneğin, içinde olduğunu görebiliriz /bin/echo.

Buna dayanarak, evnar'ın değerlerini görüntülemek için echo envar yazmamız gerekmez. Ayrıca şunları da yapabiliriz:

/bin/echo $ENVAR

Envar hala yürütülecek, örneğin:

/bin/echo $HOME

Bize verir

/home/User || /root

Tıpkı:

echo $HOME

Bize verir

/home/User || /root

Not: $HOMEolarak kısaltılır ~.

Sistem $ PATH ilişkileri ve olası bir kullanıcı etkileşimi:

Bash 4.xx'te, tam yolu olmayan bir yardımcı program kullandığımızda, sistem yukarıda belirtilen 6 değerin hepsini $PATHkullanır. Böylece, başlayacak /user/local/binve echoyürütülebilir içeriği arayan tüm içeriğini izleyecektir .

Bu durumda, /bin/echobu durumda, yürütülebilir dosyanın bulunduğu yerde duracaktır .

Bu nedenle, $PATHenvar'ı özelleştirmemizin ana nedeni , yerel değerlerinden hiçbirinde bulunmayan çalıştırılabilir dosyaları yüklemektir.

Bu tür yürütülebilir dosyaları yükledikten sonra, $PATHdeğerlerini buna göre ayarlamalıyız ve sonra onlarla çalışabileceğiz.

5. Ek - genişleyen $PATH:

Biz can export $PATHbu şekilde (Drupal için WordPress veya Drush için WP-CLI gibi bash uzantıları içerir) bash alt oturumlara:

export PATH="/home/John:$PATH"

Bu yeni bir değer katacak /home/Johniçin $PATHve sonra da hemen ardından, bu sözdizimi altında depolanır, (sağ kolon) sonra buna herhangi bir doğal değerleri ilhak olacaktır $PATH.

Bu kalıcı değişiklik, genellikle ilgili /etc/profileismin altında ve genellikle isminin altında yapılabilir .bashrc.


3
Bu cevapta çok fazla yanlış var: oturumların ve işlemlerin birleşmesi, !çalışmayan bir ortam değişkeni değerinin işe yaradığını gösteren bir örnek hakkında uyarma, çalışmayı gösteren bir örnek, alt oturumların yanlış bir nosyonu, ne yapılması gerektiği konusunda oldukça tuhaf tavsiyeler Bir kabuk değişkeni ve yanlış bir global çevre değişkenleri kavramı verdikten sonra.
JdeBP

warning about ! in an environment variable value not working that is right below an example showing it working? Lütfen örnek.
JohnDoea

quite bizarre advice about what to do after exporting a shell variable, tam olarak ne demek istiyorsun?
JohnDoea

false notion of global environment variables, tam olarak ne demek istiyorsun?
JohnDoea
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.