ในขณะที่ตัวแปรสภาพแวดล้อมสามารถมีชื่อใด ๆ (รวมถึงสตริงที่ว่างเปล่า) ที่ไม่มีเครื่องหมายเท่ากับหรือเป็นโมฆะ null เชลล์แผนที่ตัวแปรสภาพแวดล้อมกับตัวแปรเชลล์และในเชลล์ส่วนใหญ่ชื่อตัวแปรจะถูก จำกัด ตัวอักษรและตัวเลข ASCII และอักขระตัว_แรกสามารถ ' เสื้อเป็นหลัก (ยกเว้นสำหรับพารามิเตอร์ตำแหน่งและคนพิเศษอื่น ๆ เช่น$*, $-, $@, ... (ที่ไม่ได้แมปไปยังตัวแปรสภาพแวดล้อมที่สอดคล้องกัน)) นอกจากนี้โปรดทราบว่าตัวแปรบางตัวสงวนไว้ / พิเศษโดย / ถึงเชลล์
ข้อยกเว้น:
rcเปลือกและอนุพันธ์ของมันเช่นesและakangaสนับสนุนชื่อใด ๆ ยกเว้นสตริงที่ว่างเปล่าและผู้ที่มีทั้งหมดตัวเลขหรือมี=ตัวละคร (และมักจะส่งออกตัวแปรทั้งหมดของพวกเขาที่มีต่อสิ่งแวดล้อมและระวังของตัวแปรพิเศษชอบ*, status, pid... ):
; '%$£"' = test
; echo $'%$£"'
test
; '' = x
zero-length variable name
;
อย่างไรก็ตามมันใช้การเข้ารหัสของตัวเองสำหรับตัวแปรที่ชื่อไม่ได้มี alnums หรืออาร์เรย์เมื่อส่งผ่านในสภาพแวดล้อมของคำสั่งที่ถูกดำเนินการ:
$ 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และzsh(ยังbashแต่สำหรับตัวอักษรเดียวไบต์) alnums สนับสนุนในสถานที่ปัจจุบันไม่เพียง แต่คน ASCII
$ Stéphane=1
$ echo "$Stéphane"
1
ในเปลือกหอยที่คุณสามารถเปลี่ยนสถานที่จะต้องพิจารณาตัวละครมากที่สุดเช่นอัลฟา แต่ยังคงที่จะไม่ทำงานสำหรับอักขระ ASCII .เช่น คุณสามารถหลอกzshหรือkshคิดว่า£เป็นตัวอักษร แต่ไม่ใช่.หรือตัวอักษร ASCII อื่น ๆ (ซึ่งการอนุญาตให้ใช้ตัวอักษรในชื่อตัวแปรเกี่ยวข้องไม่ใช่สำหรับกลุ่ม[[:alpha:]]ตัวอย่าง)
ksh93มีตัวแปรพิเศษที่ชื่อมีจุดคล้าย${.sh.version}แต่ไม่มีการจับคู่กับตัวแปรสภาพแวดล้อมและเป็นพิเศษ .คือการทำให้แน่ใจว่ามันไม่ได้มีความขัดแย้งกับตัวแปรอื่น ๆ ถ้ามันเลือกที่จะเรียกมันว่า$sh_versionแล้วมันจะได้สคริปต์เสียที่อาจเกิดขึ้นที่ใช้ตัวแปรที่แล้ว (ดูตัวอย่างวิธีการที่zshมีปัญหาเกี่ยวกับมัน$pathหรือ$commandsตัวแปรอาร์เรย์ / กัญชาพิเศษ (ก csh ลา) ที่ทำลายบางสคริปต์)
หมายเหตุว่านอกเหนือไปจากเปลือกหอยไม่สนับสนุนตัวแปรเหล่านั้นหอยบางอย่างเช่น pdksh / mksh ทำลบพวกเขาจากสภาพแวดล้อมที่พวกเขาได้รับ ( bashเอาหนึ่งที่มีชื่อที่ว่างเปล่าash, kshและbashลบสตริงสภาพแวดล้อมที่ผู้ที่ไม่ได้มี=ตัวอักษร):
$ 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 %%%
%%%
เพื่อสรุปผลดีที่สุดคือการยึดติดอยู่กับชื่อตัวแปรการสนับสนุนจากเปลือกหอยมากที่สุดและได้พยายามที่จะใช้กรณีที่บนสำหรับตัวแปรสภาพแวดล้อม (และกรณีที่ต่ำกว่าหรือกรณีผสมสำหรับตัวแปรเปลือกไม่ส่งออก) การหลีกเลี่ยงผู้ที่มีความพิเศษในเปลือกหอย (เช่นIFS, PS1, BASH_VERSION... )
หากคุณต้องการตั้งค่าตัวแปรดังกล่าวในเชลล์ที่ไม่สนับสนุน แต่ไม่ทิ้งคุณสามารถดำเนินการทดสอบด้วยตัวเองได้โดยใช้วิธีต่อไปนี้:
#! /bin/ksh -
perl -e 'exit 1 unless defined($ENV{"a.b"})' || exec env a.b=%%% "$0" "$@"
(เห็นได้ชัดว่าถ้าคุณจำเป็นต้องทำมันในช่วงกลางของสคริปต์นั่นไม่ได้ช่วยอะไร แต่คุณสามารถดูวิธีการนั้นเพื่อบันทึกและกู้คืนสภาพแวดล้อมการประมวลผลเชลล์ผ่านการประมวลผลซ้ำ) หรือลองใช้วิธีการดีบักเกอร์:
gdb --batch-silent -ex 'call putenv("a.b=%%%")' --pid="$$"
(ที่หนึ่งดูเหมือนว่าจะทำงานร่วมกับzsh, yash, cshและtcshบน Linux amd64 แต่ไม่ได้มีการใด ๆ ของเปลือกหอยอื่น ๆ ที่ฉันพยายาม ( mksh, ksh93, bash, dash))