Trong khi các biến môi trường có thể có bất kỳ tên nào (bao gồm cả chuỗi rỗng) không chứa dấu bằng hoặc byte rỗng, shell biến các biến môi trường thành biến shell và trong hầu hết các shell, tên biến được giới hạn ở các ký tự chữ và số ASCII và _
trong đó ký tự đầu tiên có thể ' t là một chữ số (trừ các tham số vị trí và những người đặc biệt khác như $*
, $-
, $@
, ..., (mà không được ánh xạ tới các biến môi trường tương ứng)). Cũng lưu ý rằng một số biến được dành riêng / đặc biệt bởi / cho trình bao.
Ngoại lệ cho điều đó:
Các rc
vỏ và các dẫn xuất của nó giống như es
và akanga
hỗ trợ bất kỳ tên ngoại trừ chuỗi rỗng, và những người được tất cả số hoặc chứa =
ký tự (và luôn luôn xuất khẩu tất cả các biến của họ đối với môi trường, và hãy cẩn thận của các biến đặc biệt thích *
, status
, pid
...):
; '%$£"' = test
; echo $'%$£"'
test
; '' = x
zero-length variable name
;
Tuy nhiên, nó sử dụng mã hóa riêng cho các biến có tên không chứa alnums hoặc cho mảng khi được truyền trong môi trường của các lệnh đang được thực thi:
$ 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
và zsh
(còn bash
nhưng chỉ cho các ký tự single-byte) alnums hỗ trợ tại địa phương hiện nay, không chỉ những người ASCII.
$ Stéphane=1
$ echo "$Stéphane"
1
Trong các shell đó, bạn có thể thay đổi ngôn ngữ để coi hầu hết các ký tự là alpha, nhưng vẫn không hoạt động đối với các ký tự ASCII như thế nào .
. Bạn có thể đánh lừa zsh
hoặc ksh
suy nghĩ £
là một chữ cái, nhưng không phải là .
bất kỳ ký tự ASCII nào khác (trong đó việc cho phép các ký tự trong tên biến được quan tâm, không phải cho toàn [[:alpha:]]
cầu chẳng hạn).
ksh93
có các biến đặc biệt có tên chứa một dấu chấm ${.sh.version}
, nhưng chúng không được ánh xạ tới các biến môi trường và đặc biệt. Điều .
này là để đảm bảo nó không xung đột với các biến khác. Nếu nó đã quyết định gọi nó $sh_version
, sau đó nó có thể có khả năng bị phá vỡ kịch bản sử dụng mà biến đã (xem ví dụ như thế nào zsh
có vấn đề với nó $path
hay $commands
(một csh la biến mảng / băm đặc biệt) mà phá vỡ một số kịch bản).
Lưu ý rằng ngoài việc vỏ không hỗ trợ các biến, một số vỏ như pdksh / mksh làm loại bỏ chúng ra khỏi môi trường mà họ nhận được ( bash
loại bỏ một với một cái tên rỗng, ash
, ksh
và bash
loại bỏ những chuỗi môi trường không chứa một =
ký tự):
$ 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 %%%
%%%
Tóm lại, tốt nhất là gắn bó với tên biến được hỗ trợ bởi hầu hết vỏ và thậm chí cố gắng sử dụng chữ hoa cho các biến môi trường (và giảm trường hợp hoặc trường hợp hỗn hợp cho các biến shell không xuất) tránh những người là đặc biệt trong vỏ (như IFS
, PS1
, BASH_VERSION
...).
Nếu bạn cần đặt một biến như vậy trong một vỏ không hỗ trợ chúng, nhưng không loại bỏ chúng, bạn có thể tự kiểm tra lại, với một cái gì đó như:
#! /bin/ksh -
perl -e 'exit 1 unless defined($ENV{"a.b"})' || exec env a.b=%%% "$0" "$@"
(rõ ràng, nếu bạn cần thực hiện nó ở giữa tập lệnh, điều đó sẽ không có ích, nhưng sau đó bạn có thể xem cách tiếp cận đó để lưu và khôi phục môi trường thực thi shell qua trình thực thi lại). Hoặc thử cách tiếp cận trình gỡ lỗi:
gdb --batch-silent -ex 'call putenv("a.b=%%%")' --pid="$$"
(mà ai có vẻ làm việc với zsh
, yash
, csh
và tcsh
trên Linux amd64, nhưng không phải với bất kỳ vỏ khác tôi đã cố gắng ( mksh
, ksh93
, bash
, dash
)).