【Linux庖丁解牛】—環境變量!

目錄

1. 環境變量

1.1 概念介紹

1.2 命令行參數?

1.3? 一個例子,一個環境變量

1.4?認識更多的環境變量

1.5?獲取環境變量的方法

a. 指令操作

b. 代碼操作

1.6?理解環境變量的特性

a.環境變量具有全局特性

b.補充兩個概念(為后面埋一個伏筆)


1. 環境變量

1.1 概念介紹

? 環境變量(environment variables)?般是指在操作系統中用來指定操作系統運行環境的?些參數

? 如:我們在編寫C/C++代碼的時候,在鏈接的時候,從來不知道我們的所鏈接的動態靜態庫在哪 里,但是照樣可以鏈接成功,生成可執行程序,原因就是有相關環境變量幫助編譯器進行查找。

? 環境變量通常具有某些特殊用途,還有在系統當中通常具有全局特性

1.2 命令行參數?

下面我們先來做一個實驗,我們都知道在C/C++中,main函數其實是有兩個參數的(int argc,char* argv[ ]),字符指針在C語言中要么存有一個字符的地址,要么表示一個字符串的首地址,argv表示數組中存有字符串,而argc表示字符串的個數。

下面的代碼表示將數組中的所有字符串打印下來:

下面是實驗結果:?

根據結果我們可以發現有某種東西將我們命令行上面的命令(包含空格的字符串)以空格為分隔符分離成多個字符串,并保存在argv數組中。

下面我們再來寫一個代碼:

#include <stdio.h>
int main(int argc,char *argv[])
{if(argc!=2){printf("usage:%s [-a|-b|-c]\n",argv[0]);}return 0;
}

?以上代碼是在用戶沒有正確使用該命令時告訴用戶使用該命令的時候需要帶上【-a -b -c】其中的一個選項。

?所以我們就可以用main函數的命令行參數來實現程序的各種不同子功能【這也是指令選項的實現原理】。

總結:每個進程都有一張argv表,用來實現選項功能,以往我們沒有關心main函數的命令行參數是因為我們寫的程序不需要這些需求。?

小問題:我們在命令行中寫的長字符串是被誰切分了呢?

這里直接說結果:用戶每次登入系統時都會自動創建一個bash進程,該進程會幫組我們解析命令行中的長字符串。【具體bash是如何做到的我暫時還不知道呢!以后再告訴你們】

1.3? 一個例子,一個環境變量

系統預裝指令【ls、mkdir】VS 自己寫的程序

我們在使用系統級指令時,直接用它們的名稱即可。但是當我們要執行自己寫的程序時,必須要指明該指令的路徑【相對路徑或絕對路徑】。我們都知道,要執行一個程序,必須先找到它。但是這里有一個問題,系統級指令是如何根據指令名稱找到該指令的呢?

先說結論:系統中存在環境變量,來幫助系統找到目標二進制文件!

系統級指令在usr/bin/目錄下,如果我們的指令也在該目錄下也就可以和系統級指令一樣不用指明路徑了。

自己寫的程序有很多未知性,所以我們還是不要把他放到該目錄下!?

?好,接下來我們來認識一下第一個環境變量PATH

PATH是系統中默認搜索指令的路徑。?

其中的冒號將每一個默認搜索路徑分隔開來,當我們命令行中執行一個命令時,系統會根據PATH環境變量中的默認路徑【從第一個路徑開始】來查找是否存在該命令。?如果存在,則執行,否則輸出該命令未被找到。

既然如此,那如果我們將自己的路徑添加到PATH環境變量中,那我們的指令是不是也可以和系統級指令那般直接使用呢?

當然可以,我們直接修改PATH=路徑

但是這樣系統級指令就找不到了,不過我們關掉xshell重新登入PATH就恢復了

如果我們希望只添加路徑的話,如下操作可以辦到,當重新登入也會恢復原樣:

?至于為什么會回復原樣,我們需要對環境變量有更加深刻的理解!

接下來,我們從存儲的角度理解環境變量。

先說結論,在用戶登入系統時,bash進程會形成一張表->【環境變量表】,這張表的結構和命令行參數表完全相同【都是字符指針數組】。

env命令可以查看系統當中的所有環境變量,而環境變量表中存儲著這些內容!

所以,環境變量就是bash進程內部malloc的一段空間,而這段空間存儲的內容就是一個一個的字符串【環境變量】?。

至此,我們就可以理解當我們在命令行當中敲下ls -al命令時,ls -al的基本執行流程了:bash進程首先拿到“ls -al”字符串,然后切分形成命令行參數表,接著根據解析完成后的字符串到環境變量表當中找到PATH環境變量,根據PATH默認的路徑下找該命令,找到即執行,沒找到則報錯。

那環境變量最開始從哪里來的呢?->[如果不登入就沒有bash進程]

先說結論:從系統相關的配置文件中來的!

bash進程創建時就會從配置文件中拿到所有的環境變量并創建一張表!這就是我們上面說到的修改PATH環境變量為什么在重新登入時就會恢復原樣的原因。

好,那我們就來看一下什么是配置文件!

在每個Linux用戶的家目錄下都有一個.bashrc的隱藏文件。

該文件下的100多行都是先關的配置信息。?

那如果我們將自己的路徑添加到配置文件中的PATH值的時候,是不是每次登入時自己寫的程序可以和系統級指令一樣使用呢!當然如此!這里就不演示了。

1.4?認識更多的環境變量

。HOME環境變量

指定用戶的家目錄(即用于登入Linux系統時,默認的家目錄)

。LOGNAME? |? USER 【登入用戶 | 用戶】

。HISTSIZE?

記錄我們歷史上敲的最新1000行命令

。PWD? |? OLDPWD [當前工作路徑 | 上一次工作路徑]

這也是我們使用cd -可以來回切換工作路徑的原因,系統已經幫我們記錄好了。

最后,我們在回到環境變量的概念:環境變量(environment variables)?般是指在操作系統中用來指定操作系統運行環境的?些參數

此時,我們就會對這個概念有更加深刻的理解了,我們會發現每一種環境變量都有其特定的功能,有的是記錄當前用戶的,有的是記錄歷史指令的,有的是幫我們找指令的默認路徑的,還有的是記錄主機名,記錄當前工作路徑……而這些環境變量都是系統提供的,并且這些環境變量本質上是給bash進程使用,這也是間接的給用戶使用了!

1.5?獲取環境變量的方法

a. 指令操作

上面我們使用過了env【查看所有環境變量】,echo +環境變量名【查看某個環境變量】就不多說了。

export【向環境變量表中導入自己寫的環境變量】

?unset【取消某個環境變量】

b. 代碼操作

1.main函數的第三個命令行參數char *env

我們之前說main函數有兩個參數,其實還有第三個參數env,這個參數繼承了父進程bash的環境變量表,所以我們也可以通過這個參數拿到所有的環境變量。

?因為子進程會繼承父進程bash的環境變量表,所以如果我們修改bash的環境變量,那么子進程的環境變量也會隨之修改。

bash進程環境變量表修改后:

?子進程的環境變量表:

既然如此,bash的孫子進程,曾孫進程等等都會基礎bash的環境變量表。

所以說:環境變量通常具有某些特殊用途,還有在系統當中通常具有全局特性

2.getenv【系統調用】

給該函數傳遞環境變量名,該函數就會返回字符串地址【該環境變量的內容】。即可以獲得指定環境變量的內容。

上面我們說過:子進程會繼承父進程的環境變量,為什么要這樣設計呢?

這是為了讓我們的進程可以根據環境變量做個性化的操作!下面舉一個栗子:

如果我們希望寫一個只有我們自己才能運行的程序,該怎么寫呢?

我們都知道,系統當中只有bash進程認識當前用戶是誰【在環境變量USER當中記錄著】,所以我們可以通過獲取該環境變量的方式來控制我們的程序邏輯進而實現只有自己登錄系統時才能運行該程序的目的。

用戶是user2時:?

用戶是root時:? ? ??

3. environ 【全局的二級指針】

該指針指向環境變量表的首地址,所以是二級指針。所以我們也可以通過它來獲取所有的環境變量。

1.6?理解環境變量的特性

a.環境變量具有全局特性

(前面已經說明過這個特性了,這里就不贅述了)

b.補充兩個概念(為后面埋一個伏筆)

1.本地變量

我在命令行中直接定義變量i=10,發現echo命令也可以查看到該變量,但是該變量并不是環境變量,沒有記錄到環境變量表當中。

但是我們可以用set命令同時查看環境變量和本地變量。

本地變量與環境變量不同,并不會被子進程繼承,而只是在bash內部被使用。

2.我們的環境變量是在誰里面?bash!

export是把自己寫的環境變量導入到父進程bash里面。

而子進程怎么會導數據到父進程里面呢?這也太奇怪了!

原因就在于export是內建命令【built-in command】執行該指令時,不需要創建子進程,而是讓bash自己親自執行【bash自己調用函數或者系統調用完成】。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/79403.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/79403.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/79403.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

LangChain4j +DeepSeek大模型應用開發——7 項目實戰 創建硅谷小鹿

這部分我們實現硅谷小鹿的基本聊天功能&#xff0c;包含聊天記憶、聊天記憶持久化、提示詞 1. 創建硅谷小鹿 創建XiaoLuAgent package com.ai.langchain4j.assistant;import dev.langchain4j.service.*; import dev.langchain4j.service.spring.AiService;import static dev…

普通 html 項目也可以支持 scss_sass

項目結構示例 下載vscode的插件Live Sass Compiler 自動監聽編譯scss 下載插件Live Server 用于 web 服務器&#xff0c;打開 html 文件到瀏覽器&#xff0c;也可以不用這個&#xff0c;自己用 nginx 或者寶塔其他 web 工具 新建一個 index.scss打開&#xff0c;點擊 vscode 底…

網工_IP協議

2025.02.17&#xff1a;小猿網&網工老姜學習筆記 第19節 IP協議 9.1 IP數據包的格式&#xff08;首部數據部分&#xff09;9.1.1 IP協議的首部格式&#xff08;固定部分可變部分&#xff09; 9.2 IP數據包分片&#xff08;找題練&#xff09;9.3 TTL生存時間的應用9.4 常見…

SQL語句練習 自學SQL網 在查詢中使用表達式 統計

目錄 Day 9 在查詢中使用表達式 Day 10 在查詢中進行統計 聚合函數 Day 11 在查詢中進行統計 HAVING關鍵字 Day12 查詢執行順序 Day 9 在查詢中使用表達式 SELECT id , Title , (International_salesDomestic_sales)/1000000 AS International_sales FROM moviesLEFT JOIN …

基于機器學習的輿情分析算法研究

標題:基于機器學習的輿情分析算法研究 內容:1.摘要 隨著互聯網的飛速發展&#xff0c;輿情信息呈現爆炸式增長&#xff0c;如何快速準確地分析輿情成為重要課題。本文旨在研究基于機器學習的輿情分析算法&#xff0c;以提高輿情分析的效率和準確性。方法上&#xff0c;收集了近…

菲索旋轉齒輪法:首次地面光速測量的科學魔術

一、當齒輪邂逅光束&#xff1a;19世紀的光速實驗室 1849年&#xff0c;法國物理學家阿曼德菲索&#xff08;Armand Fizeau&#xff09;在巴黎郊外的一座莊園里&#xff0c;用一組旋轉齒輪、一面鏡子和一盞油燈&#xff0c;完成了人類首次地面光速測量。他的實驗測得光速為315…

上位機知識篇---PSRAM和RAM

文章目錄 前言一、RAM&#xff08;Random Access Memory&#xff09;1. 核心定義分類&#xff1a;SRAM&#xff08;靜態RAM&#xff09;DRAM&#xff08;動態RAM&#xff09; 2. 關鍵特性SRAM優點缺點應用 DRAM優點缺點應用 3. 技術演進DDR SDRAMLPDDR&#xff08;低功耗DRAM&a…

Qt QComboBox 下拉復選多選(multicombobox)

Qt QComboBox 下拉復選多選&#xff08;multicombobox&#xff09;&#xff0c;備忘&#xff0c;待更多測試 【免費】QtQComboBox下拉復選多選&#xff08;multicombobox&#xff09;資源-CSDN文庫

ElasticSearch深入解析(五):如何將一臺電腦上的Elasticsearch服務遷移到另一臺電腦上

文章目錄 0.安裝數據遷移工具1.導出數據2.導出mapping3.導出查詢模板4.拷貝插件5.拷貝配置6.導入到目標電腦上 0.安裝數據遷移工具 Elasticsearch dump是一個用于將Elasticsearch索引數據導出為JSON格式的工具。你可以使用Elasticsearch dump通過命令行或編程接口來導出數據。…

微服務中組件掃描(ComponentScan)的工作原理

微服務中組件掃描(ComponentScan)的工作原理 你的問題涉及到Spring框架中ComponentScan的工作原理以及Maven依賴管理的影響。我來解釋為什么能夠掃描到common模塊的bean而掃描不到其他模塊的bean。 根本原因 關鍵在于**類路徑(Classpath)**的包含情況&#xff1a; Maven依賴…

Python鏡像源配置:

1.用命令進行配置&#xff1a; 1. 使用命令行方式更改鏡像源 可以直接通過 pip config 命令來設置全局或用戶級別的鏡像源地址。例如&#xff0c;使用清華大學開源軟件鏡像站作為新的索引 URL&#xff1a; pip config set global.index-url https://pypi.tuna.tsinghua.edu.…

【SpringBoot】Spring中事務的實現:聲明式事務@Transactional、編程式事務

1. 準備工作 1.1 在MySQL數據庫中創建相應的表 用戶注冊的例子進行演示事務操作&#xff0c;索引需要一個用戶信息表 &#xff08;1&#xff09;創建數據庫 -- 創建數據庫 DROP DATABASE IF EXISTS trans_test; CREATE DATABASE trans_test DEFAULT CHARACTER SET utf8mb4;…

javascript 深拷貝和淺拷貝的區別及具體實現方案

一、核心區別 特性淺拷貝深拷貝復制層級僅復制對象的第一層屬性遞歸復制對象的所有層級屬性&#xff08;包括嵌套對象和數組&#xff09;引用關系嵌套對象/數組與原對象共享內存&#xff08;引用拷貝&#xff09;嵌套對象/數組與原對象完全獨立&#xff08;值拷貝&#xff09;…

pytorch對應gpu版本是否可用判斷邏輯

# gpu_is_ok.py import torchdef check_torch_gpu():# 打印PyTorch版本print(f"PyTorch version: {torch.__version__}")# 檢查CUDA是否可用cuda_available torch.cuda.is_available()print(f"CUDA available: {cuda_available}")if cuda_available:# 打印…

國內無法訪問GitHub官網的問題解決

作為一名程序員&#xff0c;在國內訪問GitHub官網經常會遇到打開過慢或者訪問失敗的問題&#xff0c;但通過一些技巧可以改善訪問體驗。GitHub訪問問題的根源在于GitHub官網訪問不穩定的主要原因在于DNS解析過程。當我們直接訪問github.com時&#xff0c;需要通過DNS服務器將域…

使用 MediaPipe 和 OpenCV 快速生成人臉掩膜(Face Mask)

在實際項目中&#xff0c;尤其是涉及人臉識別、換臉、圖像修復等任務時&#xff0c;我們經常需要生成人臉區域的掩膜&#xff08;mask&#xff09;。這篇文章分享一個簡單易用的小工具&#xff0c;利用 MediaPipe 和 OpenCV&#xff0c;快速提取人臉輪廓并生成二值掩膜圖像。 …

【動態導通電阻】GaN功率器件中動態導通電阻退化的機制、表征及建模方法

2019年,浙江大學的Shu Yang等人在《IEEE Journal of Emerging and Selected Topics in Power Electronics》上發表了一篇關于GaN(氮化鎵)功率器件動態導通電阻(Dynamic On-Resistance, RON)的研究論文。該文深入探討了GaN功率器件中動態導通電阻退化的機制、表征方法、建模…

從括號匹配看棧:數據結構入門的實戰與原理

在計算機科學的世界里&#xff0c;數據結構是程序員的 “瑞士軍刀”&#xff0c;不同的數據結構適用于不同的場景&#xff0c;能高效解決各類問題。其中&#xff0c;棧作為一種簡單卻強大的數據結構&#xff0c;在很多實際應用中發揮著關鍵作用。今天&#xff0c;我們就通過一個…

Dubbo(89)如何設計一個支持多語言的Dubbo服務?

設計一個支持多語言的Dubbo服務需要考慮以下幾個方面&#xff1a; 服務接口設計&#xff1a;確保服務接口的定義可以被不同語言實現。序列化協議&#xff1a;選擇一個支持多語言的序列化協議&#xff0c;例如Protobuf、Thrift、gRPC等。服務注冊與發現&#xff1a;確保服務注冊…

力扣面試150題--分隔鏈表

day 39 題目描述 思路 遍歷鏈表&#xff0c;每一個點與值比較&#xff0c;比值小就繼續&#xff0c;比值大就放到鏈表尾部即可 /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode() {}* ListNode(int…