Während Umgebungsvariablen einer beliebigen Namen (einschließlich dem leeren String) hat nicht ein Gleichheitszeichen oder einen Null - Byte enthält, Karte shells Umgebungsvariablen Variablen und in den meisten Muscheln, Variablennamen in ASCII - alphanumerischen Zeichen und begrenzt sind , Shell , _
wo das erste Zeichen kann‘ t sein eine Ziffer ( mit Ausnahme der Positionsparameter und andere besondere diejenigen wie $*
, $-
, $@
, ..., (die nicht zu den entsprechenden Umgebungsvariablen abgebildet werden)). Beachten Sie auch, dass einige Variablen von / für die Shell reserviert / speziell sind .
Ausnahmen davon:
Die rc
Schale und seine Derivate wie es
und akanga
unterstützen einen beliebigen Namen außer den leeren String, und diejenigen , die alle numerischen sind oder enthalten =
Zeichen (und immer alle ihre Variablen in die Umgebung zu exportieren, und passen Sie von speziellen Variablen wie *
, status
, pid
...):
; '%$£"' = test
; echo $'%$£"'
test
; '' = x
zero-length variable name
;
Es verwendet jedoch eine eigene Codierung für Variablen, deren Name keine Alarme enthält, oder für Arrays, die in der Umgebung von Befehlen übergeben werden, die ausgeführt werden:
$ 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
und zsh
(auch , bash
aber nur für Single-Byte - Zeichen) Unterstützung alnums in den aktuellen Locale, nicht nur ASCII diejenigen.
$ Stéphane=1
$ echo "$Stéphane"
1
In diesen Shells können Sie das Gebietsschema so ändern, dass die meisten Zeichen als Alpha betrachtet werden. Bei ASCII-Zeichen wie z .
. Sie können täuschen zsh
oder ksh
denken, dass £
es sich um einen Buchstaben handelt, aber nicht um dieses .
oder ein anderes ASCII-Zeichen (wenn es darum geht, Zeichen in Variablennamen zuzulassen, beispielsweise nicht für den [[:alpha:]]
Glob).
ksh93
hat spezielle Variablen, deren Name einen Punkt wie enthält ${.sh.version}
, aber diese sind nicht Umgebungsvariablen zugeordnet und sind speziell. Das .
ist um sicherzustellen , dass es nicht mit anderen Variablen in Konflikt geraten. Wenn es sich dafür entschieden hätte, es aufzurufen $sh_version
, könnte es möglicherweise Skripte beschädigt haben, die diese Variable bereits verwendet haben (siehe zum Beispiel, wie zsh
Probleme mit ihren $path
oder $commands
speziellen Array- / Hash-Variablen (a la csh) auftreten, die einige Skripte beschädigen).
Beachten Sie, dass zusätzlich zu den Schalen nicht diese Variablen, einige Shells wie pdksh Stütz- / mksh tun entfernen sie aus der Umgebung , die sie erhalten ( bash
entfernt die man mit einem leeren Namen ash
, ksh
und bash
diese Umgebung Strings entfernen, die keine enthalten =
Zeichen):
$ 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 %%%
%%%
Um es zusammenzufassen, ist am besten mit Variablennamen von den meisten Schalen unterstützt zu halten und versuchen , auch Großbuchstaben für Umgebungsvariablen zu verwenden (und Kleinschreibung oder gemischter Fall für nicht-exportierte Shell - Variablen) vermieden werden diejenigen , die in Schalen speziell sind (wie IFS
, PS1
, BASH_VERSION
...).
Wenn Sie eine solche Variable in einer Shell festlegen müssen, die sie nicht unterstützt, aber nicht verwirft, können Sie sie entweder selbst erneut ausführen.
#! /bin/ksh -
perl -e 'exit 1 unless defined($ENV{"a.b"})' || exec env a.b=%%% "$0" "$@"
(Wenn Sie dies in der Mitte des Skripts tun müssen, hilft das natürlich nicht weiter. Sie können sich jedoch diesen Ansatz ansehen , um die Shell-Ausführungsumgebung über eine erneute Ausführung zu speichern und wiederherzustellen.) Oder probieren Sie den Debugger-Ansatz:
gdb --batch-silent -ex 'call putenv("a.b=%%%")' --pid="$$"
(dass man Arbeit scheint mit zsh
, yash
, csh
und tcsh
auf Linux amd64, aber nicht mit einer der anderen Shells ich versuchte ( mksh
, ksh93
, bash
, dash
)).