是否存在无法被用户/调用覆盖的环境变量名称setenv
?据我从 POSIX1.2008 了解到,任何进程都可以编辑环境块,但必须避免覆盖 LANG 等变量。
答案1
环境是以下形式的字符串列表var=value
(按照惯例) 作为第三个参数传递给 execve() 系统调用。
当进程开始执行新命令时,该列表将被放置在进程堆栈的某个位置,就像参数列表一样(作为第二个参数传递给 的另一个字符串列表execve()
)。
在使用 libc(大多数)的程序中,在main()
调用函数之前调用初始化代码,使这些环境字符串可用作environ
数组。
它还libc
提供了可以修改程序收到的列表(的副本)的功能putenv
。然后,维护的、修改后的副本将通过 libc 的// / ... 函数(它们本身最终调用系统调用)setenv
传递给进程或其任何子进程执行的下一个命令。execvp()
execl()
system()
popen()
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中环境变量不能设为只读。