是否存在無法被使用者/呼叫覆蓋的環境變數名稱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中環境變數不能設為唯讀。