如何理解 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($$…...

华为云AI开发平台ModelArts
华为云ModelArts:重塑AI开发流程的“智能引擎”与“创新加速器”! 在人工智能浪潮席卷全球的2025年,企业拥抱AI的意愿空前高涨,但技术门槛高、流程复杂、资源投入巨大的现实,却让许多创新构想止步于实验室。数据科学家…...

多云管理“拦路虎”:深入解析网络互联、身份同步与成本可视化的技术复杂度
一、引言:多云环境的技术复杂性本质 企业采用多云策略已从技术选型升维至生存刚需。当业务系统分散部署在多个云平台时,基础设施的技术债呈现指数级积累。网络连接、身份认证、成本管理这三大核心挑战相互嵌套:跨云网络构建数据…...

19c补丁后oracle属主变化,导致不能识别磁盘组
补丁后服务器重启,数据库再次无法启动 ORA01017: invalid username/password; logon denied Oracle 19c 在打上 19.23 或以上补丁版本后,存在与用户组权限相关的问题。具体表现为,Oracle 实例的运行用户(oracle)和集…...
云原生核心技术 (7/12): K8s 核心概念白话解读(上):Pod 和 Deployment 究竟是什么?
大家好,欢迎来到《云原生核心技术》系列的第七篇! 在上一篇,我们成功地使用 Minikube 或 kind 在自己的电脑上搭建起了一个迷你但功能完备的 Kubernetes 集群。现在,我们就像一个拥有了一块崭新数字土地的农场主,是时…...

盘古信息PCB行业解决方案:以全域场景重构,激活智造新未来
一、破局:PCB行业的时代之问 在数字经济蓬勃发展的浪潮中,PCB(印制电路板)作为 “电子产品之母”,其重要性愈发凸显。随着 5G、人工智能等新兴技术的加速渗透,PCB行业面临着前所未有的挑战与机遇。产品迭代…...

新能源汽车智慧充电桩管理方案:新能源充电桩散热问题及消防安全监管方案
随着新能源汽车的快速普及,充电桩作为核心配套设施,其安全性与可靠性备受关注。然而,在高温、高负荷运行环境下,充电桩的散热问题与消防安全隐患日益凸显,成为制约行业发展的关键瓶颈。 如何通过智慧化管理手段优化散…...
Java编程之桥接模式
定义 桥接模式(Bridge Pattern)属于结构型设计模式,它的核心意图是将抽象部分与实现部分分离,使它们可以独立地变化。这种模式通过组合关系来替代继承关系,从而降低了抽象和实现这两个可变维度之间的耦合度。 用例子…...

招商蛇口 | 执笔CID,启幕低密生活新境
作为中国城市生长的力量,招商蛇口以“美好生活承载者”为使命,深耕全球111座城市,以央企担当匠造时代理想人居。从深圳湾的开拓基因到西安高新CID的战略落子,招商蛇口始终与城市发展同频共振,以建筑诠释对土地与生活的…...

【Linux】自动化构建-Make/Makefile
前言 上文我们讲到了Linux中的编译器gcc/g 【Linux】编译器gcc/g及其库的详细介绍-CSDN博客 本来我们将一个对于编译来说很重要的工具:make/makfile 1.背景 在一个工程中源文件不计其数,其按类型、功能、模块分别放在若干个目录中,mak…...

什么是VR全景技术
VR全景技术,全称为虚拟现实全景技术,是通过计算机图像模拟生成三维空间中的虚拟世界,使用户能够在该虚拟世界中进行全方位、无死角的观察和交互的技术。VR全景技术模拟人在真实空间中的视觉体验,结合图文、3D、音视频等多媒体元素…...