
我知道這VARIABLE=value
會建立一個環境變量,並export VARIABLE=value
使其可供當前 shell 建立的進程使用。env
顯示當前的環境變量,但它們位於哪裡?環境變數(或環境, 對於這個問題)?
答案1
環境並不像看起來那麼神奇。 shell 將其儲存在記憶體中並傳遞給execve()
系統呼叫。子進程將其繼承為一個名為 的陣列指標environ
。從execve
線上說明頁:
概要
#include <unistd.h> int execve(const char *filename, char *const argv[], char *const envp[]);
argv
是傳遞給新程式的參數字串數組。
按照約定,這些字串中的第一個應包含與正在執行的檔案關聯的檔案名稱。envp
是一個字串數組,通常採用 key=value 的形式,作為環境傳遞給新程式。
線上environ(7)
幫助頁也提供了一些見解:
概要
extern char **environ;
描述
該變數
environ
指向一個名為「環境」的字串指標數組。此數組中最後一個指標的值為NULL
。 (此變數必須在使用者程式中聲明,但如果頭檔來自 libc4 或 libc5,並且如果它們來自 glibc 並且定義了 _GNU_SOURCE,則在頭檔中聲明<unistd.h>
。)此字串數組可用於透過啟動該程序的exec (3) 呼叫來執行該進程。
這兩個 GNU 手冊頁都與POSIX規範
答案2
你有一點錯誤:SOME_NAME=value
建立一個 shell 變數(在大多數 shell 中)。export SOME_NAME=value
建立一個環境變數。無論好壞,大多數 Unix/Linux/*BSD shell 在存取環境變數和 shell 變數時都使用相同的語法。
從更大的意義上來說,「環境」只是伴隨程式執行的資訊。在 C 程式中,您可能會透過呼叫找到進程 ID getpid()
,在 shell 程式中您將使用變數 access: $$
。進程ID只是程式環境的一部分。我相信「環境」一詞來自一些更具理論性的電腦科學主題,例如對程式執行進行建模。環境「其中包含變數及其值之間的關聯」。
後者更強的定義是 Unix/Linux/*BSD shell 的「環境」:名稱(「變數」)與其值之間的關聯。對於大多數 Unix 風格的 shell,這些值都是字串,儘管這並不像以前那麼嚴格。如今,Ksh、Zsh 和 Bash 都有類型化變數。甚至可以導出 shell 函數定義。
使用與普通 shell 變數分開的環境涉及fork/exec
啟動所有 Unix 都使用的新進程的方法。當您使用export
名稱/值對時,該名稱/值對將出現在新執行檔的環境中,由 shell 透過execve(2)
系統呼叫啟動(通常在 後fork(2)
,除非exec
使用 shell 指令)。
在 後面execve()
,main()
new 二進位檔案的函數有其命令列參數、環境(儲存為以 NULL 結尾的字串指標數組var=value
,請參閱environ(7)
手冊頁)。繼承的其他狀態包括ulimit
設定、目前工作目錄以及execve()
呼叫者未設定 FD_CLOEXEC 的任何開啟的檔案描述符。 tty 的目前狀態(啟用回顯、原始模式等)也可以被視為新exec
程序繼承的執行狀態的一部分。
請參閱bash
手冊的說明執行環境對於簡單命令(內建或 shell 函數除外)。
Unix 環境至少與某些其他作業系統不同:VMS「詞彙」可以由子程序更改,並且該更改在父進程中可見。子行程中的VMScd
會影響父行程的工作目錄。至少在某些情況下,我的記憶力可能會下降。
有些環境變數是眾所周知的,$HOME
,$PATH
,$LD_LIBRARY_PATH
等等。有些是給定編程系統的常規信息,因此父 shell 可以將大量特殊用途的信息傳遞給某些程序,例如特定的臨時目錄,或者不顯示在ps -ef
.例如,簡單的 CGI 程式透過環境變數從 Web 伺服器繼承大量資訊。
答案3
最原始形式的環境變數只是一組名稱/值對。如 bash 手冊頁 ( man 1 bash
) 的 ENVIRONMENT 部分所述:
When a program is invoked it is given an array of strings called the
environment. This is a list of name-value pairs, of the form
name=value.
The shell provides several ways to manipulate the environment. On
invocation, the shell scans its own environment and creates a parameter
for each name found, automatically marking it for export to child pro-
cesses. Executed commands inherit the environment.
實際上,它允許您定義從目前 shell 呼叫的程式共用或唯一的行為。例如,在使用crontab
或時,visudo
您可以定義EDITOR
環境變數來定義系統預設使用的編輯器以外的另一個編輯器。對於諸如man
查看您的PAGER
環境以找出應使用哪個分頁程式來顯示手冊頁輸出的命令之類的命令也是如此。
許多 unix 指令都會讀取環境,並根據設定的內容改變它們的輸出/處理/操作。有些是共享的,有些是該程式獨有的。大多數手冊頁都包含有關環境變數如何影響所描述的程序的資訊。
其他實用範例適用於在同一平台上安裝了多個 Oracle 的系統等情況。透過設置ORACLE_HOME
,整套 oracle 命令(從PATH
環境變數載入)然後從該頂級目錄下提取設定、定義、映射和庫。對於其他程式(例如 java 及其JAVA_HOME
環境變數)也是如此。
bash 本身有許多環境變量,可以改變一系列事物的行為,包括歷史記錄(HISTSIZE
等HISTFILE
)、螢幕大小(COLUMNS
)、製表符補全(FIGNORE
, GLOBIGNORE
)區域設定和字元編碼/解碼(LANG
, LC_*
)、提示(PS1
.. PS4
)和依此類推(再次從 bash 手冊頁尋求知識)。
您也可以編寫使用您自己的自訂環境變數的腳本/程式(以傳遞設定或變更功能)。
答案4
“環境變數”是一組動態命名值,可以影響正在運行的進程在電腦上的行為。
它們是進程運行的操作環境的一部分。例如,正在執行的程序可以查詢 TEMP 環境變數的值以發現儲存暫存檔案的適當位置,或查詢 HOME 或 USERPROFILE 變數以尋找執行該程序的使用者擁有的目錄結構。
更多資訊請點這裡→http://en.wikipedia.org/wiki/Environment_variable。
關於環境變數你想知道的一切...... ↑