。# Linux系列
文章目錄
- 前言
- 一、環境變量的概念
- 二、常見的環境變量
- 三、環境變量特點及其相關指令
- 3.1 環境變量的全局性
- 3.2、環境變量的生命周期
- 四、環境變量的組織方式
- 五、C語言對環境變量的操作
- 5.1 設置環境變量:setenv
- 5.2 刪除環境變量:unsetenv
- 5.3 遍歷所有環境變量:environ
前言
環境變量是操作系統和用戶設置的一些動態鍵值對,為運行的程序提供配置信息。理解環境變量對于系統管理、軟件開發都很重要。
一、環境變量的概念
環境變量是操作系統用來存儲和傳遞與系統環境相關信息的一種機制,是以鍵值對形式定義的全局變量,供操作系統和應用程序讀取和使用。
通常格式為:
當VALUE為多個時,以‘:’符號隔開
KEY=VALUE
- KEY:變量名
- VALUE:對應值
那么它究竟有什么作用呢?我們來看這個例子:
從上面我們可以看到存在一個可執行程序test
,第一次我們執行它,程序并沒有正常運行,當然都知道因為沒有指定程序所在路徑,所以程序不能正常運行,第二次指定了不就運行成功了,那么我們的指令在執行時為什么不用指定路徑呢?在指令篇我們就介紹過,指令的本質就是一個寫好的可執行程序,當時我們說,如果我們想要讓自己寫的,可執行程序,像指令一樣直接運行,我們可以將程序拷貝到指令所在路徑下:/usr/bin
那還是沒有解釋為什么指令可以直接運行,或者說bash
是如何找到指令的可執行程序的呢?還有沒有其他方法可以使我們的可執行程序像指令一樣運行呢?接下來我們來認識一下本篇第一個環境變量:PATH
PATH
是操作系統中最核心的環境變量之一,當我們在命令行輸入一個命令時,操作系統會按照PATH
中定義的目錄依次搜索該命令對應的可執行文件,若未找到該命令對應的可執行文件就會提示:command not found
。
查看PATH
:
echo $PATH
PATH環境變量對應多個值,使用“:"隔離開
所以當我們將自己寫的可執行文件,拷貝到/usr/bin
路徑下,系統在PATH
對應的目中就可以找到。
還有什么方法可以解決這里的問題呢?只需要將我們自己寫的可執行程序所在路徑添加到PATH
環境變量中,不就也可以完成搜索了
PATH=$PATH:/home/ltn/dir
剛才的test于前面路徑存在的,可執行程序重名了,所以又換了個程序給大家演示,但這恰恰說明了系統是從第一個路徑向后搜索程序的。
我們使用which
查找指令時,就是在PATH
環境變量中搜索的,所以現在我們就可以像查找指令一樣查找我們自己的可執行程序了。
二、常見的環境變量
環境變量 | … 作用 | 對應VALUE |
---|---|---|
HOME | 當前用戶的主目錄路徑 | /home/ltn |
USER | 當前登錄用戶名 | ltn |
PWD | 當前工作目錄路徑 | /home/ltn |
HISTSIZE | 記錄歷史指令最大數 | 10000 |
查看環境變量:
查看所有環境變量:
env
查看指定環境變量:
echo $環境變量名
僅是截取的一部分
三、環境變量特點及其相關指令
為了方便接下來的講解,我先帶大家認識一個關于環境變量的系統調用接口:
頭文件:#include<stdlib.h>
參數:環境變量名
返回值:如果存在則返回一個指向環境變量名的指針,否則返回NULL
3.1 環境變量的全局性
環境變量最開始是在我們登錄xshell時,操作系統給bash
形成的,當我們執行某些指令時,bash
會創建子進程,并且將環境變量繼承下來(當然會做某些修改),簡單來說:環境變量是子進程從父進程那里繼承下來的。
接下來我們驗證一下!!!
創建我們自己的環境變量:
export ltn =”1234“
我們在當前bash
進程定義了一個環境變量,如果子進程會繼承父進程的環境變量,則可以打印出結果,否則程序什么都不輸出。
1 #include<stdio.h> 2 #include<unistd.h> 3 #include<stdlib.h> 4 int main() 5 { 6 printf("子進程的ltn->%s\n",getenv("ltn")); 7 return 0; 8 }
可以看到程序成功打印,所以子進程會繼承父進程的環境變量。
3.2、環境變量的生命周期
- 環境變量的生命周期與進程綁定
- 進程終止時,環境變量也會被回收
正是有了繼承的這種形式,我們之前所提到的權限概念,才會被每條指令遵守。
刪除環境變量:
unset ltn
四、環境變量的組織方式
我們之前在學習的C語言,不知道你有沒有聽過main
函數的參數:
int main(int argc, char *argv[], char *env[])
第三個參數我們先不驗證
1 #include<stdio.h>2 #include<unistd.h>3 #include<stdlib.h>4 int main(int argc, char *argv[], char *env[])5 {6 int i=0;7 for(;i<argc;i++)8 {9 printf("argv[%d]->%s\n",i,argv[i]); 10 }11 return 0;12 }
這樣一段代碼,當我們執行它時,結果會怎么樣呢?
可以看到我們以上面兩種不同的方式執行,程序打印出了兩種不同的結果,要知道怎么會這樣,我們還是要知道參數是什么意思:
參數一 argc
- 作用:記錄命令行參數的數量
- 規則:
- 1、
argc
的值至少為1,因為第一個參數始終是程序自身的名稱。 - 2、用戶輸入的每個參數(以空格分隔)都會增加
argc
的值。
參數二 argv
- 作用:存儲命令行參數的具體值(用空格分開的代表不同參數),以字符串數組的形式表示
- 規則:
- 1、
argv[0]
是程序名稱(可能包含路徑,取決于調用方式)。 - 2 、
argv[1]
到argv[argc-1]
是用戶輸入的參數。 - 3、
argv[argc]
是一個空指針(NULL
),表示數組結束。
參數三、env
-
作用:指向系統的環境變量數組(從bash那繼承的),每個元素是
KEY=VALUE
格式的字符串。 -
規則:
-
1、 環境變量數組以
NULL
結尾。 -
2、可以通過
getenv()
函數更安全地獲取特定環境變量。
當知道了main函數
的這些參數,我們就可以理解,為什么同一個指令加上不同的選項會有不同的功能了:當你在執行指令是帶上不同參數,它就會存入到argv
數組中,然后通過if else
語句匹配不同代碼塊。實現不同功能。
五、C語言對環境變量的操作
5.1 設置環境變量:setenv
頭文件:#include<stdlib.h>
參數:
- name:設置的環境變量名
- value:設置的環境變量值
- overwrite:是否覆蓋已有值(非零表示覆蓋)
示例:
1 #include<stdio.h>2 #include<unistd.h>3 #include<stdlib.h>4 int main(int argc, char *argv[], char *env[])5 {6 if(setenv("ltn","Hell Linux",0)==0);7 {8 printf("ltn set to->%s\n",getenv("ltn")); 9 10 }11 return 0;12 }
5.2 刪除環境變量:unsetenv
頭文件:#include<stdlib.h>
參數:
- name:環境變量名
示例:
1 #include<stdio.h>2 #include<unistd.h>3 #include<stdlib.h>4 int main(int argc, char *argv[], char *env[])5 {6 if(setenv("ltn","Hell Linux",0)==0);7 {8 printf("ltn set to->%s\n",getenv("ltn"));9 10 }11 unsetenv("ltn"); 12 printf("ltn->%s\n",getenv("ltn")); 13 return 0; 14 }
創建好,并刪除
5.3 遍歷所有環境變量:environ
environ
是一個全局變量,內部存有所有環境變量的指針,,末尾指針指向NULL,具體介紹太長,不方便展示,大家可以自己看。
示例:
1 #include<stdio.h>2 #include<unistd.h>3 #include<stdlib.h>4 extern char**environ;
W> 5 int main(int argc, char *argv[], char *env[])6 {7 char **env1=environ;8 while(*env1)9 {10 printf("%s",*env1);11 env1++; 12 }13 14 return 0;15 }
僅截取部分打印結果
下面我們來說一下第三給參數,第三參數,是一個環境變量數組,也就是說,我們可以通過直接變量得到全部環境變量:
1 #include<stdio.h>2 #include<unistd.h>3 #include<stdlib.h>4 extern char**environ;5 int main(int argc, char *argv[], char *env[])6 {7 int i=0;8 while(env[i])9 {10 printf("%s\n",env[i]);11 i++; 12 }13 14 return 0;15 }
本篇就先到這里,看完給個三連吧!!!