В то время как переменные окружения могут иметь любое имя (включая пустую строку), не содержащее знака равенства или нулевого байта, оболочки отображают переменные среды на переменные оболочки, и в большинстве оболочек имена переменных ограничиваются буквенно-цифровыми символами 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
но только для однобайтовых символов) поддерживают текущую локалию, а не только ASCII.
$ Stéphane=1
$ echo "$Stéphane"
1
В этих оболочках вы можете изменить локаль, чтобы большинство символов считалось альфа-каналом, но все же это не сработало бы для символов ASCII, таких как .
. Вы можете обмануть zsh
или ksh
думать, £
что это буква, но не тот .
или любой другой символ ASCII (если речь идет о разрешении символов в именах переменных, например, не о [[:alpha:]]
глобусе).
ksh93
имеет специальные переменные, имя которых содержит точку, похожую на точку ${.sh.version}
, но они не отображаются на переменные окружения и являются специальными. Необходимо .
убедиться, что он не конфликтует с другими переменными. Если бы он решил вызвать его $sh_version
, он мог бы иметь потенциально сломанные сценарии, которые уже использовали эту переменную (см., Например, как возникают zsh
проблемы с его $path
или $commands
специальными переменными array / hash (a la csh), которые нарушают некоторые сценарии).
Следует отметить , что в дополнение к оболочках , не поддерживающих эти переменные, некоторые оболочки , как pdksh / МКШ сделать удалить их из окружающей среды , которую они получают ( 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
)).