Sementara variabel lingkungan dapat memiliki nama apa pun (termasuk string kosong) yang tidak mengandung tanda yang sama atau byte nol, variabel shell memetakan variabel lingkungan ke variabel shell dan di sebagian besar shell, nama variabel terbatas pada karakter alfanumerik ASCII dan di _mana karakter pertama dapat ' t menjadi digit (kecuali untuk parameter posisi dan orang-orang khusus lainnya seperti $*, $-, $@, ..., (yang tidak dipetakan ke variabel lingkungan yang sesuai)). Perhatikan juga bahwa beberapa variabel dicadangkan / khusus oleh / ke shell.
Pengecualian untuk itu:
The rcshell dan turunannya seperti esdan akangamendukung nama apapun kecuali string kosong, dan mereka yang semua-numerik atau berisi =karakter (dan selalu mengekspor semua variabel terhadap lingkungan, dan waspadalah terhadap variabel khusus seperti *, status, pid...):
; '%$£"' = test
; echo $'%$£"'
test
; '' = x
zero-length variable name
;
Namun, ia menggunakan pengodeannya sendiri untuk variabel yang namanya tidak mengandung alnums atau untuk array ketika diteruskan dalam lingkungan perintah yang dijalankan:
$ 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, yashdan zsh(juga bashtetapi hanya untuk karakter bita tunggal) mendukung alnum di lokal saat ini, tidak hanya yang ASCII.
$ Stéphane=1
$ echo "$Stéphane"
1
Dalam shell itu, Anda bisa mengubah lokal untuk menganggap sebagian besar karakter sebagai alpha, tetapi tetap saja itu tidak akan berfungsi untuk karakter ASCII .. Anda dapat membodohi zshatau kshberpikir £adalah sebuah huruf, tetapi bukan itu .atau karakter ASCII lainnya (di mana memungkinkan karakter dalam nama variabel yang bersangkutan, bukan untuk [[:alpha:]]glob misalnya).
ksh93memiliki variabel khusus yang namanya mengandung titik seperti ${.sh.version}, tetapi variabel tersebut tidak dipetakan ke variabel lingkungan dan khusus. Ini .untuk memastikan tidak bertentangan dengan variabel lain. Jika telah memilih untuk menyebutnya $sh_version, maka bisa berpotensi rusak script yang digunakan bahwa variabel sudah (lihat misalnya bagaimana zshmemiliki masalah dengan nya $pathatau $commandsvariabel array / hash khusus (a la csh) yang memecah beberapa script).
Perhatikan bahwa selain cangkang yang tidak mendukung variabel-variabel tersebut, beberapa cangkang seperti pdksh / mksh memang menghapusnya dari lingkungan yang mereka terima ( bashmenghapus yang dengan nama kosong ash,, kshdan bashmenghapus string lingkungan yang tidak mengandung =karakter):
$ 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 %%%
%%%
Singkatnya, yang terbaik adalah untuk tetap dengan nama variabel didukung oleh sebagian besar kerang dan bahkan mencoba untuk menggunakan huruf untuk variabel lingkungan (dan menurunkan kasus atau kasus campuran untuk variabel shell tidak diekspor) menghindari orang-orang yang khusus dalam kerang (seperti IFS, PS1, BASH_VERSION...).
Jika Anda perlu mengatur variabel seperti itu di shell yang tidak mendukungnya, tetapi tidak membuangnya, Anda bisa mengeksekusi ulang diri sendiri, dengan sesuatu seperti:
#! /bin/ksh -
perl -e 'exit 1 unless defined($ENV{"a.b"})' || exec env a.b=%%% "$0" "$@"
(tentu saja, jika Anda perlu melakukannya di tengah-tengah skrip, itu tidak akan membantu, tetapi Anda kemudian bisa melihat pendekatan itu untuk menyimpan dan mengembalikan lingkungan eksekusi shell melalui re-exec). Atau coba pendekatan debugger:
gdb --batch-silent -ex 'call putenv("a.b=%%%")' --pid="$$"
(yang satu tampaknya bekerja dengan zsh, yash, cshdan tcshpada amd64 Linux, tapi tidak dengan salah satu kerang lain saya mencoba ( mksh, ksh93, bash, dash)).