目錄
變數
全域變數
區域變數
變數的設定
環境變數是什么?
常見的環境變數
PATH變數
main函式引數
變數
Linux變數分為自定義變數和環境變數 環境變數具有繼承性,自定義變數不會被子行程給繼承,v
- 環境變數又分為全域變數和區域變數,
- 環境變數有繼承性,父行程的子行程同樣擁有,
全域變數
需要修改組態檔,變數永久生效
區域變數
使用export命令宣告即可,變數在關閉shell時失效,
變數的設定
- 變數與變數的內容用=相隔開
- 且等號兩兩邊不能直接接空格
- 變數的名稱可以是英文字母與數字,但開頭不能用數字
myval=100 該變數為自定義變數
- 若該變數為擴增變數內容時,可用 ”$變數名稱“ 累加內容,
例如:PATH=$PATH:/home/sjp 其中PATH這個變數多加了:/home/sjp 這個內容,
- 如果要想讓其它子程式執行,則需要以export開頭將變數匯入到環境變數中
export myval 將我們的自定義變數myval匯入到環境變數中
- 【unset 變數名稱】 取消變數
- 通常大寫字符為系統默認的變數,自己定義的變數可以用小寫
- set 查看所有的變數,包括環境變數
- env 查看所有的環境變數
環境變數是什么?
環境變數可以使系統運行環境配置更加簡單靈活,可以通過設定環境變數給行程傳遞引數資訊,
常見的環境變數
PATH:指定命令的搜索路勁:
HOME:當前用戶的主作業目錄(即Linux登錄時,默認的目錄),cd ~去的就是我們的主
SHELL:當前shell,它的值是通常是/bin/shell
PATH變數
創建一個hello.c檔案:
#include<stdio.h>
int main()
{
printf("hello sjp\n");
return 0;
}
當我們把這個檔案編譯鏈接形成我們的可執行程式hello,
[sjp@iZwz97d32td9ocseu9tkn4Z lesson13]$ make
gcc -c hello.c
gcc -o hello hello.o

hello是我們的可執行程式,相當于一個命令,當我們直接敲hello去運行的時候,發現運行不了,為什么呢?

原因是命令列解釋器bash找不到這個指令,因為我們沒把hello這個指令的路徑給它,它就不知道從哪里找,所以要想運行它可以在hello前面帶 { ./ } , { ./ }是代表當前目錄下,所以我們要運行一個可執行程式為什么經常要在可執行程式前面帶{ ./ } 的原因,

還有是將hello的絕對路勁給它,這樣我們也是可以運行hello這個可執行程式,

可是我們要想讓這個hello這個指令在前面不帶任何路勁的東西,就可以我們的bash也能夠找到它,那應該怎么做呢?
我們可以參考一下我們平時敲的指令是怎么做的,例如 ls cd等等指令,這些指令在執行的時候前面是沒有加任何路勁的東西,因為它們的的路徑被包含再PATH,
我們先來看一下PATH這個環境變數的包含的內容:
[sjp@iZwz97d32td9ocseu9tkn4Z lesson13]$ echo $PATH
/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/sjp/.local/bin:/home/sjp/bin
echo $NAME //NAME是你的變數名稱 查看變數包含的內容
我們可以看到$PATH的內容包含著一條條路勁,每條路勁是由 冒號間隔著( :) ,例如/usr/local/bin是一條路徑,上面總共有7條路徑,
我們在看一下ls這個指令是在哪一條路勁底下:

這一看是不是就明白了許多,這個路徑就包含在PATH變數的里面:

其實當我們執行ls指令的時候,bash會通過PATH里面包含的路勁一條一條的找這個指令,找到了就執行,找不到就bash就會回傳【command not found】,也就是說要想讓hello在前面不帶任何路勁下,就能執行,我們只需要PATH包含hello的路徑就可以,
那么問題來了,怎么將hello的路徑匯入到PATH里面呢?
我們先找到hello在哪個路徑底下
[sjp@iZwz97d32td9ocseu9tkn4Z lesson13]$ pwd
/home/sjp/lesson13
pwd是查看路勁的命令,我們可以看到hello在/home/sjp/lesson13下,然后我們在把這條路徑匯入到PATH,如下:
[sjp@iZwz97d32td9ocseu9tkn4Z lesson13]$ export PATH=$PATH:/home/sjp/lesson13
export是設定環境變數的命令
$PATH是保留原來PATH的內容,然后在添加【:路徑】,這樣可以讓PATH的內容添加新的路徑,
我們再查看一下PATH的內容:
[sjp@iZwz97d32td9ocseu9tkn4Z lesson13]$ echo $PATH
/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/sjp/.local/bin:/home/sjp/bin:/home/sjp/lesson13
看最后面,/home/sjp/lesson13確實添加到我們的PATH里面去了,
再敲hello這條指令看一下能不能運行起來

果然,跟我們的預期是一樣的,
如果我們把PATH這個環境變數給清空后在執行指令后:
[sjp@iZwz97d32td9ocseu9tkn4Z 9_19]$ export PATH=
[sjp@iZwz97d32td9ocseu9tkn4Z 9_19]$ echo $PATH
[sjp@iZwz97d32td9ocseu9tkn4Z 9_19]$ ls
-bash: ls: No such file or directory
PATH的等號的右邊什么都沒有,就直接把PATH給清空掉了,
這時候我們再去執行ls指令的時候,bash就找不到該指令,這也證明了PATH是指定了執行檔案查找的路勁,
當你可能會說,你把PATH指令給清空了,那你豈不是得用一條一條的路勁再去配置PATH變數
其實不用那么麻煩,只要我們重新登錄我們bash就可以了,這時候組態檔就就會重新給我們的PATH進行配置,因為命令export命令的環境變數是暫時的,關閉shell就會被清空掉,而我們組態檔中的環境變數是永久有效的,
總結:
PATH環境變數是指定執行檔案到它包含的的路徑下一條一條的尋找,
export可以設定新的環境變數,但是它只是暫時的,
SHELL:
查看具體的SHELL是什么,在linux系統下的具體的SHELL是bash
[sjp@iZwz97d32td9ocseu9tkn4Z ~]$ echo $SHELL
/bin/bash
env:是environment的簡稱,可以查看所有的環境變數
main函式引數
在了解main函式之前,我們得先思考一個問題:
ls等指令是怎樣通過選項或者引數來執行不同行為?
例如 ls -l是列出檔案和目錄的所有資訊(不包括隱藏檔案的資訊) ls -a是是列出所有目錄和檔案(包括隱藏檔案)
對于我之前寫過很多的c語言與c++程式,每一個程式都會寫一個main函式,但是我之前寫的main函式都是沒有引數的,但后來我發現main函式也是可以有引數,在main函式中可以傳這3個引數
main(int argc,char*argv[ ],char* envp[ ])
那這三個引數有什么用呢?
我們先看一下下面這個程式,這個程式是將我們的argv陣列中的字符指標給列印出來,
1 #include<stdio.h>
2
3 int main(int argc,char* argv[])
4 {
5 for(int i=0;i<argc;i++)
6 {
7 printf("atgv[%d]:%s\n",i,argv[i]);
8 }
9
10 return 0;
11 }
argc是一個字符指標陣列,
經過編譯后形成我們的test可執行程式,當我們在命令列輸入./test后;

我們發現陣列的第一個字符指標指向的內容是我們在命令列輸入的./test
我們再輸入./test -a在看:

陣列中的第一個字符指標指向./test 第二個字符指標指向-a,
再輸入./test -a -b

陣列中的第一個字符指標指向./test ,第二個字符指標指向-a,第三個字符指標指向我們的-b,
由此我們可以得出char*argv[ ]這個字符指標陣列中的指標是是指向我們命令列中的輸入一個一個的字串,每一個字串是以空格相隔開的,該陣列最后一個元素是NULL,argc代表的是這個字符指標陣列有多少個元素(字符指標),

./test -a -b 是不是看起來會不會很眼熟?
這不是跟我們之前寫的ls -a -l指令這些指令非常相似,當我們執行指令的時候,ls的字符地址放在
字符指標陣列的第一個元素當中,-a放在第二個元素當中,-l放在第三個元素當中,
我們再寫一個程式test:當我們假如引數-a 的時候 test就輸出 i like you 加入引數 -b 的時候就輸出 i hate you,沒有加引數就輸出hello sjp,
1 #include<stdio.h>
2 #include<string.h>
3 int main(int argc,char* argv[])
4 {
5 if(argc==2)
6 {
7 if(strcmp(argv[1],"-a")==0)
8 {
9 printf("i like you\n");
10 }
11 else if(strcmp(argv[1],"-b")==0)
12 {
13 printf("i hate you\n");
14 }
15 }
16 else
17 {
18 printf("hello sjp\n");
19 }
20 return 0;
21}
我們來測驗一下:

現在我們明白指令是怎樣通過選項去執行不同的行為了吧,是不是很有意思,
說到這里我們就明白了main函式前兩個引數是什么呢?
那第三個引數char* envp[ ]到底是什么呢?
envp也是一個char*型別的指標陣列,envp中的指標指向的我們系統中一個個的環境變數,最后一個元素也為NULL,
envp必須先有 前面int argc,char* argv[]這兩個引數才有效,不能單獨傳envp這個引數,不然跟我們的預想不一樣,
我們寫一個test程式測驗一下這個envp這個指標陣列指向的內容是什么?
代碼如下:
29int main(int argc,char* argv[],char* envp[])
30 {
31 int i=0;
32 while(envp[i])
33 {
34 printf("envp[%d]:%s\n",i,envp[i]);
35 i++;
36 }
37 return 0;
38 }

我們可以看到envp這個陣列包含這么多的指標,當中每個指標指向的是系統中的環境變數,
所以說,每個程式中都有一個main函式,當我們的程式加載到記憶體中變成我們的行程,呼叫的該行程的父行程就會默認的傳環境變數表(envp)給子行程的main函式,這時候,子行程就可以通過環境變數表(envp)去查找環境變數,還有一些行程可以(創建自己的環境變數),所以,當我們登錄bash,系統就會傳環境變數表給我們的bash,當bash去執行指令的時候,bash會通過PATH路勁去查找相應的指令程式,然后運行該指令,

好啦,今天的分享就到這里,如果你覺得這篇文章不錯的話,希望你可以給我點個贊,你的支持將是我最好的反饋,
點個贊唄~

完!
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/301758.html
標籤:其他
