Windows和Linux的環境變數
- 2019 年 12 月 20 日
- 筆記
環境變數概述
環境變數(Environment Variables)一般是指在作業系統中用來指定作業系統運行環境的一些參數,如:臨時文件夾位置和系統文件夾位置等。
環境變數是在作業系統中一個具有特定名字的對象,它包含了一個或者多個應用程式所將使用到的資訊。例如 Windows 和 DOS 作業系統中的 path
環境變數,當要求系統運行一個程式而沒有告訴它程式所在的完整路徑時,系統除了在當前目錄下面尋找此程式外,還應到 path 中指定的路徑去找。如 tc 或 vc++ 中,set include=path1;path2;
是告訴編譯程式到哪裡去找 .h
類型的文件;當然不僅僅是指定什麼路徑,環境變數還有其它的作用的,如set dircmd=/4
設置一個環境變數的作用是在使用 dir
命令時會把 /4
作為預設的參數添加到你的 dir
命令之後,就像你的每個命令都加了 /4
參數,它實際上是給命令解釋程式 command
設置的一個環境變數,並且是給 dir
這個內部命令設置的。
很多朋友會在自己的電腦上安裝雙系統,例如 C 盤安裝 Windows 10,D 盤安裝 Windows 7。可是某些軟體往往只在Windows 10 系統中安裝,Windows 7 系統中是無法正常使用的,比較麻煩卻有效的方法是再安裝一遍。當我們了解了環境變數中的用途後就可以很好解決雙系統的軟體共用問題。為什麼在 Windows 10 中安裝了的軟體(綠色軟體和不兼容軟體除外)在 Windows 7 下無法運行呢?原因是安裝軟體時往往須要向系統目錄中複製某些文件,而使用另外一個系統時會由於缺少這些文件而無法運行,而我們可以通過設置環境變數的方法來解決這個問題。
環境變數設置
Windows 系統
Windows 系統常見環境變數如下:
- %ALLUSERSPROFILE%:局部。返回所有「用戶配置文件」的位置。
- %APPDATA%:局部。返回默認情況下應用程式存儲數據的位置。
- %CD%:局部。返回當前目錄字元串。
- %CMDCMDLINE%:局部。返回用來啟動當前的 cmd.exe 的準確命令行。
- %CMDEXTVERSION%:系統。返回當前的「命令處理程式擴展」的版本號。
- %COMPUTERNAME%:系統。返回電腦的名稱。
- %COMSPEC%:系統。返回命令行解釋器可執行程式的準確路徑。
- %DATE%:系統。返回當前日期。使用與
date /t
命令相同的格式。由cmd.exe
生成,可參考date
命令的詳細資訊。 - %ERRORLEVEL%:系統。返回使用過的命令的錯誤程式碼。通常用非零值表示錯誤。
- %HOMEDRIVE%:系統。返回連接到用戶主目錄的本地工作站驅動器號。基於主目錄值的設置。用戶主目錄是在「本地用戶和組」中指定的。
- %HOMEPATH%:系統。返回用戶主目錄的完整路徑。基於主目錄值的設置。用戶主目錄是在「本地用戶和組」中指定的。
- %HOMESHARE%:系統。返回用戶的共享主目錄的網路路徑。基於主目錄值的設置。用戶主目錄是在「本地用戶和組」中指定的。
- %LOGONSEVER%:局部。返回驗證當前登錄會話的域控制器的名稱。
- %NUMBER_OF_PROCESSORS%:系統。指定安裝在電腦上的處理器的數目。
- %OS%:系統。返回作業系統的名稱。Windows 2000 將作業系統顯示為 Windows_NT。
- %PATH%:系統。指定可執行文件的搜索路徑。由 PATH 環境變數指定的目錄下的命令可以在任意目錄中直接使用。
- %PATHEXT%:系統。返回作業系統認為可執行的文件擴展名的列表。
- %PROCESSOR_ARCHITECTURE%:系統。返回處理器的晶片體系結構。值: x86,IA64。
- %PROCESSOR_IDENTIFIER%:系統。返回處理器說明。
- %PROCESSOR_LEVEL%:系統。返回電腦上安裝的處理器的型號。
- %PROCESSOR_REVISION%:系統。返回處理器修訂號的系統變數。
- %PROMPT%:局部。返回當前解釋程式的命令提示符設置。由
cmd.exe
生成。 - %RANDOM%:系統。返回 0 到 32767 之間的任意十進位數字。由
cmd.exe
生成。 - %SYSTEMDRIVE%:系統。返回包含 Windows XP 根目錄(即系統根目錄)的驅動器。
- %SYSTEMROOT%:系統。返回 Windows XP 根目錄的位置。
- %TEMP% and %TMP%:系統和用戶。返回對當前登錄用戶可用的應用程式所使用的默認臨時目錄。有些應用程式需要 TEMP,而其它應用程式則需要 TMP。
- %TIME%:系統。返回當前時間。使用與
time /t
命令相同的格式。由cmd.exe
生成。可參考 time 命令的詳細資訊。 - %USERDOMAIN%:局部。返回包含用戶帳戶的域的名稱。
- %USERNAME%:局部。返回當前登錄的用戶的名稱。
- %USERPROFILE%:局部。返回當前用戶的配置文件的位置。
- %WINDIR%:系統。返回作業系統目錄的位置。
設置方法
環境變數分為兩類:用戶變數與系統變數,在註冊表中都有對應的項。其中用戶變數位於:
HKEY_CURRENT_USEREnvironment
系統變數位於:
HKEY_LOCAL_MACHINESYSTEMControlSet001ControlSession ManagerEnvironment
在 Windows 作業系統中可以通過我的電腦
→ 系統屬性
→ 高級系統設置
→ 環境變數
,在原有變數的基礎上添加英文狀態下的分號,然後將路徑名輸入即可。(切記,不要刪除原先的系統變數,只要用分號隔開,然後添加,最後也要加上分號)。然而在此設置的環境變數是在註冊表中具有對應的項。在 .net 中提供了一個類來獲取系統的環境變數及其值。
Windows 平台以 Win 10 為例: 右鍵此電腦
→ 屬性
:
高級系統設置
→ 環境變數
:
用戶變數僅對當前的用戶有效,系統變數對所有用戶有效。
考慮到不影響其他用戶的使用,這裡選擇設置用戶變數。選中用戶變數中的Path
→ 編輯
(如果沒有 Path,則選擇新建
Path):
env6.png
在彈出的對話框中就可以新建或編輯環境變數名和環境變數值了。
注意:Windows 下不區分大小寫,因此 windows 與 WINDOWS 都正確;而 Linux 系統是嚴格區分大小寫的。
命令行查看環境變數
在 Windows 命令行輸入 set
命令可以查看 Windows 系統當前所存在的所有的環境變數。從環境變數中我們可以得到很多資訊。
例如 PROCESSOR_IDENTIFIER 顯示處理器的架構,USERDOMAIN 顯示電腦名,USERNAME 顯示電腦用戶名,TEMP 顯示系統臨時文件夾的位置,PROMPT 顯示當前提示符的狀態燈。
env.png
也可以查看單個的環境的變數,例如輸入 set windir
顯示當前的系統文件夾的位置。輸入 set P
可以查看所有字母以P開頭的環境變數的值。也可以使用 echo 環境變數引用
來顯示,如 echo %windir%
也可以顯示當前的系統文件夾的位置。
注意:Windows 環境變數在引用的時候需要用
%
括起來,以便於和普通的字元區分。
env2.png
也可以自定義環境變數,例如我們輸入 set aa=%temp%
,就代表把臨時文件夾的值賦值給aa。我們還可以刪除環境變數,例如我們輸入 set aa=
就可以把我們剛才建立的環境變數刪除了。
有關 set
命令的其他用法請參考 set
命令幫助:在命令行輸入 set /?
回車即可查看 set
命令幫助
注意:不用擔心在DOS窗口的修改會影響
此電腦
→屬性
→高級
→環境變數
里的修改,因為 DOS 窗口的環境變數只是 Windows 環境變數的一個副本,副本的改動不會影響正本,所以在 DOS 窗口中以set
命令對環境變數的操作只對當前窗口的應用有效。要想永久加入環境變數,就要用圖形介面操作。 但是DOS 窗口的環境變數改動會觸發正本(圖形介面環境變數的修改)的刷新,這可用於使圖形介面的環境變數設置立即生效
。
Linux 系統
環境變數配置文件
Linux 中環境變數也包括系統級和用戶級,系統級的環境變數是每個登錄到系統的用戶都要讀取的系統變數,相關配置文件位於 /etc
目錄下,而用戶級的環境變數則是該用戶使用系統時載入的環境變數,僅對當前登錄的用戶有效,相關配置文件位於用戶個人目錄下,使用 ls -a
可以查看到這些文件。所以管理環境變數的文件也分為系統級和用戶級的。
首先理解一下幾個概念:
login shell
,登錄 shell:用戶通過終端登錄,以及憑藉用戶名和密碼登錄控制台(包括通過 ssh 方式)的動作是login shell
,也就是說最終會調用 login 命令的操作、需要完整的登陸流程都可稱之為 login shell。non-login shell
,非登陸 shell:用戶在圖形介面啟動一個 terminal,或者執行/bin/bash、/usr/bin/bash
等不需要重複登陸的舉動都屬於non-login shell
。interactive shell
,互動式 shell:互動式模式就是在終端上執行,shell 等待你的輸入,並且立即執行你提交的命令。這種模式也是大多數用戶非常熟悉的:登錄、執行一些命令、退出。當你退出後,shell 也終止了。non-interactive
,非互動式shell :shell 也可以運行在非互動式模式,以 shell script (非交互模式)方式執行。在這種模式 下,shell 不與你進行交互,而是讀取存放在文件中的命令,並且執行它們。當它讀到文件的結尾 EOF,shell 也就終止了。
系統級:
/etc/environment
:該文件設置的是整個系統的環境,只要啟動系統就會讀取該文件,是系統啟動時讀取的第一個文件,用於為所有進程設置環境變數。該文件並不是一個腳本文件,系統使用此文件時並不是執行此文件中的命令,而是根據KEY=VALUE
模式的程式碼(VALUE中不能有空格),對KEY
賦值以VALUE
,因此文件中如果要定義PATH
環境變數,只需加入一行形如PATH=PATH:/xxx/bin
的程式碼即可;/etc/profile
:在進入作業系統使用的第二個文件,為系統的每個用戶設置環境變數,這裡的環境變數是永久性的。當系統啟動後用戶首次登錄時,該文件被執行,並從/etc/profile.d
目錄的配置文件中搜集 shell 的設置。/etc/profile.d/*.sh
:每當進入一個 login shell 或載入桌面會話時,/etc/profile.d
目錄中的所有.sh
腳本都會執行。因為/etc/profile
文件會循環遍歷執行改目錄下的文件*.sh
文件;/etc/bashrc
:是針對所有用戶的 bash 初始化文件,在此中設定的環境變數將應用於所有用戶的 shell 中,此文件會在用戶每次打開 shell 時執行一次。(即每次新開一個終端,都會執行/etc/bashrc
)。
用戶級:
~/.pam_environment
:當使用圖形化介面設置區域和語言時,該文件會被修改。Ubuntu 系統中有該文件,CentOS 系統中沒發現有該文件。~/.bash_profile
(或~./bash_login
或~/.profile
):每個用戶都可使用該文件輸入專屬於自己的 shell 資訊,當用戶登錄時,該文件僅僅執行一次。默認情況下,該文件設置一些環境變數、讀取用戶的~/.bashrc
文件。(如果~/
目錄下沒有.bash_profile
,則新建立一個)。當一個shell
關閉時,在.bash_profile
中定義的系統變數則會失效。因此,每打開一個新的login shell
時都要運行一次source .bash_profile
,而且針對當前用戶。該文件中的讀取會在~/.pam_environment
文件之後,推薦在這裡進行個人環境變數設置;~/.bashrc
:該文件包含專用於某個用戶的 bash shell 的 bash 資訊,當登錄時以及每次打開新的shell
時,該該文件都會被讀取;~/.bash_logout
:當每次退出系統(退出bash shell
)時執行該文件。
登陸 shell 與非登陸 shell 讀取 shell 配置文件的順序:
其中,實線的的方向是主線流程,虛線的方向則是被調用(或讀取)的配置文件 ,執行完 bash 操作後退出 bash shell
時會執行~/.bash_logout
文件。
對於 login shell
讀取文件的順序是:
/etc/profile
~/.bash_profile
~/.bash_login
~/.profile
其中,/etc/profile
是必須要執行的,後面 3 個按照順序讀取存在的那一個,而後面的就不會再執行。退出交互控制台執行的文件是 ~/.bash_logout
。
而 ~/.bashrc
是在 non-login shell
啟動時執行的,也就意味著在圖形介面每開啟一次 terminal,就會讀取一次該文件。在很多 Red hat 和 Ubuntu 的發行版中,如果 .bashrc
存在於 /home目錄下的某個用戶目錄中,它將從 .bash_profile
或 .profile
中運行。
另:/etc/environment
是整個系統的環境,而 /etc/profile
是所有用戶的環境,前者啟動系統後就會去讀取該文件,後者只有在用戶登錄的時候才去讀取。
了解他們的執行順序後,就知道環境變數該怎麼放了。要想對所有的用戶生效,那就需要設置系統級的環境變數。反之,需要修改用戶級的文件。建議將 Java 的環境變數都配置於/etc/profile
(所有用戶可用)或 ~/.bash_profile
、~/.bash_login
、~/.profile
中(僅當前用戶可用,優先存在哪一個文件就配置在哪一個文件中)。
選擇哪些文件配置環境變數
許多人都在 /etc/profile
文件中設置系統級環境變數,但是不建議這樣做。執行 cat /etc/profile
可以看到如下內容:
# It's NOT a good idea to change this file unless you know what you # are doing. It's much better to create a custom.sh shell script in # /etc/profile.d/ to make custom changes to your environment, as this # will prevent the need for merging in future updates.
說明一般不建議修改該文件,因為作業系統升級時無法自動合併這裡配置的環境的變數,而且一旦配置出錯影響範圍較大。該文件後面還有這樣一段內容:
for i in /etc/profile.d/*.sh ; do if [ -r "$i" ]; then if [ "${-#*i}" != "$-" ]; then . "$i" else . "$i" >/dev/null fi fi done
說明每次執行 /etc/profile
文件都會循環遍歷執行 /etc/profile.d
目錄下的 .sh
文件,所以建議把某一類系統環境變數單獨配置到某個 .sh
文件中,放在 /etc/profile.d
目錄下即可。
如果要單獨為某個用戶設置環境變數,可以將環境變數配置在 ~/.bashrc
文件中。
操作環境變數的命令
Linux 下也有查看、設置環境變數的命令。查看或修改環境變數可以使用以下幾個命令:
export
:直接使用使用該命令可以列印出當前所有環境變數,使用export 變數名
形式的命令可以列印出某個環境變數的值,使用export 變數名=變數值
可以用來臨時(只對當前 shell 有效,shell關閉了,該變數也就失效了)設置某個環境變數的值。其用法與 Windows 下的 set 命令基本類似。有關 export 命令的其他用法請參考 export 命令的幫助說明。- echo 命令結合
$
:使用echo $變數名
形式的命令可以列印出某個環境變數名。Linux 下使用$
來引用某個環境變數。 printenv
:該命令單獨使用可以輸出本地所有環境變數,也可以使用printenv 變數名
形式的命令列印出某個環境變數的值,就像export
命令列印某個環境變數的值一樣。env
:該命令也可以來顯示所有環境變數,但不能用於顯示單個的環境變數。該命令也可以用來臨時修改某個環境變數的值,這種用戶類似於 export 臨時修改環境變數的值。set
:單獨使用該命令可以查看為某個特定進程設置的所有環境變數,包括局部變數、全局變數 以及用戶定義變數。- ,使用
set 變數名=變數值
形式的命令可以設置某個環境變數的值,如果未指定變數值,則該變數值將被設為NULL
。 setenv
:該命令屬於 C shell。設置環境變數的語法為setenv 變數名 變數值
;unset
:使用unset 變數名
形式的命令可以臨時清除某個環境變數,再次查看該環境變數將看不到結果。readonly
:設置只讀環境變數,如readonly HELLO
。如果使用了readonly
命令的話,變數就不可以被修改或清除了。
不同於 Windows 系統,Linux 系統上的環境變數名是區分大小寫的,通常用全部大寫的字母表示。
命令 env、printenv 和 set 之間的差異很細微。set 命令會顯示出全局變數、局部變數以及用戶定義變數。它還會按照字母順序對結果進行排序。env 和 printenv 命令同 set 命令的區別在於前兩個命令不會對變數排序,也不會輸出局部變數和用戶定義變數。在這種情況下,env 和 printenv 的輸出是重複的。