Linux操作系统之进程(四):命令行参数与环境变量
目录
前言:
什么是命令行参数
什么是环境变量
认识环境变量
PATH环境变量
HOME
USER
OLDPWD
本地变量
本地变量与环境变量的差异
核心要点回顾
结语:
前言:
大家好,今天给大家带来的是一个非常简单,但也十分重要知识点,命令行参数与环境变量的有关内容。要理解本文的知识点,需要有一些前置的基础,具体可以查看我的Linux系统文章的专栏:跳转地址
什么是命令行参数
从广义的概念上来讲,命令行参数是指在执行程序时通过命令行界面(如终端、命令提示符等)传递给程序的额外信息或选项。
大家在Linux系统中在终端输入各种指令,后面的选项其实就是命令行参数。
那么大家知道这些命令,例如ls -l,ps -ajx的本质是什么吗?
今天让我来告诉你吧。他们的本质其实就是一个程序。
大家在学习C语言时,main函数后面有着参数吗?大多数情况下都没有吧。
但实际上,在 C 语言 中,main()
函数可以接收 命令行参数(command-line arguments),其标准形式如下:
int main(int argc, char *argv[]) { ... }
我们把main函数的(int argc,char * argv[])称为命令行列表,argc为参数的个数,argv是参数的清单。
参数 | 类型 | 说明 |
---|---|---|
argc | int | 参数个数(Argument Count),包括程序名本身 |
argv | char*[] | 参数向量(Argument Vector),字符串数组,存储所有参数 |
这些都是理论,大家可能理解不了,那么就实战来看一下吧!
我们现在有以下文件:
Makefile:
# 定义编译器和编译选项
CXX = g++
CXXFLAGS = -Wall -std=c++11# 定义目标文件和可执行文件名
TARGET = test
SRC = test.c# 默认目标
all: $(TARGET)# 直接生成可执行文件(不生成.o文件)
$(TARGET): $(SRC)$(CXX) $(CXXFLAGS) -o $@ $<# 清理生成的文件
clean:rm -f $(TARGET)# 运行程序
run: $(TARGET)./$(TARGET).PHONY: all clean run
test.c:
#include <stdio.h>int main(int argc, char *argv[])
{printf("命令行参数个数: %d\n", argc);for (int i = 0; i < argc; i++) {printf("参数 %d: %s\n", i, argv[i]);}
}
我们在终端,当前文件夹路径下输入make生成可执行文件test,随后./test运行该文件:
我们看见,输出的结果为1,参数打印的结果刚好是我们的运行命令:./test
那我们再多测试几次呢?
我们大概可以得出结论,我们运行程序,就相当于调用main函数,给main函数传参。
按照空格打散的规则,划分为不同的字符串。argc就代表这些参数的个数,而argv这个字符串数组则负责保存这些参数。
我们在main函数中通过argv可以获取到这些参数,从而实现指令的那些不同选项的功能的划分,例如,我们可以写一个简单的例子:
我们修改test代码如下:
#include <stdio.h>int main(int argc, char *argv[])
{if(strcmp(argv[1],"-l") == 0){printf("执行-l命令\n");}else if(strcmp(argv[1],"-a") == 0){printf("执行-a命令\n");}else{printf("没有找到命令\n");}
}
make重新编译生成可执行文件。
这样,就模拟实现了一个简单的指令根据不同选项执行对应选项的功能。
什么是环境变量
刚刚我们只展示了main函数的两个参数,但实际上,在 C 语言 中,除了标准的 argc
和 argv
之外,main()
函数在某些环境下(如 Linux/UNIX 系统)还可以接收 第三个参数 envp
,用于访问 环境变量。
那么什么是环境变量呢?
请看以下实验:
修改test.c代码如下:
#include <stdio.h>
#include<string.h>int main(int argc, char *argv[], char *envp[])
{for(int i = 0; envp[i] != NULL; i++){printf("第%d个环境变量: %s\n", i, envp[i]);}
}
运行test,有以下结果:
会给我们打印出这一系列的,形如:Key=Value格式的信息。
以此格式构建的,具有“全局”属性的变量,叫做全局变量。环境变量 是操作系统级别的 Key=Value 配置,用于影响所有子进程。
认识环境变量
接下来,就让我们来认识几个环境变量,来增加我们对环境变量这个概念的理解与认识。
PATH环境变量
PATH 是操作系统中最重要的环境变量之一,它决定了 系统在哪些目录中查找可执行程序。当你输入一个命令(如 ls 、ps )时,系统会按照 PATH 中列出的目录顺序搜索该命令对应的可执行文件。
我们知道,其实每个指令都是系统已经写好的可执行文件,那么为什么我们在执行我们的可执行文件时,都是路径+文件名的形式,比如可执行文件在当前路径,我们就是./+路径名,如果在其他路径,就是其他路径+文件名,可是我们执行系统指令时,却从来没有加过路径,输入名字就可以直接执行,这是为什么呢?
答案是,如果不带路径,我们的系统就找不到我们的文件。要是想让系统找到,由于系统默认在user/bin等目录下找,我们可以把exe拷贝到该目录。
但是为什么系统知道命令都在user/bin等目录下,这是什么原因呢??
答案就是环境变量PATH,PATH告诉shell应该去哪里查!
PATH环境变量由多个路径组成,每一个路径之间:作为分隔符。Shell默认会去以冒号为分隔符的多个子路径下去查命令。
既然这样,如果我们修改一下PATH,增加我们当前test所在工作路径,那么岂不是执行test时就不用输入前置路径了吗?
请看以下实验:
我们用echo打印出该PATH环境变量,可以看见一开始是没有当前目录的。
随后我们pwd找到当前目录,通过PATH=$PATH:[当前目录]
修改PATH,可以看见,现在已经修改完毕了。
那我们此时使用test来运行可以吗?
依然是不行的,这是因为test本身其实是一个Shell的内置命令,优先级高于我们自己的程序,所以我们需要修改一下我们的可执行文件的名字。找到Makefile,修改最后生成文件名为Test。
重新编译生成可执行文件,输入Test:
可以发现已经可以直接运行了,那我们在进入上级目录试试:
也是可以的,这就验证了我们之前所说的:Shell默认会去以冒号为分隔符的多个子路径下去查命令。
但实际上,通过PATH=这个操作来修改是临时的,当我们重启终端,再次查看就会恢复为一开始的PATH。那么有没有什么方法可以永久修改呢?
有的兄弟,有的,像这样的方法我们还有九个(bushi)
在每次重新打开终端时,我们得先想一下,最初的PATH等环境变量,他们是怎么来的呢?
答案是在系统的配置文件里
用户登录云服务器时,系统会启动一个 登录 Shell 进程。该 Shell 会依次读取系统级和用户级的配置文件,最终形成自己的环境变量表。当 Shell 通过 fork()
创建子进程时,子进程会继承这份环境变量表的副本;若子进程调用exec() 加载新程序,默认会继续传递该环境变量表。(exec()代表 “执行”(execute),用于在当前进程中加载并运行一个新的程序。它不是一个单独的命令,而是一系列系统调用和 Shell 内置命令的统称。)
我们在自己的家目录输入 ll 指令,可以在这些文件中找到两个文件:
这两个文件就是我们的配置文件 (在部分系统中,.profile可能叫做.bash_profile
)。
我们可以打开这两个文件看一眼:
可以看见,密密麻麻的全是配置文件。这也就是每次登录后,用户都第一时间处于自己的家目录的原因,因为只有在自己的家目录,才能找到这两个配置文件。
我们在.profile文件中可以查看到,这里是对我们的PATH环境变量配置的地方,我们可以尝试更改.profile文件:
在末尾添加这一段代码:
# 添加自定义路径到 PATH if [ -d "/home/ubuntu/dailycode/命令行参数与环境变量博客代码" ] ; thenPATH="/home/ubuntu/dailycode/命令行参数与环境变量博客代码:$PATH" fi
注意,我们这里双引号的内容,应该替换成你想要增加的路径。我这里想要增加的是:“/home/ubuntu/dailycode/命令行参数与环境变量博客代码”该路径。
保存并退出,我们打印一下PATH观看,
发现并没有失效,所以我们可以使用一下source命令使一个配置文件生效:
可以看见,PATH环境变量成功被改变了,重新进入终端,也是相同的PATH:
(记得把.profile改回原样哦~)
HOME
在环境变量表中,还有一个环境变量叫做HOME,这个环境变量又有什么作用呢?
首先我们要先明确一个过程:
"当用户通过SSH登录Linux系统时,系统会为该会话创建一个新的bash进程作为登录Shell。这个bash进程首先会读取/etc/profile和用户主目录下的.profile等配置文件,通过这些配置文件设置自己的环境变量表和工作目录(cwd),然后才向用户呈现交互界面。此时的环境变量配置是专属于这个bash进程的,其他进程(包括后续创建的子进程)会继承这份环境变量的副本,但无法反向修改父进程的环境。"
"bash进程在初始化时,会将自己的当前工作目录(cwd)设置为用户主目录(即$HOME环境变量指向的路径)。所以这也就是为什么,我们在登录后默认处于自己的家目录的原因。HOME变量其实就是指向该用户的家目录"
USER
在环境变量里,有一个叫做USER的环境变量。
这个环境变量用来标识当前登录用户的用户名,通常可以用来实现 程序判断用户身份,从而根据用户不同实现不同的供暖。
我们可以举一个小例子:
修改test.c代码如下:
#include <stdio.h>
#include<string.h>
#include<stdlib.h>int main(int argc, char *argv[], char *envp[])
{const char *who=getenv("USER");if(strcmp(who,"root")==0){printf("你是root用户,执行root命令\n");}else if(strcmp(who,"ubuntu")==0){printf("你是ubuntu用户,执行ubuntu命令\n");}else{printf("你是其他用户,执行其他命令\n");}
}
运行后有以下结果
随后我们用su命令将自己切换为root,再次运行,就会得到不一样的结果,
OLDPWD
OLDPWD如同他的名字一样,就是随时指向上一次访问的位置 ,它保存了用户在执行 cd
命令切换目录 之前 的路径。
这也是我们cd -命令的实现逻辑。
本地变量
在Shell中,我们也可以定义本地变量。
我们可以发现,定义的本地变量并不在env表里,此时我们可以使用set,unset来将本地变量设置到,或者用export将本地变量提升到环境变量表里。
但请注意,这个设置到本地变量里仍然只在当前Shell里生效。使用export将本地变量提升到环境变量表里后,我们创建子进程,子进程也会看见我们提升的本地变量。
本地变量与环境变量的差异
- 环境变量可以被子进程继承,而本地变量不可以
- 环境变量可以被bash之后的所有进程看见,所以环境变量具有全局性
为什么呢?:
a、系统的配置信息,尤其是具有指导性的配置信息,他是系统配置起效的一种表现
b、进程具有独立性,环境变量可以用来进程间传递数据 (只读的形式)
核心要点回顾
-
命令行参数:
-
通过main函数的argc和argv参数接收
-
允许程序根据不同的输入参数执行不同的功能
-
是Linux命令选项功能实现的基础机制
-
-
环境变量:
-
通过main函数的envp参数或getenv()函数访问
-
是系统级别的全局配置信息
-
影响所有子进程的行为
-
包括PATH、HOME、USER等重要变量
-
-
关键区别:
-
命令行参数是程序运行时临时传入的
-
环境变量是系统预先配置的全局设置
-
环境变量可以被子进程继承,具有持久性
-
结语:
通过本文的学习,我们深入探讨了命令行参数和环境变量这两个在Linux系统中至关重要的概念。他们两个概念是程序与操作系统交互的重要桥梁,也是开发者必须掌握的基础知识。
希望本文能帮助你更好地理解Linux系统的工作机制。如果有任何疑问,欢迎在评论区留言讨论!
相关文章:

Linux操作系统之进程(四):命令行参数与环境变量
目录 前言: 什么是命令行参数 什么是环境变量 认识环境变量 PATH环境变量 HOME USER OLDPWD 本地变量 本地变量与环境变量的差异 核心要点回顾 结语: 前言: 大家好,今天给大家带来的是一个非常简单,但也十…...

Typora-macOS 风格代码块
效果: 替换 Typora安装目录中 themes 文件夹下的 base.user.css 文件,直接替换即可,建议先备份。 css: /* 语法高亮配色 */ .CodeMirror-line .cm-number { color: #b5cea8; } /* 数字 - 浅绿色 */ .CodeMirror-line .…...
如何迁移SOS数据库和修改sos服务的端口号
一. 迁移SOS数据库。 1. 对SOS整个库进行拷贝。压缩拷贝等都可以 2. 找到SOS安装目录下的这个目录 /SOS7/SERVERS7/LOCAL/ 在此目录下会发现,有SOS服务库的文件夹。拷贝你要迁移的SOS数据库 3. 进入该文件夹,找到:serverdb.cfg 打开后&…...

ansible自动化playbook简单实践
方法一:部分使用ansible 基于现有的nginx配置文件,定制部署nginx软件,将我们的知识进行整合 定制要求: 启动用户:nginx-test,uid是82,系统用户,不能登录 启动端口82 web项目根目录/…...

20250526惠普HP锐14 AMD锐龙 14英寸轻薄笔记本电脑(八核R7-7730U)的显卡驱动下载
20250526惠普HP锐14 AMD锐龙 14英寸轻薄笔记本电脑(八核R7-7730U)的显卡驱动下载 2025/5/26 14:44 百度:AMD 7700 显卡驱动 amd APU 显卡驱动 https://item.jd.com/100054819707.html 惠普HP【国家补贴20%】锐14 AMD锐龙 14英寸轻薄笔记本电脑(八核R7-7730U 16G 1T…...
WIN11使用vscode搭建c语言开发环境
安装 VS Code 下载地址: Visual Studio Code - Code Editing. Redefined 安装时勾选 "添加到 PATH"(方便在终端中调用 code 命令 下载 MSYS2 官网:MSYS2 下载 msys2-x86_64-xxxx.exe(64位版本)并安装。 默认安装路径…...

2025年5月蓝桥杯stema省赛真题——象棋移动
上方题目可点下方去处,支持在线编程~ 象棋移动_scratch_少儿编程题库学习中心-嗨信奥 程序演示可点下方,支持源码和素材获取~ 象棋移动-scratch作品-少儿编程题库学习中心-嗨信奥 题库收集了历届各白名单赛事真题和权威机构考级…...

AI重构SEO关键词精准定位
内容概要 随着AI技术深度渗透数字营销领域,传统SEO关键词定位模式正经历系统性重构。基于自然语言处理(NLP)的智能语义分析引擎,可突破传统关键词工具的局限性,通过解析长尾搜索词中的隐含意图与语境关联,…...
C++ 模板元编程语法大全
C 模板元编程语法大全 模板元编程(Template Metaprogramming, TMP)是C中利用模板在编译期进行计算和代码生成的强大技术。以下是C模板元编程的核心语法和概念总结: 1. 基础模板语法 类模板 template <typename T> class MyClass {// 类定义 };函数模板 t…...

SPSS跨域分类:自监督知识+软模板优化
1. 图1:SPSS方法流程图 作用:展示了SPSS方法的整体流程,从数据预处理到模型预测的关键步骤。核心内容: 领域知识提取:使用三种词性标注工具(NLTK、spaCy、TextBlob)从源域和目标域提取名词或形容词(如例句中提取“excellent”“good”等形容词)。词汇交集与聚类:对提…...
【术语扫盲】BSP与MSP
专业解释版: MSP(Microcontroller Support Package) 定义:MSP 是微控制器支持包,包含 MCU 的启动代码、寄存器配置、驱动库等,主要针对 芯片本身。 作用:提供通用的底层硬件抽象,方…...

vscode的Embedded IDE创建keil项目找不到源函数或者无法跳转
创建完Embedded IDE项目后跳转索引很容易找不到源函数或者无法跳转,原因是vscode工作区被eide覆盖了,需要手动往当前目录下的.vscode/c_cpp_properties.json里添加路径 打开eide.json ,找到folders, 里面的name是keil里工程的虚拟…...
HTTP/2与HTTP/3特性详解:为你的Nginx/Apache服务器开启下一代Web协议
更多服务器知识,尽在hostol.com 嘿,各位站长和服务器管理员朋友们!咱们天天跟网站打交道,都希望自己的网站能像火箭一样快,用户体验“嗖嗖”的。但你知道吗?除了服务器硬件配置、代码优化、CDN加速这些“常…...

构建高效智能客服系统的8大体验设计要点
构建一流的客户服务中心体验,企业需要以用户需求为核心,将智能化流程、前沿科技与人文关怀有机结合,打造流畅、高效且富有温度的服务生态。在客户需求日益多元化的今天,单纯的问题解决能力已无法满足期待,关键在于通过…...

CppCon 2014 学习:Making C++ Code Beautiful
你说的完全正确,也很好地总结了 C 这门语言在社区中的两种典型看法: C 的优点(Praise) 优点含义Powerful允许底层控制、系统编程、高性能计算、模板元编程、并发等多种用途Fast无运行时开销,接近汇编级别性能&#x…...
副本(Replica)在Elasticsearch中扮演什么角色?
在Elasticsearch(ES)中,副本(Replica)是主分片(Primary Shard)的镜像拷贝,与主分片共同构成分布式索引的高可用性和高性能架构。副本的设计目标是解决数据冗余、负载均衡和故障恢复等核心问题,其具体作用和原理如下: 一、副本的核心角色与功能 1. 数据冗余与故障恢…...

据传苹果将在WWDC上发布iOS 26 而不是iOS 19
苹果可能会对其操作系统的编号方式做出重大改变,基于年份的新版系统会将iOS 19重新命名为 iOS 26,同时 macOS 也会以同样的方式命名。 苹果的编号系统相当简单,版本号每年都会像钟表一样定期更新。然而,今年秋天情况可能有所不同&…...
整理了Windows(7—11)官方镜像下载链接和各版本区别介绍
原文《整理了Windows(7—11)官方镜像下载链接和各版本区别介绍》 引言 在安装或重装Windows系统时,使用微软官网提供的正版ISO镜像可以保证系统完整性和安全更新,避免使用第三方盗版镜像带来的恶意软件、广告风险。 本期汇总了微…...
数据库主键与索引详解
目录 主键核心特性 主键必要性问题 索引核心解析 基本定义 优劣分析 索引类型对比 数据结构实现 工作原理 主键与索引核心区别 主键核心特性 唯一标识:确保字段数据不重复且不为空数量限制:每表仅允许存在一个主键存储类型:通常采用…...
RTOS:启动调度器的作用(含源码逐行解读)
文章目录 前言一、启动调度器二、详细逻辑分析三、逐行分析3.1、traceENTER_vTaskStartScheduler3.2、configASSERT( ( sizeof( UBaseType_t ) * taskBITS_PER_BYTE ) > configNUMBER_OF_CORES );3.3、xReturn prvCreateIdleTasks();3.4、xTimerCreateTimerTask();3.5、fre…...
【Python 进阶】抽象基类(Abstract Base Class)
abc 模块和抽象基类(Abstract Base Class)的概念: 本文的示例代码来源于 break-a-scene. abc 是 Python 标准库中的一个模块,全称是 “Abstract Base Classes”(抽象基类)。它提供了一种定义抽象类和抽象方法的机制。在以下代码…...
Armv7l或树莓派32位RPI 4B编译faiss
pip3 install faiss-cpu当然找不到预编译的包 手动下载 git clone https://github.com/facebookresearch/faiss.git cd faiss #能需要切换到特定版本标签,例如 v1.7.1,这个版本Cmake 3.18可以过,因为apt install安装的cmake只更新到这里&am…...

嵌入式开发STM32 -- 江协科技笔记
1.背景介绍及基础认知 8大输入输出 斯密特触发器:高于设定阈值输出高电平,低于设定阈值输出低电平 有关上拉输入、下拉输入、推挽输出、开漏输出、复用开漏输出、复用推挽输出以及浮空输入、模拟输入的区别 1、上拉输入:上拉就是把电位拉高…...

[网页五子棋][用户模块]客户端开发(登录功能和注册功能)
文章目录 客户端开发登录功能htmlcsscommon.csslogin.css jQuery引入 jquery 运行程序注册功能 客户端开发 登录功能 html <!DOCTYPE html> <html lang"en"> <head> <meta charset"UTF-8"> <meta name"viewport&…...
nt!MiInitializeSystemCache函数分析之PointerPte->u.List.NextEntry的由来
第一部分: 1: kd> dd 0xc0304200 c0304200 c10c0000 00000000 00000000 00000000 c0304210 00000000 00000000 00000000 00000000 c0304220 00000000 00000000 00000000 00000000 c0304230 00000000 00000000 00000000 00000000 c0304240 00000000 00000000…...

MQTT协议,EMQX部署,MQTTX安装学习
一、MQTT概述 1.什么是MQTT MQTT是一种基于“发布订阅“”模式的消息传输协议。 消息:设备和设备之间传输的数据,或者服务和服务之间要传输的数据。 协议:传输数据时所遵循的规范。 2.常见的通讯模式 (1)客户端-服…...
如何理解UDP 和 TCP 区别 应用场景
UDP与TCP的定义、特性、使用场景及对比表格 定义 UDP(User Datagram Protocol)是一种无连接的传输层协议,提供不可靠的数据报服务。 TCP(Transmission Control Protocol)是一种面向连接的传输层协议,提供…...

60天python训练计划----day40
DAY 40 训练和测试的规范写法 知识点回顾: 彩色和灰度图片测试和训练的规范写法:封装在函数中展平操作:除第一个维度batchsize外全部展平dropout操作:训练阶段随机丢弃神经元,测试阶段eval模式关闭dropout 一.单通道图…...

干泵,干式螺杆真空泵
干式真空泵: 无油干式机械真空泵(又简称干式机械泵)是指泵能从大气压力下开始抽气,又能将被抽气体直接排到大气中去,泵腔内无油或其他工作介质,而且泵的极限压力与油封式真空泵同等量级或者接近的机械真空泵…...

Tailwind CSS 实战:基于 Kooboo 构建 AI 对话框页面(五):语音合成输出与交互增强
Tailwind CSS 实战,基于Kooboo构建AI对话框页面(一) Tailwind CSS 实战,基于Kooboo构建AI对话框页面(二):实现交互功能 Tailwind CSS 实战,基于 Kooboo 构建 AI 对话框页面&#x…...