如何理解 Linux 命令行参数与环境变量7
一、命令行参数
1.1参数介绍
在写C语言程序时,main函数是否可以带参数呢?------ 是可以的
- int argc: 命令行参数的个数
- char *argv[ ]: 字符指针数组(指向各个命令行参数的字符指针所构成的数组)
我们写一段代码来打印一下看这些参数存着什么信息:
#include<stdio.h>
#include<stdlib.h>
int main(int argc, char* argv[])
{for (int i = 0; i < argc; i++) {printf("argv[%d]: %s\n", i, argv[i]);}return 0;
}
运行结果:
直接运行数组中只保存了一个元素,是可执行程序的名称
[zyq@iZf8z3j2ckkap6ybtz8qseZ file]$ ./myprocess
argv[0]->./myprocess
在后面加点选项再运行一下:
可见数组中第一个元素始终是程序的名称,数组后依次保存着选项信息
[zyq@iZf8z3j2ckkap6ybtz8qseZ file]$ ./myprocess -a
argv[0]->./myprocess
argv[1]->-a
[zyq@iZf8z3j2ckkap6ybtz8qseZ file]$ ./myprocess -a -b
argv[0]->./myprocess
argv[1]->-a
argv[2]->-b
[zyq@iZf8z3j2ckkap6ybtz8qseZ file]$ ./myprocess -a -b -c
argv[0]->./myprocess
argv[1]->-a
argv[2]->-b
argv[3]->-c
[zyq@iZf8z3j2ckkap6ybtz8qseZ file]$ ./myprocess -a -b -c -d
argv[0]->./myprocess
argv[1]->-a
argv[2]->-b
argv[3]->-c
argv[4]->-d
结论:
我们在命令行数组的字符串,会被操作系统分割开,存储于变长字符指针数组argv[ ]中

1.2 命令行参数的意义
- 命令行参数的本质是交由程序不同的选择,用来定制不同的程序功能,使我们在一个程序中,根据参数选项的不同而执行不同的功能
- 在Linux中,相同的指令搭配不同的选项实现不同的功能,就是这个原理:ls -a ls -l
#include<stdio.h>#include<unistd.h>#include<stdlib.h>#include<string.h>int main(int argc,char* argv[]){if(argc!=2){printf("请通过选项来选择功能:-a -b -c\n");return 1;}if(strcmp(argv[1],"-a")==0){printf("功能1\n");}else if(strcmp(argv[1],"-b")==0){printf("功能2\n");}else if(strcmp(argv[1],"-c")==0) {printf("功能3\n");}else{printf("command not found\n");}return 0;}
[zyq@iZf8z3j2ckkap6ybtz8qseZ file]$ ./myprocess
请通过选项来选择功能:-a -b -c
[zyq@iZf8z3j2ckkap6ybtz8qseZ file]$ ./myprocess -a
功能1
[zyq@iZf8z3j2ckkap6ybtz8qseZ file]$ ./myprocess -b
功能2
[zyq@iZf8z3j2ckkap6ybtz8qseZ file]$ ./myprocess -c
功能3
[zyq@iZf8z3j2ckkap6ybtz8qseZ file]$ ./myprocess -d
command not found
1.3 命令行参数传递
- 命令行中启动的程序都会变成进程,并且都是bash的子进程
- 命令行输入的字符串默认是给父进程bash输入的
验证:
当我们运行如下代码:
#include<stdio.h>#include<unistd.h>#include<stdlib.h>#include<string.h>int main(int argc,char* argv[]){printf("I am paraent pid:%d ppid:%d\n ",getpid(),getppid()); return 0;}多次运行发现该进程的父进程都是27017 (bash)
[zyq@iZf8z3j2ckkap6ybtz8qseZ file]$ ./a.out I am paraent pid:27285 ppid:27017 [zyq@iZf8z3j2ckkap6ybtz8qseZ file]$ ./a.out I am paraent pid:27309 ppid:27017
二、环境变量
2.1 引入
通过对命令行参数的学习,我们了解了 指令+选项 的原理是什么,而指令也是可执行程序,相比于我们自己写的程序,指令只需要指令名称+选项就可以直接运行,但是我们自己写的程序想要运行就得加 ./,
原因是什么呢?
-----Linux存在一些全局的设置,告诉命令行解释器应当去哪些路径下寻找可执行程序,系统的很多配置在登陆Linux系统时,就已经加载到bash进程中了,bash在执行命令的时候需要先找到命令,这些路径就存储与环境变量(PATH)中
2.2 环境变量:PATH
PATH : 指定命令的搜索路径
//可以通过 echo $PATH 来查看其内容

- 这一串路径以 :分割
- 像 ls pwd 等指令的路径就存储于这写特定路径中,所以直接可以用指令名称运行
- 用户自己编写的程序默认并没有保存在环境变量中,直接使用程序名字系统查找不到指令的具体路径,所以需要加 ./ 才能运行
问题:怎样才能使用户编写的程序可以直接用程序名字运行呢?
---------只需要将程序的路径加载到PATH环境变量中就可以了
例如:可执行程序名字叫:mycode 存储路径:/home/zyq/file
$ PATH=$PATH:/home/ll/xxx/10# 注意:必须加上$符号,否则会把PATH中所有内容覆盖掉
[zyq@iZf8z3j2ckkap6ybtz8qseZ file]$ PATH=$PATH:/home/zyq/file
[zyq@iZf8z3j2ckkap6ybtz8qseZ file]$ echo $PATH
/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/zyq/.local/bin:/home/zyq/bin:/home/zyq/file
[zyq@iZf8z3j2ckkap6ybtz8qseZ file]$ mycode
hello world
但是这样有一个问题,当我们重启系统时,PATH环境变量中的内容又会恢复原样
这是因为我们查询到的环境变量都是内存级的,最开始的环境变量并不是存储于内存中,而是存储于配置文件中的,当系统登录时,会将配置文件中的信息导入到内存中,顾重新启动会导致内容又会恢复原样,所以想要永久让我们使用程序名字直接运行程序需要将路径保存到配置文件中去(不建议随便更改配置文件中数据)
配置文件存储于家目录中,比如 .bash_profile 文件,我们可以直接在后面追加程序的路径即可

2.3 HOME环境变量
HOME : 指定用户的主工作目录(即用户登陆到Linux系统中时,默认的目录)
[zyq@iZf8z3j2ckkap6ybtz8qseZ ~]$ echo $HOME
/home/zyq
2.4 SHELL环境变量
SHELL : 当前Shell,它的值通常是/bin/bash
[zyq@iZf8z3j2ckkap6ybtz8qseZ ~]$ echo $SHELL
/bin/bash
2.5 与环境变量相关的命令
1. echo: 显示某个环境变量值
2. export: 设置一个新的环境变量
3. env: 显示所有环境变量
4. unset: 清除环境变量
5. set: 显示本地定义的shell变量和环境变量
2.6 如何获取环境变量
-
通过第三方变量environ获取
extern char **environ;//第三方变量for(int i=0;environ[i];i++){//environ[i]中保存着环境变量printf("env[i]:%s\n",environ[i]);}

- 通过命令行第三个参数
main函数还可以传第三个参数,储存系统的环境变量信息,由系统提供
#include<stdio.h>#include<unistd.h>int main(int argc,char* argv[],char* env[]){int i=0;for(i=0;env[i];i++)printf("env[%d]:%s\n",i,env[i]); return 0;}
- 通过C库函数 getenv()获得
char *getenv(const char *name); // 通过名字获取环境变量
#include<stdio.h>#include<unistd.h>int main(){char* ret=getenv("PATH");printf("%s",ret); return 0;}
理解:
环境变量信息在系统启动时就从配置文件中被加载到了bash进程中,而所有命令行执行的程序都是bash的子进程,通过子进程也可以获取到环境变量,说明父进程的环境变量信息可以被子进程继承获得,环境变量具有系统全局性
2.7 环境变量与本地变量
- 环境变量:可以被子进程继承获得,具有系统全局性
- 本地变量:只能在当前进程被访问,不能被子进程继承
[zyq@iZf8z3j2ckkap6ybtz8qseZ file]$ HELLO=123456 //创建名为HELLO的本地变量
查看本地变量:
[zyq@iZf8z3j2ckkap6ybtz8qseZ file]$ echo $HELLO //查看方法与环境变量一致
123456
ps:虽然本地变量可以被查找出来,但是其并没有与环境变量存在一个地方,通过env查找所有环境变量里面依旧找不到HELLO
可以通过指令来将本地变量导为环境变量:
[zyq@iZf8z3j2ckkap6ybtz8qseZ file]$ export HELLO=12345

问题来了:
指令export的本质是可执行程序,那他执行一定会创建子进程,子进程可以访问父进程的资源是因为继承,而子进程做一些环境修改父进程是看不到的,那为什么bash可以查找到HELLO的信息呢?
这是因为echo export等指令是内建命令,内建命令是有bash直接执行的,不需要创建子进程,而Linux 80%的指令都是创建子进程执行的
相关文章:
如何理解 Linux 命令行参数与环境变量7
一、命令行参数 1.1参数介绍 在写C语言程序时,main函数是否可以带参数呢?------ 是可以的 int argc: 命令行参数的个数char *argv[ ]: 字符指针数组(指向各个命令行参数的字符指针所构成的数组) 我们写一段代码来打印一下看这…...
奥特曼回应GPT5
欢迎再次与大家会面!在积累了大量的信息和趋势后,今天我们将深入了解 Sora、OpenAI 董事会、以及近期与其有关的所有声讨。我们将直接跳入与 OpenAI 首席执行官 Sam Altman 的深度访谈,探讨从 AGI 到 GPT-5 的未来,以及 Sam 对人工…...
QT----给程序添加上任务栏托盘图标和退出
让我们的程序拥有任务栏托盘图标,实现程序后台运行,退出等功能 1、关闭程序保持后台 重写关闭事件,忽略点击窗口关闭 void MainWindow::closeEvent(QCloseEvent *event) {// 隐藏窗口,而不是真正关闭setVisible(false);// 忽略关闭事件&am…...
arm地址对齐的总结
static void axi_azx_writeb(u8 value, u8 __iomem *addr) { u32 data; u32 offset; offset (u64)addr & 0x03; // 编译器不允许地址做& 操作时要强转为数据 addr (u8 __iomem *)((u64)addr & 0xFFFFFFFFFFFFFFFC); // __iomem是个64位的地址 u8表示从这个地址…...
就业班 2401--3.13 走进网络
走进网络 长风破浪会有时,直挂云帆济沧海。 1.认识计算机 1.计算机网络是由计算机和通讯构成的,网络研究的是“通信”。 ------1946 世界上第一台计算机 2.终端:只有输入和输出功能,没有计算和处理功能。 3.数据:一串…...
SWIFT介绍和学习(简单入门级别)
SWIFT介绍和学习 SWIFT功能介绍SWIFT快速使用LLM及LLM最佳实践(LLM系列文章)部署指南 vllm非官方介绍资料 项目地址:https://github.com/modelscope/swift 任何有疑惑的地方,参考项目首页readme寻求答案 SWIFT功能介绍 SWIFT&…...
智慧城市:提升城市治理能力的关键
目录 一、智慧城市的概念及特点 二、智慧城市在提升城市治理能力中的应用实践 1、智慧交通:提高交通治理效率 2、智慧政务:提升政府服务水平 3、智慧环保:加强环境监测与治理 4、智慧安防:提高城市安全水平 三、智慧城市在…...
golang 对接第三方接口 RSA 做签(加密) 验签(解密)
一、过程 1.调用第三方接口前,一般需要按规则将参数按key1value1&key2value2 阿斯克码排序,sign参数不参与加密 2.将排序并连接好的参数字符串通过我方的私钥证书(.pem)进行加密得到加密串,当然加密得到的是 []byte 字节流&…...
Spring Data访问Elasticsearch----Elasticsearch存储库Repositories
Spring Data访问Elasticsearch----Elasticsearch存储库Repositories 一、自动创建具有相应映射的索引二、存储库方法的注解2.1 Highlight2.2 SourceFilters 三、基于注解的配置四、Spring命名空间Namespace 本文包括Elasticsearch存储库实现的细节。 例1:示例Book实…...
初探 Cocos Creator: 碰撞与物理系统
前言 不知道你刚开始玩碰撞时,会不会遇到始终无法触发碰撞事件?玩物理系统时,自由落体的刚体会穿过 “地面” 刚体等情况?没错我全都遇到过,那么下面我就用红蓝色方块,简单实战一下 Cocos Creator 的碰撞与…...
Vue组件封装方案对比——v-if方式与内置component方式
近期在准备搭建一个通用组件库,而公司现有的各个系统也已有自己的组件库只是没抽离出来,但是目前有两套不同的组件封装方案,所以对于方案的选择比较困惑,于是对两种方式进行了对比,结合网上找到的一些开源组件库进行分…...
python与excel第四节 批量新增、删除工作表
在多个工作簿中批量新增工作表 假设,一个文件夹下面有多个excel文件,需要再每个excel文件中增加一个sheet。 例子: import osimport xlwings as xw file_path D:\\TEST\\python与excelfile_list os.listdir(file_path) sheet_name 产品…...
计算机网络——计算机网络体系结构
计算机网络——计算机网络体系结构 计算机网络体系结构的由来正确认识分层协议与层次划分著名的几个体系结构OSI体系结构TCP/IP体系结构5层体系结构 我们今天来了解一下计算机网络体系结构: 计算机网络体系结构的由来 俗话说,“没有规矩,不…...
近期常用linux命令总结
linux mv [options] source dest : 移动文件 cp [options] source : 复制文件 ps -a: 列出所有进程 ps -ef | grep 进程关键字: 查找指定进程 (-e 显示所有进程 -f 全格式) docker docker images 显示所有镜像 docker pull [IMAGE_NAME] : 拉取某个镜像…...
变配电站配电监控解决方案--变电站综合自动化系统
变电站综合自动化系统 Acrel-1000变电站综合自动化监控系统是我司根据电力系统自动化及无人值守的要求,总结国内外的研究和生产的先进经验专门研制出的新一代电力监控系统。本系统具有保护、遥测、遥信、遥脉、遥调、遥控功能,可实现无人或少人值守功能…...
【ollama】linux、window系统更改模型存放位置,全网首发2024!
首先是window系统 so easy 直接进入系统环境变量添加就行 其次是linux系统 全靠自己试出来的,去Ollama官网找半天文档不知道在哪,而且linux也没有说:【 https://github.com/ollama/ollama/blob/main/docs/README.md https://github.com/o…...
Spring 被打暴了! vs Javalin vs Solon
测试仅供参考。不同的环境、场景,效果会不同。 测试记录: 项目SpringBoot2SpringBoot3JavalinSolon运行时java 17java 17java 17java 17测试前状态/内存101.1Mb112.9Mb66.1Mb45.6Mb测试后状态/内存996.3Mb326.9Mb457.3Mb369.2Mb测试后状态/并发2万2.6万…...
IDEA中快速配置Git
Git介绍: Git下载 idea中配置Git...
vscode用SSH远程开发c语言
vscode配置远程 这里我使用虚拟机进行展示,首先需要你的虚拟机安装好ssh 没安装好就执行下面的命令安装并开启服务 sudo apt-get install ssh sudo service ssh start ps -e | grep sshvscode安装 remote-ssh扩展 点击左下角的远程连接,我这里已经连接…...
鸿蒙Next 支持数据双向绑定的组件:Checkbox--Search--TextInput
Checkbox $$语法,$$绑定的变量发生变化时,会触发UI的刷新 Entry Component struct MvvmCase { State isMarry:boolean falseStatesearchText:string build() {Grid(){GridItem(){Column(){Text("checkbox 的双向绑定")Checkbox().select($$…...
前端路由管理方案
前端路由管理方案是现代Web应用开发中的核心技术之一,它决定了用户如何与单页面应用(SPA)交互,以及页面如何在不刷新的情况下实现动态切换。随着前端框架的普及,路由管理从简单的URL跳转演变为复杂的导航控制、权限校验…...
LaserGRBL:从零开始掌握激光雕刻的完整免费指南
LaserGRBL:从零开始掌握激光雕刻的完整免费指南 【免费下载链接】LaserGRBL Laser optimized GUI for GRBL 项目地址: https://gitcode.com/gh_mirrors/la/LaserGRBL 想要将创意变为现实?寻找一款简单易用且功能强大的激光雕刻控制软件࿱…...
Rust 宏系统在工程化中的应用
Rust宏系统在工程化中的应用 Rust以其高性能和内存安全性著称,而宏系统则是其元编程能力的核心体现。在工程化开发中,宏能够显著减少重复代码、提升开发效率,并增强代码的可维护性。无论是自动生成样板代码,还是实现领域特定语言…...
STM32项目交付新姿势:用CoFlash把.bin/.elf文件甩给客户,告别源码工程
STM32项目交付新姿势:用CoFlash实现二进制文件的安全传递 在嵌入式开发领域,知识产权保护与高效协作往往是一对难以调和的矛盾。传统开发模式下,工程师不得不将完整的Keil或CubeIDE工程源码打包交付给客户或生产部门,这不仅暴露了…...
3步彻底清理Windows系统:Bulk Crap Uninstaller批量卸载工具终极指南
3步彻底清理Windows系统:Bulk Crap Uninstaller批量卸载工具终极指南 【免费下载链接】Bulk-Crap-Uninstaller Remove large amounts of unwanted applications quickly. 项目地址: https://gitcode.com/gh_mirrors/bu/Bulk-Crap-Uninstaller 在Windows系统中…...
如何将闲置电视盒子变身高性能服务器:Amlogic S9xxx Armbian终极指南
如何将闲置电视盒子变身高性能服务器:Amlogic S9xxx Armbian终极指南 【免费下载链接】amlogic-s9xxx-armbian Supports running Armbian on Amlogic, Allwinner, and Rockchip devices. Support a311d, s922x, s905x3, s905x2, s912, s905d, s905x, s905w, s905, s…...
GoTTY安全最佳实践:如何配置TLS、认证和权限保护
GoTTY安全最佳实践:如何配置TLS、认证和权限保护 【免费下载链接】gotty Share your terminal as a web application 项目地址: https://gitcode.com/gh_mirrors/got/gotty GoTTY是一款能够将终端共享为Web应用的工具,让用户可以通过浏览器远程访…...
2026 年开封钢结构企业怎么选?6 家合规优质企业实力详解
2026 年开封钢结构企业怎么选?6 家合规优质企业实力详解随着开封城市建设与产业升级持续推进,超高层钢结构、大跨度公共建筑、大型工业综合体等高端钢结构项目需求逐步增长,据河南省钢结构协会 2026 年行业报告显示,具备双壹级及以…...
别再只用Last Click了!用Python的Shapley Value给你的营销渠道算笔‘公平账’
用Shapley Value破解营销渠道归因难题:Python实战指南 营销团队最头疼的问题莫过于:明明在多个渠道投放了广告,却说不清每个渠道到底贡献了多少业绩。传统归因模型(如最终点击)的简单粗暴,常常导致预算分配…...
Mintegral 广告平台 ROI 指数排名进入全球前四,多维度数据验证全球流量竞争力
2026年4月,全球知名移动营销归因机构 Singular 发布了《Singular ROI Index 2026》报告。程序化互动式广告平台 Mintegral 凭借稳定的流量质量、精准的触达能力以及出色的获客表现,成功入选“ROI 指数榜”和“MTA ROI 排行榜”两大榜单。从整体表现来看&…...


