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 rc
shell dan turunannya seperti es
dan akanga
mendukung 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
, yash
dan zsh
(juga bash
tetapi 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 zsh
atau ksh
berpikir £
adalah sebuah huruf, tetapi bukan itu .
atau karakter ASCII lainnya (di mana memungkinkan karakter dalam nama variabel yang bersangkutan, bukan untuk [[:alpha:]]
glob misalnya).
ksh93
memiliki 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 zsh
memiliki masalah dengan nya $path
atau $commands
variabel 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 ( bash
menghapus yang dengan nama kosong ash
,, ksh
dan bash
menghapus 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
, csh
dan tcsh
pada amd64 Linux, tapi tidak dengan salah satu kerang lain saya mencoba ( mksh
, ksh93
, bash
, dash
)).