Ortam değişkenleri, eşittir işareti veya boş bayt içermeyen herhangi bir ada sahip olabilir (boş dize dahil), harita ortamı değişkenlerini kabuk değişkenlerine kabuklar ve çoğu kabukta, değişken adları ASCII alfanümerik karakterlerle ve _
ilk karakterin yapılabileceği yerlerle sınırlıdır. t bir rakam olması (konumsal parametreler ve benzeri diğer özel olanlar hariç $*
, $-
, $@
, ..., (ilgili ortam değişkenleri eşlenen edilmeyen)). Ayrıca bazı değişkenlerin kabuk tarafından / özel tarafından ayrıldığını unutmayın .
Bunun istisnaları:
rc
Kabuk ve benzeri türevleri es
ve akanga
boş dize dışında herhangi bir ad desteklemek ve tüm sayısal veya ihtiva edenler =
karakterleri (her zaman ve çevre için tüm değişkenleri ihracat ve özel değişkenlerin dikkat ister *
, status
, pid
...):
; '%$£"' = test
; echo $'%$£"'
test
; '' = x
zero-length variable name
;
Bununla birlikte, adı kod içermeyen değişkenler için veya yürütülen komutlar ortamında geçirildiğinde diziler için kendi kodlamasını kullanır:
$ rc -c '+ = zzz; __ = zzz; a = (zzz xxx); env' | sed -n /zzz/l
__2b=zzz$
__5f_=zzz$
a=zzz\001xxx$
$ env +=x rc -c "echo $'+'"
x
$ env __2b=x rc -c "echo $'+'"
x
AT & T ksh
, yash
ve zsh
(aynı zamanda bash
ama sadece tek bayt karakterler için) geçerli yerele değil, yalnızca ASCII olanlar destek alnums.
$ Stéphane=1
$ echo "$Stéphane"
1
Bu kabuklarda, çoğu karakteri alfa olarak kabul etmek için yerel ayarları değiştirebilirsiniz, ancak yine de ASCII karakterleri için işe yaramaz .
. Kandırmak zsh
ya ksh
da düşünmek £
bir mektuptur, ama o .
ya da başka bir ASCII karakterini değil (değişken isimlerindeki karakterlere izin vermek, [[:alpha:]]
örneğin dünya için değil ).
ksh93
adı gibi bir nokta içeren özel değişkenlere sahip ${.sh.version}
, ancak bunlar çevre değişkenleriyle eşlenmemiş ve özel. .
Emin diğer değişkenlerle çakışmaması yapmaktır. Onu aramaya seçilmiş olsaydı $sh_version
, o zaman potansiyel olarak değişken zaten (nasıl mesela gördükleri kullanılan komut dosyalarını ele geçirmiş olabilir zsh
onun ile sorunları vardır $path
ya $commands
bazı komut kırmak olduğunu) özel dizi / karma değişkenler (a la csh).
Bu değişkenleri desteklemeyen kabukları ek olarak, do mksh pdksh gibi bazı kabukları / o Not kaldırmak aldıkları çevreden onları ( bash
boş bir isimle birini kaldırır ash
, ksh
ve bash
bir içermeyen bu çevre dizeleri kaldırmak =
karakteri):
$ env %%%=test 1=%%% a.b=%%% mksh -c env | grep %%%
$ env %%%=test 1=%%% a.b=%%% bash -c env | grep %%%
%%%=test
a.b=%%%
1=%%%
$ perl -le '$ENV{""}="%%%"; exec "bash", "-c", "env"' | grep %%%
$ perl -le '$ENV{""}="%%%"; exec "zsh", "-c", "env"' | grep %%%
=%%%
$ echo 'main(){char*a[]={"sh","-c","env",0};char*e[]={"%%%",0};
execve("/bin/ash",a,e);}'|tcc -run - | grep %%%
$ echo 'main(){char*a[]={"sh","-c","env",0};char*e[]={"%%%",0};
execve("/bin/zsh",a,e);}'|tcc -run - | grep %%%
%%%
Özetle, iyi (en kabukları ile desteklenen değişken adları ile sopa ve hatta kabuklarda özel olanlar kaçınarak ortam değişkenleri için büyük harf kullanmayı deneyin (ve ihraç kabuk değişkenleri için durum ya da karışık harfe) ETMEK böyle IFS
, PS1
, BASH_VERSION
...).
Eğer böyle bir değişkeni, onları desteklemeyen, fakat onları atmayan bir kabuğa ayarlamanız gerekiyorsa, kendinizi aşağıdaki gibi yeniden ifade edebilirsiniz:
#! /bin/ksh -
perl -e 'exit 1 unless defined($ENV{"a.b"})' || exec env a.b=%%% "$0" "$@"
(Açıkçası, betiğin ortasında yapmanız gerekiyorsa, bu işe yaramayacak, ancak kabuk yürütme ortamını bir yeniden yürütme işlemine kaydetmek ve geri yüklemek için bu yaklaşıma bir göz atabilirsiniz ). Veya hata ayıklayıcı yaklaşımını deneyin:
gdb --batch-silent -ex 'call putenv("a.b=%%%")' --pid="$$"
(tek çalışmak gibi görünüyor zsh
, yash
, csh
ve tcsh
Linux amd64 üzerinde değil, denedim diğer kabukları (herhangi biriyle mksh
, ksh93
, bash
, dash
)).