洛陽(yáng)網(wǎng)站建設(shè)的公司哪家好深圳網(wǎng)絡(luò)營(yíng)銷的公司哪家好
環(huán)境:centos7.6,騰訊云服務(wù)器
Linux文章都放在了專欄:【Linux】歡迎支持訂閱🌹
相關(guān)文章推薦:
【Linux】馮.諾依曼體系結(jié)構(gòu)與操作系統(tǒng)
【Linux】進(jìn)程理解與學(xué)習(xí)Ⅰ-進(jìn)程概念
淺談Linux下的shell--BASH
【Linux】進(jìn)程理解與學(xué)習(xí)Ⅱ-進(jìn)程狀態(tài)
前言
什么是變量?
在學(xué)習(xí)之前我們要先搞清楚這個(gè)概念,就比如說(shuō)【y=ab+cd】,在這里,等號(hào)左邊的就是變量,等號(hào)右邊的則是變量的內(nèi)容。變量是bash中非常重要的一個(gè)存在,在Linux下變量又分為自定義變量以及環(huán)境變量。本次章節(jié)講對(duì)此做相關(guān)理解。
變量的定義與查看
變量的定義與查看
由我們用戶自己來(lái)直接定義的變量叫做自定義變量(也可以說(shuō)時(shí)本地變量),上面說(shuō)過(guò)等號(hào)左邊為變量名,右邊為變量的內(nèi)容,我們便可以根據(jù)此特點(diǎn)直接定義一個(gè)自定義變量。(我們可以通過(guò)echo $變量名來(lái)查看該變量的內(nèi)容)如下:

★注意點(diǎn):
這里我們?cè)诙x變量時(shí),有以下幾點(diǎn)需要注意:
等號(hào)兩邊不能直接跟空格,否則會(huì)報(bào)錯(cuò)
等號(hào)左邊的變量名的開(kāi)頭只能是英文字母(比如:2myval這種寫法錯(cuò)誤)
假如我們想要保持一個(gè)變量的內(nèi)容,并用該變量名去定義另一個(gè)變量時(shí),我們要在該變量名稱前加上$符號(hào)(比如我用myval的內(nèi)容去定義age,就要寫成age=$myval.其中$的作用便是保留原有變量的內(nèi)容,記住這一點(diǎn),后面配置PATH中會(huì)用到此特點(diǎn))
在定義變量時(shí),前面加export,就會(huì)將該變量導(dǎo)入環(huán)境變量表中(環(huán)境變量后面會(huì)講)

變量的取消定義
我們可以使用unset 變量名的指令來(lái)取消該變量的定義,如下:

環(huán)境變量
什么是環(huán)境變量呢?相信學(xué)習(xí)Java、Python的老鐵們應(yīng)該會(huì)有一個(gè)更深刻的認(rèn)識(shí),因?yàn)樵趯慗ava之前,相信大家都會(huì)安裝jdk,并在Windows下配置相關(guān)環(huán)境變量,配置完成后才能正常編寫。如下圖所示,這就是Windows下的環(huán)境變量:

Windows下的環(huán)境變量
說(shuō)了這么多,還是沒(méi)說(shuō)到環(huán)境變量究竟是什么?
實(shí)際上環(huán)境變量一般是指在操作系統(tǒng)中用來(lái)指定操作系統(tǒng)運(yùn)行環(huán)境的一些參數(shù)。Linux中同樣也存在著相關(guān)的環(huán)境變量。
這里舉個(gè)例子:我們?cè)诰帉慍/C++代碼的時(shí)候,在鏈接的時(shí)候,從來(lái)不知道我們的所鏈接的動(dòng)態(tài)靜態(tài)庫(kù)在哪里,但是照樣可以鏈接成功,生成可執(zhí)行程序,原因就是有相關(guān)環(huán)境變量幫助編譯器進(jìn)行查找。
不僅如此,環(huán)境變量通常還具有全局屬性,并且一般都是以大寫字符來(lái)表示。而由各個(gè)環(huán)境變量在一起構(gòu)成的集合,一般我們稱之為環(huán)境變量表,環(huán)境變量表可以被子進(jìn)程繼承。(先說(shuō)結(jié)論)
常見(jiàn)環(huán)境變量
以上所講都只是一些概念層次的知識(shí),接下來(lái)我們講幾個(gè)比較常見(jiàn)的環(huán)境變量,以便于大家能更好的理解。
PATH : 指定命令的搜索路徑
SHELL : 當(dāng)前Shell,它的值通常是/bin/bash。
USER:當(dāng)前用戶
PATH
我們?cè)趯懲甏a并編譯,生成一個(gè)可執(zhí)行程序時(shí),為什么運(yùn)行的時(shí)候要加./?實(shí)際上運(yùn)行一個(gè)程序的前提是找到該程序。只有找到它,才能運(yùn)行它,而./的含義大家應(yīng)該知道,表示的是當(dāng)前所在路徑。

那么為什么我們輸入ls的時(shí)候,則不用指定ls所在的具體位置呢?這里就涉及到了PATH,我們可以輸入指令echo $PATH來(lái)查看PATH這個(gè)環(huán)境變量的內(nèi)容,并且輸入指令which ls:來(lái)查看ls所在的路徑。就會(huì)發(fā)現(xiàn)原來(lái)ls所在的路徑在PATH里。

而PATH的作用則是指定搜索路徑,所以我們輸入指令ls的時(shí)候,會(huì)自動(dòng)去PATH中搜尋路徑,發(fā)現(xiàn)PATH中有l(wèi)s所在的路徑,因此我們直接輸入ls的時(shí)候,不用我們手動(dòng)指定路徑,也可以運(yùn)行l(wèi)s。但是如果我們不手動(dòng)指定我們自己寫的程序mytest,則會(huì)報(bào)錯(cuò),因?yàn)榄h(huán)境變量中并沒(méi)有mytest所在的路徑。

那么我們可不可以像Windows一樣,配置我們的環(huán)境變量呢?答案是可以的。
PATH環(huán)境變量的配置
我們可以使用指令export PATH=$PATH:自定義路徑(上面在變量的定義中講了$的作用就是保留PATH的原有內(nèi)容,PATH中:是分隔符,所以我們這樣來(lái)定義就相當(dāng)于給PATH追加了一個(gè)內(nèi)容。)如下:

環(huán)境變量的查看
一、env指令
我們可以直接輸入指令env,便可以查看當(dāng)前bash下的所有環(huán)境變量

二、通過(guò)指針數(shù)組訪問(wèn)
實(shí)際上,我們的環(huán)境變量表是一個(gè)指針數(shù)組結(jié)構(gòu),而環(huán)境變量會(huì)被子進(jìn)程所繼承。我們便可以利用此特點(diǎn)來(lái)使用我們自己寫的函數(shù)打印出環(huán)境變量。其實(shí)我們?cè)趯憁ain函數(shù)時(shí),實(shí)際上main函數(shù)有三個(gè)參數(shù):int argc、char* argv[]、char*envp[]。而char*envp[]這個(gè)指針數(shù)組中的內(nèi)容,就指向我們所說(shuō)的環(huán)境變量表的內(nèi)容的起始地址。如下:

我們可以通過(guò)代碼來(lái)驗(yàn)證一下:
#include<stdio.h> int main(int argc,char* argv[],char* envp[]){ for(int i=0; envp[i]; ++i){ printf("envp[%d]:%s\n",i,envp[i]);} }

運(yùn)行結(jié)果
三、通過(guò)全局變量environ獲取
#include<stdio.h>int main(int argc,char* argv[],char* envp[]){extern char** environ;for(int i=0; environ[i]; ++i) {printf("environ[%d]:%s\n",i,environ[i]);}}
四、通過(guò)系統(tǒng)調(diào)用函數(shù)getenv()來(lái)獲取我們想要的環(huán)境變量
我們可以通過(guò)系統(tǒng)調(diào)用函數(shù)getenv()來(lái)獲取我們想要查看的環(huán)境變量,如下:
#include<stdio.h>
#include<stdlib.h>//頭文件int main(){printf("%s",getenv("PATH"));}
關(guān)于環(huán)境變量的理解
先來(lái)看以下代碼:

我們從中可以得出結(jié)論:
只有環(huán)境變量會(huì)被子進(jìn)程所繼承,自定義變量并不會(huì)。自定義變量只能在自己的shell內(nèi)使用。實(shí)際上在環(huán)境變量的查看中我們也驗(yàn)證了這一點(diǎn):即main函數(shù)實(shí)際上的第三個(gè)參數(shù),便是用來(lái)接收環(huán)境變量表的指針數(shù)組。

★總結(jié)
上面講的有些零碎,這里做一個(gè)總結(jié):
【y=a】等號(hào)左邊表示的是變量名,右邊表示變量?jī)?nèi)容
我們可以通過(guò)echo $變量名的指令,來(lái)查看該變量的內(nèi)容
在定義變量時(shí),前面加上export,則會(huì)將該變量導(dǎo)入環(huán)境變量表
環(huán)境變量表實(shí)際上是所有環(huán)境變量的集合,本質(zhì)上是一個(gè)指針數(shù)組,每一個(gè)數(shù)組元素都是指針,指向?qū)?yīng)的環(huán)境變量的內(nèi)容的起始位置。(最后一個(gè)位置為NULL)
set指令會(huì)打印出所有的變量的內(nèi)容(本地、環(huán)境),env則只打印環(huán)境變量的內(nèi)容
環(huán)境變量我們可以通過(guò)main函數(shù)中的指針數(shù)組來(lái)查看(環(huán)境變量會(huì)被子進(jìn)程繼承,所以我們寫的程序也可以拿到父進(jìn)程bash的環(huán)境變量表)、也可以通過(guò)全局變量environ來(lái)查看,或者通過(guò)函數(shù)getenv()來(lái)獲取。
環(huán)境變量可以被所有子進(jìn)程繼承,但是自定義變量則只可以在自己的shell中使用。
我們可以通過(guò)unset 環(huán)境變量名 來(lái)取消該環(huán)境變量。
環(huán)境變量實(shí)際上是內(nèi)存級(jí)別的一張表,當(dāng)我們登錄系統(tǒng)時(shí),os會(huì)給用戶形成特定的環(huán)境變量表。而環(huán)境變量對(duì)應(yīng)的數(shù)據(jù)實(shí)際上保存在了系統(tǒng)的相關(guān)配置文件中(bashrc、profile等)。

環(huán)境變量的相關(guān)配置文件部分內(nèi)容
命令行參數(shù)
在上面我們講到了main函數(shù)中的三個(gè)參數(shù),為int argc、char* argv[]、char* envp[]。其中我們了解了第三個(gè)參數(shù),也就是用來(lái)接收環(huán)境變量表的指針數(shù)組。那么前面兩個(gè)呢?
argc:傳入的元素個(gè)數(shù)(也就是我們輸入的指令的個(gè)數(shù))
char* argv[]:也是一個(gè)表,只不過(guò)這張表存放的是指向傳入的元素的起始位置的指針。其中,最后一個(gè)有效元素的下一個(gè)內(nèi)容為NULL(這張表由bash制作)

當(dāng)然,我們也可以寫以下代碼來(lái)驗(yàn)證:
#include<stdio.h>//argc:傳入的元素個(gè)數(shù) //argv:用來(lái)存放元素內(nèi)容起始位置的指針數(shù)組int main(int argc,char* argv[]) { printf("傳入的元素個(gè)數(shù)為:%d\n",argc);printf("傳入的有效元素內(nèi)容為:\n"); for(int i=0; i<argc; i++) { printf("argv[%d]:%s\n",i,argv[i]);} return 0; }

運(yùn)行結(jié)果
為什么我們輸入ls -a 與ls -l 的功能不同,原理也在于此,即對(duì)命令行參數(shù)進(jìn)行相關(guān)指令設(shè)置。我們也可以實(shí)現(xiàn)一個(gè)簡(jiǎn)單的任務(wù):如下:
#include<stdio.h>#include<stdlib.h>#include<string.h>#include<unistd.h>void Utest(char* st){printf("%s:-[a | b]\n",st);}int main(int argc,char* argv[]){//身份驗(yàn)證,只有qidunyan用戶可以進(jìn)行操作if(strcmp(getenv("USER"),"qidunyan")){printf("%s用戶非法\n",getenv("USER"));return 0;}//指令輸入錯(cuò)誤 if(argc!=2){printf("指令錯(cuò)誤,請(qǐng)重新輸入:\n");Utest(argv[0]);}
// ./mytest -aif(strcmp(argv[1],"-a")==0){printf("執(zhí)行A任務(wù)\n");//...sleep(3);printf("執(zhí)行完畢\n");} else if(strcmp(argv[1],"-b") == 0){printf("執(zhí)行B任務(wù)\n");//...sleep(3);printf("執(zhí)行完畢\n");}else {printf("指令錯(cuò)誤,重新輸入:\n");Utest(argv[0]);}return 0;}

運(yùn)行結(jié)果
end.
生活原本沉悶,但跑起來(lái)就會(huì)有風(fēng)!🌹