Есть ли имена переменных окружения, которые не могут быть перезаписаны пользователем/вызовом setenv
? Насколько я понимаю из POSIX1.2008, любой процесс может редактировать блок окружения, но должен избегать перезаписи таких переменных, как LANG и т. д.
решение1
Окружение представляет собой список строк в форме var=value
(условно), который передается как третий аргумент системного вызова execve().
Этот список помещается куда-то в стек процесса, когда он начинает выполнять новую команду, точно так же, как и список аргументов (еще один список строк, переданный в качестве второго аргумента execve()
).
В программах, использующих libc (большинство), код инициализации, вызываемый перед main()
вызовом функции, делает эти строки окружения доступными в виде environ
массива.
libc
Также предоставляет функции putenv
и setenv
, которые могут изменять (копию) этого списка, полученного программой. Эта поддерживаемая, измененная копия затем будет передана следующей команде, выполняемой процессом или любым из его потомков через функции / execvp()
/ execl()
/ system()
... popen()
libc (которые сами в конечном итоге вызывают execve()
системный вызов).
Теперь, когда вы создаете список строк, которые вручную передаете в execve()
системный вызов, вы можете передавать строки типа foo
(без =
символа) или =bar
(с пустым именем переменной), setenv
не позволит вам этого сделать ( setenv("", "bar", 1)
отклоняется).
setenv("a=b", "c")
также будет отклонено. Таким образом, строки, которые будут определены, setenv
всегда будут иметь формат x=y
, где x
не может быть пустым.
Это единственное ограничение (также применяемое putenv
). Ну, это строки с завершающим NUL-символом, и, конечно, символ NUL не может появляться в имени или значении переменной.
setenv("*", "x", 1)
, или setenv("\n\n", "", 1)
все в порядке, если setenv()
говорить о ядре. Теперь, сможете ли вы сделать что-то полезное с ними, это другой вопрос.
решение2
Нет, нет ограничений на то, какие переменные окружения могут быть изменены процессом. Однако имейте в виду, что каждый процесс имеет своисобственная копияунаследованной среды, и процесс не может изменить никакую переменную среды в любом другом процессе. Вызов setenv
может изменить среду только в пределах вызывающего процесса.
решение3
export MYENV=value
readonly MYENV
решение4
Я думаю, это полностью зависит от используемой вами оболочки.
В Bash UID
одно BASH_VERSINFO
и то же, согласно странице руководства.
С другой стороны в csh согласно руководствуПеременные среды нельзя сделать доступными только для чтения.