Linux: 命令行参数和环境变量究竟是什么?
Linux: 命令行参数和环境变量究竟是什么?
- 一、命令行参数
- 1.1 main函数参数意义
- 1.2 命令行参数概念
- 1.3 命令行参数实例
- 二、环境变量
- 2.1 环境变量概念
- 2.2 环境变量:PATH
- 2.2.1 如何查看PATH中的内容
- 2.2.2 如何让自己的可执行文件不带路径运行
- 2.3 环境变量:PWD
- 2.3 环境变量: HOME
- 三、获取环境变量的3种方式
- 3.1 getenv()函数
- 3.2 main函数传参
- 3.3 通过第三方变量environ获取(extern char** environ)
- 四、环境变量如何获取
- 4.1 子进程环境变量获取方式
- 4.2 父进程环境变量获取方式
- 五、本地变量和环境变量
- 六、Linux命令分类和环境变量相关的命令
一、命令行参数
在main函数中,我们可以给main函数传递3个参数(库函数头为main(int argc, char *argv[], char *env[])
)(这里我们只用前两个参数)。那究竟如何给main函数传递参数呢?每个参数分别表示什么?
1.1 main函数参数意义
main函数中,argc表示指针数组arvg中有效元素的个数。接下来我们来看一段代码!
#include <stdio.h>
#include <string.h>
#include <stdlib.h>int main(int argc, char* argv[])
{ int i = 0; for(; i < argc; i++) { printf("%d: %s\n", i, argv[i]); }
}
【运行现象】:
1.2 命令行参数概念
1.1中main()函数在运行时,我们输入的指令会被bash或shell当成一个大的字符串,并以空格的形式分割成若干个小的字符串。而这些小字符串会形成一张指针数组表,bash或shell会指针数组有效个数传给argc参数
,指针数组表地址传给argc参数
。
我们在来看看系统指令现象,来对比上述mian函数。
我们将上述这种ls
、ls -l
、ls -l -a
称之为命令行参数。输入的指令会被bash或shell以空格分割成小字符串,并形成一种指针数组表用于存放每一个小的字符串,并将该指针数组的有效个数传递给mian函数的argc参数,而指针数组表的地址传递给argv参数。其中./mybin
、ls
这种为可执行程序、其他的为选项。命令行参数可以让同一段代码通过不同的选项来实现不同的功能!!
1.3 命令行参数实例
下面我们希望一段代码,通过不同的指令来实现简单的计算器。其中格式为可执行程序 功能参数(add、sub、mul、div) 两个参与运算的数据d1 d2
。
显然我们需要给mian函数中,有效字符的个数为4,此时我们仅需比较argv[1]传递的字符串是什么即可判断对于的功能选项。下面我们来看看如何实现吧!
#include <stdio.h>
#include <string.h>
#include <stdlib.h>int main(int argc, char *argv[])
{ if(argc != 4)//传入数据错误,显示正确使用手册 { printf("Use error\nUsage %s op[-add|sub|mul|div] d1 d2\n", argv[0]); return 1; } int x = atoi(argv[2]);//将字符窜转整型 int y = atoi(argv[3]); if(strcmp(argv[1], "add")==0) { int result = x + y; printf("%d + %d = %d\n", x, y, result); } else if(strcmp(argv[1], "sub")==0) { int result = x - y; printf("%d - %d = %d\n", x, y, result); } else if(strcmp(argv[1], "mul")==0) { int result = x * y; printf("%d * %d = %d\n", x, y, result); } else if(strcmp(argv[1], "div")==0) { if(y == 0)//非法数据、除数为0{printf("%d/%d=error! div zero\n", x, y);}else {int result = x / y;printf("%d / %d = %d\n", x, y, result);}}else{printf("Use error\nUsage %s op[-add|sub|mun|div] d1 d2\n", argv[0]);}return 0;
}
【测试结果】:
二、环境变量
在shell中,对于系统指令(ls
、pwd
)的我们直接在命令行输入相关指令便可执行对于的功能;但对于用于自己编写的可执行程序,运行时必须在前加./
来指令程序的相对路径。而这种差异就和环境变量有关!!
2.1 环境变量概念
环境变量(environment variables)一般是指在操作系统中,用于指定操作系统运行环境的一些参数。环境变量通常具有特殊用途,并且具有全局特性!!
比如我们在编写C/C++程序时,我们不知道、也不关心所谓的动/静态库在哪里。但我们每次都能编译成功,形成可执行程序。原因在于有相关的环境变量帮助编译器进行查找!!
下面我们来看看操作系统中,究竟有哪些常见的环境变量!
2.2 环境变量:PATH
PATH是用于指定系统搜索路径的环境变量。
在命令行参数讲解中,有一个小细节。系统指令可以直接只需在命令行输入相关指令便可执行对于的功能,而我们自己的可执行程序必须在前面加./
,否则会报错:command not found
。这是为啥呢?
原因在于运行一个可执行程序前,操作系统需要得到该可执行程序的路径
。这只是为啥我们自己的可执行程序必须加./
才能运行。至于系统指令,原因在于环境变量PATH
中保存着一系列系统搜索路径。运行系统指令时,操作系统会依次搜索PATH
中保存的路径,只要PATH中保存了当前指令的存在路径,程序便可以运行成功!!
2.2.1 如何查看PATH中的内容
我们可以通过指令echo $PATH
来查看PATH中保存的内容。PATH保存的路径会以冒号作为分割符,将路径分隔开!
2.2.2 如何让自己的可执行文件不带路径运行
$emsp;让自己的可执行程序不带路径运行通常由两种方法:将可执行文件路径添加到PATH环境变量中、将可执行文件拷贝到系统的指定路径下!!
【将可执行文件路径添加到PATH环境变量】:
我们可以通过指令PATH=&PATH:可执行文件路径
将可执行文件路径添加到PATH环境变量!!
- 上述行为都是对内存中的数据进行操作。默认更改的环境变量、仅限于本次登录!!
【将可执行文件拷贝到系统的指定路径下】:
tips:
- 上述将指定文件拷贝到系统指定路径下的行为也被称为程序安装!!系统运行可执行程序时,默认会在环境变量和系统指令路径下进行查找!
2.3 环境变量:PWD
$emsp;我们在来看看下面这些指令:
我们发现pwd指令每次都能成功获取到当前工作坐在路径!这时为何?
原因在于系统中存在一个环境变量PWD
,该环境变量用于保存用户的当前工作路径。每次执行pwd执行时,pwd会读取环境变量PWD中的内容,并回显给用户!
2.3 环境变量: HOME
我们每次在登录shell时,为什么对于root账号,所处工作目录为/root
;而对于普通用户,则是/home xxx
?
原因在于系统中存在某些环境变量,在我们还未登录时就已经被加载了。这些变量是由操作系统的配置文件或命令行参数指定的。当用于登录shell时,该环境变量会识别出用户的身份,从而初始化环境变量HOME。最后shell直接通过cd $HIME
达到上述现象。
shell环境变量加载流程
三、获取环境变量的3种方式
在Linux中,我们可以通过env
指令来查看当前进程中的所有环境变量。而获取环境变量通常有以下3种方式。
3.1 getenv()函数
在Linux中,提供一个名为getenv函数(char *getenv(const char *name);
);该函数可以获取环境变量中的内容。
例如:
【源代码】:
int main(int argc, char *argv[], char *env[])
{ printf("PATH:%s\n", getenv("PATH"));; return 0;
}
【运行结果】:
3.2 main函数传参
在命令行参数中,我们已经提到过mian函数可以传3个参数,mian函数原型为:main(int argc, char *argv[], char *env[])
。
程序在启动时,系统可以选择的给进程(main函数)提供两张表:命令行参数表(argc维护)、环境变量表(env维护)。
【源代码】:
#include <stdio.h>int main(int argc, char *argv[], char* env[])
{for(int i = 0; env[i]; i++)printf("env[%d]: %s\n", i, env[i]);return 0;
}
【运行结果】:
3.3 通过第三方变量environ获取(extern char** environ)
在shell中,环境变量会以写时拷贝的方式继承给子进程。换而言之,环境变量具有全局属性,父子进程以写时拷贝的方式看到同一种环境变量表。
那子进程如何“继承”的环境变量表呢?
libc中定义的全局变量environ指向环境变量表,environ没有包含在任何头文件中,所以在使用时 要用extern声明。
实例:
【源代码】:
#include <stdio.h>int main()
{extern char **environ;for(int i = 0; environ[i]; i++)printf("environ[%d]: %s\n", i, environ[i]);return 0;
}
【运行结果】:
四、环境变量如何获取
4.1 子进程环境变量获取方式
命令行启动的进程都是shell或bash的子进程,而子进程的环境变量都是父进程以命令行参数的形式传递给子进程的。
4.2 父进程环境变量获取方式
在shell中直接修改环境变量PATH虽然可行,但这是直接更改shell进程内部的环境变量信息。在下一次登录时,该修改值会被恢复!!
这是由于父进程(准确的来说是shell)每次重新登录时,都会形成新的bash解释器,并且bash解释器会自动读取配置文件./.bash_profile
(在家目录下)中的信息,为shell进程形成一张环境变量表!!即父进程shell的环境变量信息是以脚本配置文件的形式存在的!!
五、本地变量和环境变量
在shell中除了系统默认的环境变量,也可以手动添加环境变量!
【例如】:
MYENV=helloLinux
当上述添加的环境变量并未添加到环境变量表中,被称为本地变量。使用export
指令可以将本地变量导入环境变量表中,变为环境变量!!即export MYENV
。
本地变量只在bash进程内部有效,不会被子进程所继承;而环境变量通过让所有子进程继承的方式,实现全局性!
六、Linux命令分类和环境变量相关的命令
在Linux中,Linux命令分为常规命令和内建命令。
命令种类 | 用途 |
---|---|
常规命令 | fork让子进程执行的。具体表现在对环境变量PATH 清空后,诸如ls、cd、mkdir、touch 等指令失效 |
内建命令 | shell内部的一个函数,可以直接读取shell内部的本地变量。如export、pwd 等 |
环境变量相关的命令
命令种类 | 用途 |
---|---|
echo | 显示某个环境变量值 |
export | 设置一个新的环境变量 |
env | 显示所有环境变量 |
unset | 清除环境变量 |
set: | 显示本地变量和环境变量 |
相关文章:

Linux: 命令行参数和环境变量究竟是什么?
Linux: 命令行参数和环境变量究竟是什么? 一、命令行参数1.1 main函数参数意义1.2 命令行参数概念1.3 命令行参数实例 二、环境变量2.1 环境变量概念2.2 环境变量:PATH2.2.1 如何查看PATH中的内容2.2.2 如何让自己的可执行文件不带路径运行 2.3 环境变量…...

数学系C++ 类与对象 STL(九)
目录 目录 面向对象:py,c艹,Java都是,但c是面向过程 特征: 对象 内敛成员函数【是啥】: 构造函数和析构函数 构造函数 复制构造函数/拷贝构造函数: 【……】 实参与形参的传递方式:值…...

CSS技巧专栏:一日一例 2.纯CSS实现 多彩边框按钮特效
大家好,今天是 CSS技巧一日一例 专栏的第二篇《纯CSS实现多彩边框按钮特效》 先看图: 开工前的准备工作 正如昨日所讲,为了案例的表现,也处于书写的习惯,在今天的案例开工前,先把昨天的准备工作重做一遍。 清除浏览器的默认样式定义页面基本颜色设定body的样式清除butt…...
JCEF 在idea 开发 java 应用
JCEF(Java Chromium Embedded Framework)是一个Java库,用于在Java应用程序中嵌入Chromium浏览器引擎。如果您想在IDEA开发环境中使用JCEF,您可以按照以下步骤进行操作: 1. 下载JCEF库文件:您可以从JCEF的官…...

绝区伍--2024年AI发展路线图
2024 年将是人工智能具有里程碑意义的一年。随着新模式、融资轮次和进步以惊人的速度出现,很难跟上人工智能世界发生的一切。让我们深入了解 2024 年可能定义人工智能的关键事件、产品发布、研究突破和趋势。 2024 年第一季度 2024 年第一季度将推出一些主要车型并…...
C++:.front()函数作用
在C中,.front() 函数是容器(如 std::vector、std::deque、std::list 的某些实现等)的成员函数,用于访问容器中的第一个元素。这个函数返回对容器中第一个元素的引用(对于非const容器)或const引用࿰…...

Linux系统备份工具TimeShift
Linux系统备份 Linux系统备份工具TimeShift Linux系统备份工具TimeShift 0. 前言1. 安装2. 启动3. 使用法一、图形界面操作(方便)法二、终端命令操作(高端) Linux系统备份工具TimeShift Linux系统备份工具TimeShift 0. 前言 Time…...

Google重大更新--解读Android Auto认证4.3
Google在今年五月更新了Android Auto 4.2.2版本,而在2024年7月他们推出了Android Auto 4.3版本,这是自2023年9月以来对Android Auto 4.2版本的一次重大更新。 为了确保合规性和顺利认证,OEM和Tire1必须确保PDK组件版本与正在认证的主机的Rece…...

scala基础
scala基础: hello world: 写scala可运行文件的注意事项1、如果一个scala文件要运行,class要改成object2、如果是class,就仅单纯代表一个类,如果是object代表的是单例对象3、scala语法中,一句话结束不需要加分号4、scal…...
小红书选品中心商家采集 小红书商家电话采集软件
可采集名称销量评分联系方式等 需要有1000粉丝以上已实名认证过的小红书达人才可以使用 以下是一个示例程序,可以用于批量获取小红书选品中心商家的信息: import requestsdef get_merchants(page_num):url f"https://www.xiaohongshu.com/selec…...
JavaScript基础: JavaScript 数字类型
JavaScript 中的数字类型是用来表示数值的数据类型。JavaScript 的数字类型是基于 IEEE 754 标准的双精度浮点数格式,这意味着它可以表示非常大和非常小的数值,以及小数。 数字字面量 在 JavaScript 中,数字可以直接以字面量的形式书写&…...

【网络安全】漏洞挖掘之Spring Cloud注入漏洞
漏洞描述 Spring框架为现代基于java的企业应用程序(在任何类型的部署平台上)提供了一个全面的编程和配置模型。 Spring Cloud 中的 serveless框架 Spring Cloud Function 中的 RoutingFunction 类的 apply 方法将请求头中的“spring.cloud.function.routing-expression”参数…...
面试官:MySQL死锁是什么,如何解决?
MySQL死锁概述 定义:多个操作相互等待对方释放资源,导致无法继续执行的情况。场景:通常发生在多个事务同时试图锁定对方已锁定的资源时。 MySQL锁的分类 粒度分类: 表级锁:锁定整个表,简单但并发能力低。…...

CSS原子化
目录 一、定义 二、原子化工具 2.1、tailwind 2.1.1、以PostCss插件形式安装 2.1.2、不依赖PostCss安装 2.1.3、修改原始配置 2.2、unocss 三、优缺点 3.1、优点 3.2、缺点 一、定义 定义:使用一系列的助记词,利用类名来代表样式。 二、原子化…...

【Python的pip配置、程序运行、生成exe文件】
Python的pip配置、程序运行、生成exe文件 一、安装Python 通过官网下载对应的版本,安装即可。 下载地址:https://www.python.org/downloads/ Python标准库查看(Python自带库) Python 标准库文档 安装Python的时候,…...
神经网络习题
不具有权重共享的网络是: **多层感知机(Multilayer Perceptron,MLP): ** 特点:每一层的每一个神经元都与上一层的每一个神经元全连接,权重独立于每个连接,不存在权重共享。 权重共享…...

deepstream段错误
😐 错误: 探针中由于使用了pyds.get_nvds_buf_surface(hash(gst_buffer), frame_meta.batch_id)导致的段错误(segmentation fault)。 解决方式:...

《梦醒蝶飞:释放Excel函数与公式的力量》10.1.1函数简介
10.1.1函数简介 BIN2DEC函数是Excel中用于将二进制数转换为十进制数的函数。它在处理二进制数时非常有用,尤其是在电子工程、计算机科学等领域。 10.1.2函数语法: BIN2DEC(number) number:这是要转换的二进制数,必须是以字符串…...
Bert 变种, T5模型
NLP-预训练模型-2019-NLU:DistilBERT【 BERT模型压缩】【模型大小减小了40%(66M),推断速度提升了60%,但性能只降低了约3%】_distillbert-CSDN博客 https://zhuanlan.zhihu.com/p/673535548 大语言模型系列-T5_t5模型…...

技术赋能政务服务:VR导视与AI客服在政务大厅的创新应用
在数字化转型的浪潮中,政务大厅作为服务民众的前沿阵地,其服务效率和质量直接影响着政府形象和民众满意度。然而,许多政务大厅仍面临着缺乏智能化导航系统的挑战,这不仅增加了群众的办事难度,也降低了服务效率。维小帮…...

Linux应用开发之网络套接字编程(实例篇)
服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …...

AI Agent与Agentic AI:原理、应用、挑战与未来展望
文章目录 一、引言二、AI Agent与Agentic AI的兴起2.1 技术契机与生态成熟2.2 Agent的定义与特征2.3 Agent的发展历程 三、AI Agent的核心技术栈解密3.1 感知模块代码示例:使用Python和OpenCV进行图像识别 3.2 认知与决策模块代码示例:使用OpenAI GPT-3进…...

Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例
使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件,常用于在两个集合之间进行数据转移,如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model:绑定右侧列表的值&…...
电脑插入多块移动硬盘后经常出现卡顿和蓝屏
当电脑在插入多块移动硬盘后频繁出现卡顿和蓝屏问题时,可能涉及硬件资源冲突、驱动兼容性、供电不足或系统设置等多方面原因。以下是逐步排查和解决方案: 1. 检查电源供电问题 问题原因:多块移动硬盘同时运行可能导致USB接口供电不足&#x…...

STM32标准库-DMA直接存储器存取
文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA(Direct Memory Access)直接存储器存取 DMA可以提供外设…...

Java-41 深入浅出 Spring - 声明式事务的支持 事务配置 XML模式 XML+注解模式
点一下关注吧!!!非常感谢!!持续更新!!! 🚀 AI篇持续更新中!(长期更新) 目前2025年06月05日更新到: AI炼丹日志-28 - Aud…...
Spring AI 入门:Java 开发者的生成式 AI 实践之路
一、Spring AI 简介 在人工智能技术快速迭代的今天,Spring AI 作为 Spring 生态系统的新生力量,正在成为 Java 开发者拥抱生成式 AI 的最佳选择。该框架通过模块化设计实现了与主流 AI 服务(如 OpenAI、Anthropic)的无缝对接&…...

成都鼎讯硬核科技!雷达目标与干扰模拟器,以卓越性能制胜电磁频谱战
在现代战争中,电磁频谱已成为继陆、海、空、天之后的 “第五维战场”,雷达作为电磁频谱领域的关键装备,其干扰与抗干扰能力的较量,直接影响着战争的胜负走向。由成都鼎讯科技匠心打造的雷达目标与干扰模拟器,凭借数字射…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...

【从零学习JVM|第三篇】类的生命周期(高频面试题)
前言: 在Java编程中,类的生命周期是指类从被加载到内存中开始,到被卸载出内存为止的整个过程。了解类的生命周期对于理解Java程序的运行机制以及性能优化非常重要。本文会深入探寻类的生命周期,让读者对此有深刻印象。 目录 …...