深入了解Linux系統—— 環境變量

命令行參數

我們知道,我們使用的指令它本質上也是一個程序,我們要執行這個指令,輸入指令名然后回車即可執行;但是對于指令帶選項,又是如何實現的呢?

問題:main函數有沒有參數?

在我們之前寫代碼的時候,我們知道main函數是程序的入口;但是操作系統在執行程序之前,會先執行一個入口函數(_start),然后由這個入口函數去調用我們的main函數。

那我們的main函數到底有沒有參數?答案是有的。

我們先來看下面運行程序的現象:

#include <stdio.h>
int main(int argc, char* argv[])
{for(int i = 0;i<argc;i++){printf("argv[%d] : %s\n",i,argv[i]);}return 0;
}

在這里插入圖片描述

這里,我們在命令行中打開某個可執行程序,后面跟上選項(指令 -選項);

可以看到在main函數中我們是可以訪問命令行輸入的內容的(命令行參數)。

main函數的參數都有哪些內容呢?

  • argc:命令行參數的個數
  • argv:命令行參數的內容(char*類型的數組,最后以NULL結尾)
  • env:環境變量表(在文章后面內容中詳細講解)。

在這里有一個疑問,我們在命令行輸入的內容是如何轉化成argv表,并傳遞給main函數的呢?

這個就比較簡單了,我們在命令行中輸入的內容,由我們的命令行解釋器bash對這些內容進行拆分,然后形成命令行參數表(argv)和參數的個數argc

然后再通過調用等一系列操作(bash創建子進程,通過execve系統調用)將參數傳遞給main函數。

簡單來說,就是命令行解釋器(bash)對我們命令行內容進行拆分,然后形成命令行參數個數argc和命令行參數列表argv

在這里插入圖片描述

所以,有了命令行參數列表,我們程序就可以實現不同的子功能(命令 + 選項的實現原理)

環境變量

在了解環境變量之前,先思考一個問題,為什么在執行我們自己寫的程序時就要帶路徑,而使用指令程序時就不用帶路徑?

我們想要運行一個程序,首先要先找到這個程序(bash去找)

這個問題就很簡單了,我們的指令程序都在/usr/bin目錄下,而我們的程序不在usr/bin目錄下。

但是,為什么在usr/bin路徑下的程序,在執行時不需要帶路徑?

  • 環境變量一般指操作系統中用來指定操作系統運行環境的一些參數。
  • 例如:我們在寫的C/C++代碼,在鏈接的時候,我們不知道所鏈接的動靜態庫在哪里,但是依然可以鏈接成功生成可執行程序,其原因就是:有關環境變量幫助編譯器進行查找
  • 環境變量通常具有某些特殊用途,在操作系統中通常具有全局性

查看環境變量

  • 查看所有環境變量:env
  • 查看一個環境變量:ench $環境變量名

在這里插入圖片描述

設置環境變量

export

我們現在能夠看到環境變量了,我們可不可以修改環境變量?當然是可以的

export新增環境變量

我們可以使用export指令來新增一個新的環境變量,具體語法如下:

export name=val

在這里插入圖片描述

export除了新增一個環境變量,我們還可以使用它來修改一個已經存在的環境變量的值。

在這里插入圖片描述

這里如果進行了上述修改,我們的大部分指令都無法使用了,因為在當前PATH路徑下,bash找不到可執行程序。

但是存在一些還可以使用的指令,因為這些指令是bash進程自己執行的,比如export

在本篇文章后序內容詳細敘述

unset

我們可以新增一個環境變量,那我們可不可以刪除一個環境變量?當然也是可以的

unset指令可以刪除一個環境變量,用法如下:

unset name

在這里插入圖片描述

常見的環境變量

PATH

PATH環境變量,它指的是命令的搜索路徑;

為什么在usr/bin路徑下的程序,在執行時不需要帶路徑?

我們要運行一個程序,首先要找到它,所以我們自己寫的程序運行時需要帶路徑;

而在usr/bin路徑下的指令程序不需要帶路徑,這是因為存在環境變量PATH幫助bash去查找執行程序。

在這里插入圖片描述

所以,當我們把我們自己寫的程序所在的路徑加入到PATH中,或者將我們的可執行程序放到/usr/bin目錄下,我們運行我們自己寫的程序就也不需要帶路徑了。

這里就不演示了,感興趣的可以去嘗試一下

HOME

Linux中,當我們執行cd ~指令時,我們會進入當前用戶的家目錄;但是,操作系統是如何知道我們當前用戶的家目錄呢?

這里就直接說了:存在一個環境變量HOME;當我們執行cd ~時,bash就會在環境變量表中查找HOME,然后進行到HOME加目錄中。

在這里插入圖片描述

此外,root用戶的家目錄和普通用戶的家目錄還是存在一定差別的

在這里插入圖片描述

SHELL

SHELL環境變量,它表示當前的shell,也就是當前使用的命令行解釋器;

一般情況下是/bin/bash

在這里插入圖片描述

更多的環境變量

除了上述的環境變量,還存在非常多的環境變量,這里簡單了解一下

在這里插入圖片描述

  • HOSTNAME:當前系統的主機名
  • HISTSIZEbash記錄歷史指令的個數
  • SSH_TTY:當前通過SSH會話鏈接終端設備的路徑
  • PWD:表示當前路徑
  • USER:當前用戶的登錄名
  • LOGNAME:可以理解為和user一樣
  • _:表示上次路徑

獲取環境變量

在上述中,講述了使用envecho $查看環境變量,那我們現在想要通過寫代碼時獲取環境變量該如何去做呢?

main函數參數

在上面敘述main函數參數時,提到main函數還存在第三個參數env,我們就可以通過這個參數來獲取環境變量

#include <stdio.h>
int main(int argc, char* argv[], char* env[])
{int i = 0;for(;env[i]!=NULL;i++){printf("env[%d] : %s\n",i,env[i]);}return 0;
}

在這里插入圖片描述

系統調用

main函數第三個參數env它是環境變量參數表,我們查看起來不是很方便;

我們可以通過系統調用來在代碼中獲取環境變量的值:

getenv

在這里插入圖片描述

getenv,我們把要查看環境變量的名字傳參給getenv函數,它會返回我們查詢環境變量的值。

#include<stdio.h>
#include<stdlib.h>
int main()
{printf("%s\n",getenv("PATH"));return 0;
}

在這里插入圖片描述

putenv對于這個函數,這里就先不敘述,在后序文章中再詳細講解。

通過第三方變量獲取

libc在定義著一個全局變量environ,它始終指向當前的環境變量表;

它不存在于任何頭文件,我們在使用它時,需要使用extern聲明。

#include<stdio.h>
int main(int argc, char* argv[])
{extern char** environ;int i = 0;for(;environ[i]!=NULL;i++){printf("environ[%d] : %s\n",i,environ[i]);}
}

在這里插入圖片描述

執行程序,我們可以發現依然可以獲取全部的環境變量。

此外,父進程的環境變量可以被子進程繼承;就比如父進程bash創建我們的子進程時,

理解環境變量

要理解環境變量,這里我們先思考一個問題,環境變量存儲在哪里?

在執行一個程序時,首先要找到到這一個程序,那誰去找呢?

答案是bash去找,通過環境變量PATH去找,在bash中存儲著一份環境變量表;

現在又存在一個問題,當我們修改環境變量以后,退出登錄,再次登錄時我們會發現環境變量又變為修改前的值了。

所以環境變量最開始是存儲在哪里呢?

答案:在系統的配置文件中

那我們現在是不是就可以這樣去理解了:在我們每次登錄時,操作系統為我們創建一個bash,再將環境變量表拷貝一份到bash中;這樣我們每次登錄bash中都存在一份環境變量表。

環境變量特性

  • 環境變量通常具有全局屬性,可以被子進程繼承下去。

環境變量表

在上訴代碼中,我們無論是使用main函數參數env還是全局指針變量environ進行訪問全局變量是時,循環條件寫的都是env[i]!=NULL/environ[i]!=NULL

這是因為,環境變量表它本質上就是一個指針數組,數組最后以NULL結尾。

在這里插入圖片描述

補充

本地變量

在操作系統中除了環境變量之外,還存在著本地變量;

就比如我們在命令行直接輸入i=1,這樣我們使用env查看環境變量時是查看不到i的;但是我們可以使用echo $i來查看變量i的值。

在這里插入圖片描述

env是查看所有的環境變量,而如果我們想要查看所有的本地變量,就要使用set,它能顯示出所有的環境變量和本地變量;當然我們也可以使用echo $查看某一個變量的值。

這里可能感覺怪怪的,為什么要存在本地變量呢?

  1. 作用域限制
    本地變量僅在當前Shell會話或函數內部有效,不會傳遞給子進程或其他Shell環境。這種隔離性避免了變量被意外修改或污染其他進程的運行環境。
  2. 臨時數據存儲
    適用于臨時存儲中間計算結果或循環控制變量(如計數器),用完即棄,無需長期保留,簡化資源管理。
  3. 安全性增強
    若變量包含敏感信息(如臨時密鑰),使用本地變量可防止其被子進程繼承,降低數據泄露風險。
  4. 避免命名沖突
    在腳本或函數中使用本地變量(如通過local關鍵字聲明),能隔離同名變量的影響,提升代碼的模塊化和可維護性。

以博主現在的認知,簡單理解就是為了滿足bash的語法

內建命令

這個問題在上面簡單描述了,我們的環境變量是存在于bash中的,因為我們所有執行的程序都是bash去執行的,bash需要這些環境變量來完成執行我們的程序;

在修改PATH時,我們發現一個問題,將PATH修改之后,一部分指令不能執行了,但是一部分指令是可以執行的,這是為什么呢?

這里簡單解釋一下:

我們可以將指令分為兩部分:

  • 普通命令:bash通過創建子進程,然后讓子進程去執行;
  • 內建命令:bash自己通過函數調用或者系統調用去完成,不需要創建子進程。

這里內建命令像export就是bash自己直接去完成的,我們就是修改了PATH對它是沒有影響的,所以它可以執行;

到這里本篇文章內容大致就結束了,感謝支持

簡單總結:

  1. 了解命令行參數,理解main函數是三個參數
  2. 環境變量,查看env/echo、設置環境變量export
  3. 了解常見的環境變量
  4. 通過main函數參數、系統調用、environ獲取環境變量
  5. 理解環境變量具有全局性、環境變量表的結構
  6. 簡單了解本地變量和內建命令

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

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

相關文章

pip安裝包時網絡不暢,替換國內PyPI鏡像源

1、PyPI 鏡像源 1.1、定義 PyPI 鏡像源是對 Python Package Index&#xff08;PyPI&#xff09;官方倉庫的復制。 PyPI 是 Python 社區中最大的軟件包倉庫&#xff0c;存儲著大量的 Python 包&#xff0c;供開發者們下載和使用。 然而&#xff0c;由于 PyPI 服務器位于國外&a…

貪心算法解決會議安排問題

文章目錄 前言 一、什么是貪心算法&#xff1f; 貪心算法的基本概念&#xff1a;貪心算法并不從整體最優上加以考慮&#xff0c;所做的選擇只是在某種意義上的局部最優選擇。 二、會議安排題目 1.題目理解 2.思路剖析 總結 前言 本文將主要介紹貪心算法需要注意的地方以…

從入門到登峰-嵌入式Tracker定位算法全景之旅 Part 4 |IMU 死算與校正:慣性導航在資源受限環境的落地

Part 4 |IMU 死算與校正:慣性導航在資源受限環境的落地 本章聚焦 ESP32-S3 平臺上如何利用 LSM6DS3 IMU 實現 死算(Dead Reckoning),并結合 零速更新(ZUPT) 或 磁力計輔助 進行 漂移校正,最終通過 EKF/UKF 融合提升定位精度。 一、傳感器簡介與校準 LSM6DS3 主要參數 加速…

力扣1128題解

記錄 2525.5.4 題目&#xff1a; 思路&#xff1a; 先將dominoes[i]的二元全部變為前大后小的形式&#xff0c;再遍歷該數組&#xff0c;用數組來記錄。 代碼&#xff1a; class Solution {public int numEquivDominoPairs(int[][] dominoes) {int [] [] cnt new int [10…

with的用法

Python SQLite 操作詳解 本文檔詳細解釋了使用 Python 操作 SQLite 數據庫時涉及的關鍵概念和代碼實踐&#xff0c;包括 with 語句、事務處理、批量插入以及相關的優化建議。 一、with 語句的作用&#xff08;自動關門的保險庫&#xff09; with sqlite3.connect(city_1301.d…

力扣解題匯總(困難)

文章目錄 技巧42_接雨水 技巧 42_接雨水 class Solution {public int trap(int[] height) {int LMax 0, RMax 0;int len height.length;int[] L2R new int[len];int[] R2L new int[len];//計數每一個格的左右邊最高柱for (int i 0; i < len; i) {LMax Math.max(LMa…

【Redis】Redis常用命令

4.Redis常見命令 4.1 Redis數據結構介紹 Redis是一個key-value的數據庫&#xff0c;key一般是String類型&#xff0c;不過value的類型多種多樣&#xff1a; 命令太多&#xff0c;不需要死記&#xff0c;學會查詢就好了~ Redis為了方便我們學習&#xff0c;將操作不同數據類型…

Ubuntu 系統上廣受好評的瀏覽器推薦

日常使用與開發者首選 Firefox 特點&#xff1a;開源、隱私保護強大&#xff0c;支持豐富擴展&#xff08;如開發者工具、廣告攔截&#xff09;&#xff0c;默認預裝且跨平臺兼容368。 適用場景&#xff1a;日常瀏覽、開發者調試&#xff08;支持實時 CSS/JS 編輯&#xff09;、…

Rust Trait 學習

概述 特征&#xff08;trait&#xff09;是rust中的概念&#xff0c;類似于其他語言中的接口&#xff08;interface&#xff09;。特征定義了一個可以被共享的行為&#xff0c;只要實現了特征&#xff0c;你就能使用該行為。 如果不同的類型具有相同的行為&#xff0c;那么我們…

JavaScript性能優化實戰(9):圖像與媒體資源優化

引言 在當今視覺驅動的網絡環境中,圖像和媒體資源往往占據了網頁總下載量的60%-80%,因此對圖像和媒體資源進行有效優化已成為前端性能提升的關鍵領域。盡管網絡帶寬持續提升,但用戶對加載速度的期望也在不斷提高,特別是在移動設備和網絡條件不穩定的場景下。 本文作為Jav…

NHANES指標推薦:LC9

文章題目&#xff1a;Association between lifes crucial 9 and kidney stones: a population-based study DOI&#xff1a;10.3389/fmed.2025.1558628 中文標題&#xff1a;生命的關鍵 9 與腎結石之間的關聯&#xff1a;一項基于人群的研究 發表雜志&#xff1a;Front Med 影響…

谷歌 NotebookLM 支持生成中文播客

谷歌 NotebookLM 支持生成中文播客。 2025 年 4 月 29 日&#xff0c;NotebookLM 宣布其 “音頻概覽”&#xff08;Audio Overviews&#xff09;功能新增 76 種語言支持&#xff0c;其中包括中文。用戶只需將文檔、筆記、研究材料等上傳至 NotebookLM&#xff0c;然后在設置中選…

ElasticSearch深入解析(十):字段膨脹(Mapping 爆炸)問題的解決思路

文章目錄 一、核心原理&#xff1a;動態映射的雙刃劍1. 動態映射的工作機制2. 映射爆炸的觸發條件3. 底層性能損耗 二、典型場景與案例分析1. 日志系統&#xff1a;動態標簽引發的災難2. 物聯網數據&#xff1a;設備屬性的無序擴展 三、系統性解決方案1. 架構層優化2. 配置層控…

交互式智能體面臨長周期決策和隨機環境反饋交互等挑戰 以及解決辦法

交互式智能體面臨長周期決策和隨機環境反饋交互等挑戰 以及解決辦法 目錄 交互式智能體面臨長周期決策和隨機環境反饋交互等挑戰 以及解決辦法隨機初始化參數,lora但是訓練需要更加細粒度的評價指數(對思考過程評價,對得出結果的證明評價,對結果評價)用戶進看到結果《RAGE…

4:機器人目標識別無序抓取程序二次開發

判斷文件是否存在 //判斷文件在不在 int HandEyeCalib::AnsysFileExists(QString FileAddr) {QFile File1(FileAddr);if(!File1.exists()){QMessageBox::warning(this,QString::fromLocal8Bit("提示"),FileAddrQString::fromLocal8Bit("文件不存在"));retu…

【Touching China】2007-2011

文章目錄 1、20072、20083、20094、20105、2011 1、2007 錢學森 身份&#xff1a;中國航天事業奠基人&#xff0c;中國科學院、中國工程院資深院士獲獎事跡&#xff1a;錢學森1955年沖破重重阻力回到祖國&#xff0c;長期擔任火箭導彈和航天器研制的技術領導職務。他以總體、動…

linux常用基礎命令_最新版

常用命令 查看當前目錄下個各個文件大小查看當前系統儲存使用情況查看當前路徑刪除當前目錄下所有包含".log"的文件linux開機啟動jar更改自動配置文件后操作關閉自啟動linux靜默啟動java服務查詢端口被占用查看軟件版本重啟關機開機啟動取別名清空當前行創建文件touc…

Mamba+Attention+CNN 預測模型:破局長程依賴的計算機視覺新范式

目錄 一、引言:從 CNN 到 Mamba 的視覺建模進化之路 二、模型關鍵組成部分解析 (一)CNN 基干:局部特征提取器 (二)Mamba 塊:長程依賴建模核心 (三)注意力機制:特征交互增強器 三、模型創新點 四、模型原理與作用 五、優缺點對比 六、應用領域 一、引言:從 C…

LangChain4j +DeepSeek大模型應用開發——8 Function Calling 函數調用

Function Calling 函數調用也叫 Tools 工具 入門案例 例如&#xff0c;大語言模型本身并不擅長數學運算。如果應用場景中偶爾會涉及到數學計算&#xff0c;我們可以**為他提供一個 “數學工具”。**當我們提出問題時&#xff0c;大語言模型會判斷是否使用某個工具。 創建工具…

【Prometheus-Mongodb Exporter安裝配置指南,開機自啟】

目錄 內容概述 一、創建MongoDB監控專用用戶二、安裝MongoDB Exporter三、啟動Exporter服務四、配置Systemd服務五、服務管理命令六、Prometheus集成配置七、Grafana看板 內容概述 本教程詳細演示了如何在Linux系統中部署MongoDB Exporter以監控MongoDB數據庫&#xff0c;并將…