6 puan yazan GN⁺ 2025-10-15 | 2 yorum | WhatsApp'ta paylaş
  • Yazılım hızla gelişmiş olsa da işletim sisteminin ortam değişkeni sistemi hâlâ onlarca yıl önceki yapısını koruyor
  • Ortam değişkenleri, namespace'i ve tipi olmayan genel bir string sözlüğü biçiminde, son derece basit bir yapıya sahip
  • Linux'ta ortam değişkenleri execve sistem çağrısı üzerinden ebeveyn süreçten çocuğa aktarılır
  • Bash, glibc, Python gibi yapılar ortam değişkenlerini sırasıyla hash map, dizi ve sözlük sarmalayıcısı biçiminde yönetir
  • POSIX standardı adlarda yalnızca büyük harf kullanımını şart koşmaz; pratikte küçük harfli adların kullanımı da önerilir ve kurallar esnektir

Ortam değişkeni nedir

  • Programlama dilleri hızla gelişmiş olsa da işletim sisteminin sunduğu süreç çalıştırma temeli, özellikle ortam değişkenleri tarafında neredeyse hiç değişmedi
  • Bir uygulama çalıştırılırken ayrı bir dosya ya da IPC kullanmadan çalışma zamanı parametreleri aktarmak gerektiğinde, gerçekte ortam değişkeni tabanlı arayüze başvurmak zorunda kalınıyor
  • Ortam değişkenleri, namespace'i de tipi de olmayan, düz bir string sözlüğü işlevi görüyor

Ortam değişkenlerinin oluşturulması ve aktarım yapısı

  • Ortam değişkenleri, süreçler arasında değer aktarmanın geleneksel yolu olup ebeveyn süreç çocuk süreci çalıştırırken birlikte iletilir
    • Yani yapı, ebeveyn süreçten çocuk sürece miras alınması şeklindedir
  • Linux'ta execve sistem çağrısı yürütülebilir dosyayı, argümanları ve ortam değişkenleri dizisini (envp) parametre olarak alır
    • Örnek çalıştırma komutu: ls -lah ise
      • filename: /usr/bin/ls
      • argv: ['ls', '-lah']
      • envp: ['PATH=...','USER=...']
  • Ebeveyn süreç, mevcut ortamı çocuğa olduğu gibi aktarabileceği gibi tamamen yeni bir ortam da kurabilir
    • Neredeyse tüm araçlar (Bash, Python subprocess.run, C kütüphanesi execl vb.) ortam değişkenlerini aynen aktarır
    • İstisna olarak login gibi bazı araçlar yeni bir ortam oluşturur

Ortam değişkenlerinin saklandığı yer ve iç işleme

  • Çekirdek, program başlangıcında ortam değişkenlerini null-terminated string biçiminde stack üzerine yerleştirir
  • Bu veriyi programın doğrudan değiştirmesi zordur; genelde program içinde kopyalanıp kendi yapısı içinde yönetilir
  • Dillerin ve shell'lerin ortam değişkenlerini saklama biçimleri
    • Bash: stack yapılı bir hash map (sözlük) ile yönetir
      • Her fonksiyon çağrısında yerel scope için bir map oluşturulur
      • Yalnızca export edilmiş değişkenler çocuk sürece aktarılır
      • local ile tanımlanan değişkenler de export yoluyla çocuk sürece aktarılabilir
        • Örnek: export PATH ile yerel değişiklik çocuğa yansıtılır ama globale etki etmez
    • glibc (C kütüphanesi): putenv, getenv üzerinden environ adlı dinamik dizi yapısını yönetir
      • Dizi yapısı nedeniyle hem sorgulama hem de değiştirme doğrusal zaman karmaşıklığına sahiptir
      • Bu yüzden yüksek performans gerektiren veri saklama amaçları için uygun değildir
    • Python: İçeride os.environ ile sözlük gibi sunulur ama gerçekte C kütüphanesindeki environ dizisiyle bağlantılıdır
      • os.environ değeri değiştiğinde os.putenv çağrılır ve C kütüphanesine de yansır
      • Ters yönde senkronizasyon olmadığı için tek yönlülük vardır

Ortam değişkenlerinin formatı ve izin verilen kapsam

  • Linux çekirdeği ve glibc, ortam değişkeni formatı konusunda oldukça toleranslıdır
    • Aynı adın yinelenmesiyle birden çok değer bulunabilir
    • = olmadan da kaydedilebilir ve emoji gibi özel karakterlere dair kısıtlama yoktur
  • Kullanılabilir boyut sınırı
    • Tek bir değişken: 128 KiB (genelde x64 ortamında)
    • Toplam: 2 MiB (komut satırı argümanlarıyla paylaşılır)
    • Ortam değişkenleri stack alanının 1/4'ünü geçemeyecek şekilde sınırlandırılmıştır

Ortam değişkenlerinin tuhaflıkları ve edge case'leri

  • Bash, garip ortam değişkenleri (yinelenen adlar, = içermeyen girdiler vb.) söz konusu olduğunda yinelenen adları kaldırır ve anormal girdileri yok sayar
  • Değişken adında boşluk varsa Bash bu adı referanslayamaz, ama yine de çocuk sürece aktarabilir
    • Örneğin Nushell, Python vb. araçlar boşluk içeren adlara sahip değişkenler oluşturabilir
    • Bash bu tür girdileri ayrı bir hash map (invalid_env) içinde tutup yönetir

Standart ortam değişkeni formatı ve adlandırma kuralları

  • POSIX standardı, adda eşittir işareti (=) bulunmadığı sürece bunu değişken olarak kabul eder
    • Resmî öneri: ad yalnızca büyük harf, rakam ve alt çizgi içermeli (ilk karakter rakam olamaz)
    • Küçük harfli değişkenler uygulamaya özel namespace için ayrılmıştır
    • Standart araçlar yalnızca büyük harf kullanır, ancak küçük harfli değişken kullanımı da serbesttir
  • Pratikte geliştiriciler çoğunlukla ALL_UPPERCASE biçiminde adlandırma yapar
  • Önerilen kural: değişken adı için ^[A-Z_][A-Z0-9_]*$ regex'i, değer için UTF-8 kullanımı
    • İstisna ya da uyumluluk kaygısı varsa POSIX Portable Character Set (ASCII) kullanılması önerilir

Sonuç

  • Ortam değişkenleri hâlâ eski ama vazgeçilmez bir arayüz olarak işletim sistemi ile uygulamalar arasında sınır görevi görüyor
  • Yapısal sınırlamalarına rağmen Bash, C, Python vb. bunları kendi yöntemleriyle sarmalayıp kullanmayı sürdürüyor
  • Modern sistemlerde daha net namespace'lere ve tip sistemine sahip yapılandırma yönetimi yaklaşımlarına duyulan ihtiyaç giderek artıyor

2 yorum

 
howudoin 2025-10-15

İlk bakışta önemi azalıyormuş gibi görünse de Docker ve bulutun ortaya çıkışıyla yeniden kaçınılmaz hale geldi.

 
GN⁺ 2025-10-15
Hacker News yorumu
  • SRE/Sysadmin/DevOps/her neyse olarak çalışıyorum; blog yazısında ortam değişkenlerinin standartlaştırılması hakkında nispeten hafif şeylerden bahsedilmişti ama alternatif yaklaşımların da benzer şekilde can sıkıcı sorunlar yarattığını, özellikle de işin içine gizli bilgiler (secrets) girdiğinde, belirtmek istiyorum
    Uygulamanın Hashicorp Vault/OpenBao/Secrets Manager gibi belirli bir gizli bilgi deposuna (vault) erişecek şekilde tasarlanması hızla ciddi bir vendor lock-in yaratıyor ve bu durum kütüphane düzeyine kadar yayıldığı için değiştirmesi çok zor oluyor
    Vault'un erişilebilirliği kritik hale geliyor ve yükseltme ya da bakım gerektiğinde operasyon ekibi ciddi biçimde zor durumda kalıyor
    Gizli bilgileri config dosyasıyla iletmek istediğinizde, bu sırları nasıl yerleştireceğiniz ayrı bir sorun oluyor; çünkü config dosyaları çoğu zaman herkese açık yollarda bulunuyor
    Sonunda ya "ayrıcalıklı bir sistemin uygulamaya vermeden önce şablonu doldurmasına" ya da "tüm config dosyasını gizli bilgi deposunda tutup uygulamaya vermeye" dayanıyorsunuz
    Şablon işi hataya çok açık ve tüm config dosyasını gizli bilgi deposuna taşıdığınızda da birinin yanlış dosya yükleme riski yüzünden ayrıca stres çıkıyor
    Bugün çoğu sistem container üzerinde çalışıyor ama altyapıyı çok disiplinli yöneten bir şirket değilseniz config dosyaları sürekli alakasız yerlere konuyor; bu da mount sürecini daha kafa karıştırıcı hale getiriyor ve sık hata doğuruyor
    JSON/YAML/TOML hangi formatı kullanırsanız kullanın kendine has bug'lar günlük hayatın parçası; örneğin YAML'ın Norway sorunu gibi
    Gizli bilgilerin Kubernetes Secrets API üzerinden alındığını da gördüm ama bu da yine güçlü bir vendor bağımlılığı problemiyle geliyor
    Özellikle operator benzeri sistemler tasarlamıyorsanız bu yaklaşımı çok önermem
    Subprocess üzerinden ortam değişkeni ayarlarken ortaya çıkan sorunları da gördüm ama bugün ekiplerin bunun yerine daha dayanıklı olan ve bağımsız ölçeklenebilen message bus tabanlı sistemler kullandığını düşünüyorum

    • Bizim ekipte hafif, genel amaçlı bir Secrets kütüphanesi yapıp arka tarafta AWS Secrets Manager gibi vendor'a özgü backend'leri plugin şeklinde bağlayarak kullandığımız bir deneyim olmuştu
      Yerel cache ayarı ve parametre bazında cache bypass seçenekleri vardı; böylece gerçek vendor'a bağımlı mantık sadece backend'de kalıyor, kütüphane ile uygulama ise vendor'dan bağımsız kalabiliyordu
      Vault'a geçerken de sadece bir backend daha ekleyip ayarları değiştirdik ve sorunsuzca uyguladık

    • Kubernetes secret API'sinin neden vendor bağımlılığı (lock-in) problemi olarak görüldüğünü merak ediyorum
      Acaba deployment yaml'ını Kubernetes deploy'u dışında başka bir amaçla kullanmaya çalıştığınız bir durum mu vardı?
      Çoğu uygulamada secret'ı container'a mount edip ardından ortam değişkeni ya da json dosyası olarak uygulamaya verirseniz, ortamdan bağımsız şekilde okuyup yazabilirsiniz
      Bildiğim kadarıyla etcd backend şifrelemesi de KMS ile yapılandırılabiliyor

    • Gizli bilgileri Kubernetes Secrets API üzerinden almanın neden lock-in olduğu tam olarak bana da mantıklı gelmiyor
      Temelde K8s secrets şifrelenmiş olarak saklanmadığı için, bunun anlamlı olması adına (0) zaten K8s kullanıyor olmanız, (1) kontrol düzleminde şifrelemeyi etkinleştirmeniz ve (2) CSI driver gibi ek çözümler kullanmanız gerekiyor
      Ayrıca Secret Store CSI Driver, Conjur dahil çeşitli backend'leri desteklediği için aslında lock-in'in tersine bir durum söz konusu

    • Bu yüzden config tarafında hâlâ env vars ve dotenv ağırlıklı gidiyorum
      Ortam değişkeni tabanlı yapı çok basit ve secret manager gibi çeşitli araçlarla da çok uyumlu
      Son birkaç yılda YAML tabanlı sOps'a da yavaş yavaş ilgi duymaya başladım
      YAML, uygulama yapılandırmasını ifade etmek için gerçekten sezgisel ve sops ile yalnızca belli kısımları şifreleyerek yönetmek de kolay
      GPG anahtar yönetimi biraz zahmetli olsa da bunu Vault ya da OpenBao gibi araçlarla çözmek mümkün
      Ama tabii bu süreçte yine vendor lock-in konusu çıkıyor; gerçi OpenBao bu konuda biraz daha iyi gibi

    • Komut çalıştırma sonucuyla da ortam değişkeni alınabilir; böylece şablon süreci olmadan ve vendor lock-in yaşamadan çözmek mümkün olur

  • Bir başka ilginç nokta: setenv() POSIX'te temelden bozuk, bu yüzden kütüphane kodunda asla kullanılmaması gerektiğini düşünüyorum
    Uygulama kodunda kullanılması gerekse bile son çare olmalı ve mutlaka thread oluşturmadan önce kullanılmalı
    getenv() ortam değişkeninin özgün işaretçisini doğrudan döndürdüğü için, setenv() değişkenin üstüne yazdığında hiçbir koruma mekanizması yok
    Çok dikkatli olmak gerekiyor

    • Ortam değişkenlerini düzgün ayarlamak için execve() ile set etmek gerektiğini düşünüyorum
      Bu yaklaşım yalnızca exec() öncesi/sonrası ortam değişkeni üzerinden bilgi aktarılırken uygun

    • Kütüphane kodunda neden setenv kullanmanız gereksin, bunu anlamıyorum

    • Solaris bu sorunu çözdü ama Linux hâlâ aynı yaklaşımda ısrar ediyor

    • NetBSD'de uzun zamandır getenv_r() diye güvenli bir alternatif var, FreeBSD de bunu yakın zamanda benimsedi
      macOS'un da muhtemelen yakında izleyeceğini düşünüyorum
      Bunu glibc ya da POSIX'e ekleme girişimleri olmuştu ama reddedildi
      Çeşitli platformlarda yaygınlaştıkça bir gün resmî olarak da kabul görmesini umuyorum
      NetBSD getenv_r belgesi
      FreeBSD commit'i

  • Ortam değişkenleri gizli bilgi taşımak için sık kullanılıyor ama bunun çok iyi bir pratik olduğunu düşünmüyorum
    Linux'ta aynı kullanıcıyla çalışan tüm süreçler birbirlerinin ortam değişkenlerine bakabiliyor
    Tehdit modeliniz ne olursa olsun, özellikle geliştirici makinelerinde aynı kullanıcı altında çalışan süreç sayısı çok fazla olduğu için bu endişe verici
    Bu sorun, LLM agent'ları gibi container dışında birden fazla sürecin dolaştığı ortamlarda daha da ciddi hale geliyor
    Ayrıca ortam değişkenleri genellikle alt süreçlere de aynen miras kalıyor; bu yüzden gizli bilgiye yalnızca tek bir sürecin ihtiyacı olsa bile gereksiz yere yayılma eğilimi oluşuyor
    systemd, ortam değişkenlerini DBUS üzerinden tüm sistem istemcilerine gösteriyor ve resmî belgelerinde de ortam değişkenlerinde gizli bilgi tutulmaması uyarısı yer alıyor
    Eğer bu gerçekten böyleyse, root'a özel bir unit için ayarlanmış ortam değişkenlerinin normal kullanıcılara da görünebileceği anlamına gelir ki bence pek çok sistem yöneticisi için oldukça şok edici olur
    Sonuçta yalnızca secret manager'ın geçici dosya paylaşımı yoluyla secret aktardığı yapılar (ör. 1Password'in op CLI'ı, flask, terraform vb.) hem ortam değişkeni hem düz metin dosya ifşasından kurtulabilen tek çözüm gibi görünüyor
    systemd'nin credentials sistemi de böyle çalışıyor. Ama destek hâlâ çok sınırlı
    Ortam değişkenleri ya da düz metin dosyalar olmadan secret aktarmanın iyi bir yolunu bilen varsa paylaşmasını isterim
    Örneğin 1Password op client tarafında, her oturum için benden ayrıca onay istediği için CLI oturumlarında bunu güvenli hissediyorum; kötü niyetli bir süreç op ikilisini çağırsa bile yine ayrı onay istiyor
    Şimdi geriye kalan sorun, bu secret'ı gerçekten ona ihtiyaç duyan sürece nasıl aktaracağınız; yani sanki yine başladığımız yere dönüyoruz
    systemd ortam değişkenleri resmî dokümantasyon bağlantısı

    • 2012 civarından beri ortam değişkenleri normal bellek kadar güvenli hale geldi
      İlgili commit kaydı
      Başka bir sürecin ortam değişkenlerini okumak için artık mutlaka ptrace yetkisi gerekiyor; zaten ptrace ile okuyabiliyorsanız gerçekte tüm gizli bilgileri de okuyabilirsiniz, dolayısıyla bunun ayrı bir endişe olması anlamsız deniyor
      Komut satırı bilgisi (cmdline) farklı bir konu ama ortam değişkenleri artık bu yolla kolayca sızmıyor

    • Çoğu işletim sisteminin güvenlik modelinde, bir kullanıcı olarak çalışmak o kullanıcının tüm yetkilerini bütünüyle devretmek anlamına gelir
      FreeBSD'nin capsicum'u, Linux'un landlock'u, SELinux, AppArmor, Windows'un integrity label'ı gibi ek güvenlik katmanları istisna olabilir ama çoğunun sınırları belirgin
      Sonuçta kendi süreçlerimi öldürmekte, durdurmakta ya da debug etmekte özgürüm; ptrace/process_vm_readv/ReadProcessMemory vb. yollarla bana ait süreçlerdeki secret'lara her zaman erişebilirim
      Tamamen farklı güvenlik modelleri de var (kusursuz capability tabanlı işletim sistemleri gibi) ama büyük çoğunluk bu modeli izliyor; dolayısıyla bu sınırları ve sorumluluğu kabul etmek gerekiyor

    • Ortam değişkenleri ya da düz metin dosyalar kullanmadan secret aktarmanın iyi bir yolu olarak memfd_secret aklıma geliyor
      memfd_secret man page
      Dil ve framework desteği çok yaygın değil; özellikle Rust'ta ve belki Go'da da mümkünse FFI üzerinden denenebilir
      PHP tarafında bunu sarmalayıp eklemeyi düşünmüştüm ama php-fpm'i de modifiye etmek istemediğim için yarım kaldı
      Pratikte en güvenli yol, süreç yöneticisinin secret dosya tanımlayıcısını önceden açıp alt sürece aktarması ve bunun bellek vb. alanlara saçılmadan kullanılabilmesi olurdu

    • Klasik Unix güvenlik modeli, biraz iyileştirilmiş biçimleriyle hâlâ çok yaygın ama ucuz hesaplama ortamları ya da modern senaryolar için sınırları oldukça belirgin
      Sırları başka süreçlerden gizlemeniz gerekiyorsa bunun doğru yolu en başta onları farklı kullanıcılar altında çalıştırmaktır
      Ya da tamamen uzaktan erişim modeline geçebilirsiniz ama bunun da kendi dezavantajları ve karmaşıklığı var

    • Bugün container platformlarında config veya secret'ları ortam değişkeniyle vermek tavsiye edilen bir yaklaşım olma eğiliminde
      Container içinde diğer süreçlerin ortam değişkenlerini görememesi üzerine tasarlanmış durumda
      Ortam değişkenlerinin alt süreçlere miras kalması da bilinçli bir tasarım; çünkü secret değerini bilen ortam düzenleyicisi aynı ortamı doğrudan kuruyor
      Endişe edilen sorunların çoğunu büyük problem olarak görmüyorum; istenirse bunu daha somut biçimde tartışabilirim

  • Birçok yorum secret yönetimi ve sorunları etrafında dönüyor ama ortam değişkenlerinin avantajlarını da düşünmekte fayda var
    Ortam değişkenleri, Unix süreçlerini yapısal olarak birbirine bağlayan "süresiz kapsamlı, dinamik genişleyen değişken bağlama" mekanizmasıdır
    Bunu yalnızca basit metin dosyalarıyla kıyaslamaktansa, ortam değişkenlerinin varlık nedeninin alt süreçlere güvenli bağlam aktarımı yapmak olduğunu hatırlamak gerekir
    İç içe shell'ler ya da karmaşık programların alt süreçleri gibi, süreç yapısı ne kadar karmaşık olursa ortam değişkenlerinin rolü de o kadar değerli hale gelir

  • Varlock'u gerçekten faydalı bulduğum için tavsiye etmek istiyorum
    Bir projede gereken ortam değişkenlerinin zorunlu/opsiyonel durumunu, veri tiplerini ve nereden alınacaklarını açıkça tanımlıyor; yönetimi de kolaylaştırıyor
    Varlock resmî sitesi

  • Pratik deneyimden bir örnek vereyim: ortam değişkenlerinin ne kadar karmaşıklaşabileceğini eski şirketimde yaşadım; belirli bir ENV değişkeninin nerede set edildiğini debug etmeye çalışırken tamamen kaybolmuştum
    Başta bunun .bashrc gibi tek bir yerde tanımlandığını sanıyordum ama aslında şirket geneli, bölge, iş birimi, takım, bireysel katman vb. en az 10 seviyelik bir zincir üzerinden ayarlanıyordu
    Sonunda ancak bash debug bayrağını açınca bunun nerede set edildiğini adım adım izleyebildim

    • Başka dilleri de destekliyor mu bilmiyorum ama Node.js yakın zamanda ortam değişkeni erişimlerini ve değişikliklerini tam olarak izleyen bir komut satırı bayrağı ekledi
      Node.js --trace-env belgesi
      Değerler sayısız API üzerinden set edilebildiği ya da değiştirilebildiği için karmaşık debug senaryolarında çok faydalı görünüyor

    • İnsanın aklına "tek bir namespace yeterli olmaz mıydı" dedirten bir durum

  • Ben ortam değişkeni kullanımını çok uzun zaman önce bıraktım
    Şimdi derleyicinin yanına bir dmd.conf dosyası koyuyor ve derleyicinin bunu doğrudan okumasını sağlıyorum

  • Ortam değişkenlerinin en ciddi sorunu, örtük ve opak olmaları
    *nix dünyasında çoğu uygulama ortam değişkenlerine dayanma eğiliminde
    Daha açık ve şeffaf yapılandırma yöntemleri (config dosyaları, remote servisler, komut satırı argümanları) ayrıca desteklense bile, bu alanda ortam değişkeni desteği bir gelenek haline gelmiş durumda
    Sonuç olarak ortam değişkenleri de çocuk süreçler için klonlanıp genişletilen küresel bir hash map; 1979'da makul bir tasarım olabilir ama bugün çoğu zaman zararlı hale geliyor
    Örneğin Kubernetes varsayılan olarak "service link" ortam değişkenleriyle container ortamını kirletiyor
    Uygulamanın beklediği ortam değişkenleri ile varsayılan env var'lar çakıştığında, debug etmek son derece zorlaşıyor
    Kubernetes resmî dokümantasyonu
    Bunun dışında da /bin, /usr/bin, /lib, /usr/lib gibi eski kalıpları sorgulamadan sürdürme eğiliminin çok yaygın olduğunu düşünüyorum
    Bkz: eski dizinlerin korunmasına dair Ubuntu Soru-Cevap

    • hjkl gibi tuş kombinasyonları da bu tür köhne alışkanlıkların tipik örneği sayılabilir
      vi'daki hjkl, 40 yıl önceki dumb terminal'lerden geliyor ve o terminal de çok az satmıştı
      (Nokia N9'dan bile daha az)
  • Linux'ta her ortam değişkeni ayarladığımda içime bir huzursuzluk çöküyor
    Resmî olarak çalışan yöntem dağıtımdan dağıtıma biraz değişiyor ve internetteki yönergeleri izleseniz bile yeniden başlatınca ya da terminali kapatınca her şey kayboluyor
    Keşke Windows'taki gibi küresel olarak kullanılabilen basit bir GUI ortam değişkeni düzenleyicisi olsa
    Windows'ta değişikliklerin yansıması için terminali yeniden açmanız gerekiyor ama onun dışında hep düzgün çalışıyor

    • Ortam değişkenleri oturum değiştiğinde doğal olarak kalıcı olmaz; bu yüzden her oturumda yeniden çalışan bir yere (giriş/terminal vb.) yazmanız gerekir
      Girişte .bash_profile, alt oturumlarda ise .bashrc çalışır
      .bash_profile içinden .bashrc'yi source edip ayarların çoğunu .bashrc'de tutarsanız yönetmek kolaylaşır
      Bash yerine zsh/fish gibi başka bir shell kullanıyorsanız ona göre düzenlemeniz gerekir
      Linux'ta tüm terminaller için geçerli olan resmî ve birleşik bir ortam değişkeni GUI'si yok
      Karmaşık bir parsing GUI'si yapılabilir ama düz metin düzenleyiciyle değiştirmek genelde daha kolaydır

    • Ağırlıklı olarak Linux kullanan biri olarak Windows'un bu davranışı bana daha rahatsız edici geliyor
      Çok fazla uygulama ortam değişkenlerini kirletiyor; bir şey çalışmadığında sonunda $SOFTWARE'ın tuhaf bir klasörden çalıştırıldığını fark etmek gibi karışıklıklar sık yaşanıyor

    • systemd kullanıyorsanız /etc/environment ya da /etc/environment.d/ içine KEY=VALUE yazma yöntemi de var
      Hatta bunun için bir GUI bile yapılabilir gibi
      Ama ortam değişkenleri çalışan süreçlere sonradan enjekte edilemez; etkili olması için yeniden başlatmak gerekir, bu da doğal bir sınır
      systemd resmî dokümantasyonu

    • xkcd Standards karikatürü
      Linux'ta ortam değişkeni ayarlamanın zaten 14 farklı rekabet eden yolu varken "haydi bunu birleştirelim" derseniz, ertesi gün 15. standart ortaya çıkar; bunu eğlenceli şekilde anlatıyor

  • En sevdiğim ortam değişkeni bilgisi şu: herkesin doğal olarak ortam değişkeni sandığı PS1 gibi değerler aslında ortam değişkeni değil, shell değişkenidir
    PS1'i env komutuyla da göremezsiniz