Linux ortam değişkeni adlarında izin verilen karakterler


143

Linux ortam değişkeni adlarında hangi karakterlere izin verilir? Man sayfaları ve webdeki üstünkörü aramam, sadece değişkenlerle nasıl çalışılacağı hakkında bilgi üretti, ancak hangi isimlere izin verildiğini değil.

Ben gibi bir nokta içeren tanımlı bir ortam değişkeni gerektiren bir Java programı var com.example.fancyproperty. Windows ile ben bu değişkeni ayarlayabilirsiniz, ancak linux (SuSE ve Ubuntu denedim) ayarı hiç şansım yoktu. Bu değişken isme bile izin veriliyor mu?


3
Neyse ki, programın bir Java sistem özelliğinden ( -Dkomut satırı seçeneği ile bildirildi) mutlu olduğunu buldum , bu yüzden şimdi çalışıyor. Açıkçası program bana söylemeden her iki değişken kümesinde de görünüyor. Ama yine de hangi ortam değişkeni adlarına izin verildiğini merak ediyorum.
Christian Semrau

@AleksandrDubinsky Sildim. Bu benzerdir ancak takma ad tanımıyla tam olarak çevre değişkenleri hakkında stackoverflow.com/questions/24690640/…
Lime

1
Eğer kullanıyorsanız Bahar , varsayılan SystemEnvironmentPropertySource da yukarı bakacak com_example_fancypropertyve COM_EXAMPLE_FANCYPROPERTY.
Aleksandr Dubinsky

Yanıtlar:


203

Gönderen Açık Grubu :

Bu dizeler name = value biçimindedir; isimleri '=' karakterini içeremez. Değerlerin IEEE Std 1003.1-2001'e uygun sistemlerde taşınabilir olması için, değer taşınabilir karakter kümesindeki karakterlerden oluşmalıdır ( NUL hariç ve aşağıda belirtildiği gibi ).

Bu nedenle adlar = ve NUL dışında herhangi bir karakter içerebilir, ancak:

IEEE Std 1003.1-2001'in Kabuk ve Yardımcı Programlar birimindeki yardımcı programlar tarafından kullanılan ortam değişkeni adları, yalnızca Taşınabilir Karakter Kümesinde tanımlanan karakterlerden büyük harf, rakam ve '_' (alt çizgi) oluşur ve bir rakamla başlamaz . Bir uygulama tarafından başka karakterlere izin verilebilir; başvurular bu tür isimlerin varlığını tolere etmelidir.

Bu nedenle, adlar geçerli olsa da, kabuğunuz harfler, sayılar ve alt çizgiler dışında hiçbir şeyi desteklemeyebilir.


8
Sadece kontrol etmek: ikinci alıntı normatif değildir: sadece POSIX'in yardımcı programları için özel olarak tanımladığı değişkenlerin [a-zA-Z_][a-zA-Z0-9_]*(dolaylı olarak bu formun daha akla yatkın olduğunu gösterir) olduğunu gözlemler , ancak gerçek spec (alıntı 1) herhangi bir şeyi desteklemek için tüm uygulama gerektirir.= ve NUL?
Ciro Santilli 法轮功 冠状 病 六四 事件 法轮功

3
Ayrıca, "taşınabilir karakter kümesi" pubs.opengroup.org/onlinepubs/000095399/basedefs/… boşluklar ve yazdırılamazlar gibi şeyler içerir: yani bunları kullanabilir miyiz, kullanamaz mıyız?
Ciro Santilli 法轮功 冠状 病 六四 事件 法轮功

3
Bu tam olarak gözlemlediğim şey. Shell, değişken karakterlerin bir parçası olarak özel karakterleri sevmez. Ancak bir program veya komut dosyası (örn. Java veya perl) adında özel karakterler içeren bir değişkeni başlattığında ve başka bir yürütülebilir dosya (alt işlem) çağırdığında, ikinci yürütülebilir dosya bu değişkene sorunsuz bir şekilde erişebilir.
Ey

1
@checksum, UPPERCASE, kabuk dahil olmak üzere POSIX tarafından belirtilen araçların anlamı olan değişken adları için açıkça belirtilmiştir; en az bir küçük harf içeren isimler uygulama kullanımı için açıkça ayrılmıştır. Bu nedenle, en iyi uygulama, istemeden üzerine yazmadığınızdan emin olmak için uygulamalarınızın değişken adlarına en az bir küçük harf karakteri dahil etmektir (bir kabuk değişkeni ayarlamak, benzer adlandırılmış ortam değişkenlerinin üzerine yazacağı için) sistemi. Bkz. Pubs.opengroup.org/onlinepubs/9699919799/basedefs/…
Charles Duffy

2
@CiroSantilli 烏坎 事件 2016 六四 事件 法轮功, bunları ortam değişkenlerinde kullanabilirsiniz; Eğer olamaz kabuk değişkenleri bunları kullanmak ve bu ortam değişkenleri kabuğun erişilebilir olmasını garanti edilmez.
Charles Duffy

37

IEEE Std 1003.1-2008 / IEEE POSIX P1003.2 / ISO 9945.2 Kabuk ve Araçlar standardının kabuklar üzerindeki POSIX standartları bölümü, değişken adlar için sözcüksel kuralı tanımlamaz, ancak kaynağa yapılan özlü bir bakış, benzer bir şey kullandığını gösterir.

[a-zA-Z_]+[a-zA-Z0-9_]*

(Düzenle: 2. karakter sınıfına eksik alt çizgi eklendi.)

Kısa bir not, bazı mermiler normal ifadedeki + işaretini desteklemediğinden, potansiyel olarak daha taşınabilir bir normal ifade şunlar olabilir:

[a-zA-Z_]{1,}[a-zA-Z0-9_]{0,}


4
Teşekkürler Aiden. Sanırım ikinci köşeli parantez setinde eksik bir alt çizgi var: Muhtemelen okumalı: [a-zA-Z_][a-zA-Z0-9_]* Benim gibi bash-4.1'e biraz belirsiz (616'000 kod satırı) referans bulanlar için, birkaç ipucu ilgili kod satırlarını bulun: subst.c: param_expand(), in the default case-> general.h:/ * Yasal bir kabuk tanımlayıcısının tam olarak ne içerdiğini tanımlayın. * / #farklı legal_variable_starter (c) (ISALPHA (c) || ​​(c == ' ')) #define legal_variable_char (c) (ISALNUM (c) || ​​c == ' ')
Chris

3
İlk karakter sınıfında buna gerek yoktur.
scravy

2
@ scravy true, regexp'i kaynaktan aldım ama + 'yı tutacağım.
Aiden Bell

4
POSIX şunları tanımlar: 3.231 Ad a word consisting solely of underscores, digits, and alphabetics from the portable character set. The first character of a name is not a digit .

Kabuk bölümünde değil, ancak ortam değişken adlandırma kurallarını içeren (ve aslında kabuk kullanımı için ayrılmış adları tartışan) kesinlikle POSIX standartları vardır. Bkz. Pubs.opengroup.org/onlinepubs/9699919799/basedefs/…
Charles Duffy

12

Hızlı testlerim temelde C değişken isimleriyle aynı kurallara uyduklarını gösterdi.

  1. az, AZ _ve 0-9
  2. Bir sayı ile BAŞLATILAMAZ

Bu .onların içini dışlıyor . Herhangi bir geçersiz değişken adı ile ilişkilendirilir unknown command.

Bu, çoğunlukla BASH uyumlu olan ZSH'de test edildi.


6

'İzin verilen' ile ne demek istediğinize bağlı.

Windows'u nonce için yok sayılıyor:

Ortam, bir programın ana işlevine aktarılan bir dizeler dizisidir. Execve (2) öğesini okursanız, bu dizelerde null sonlandırma dışında herhangi bir gereksinim veya sınır göremezsiniz.

Kural olarak, her dize NAME = değerinden oluşur. Alıntılama kuralı yoktur, bu nedenle bu kuralda adında '=' olamaz.

Normal insanlar bu ipleri kabuklarıyla tartışarak koyarlar. Her kabuğun geçerli değişken NAME'ler hakkında kendi fikirleri vardır, bu yüzden ne düşündüğünü görmek için anın kabuğunun man sayfasını okumanız gerekir.

Genellikle, com.baseball.spit = fleagh gibi şeyler Java sistem özellikleridir ve bazı Java programlarının çevreye düşmeye istekli olup olmadığı, bunları -D ile belirtmek daha iyidir.


Daha önce değişkenin bir ortam değişkeni olarak ayarlamaya çalışmak yerine bir Java sistem özelliği gibi biçimlendirildiği sonucuna varmalıydım.
Christian Semrau


4

EVET, BUNU YAPABİLİRSİN.

Bu sahneyi uygulamak için kullanın execve envkomut verin.

Docker'da Test Fikstürü

docker run -it --rm alpine:3.10

Kapta komut çalıştır:

exec env spring.application_name=happy-variable-name ${SHELL:-/bin/sh}

Ortam değişkenlerini doğrulayın:

HOSTNAME=bd0bccfdc53b
SHLVL=2
HOME=/root
spring.application_name=happy-variable-name
TERM=xterm
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
PWD=/

ps auxPID'nin değişmediğini doğrulamak için kullanın

PID   USER     TIME  COMMAND
    1 root      0:00 /bin/sh
   12 root      0:00 ps aux

pythonOrtam değişkenini doğrulamak için kullanın

apk add python
python -c 'import os; print(os.environ["spring.application_name"])'

ÇIKTI happy-variable-name.

Ne oluyor?

  1. Shell çağrı yerleşik yürütme
  2. Kabuk yerleşik exec çağrısı syscall.exec oluşturma işlemi 'env' geçerli kabuk yerine
  3. env süreç çağrı enys işlemi yerine syscall.execvp oluşturma işlemi '/ bin / sh'

Diğer yol

  • Docker görüntüsü

Docker kullanıyorsanız, Dockerfile'da değişken ayarlayabilirsiniz

FROM busybox
ENV xx.f%^&*()$#ff=1234
  • Kubernetes yapılandırması

Kubernetes kullanıyorsanız, ConfigMap ile değişken ayarlayabilirsiniz

test.yaml

apiVersion: v1
kind: ConfigMap
metadata:
  name: foo-config
data:
  "xx.ff-bar": "1234"

---
apiVersion: v1
kind: Pod
metadata:
  name: foobar
spec:
  containers:
    - name: test-container
      image: k8s.gcr.io/busybox
      command: [ "/bin/sh", "-c", "env" ]
      envFrom:
      - configMapRef:
          name: foo-config
  restartPolicy: Never

Bölmeyi dağıt kubectl apply -f test.yaml

kubectl logs foobarÇıktıyı doğrulayın :

xx.ff-bar=1234

ConfigMap '-', '_' veya '' izin verir.


0

Çoğu kabuk çevre değişkenlerinin ayarlanmasına izin vermeyecek olsa da (diğer yanıtlarda belirtildiği gibi), ihtiyacınız varsa standart olmayan çevre değişkenlerine sahip diğer programları kullanarak çalıştırabilirsiniz env(1).

Örneğin, tüm ortamı ve ayarı Strange.Env:Vardeğer olarak silmek ve fooonu basan perl programını yürütmek:

env -i Strange.Env:Var=foo perl -MData::Dumper -E 'say Dumper(\%ENV)'

yazdıracak

$VAR1 = {
          'Strange.Env:Var' => 'foo'
        };
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.