目錄
1.基本變量
2.通過代碼獲取環境變量
2.1 main傳參?
2.2 全局變量environ?
2.3 系統調用getenv()?
3.在腳本文件中添加環境變量
4.環境變量通常是具有全局屬性
1.基本變量
環境變量(environment variables)一般是指在操作系統中用來指定操作系統運行環境的一些參數如:我們在編寫C/C++代碼的時候,在鏈接的時候,從來不知道我們的所鏈接的動態靜態庫在哪里,但是照樣可以鏈接成功,生成可執行程序,原因就是有相關環境變量幫助編譯器進行查找。環境變量通常具有某些特殊用途,還有在系統當中通常具有全局特性。
常見環境變量
- PATH : 指定命令的搜索路徑
- HOME : 指定用戶的主工作目錄(即用戶登陸到Linux系統中時,默認的目錄)
- SHELL : 當前Shell,它的值通常是/bin/bash。
- USER:當前帳號使用者
查看環境變量方法
echo $NAME //NAME:你的環境變量名稱
env 查看所有環境變量
測試PATH
- 創建myproc.c文件
#include <stdio.h> int main() {printf("hello world!\n");return 0; }
- 對比 ./myproc 執行和之間 myproc 執行
- 要執行一個命令,必須先要找到這個對應的可執行程序!為什么有些指令可以直接執行,不需要帶路徑,而我們的二進制程序需要帶路徑才能執行?
- 將我們的程序所在路徑加入環境變量PATH當中, export PATH=$PATH:myproc 程序所在路徑
- 對比測試
- 還有什么方法可以不用帶路徑,直接就可以運行呢?那就是把我們寫的可執行程序移動到PATH默認路徑中。?
默認更改環境變量,只限于本次登陸,重新登陸,環境變量會自動被恢復。那這是為什么呢?
因為這些環境變量的值是存在配置文件中的,每次登錄都會重新讀取配置文件。
測試HOME
- 用root和普通用戶,分別執行 echo $HOME ,對比差異. 執行 cd ~; pwd ,對應 ~ 和 HOME 的關系
?可以發現不同用戶有不同的主目錄即HOME。
為什么普通用戶默認所處目錄/home/xxxx,而root是 /root ???
登陸的時候
- 輸入用戶名&&密碼
- 認證
- 形成環境變量(肯定不止一個,PATH,PWD,HOME)
- 根據用戶名,初始化HOME。root:HOME=/root,普通用戶:HOME=/home/xxxx
- cd $HOME
系統中會存在大量的環境變量,每一個環境變量都有它自己的特殊用途,用來完成特定的系統功能!
2.通過代碼獲取環境變量
獲取環境變量有三種方式:
2.1 main傳參?
系統啟動我們的程序的時候,可以選擇給我們的進程(main)提供兩張表
- 命令行參數表
- 環境變量表
命令行參數表之前文章已經講過了。這里講一下環境變量表。?我們執行下面代碼,使用main函數的第三個參數
#include <stdio.h>
int main(int argc, char *argv[], char *env[])
{int i = 0;for(; env[i]; i++){printf("%s\n", env[i]);}return 0;
}
運行結果:
2.2 全局變量environ?
libc中定義的全局變量environ指向環境變量表,environ沒有包含在任何頭文件中,所以在使用時 要用extern聲明。不聲明也可以。使用通過第三方變量environ獲取環境變量:
#include <stdio.h>
int main(int argc, char *argv[])
{extern char **environ;int i = 0;for(; environ[i]; i++){printf("%s\n", environ[i]);}return 0;
}
2.3 系統調用getenv()?
通過系統調用獲取或設置環境變量:getenv()函數來訪問特定的環境變量
#include <stdio.h>
#include <stdlib.h>
int main()
{//打印PATH的內容printf("%s\n", getenv("PATH"));return 0;
}
3.在腳本文件中添加環境變量
環境變量生成原理 :
命令行啟動的進程都是shell/bash的子進程,子進程的命令行參數和環境變量是父進程bash給我們傳遞的!而父進程的環境變量信息是以腳本配置文件的形式存在的!
而我們直接在命令行更改的是bash進程內部的環境變量信息!每一次重新登陸,都會給我們形成新的bash解釋器,并且新的bash解釋器自動從讀取形成自己的環境變量表信息!
每一次登陸的時候,你的bash進程都會讀取 .bash_profile。配置文件中的內容,為我們bash進程形成一張環境變量表信息!
如果想要想要自己創建的一個環境變量在每次登錄時都存在,可以在主目錄下使用 ll -a,查看隱藏的 .bash_profile ,并對其進行修改
?添加自己創建的環境變量:
查看是否成功:?
4.環境變量通常是具有全局屬性
- 環境變量通常具有全局屬性,可以被子進程繼承下去
我們在命令行中創建一個本地定義變量OURENV ,運行下面代碼
#include <stdio.h>
#include <stdlib.h>
int main()
{printf("OURENV:%s\n",getenv("OURENV"));return 0;
}
運行結果:?
?可以發現:通過export 將局部變量添加到環境變量中,才能被命令行bash的子進程myproc得到。
本地變量vs環境變量
- 本地變量只在bash進程內部有效,不會被子進程繼承下去
- 環境變量通過讓所有的子進程繼承的方式,實現自身的全局性!
如果我們把PATH該為空字符串,我們可以發現有些指令可以運行,而有些指令卻不可以運行
Linux的命令分類:
- 常規命令,shell 通過fork讓子進程成執行的,像ls touch ,所以PATH為空后不能執行。
- 內建命令,shell命令行的一個函數,向pwd,cd,是可以直接讀取shell內部定義的本地變量
和環境變量相關的命令
- echo: 顯示某個環境變量值
- export: 設置一個新的環境變量
- env: 顯示所有環境變量
- unset: 清除環境變量
- set: 顯示本地定義的shell變量和環境變量
沒有export 的變量都是本地變量。可以通過set顯示,unset清除
本篇結束!