当前位置: 首页 > news >正文

八、命令行参数和环境变量

八、命令行参数和环境变量

    • 8.1 命令行参数
    • 8.2 环境变量概念
    • 8.3 常见环境变量
    • 8.4 查看环境变量
      • 指令
      • 测试 PATH
    • 8.5 环境变量相关命令
    • 8.6 环境变量组织方式
    • 8.7 环境变量通常具有全局属性
        • 进程创建机制
        • 环境变量的存储结构
        • 代码执行流程
        • 总结
    • 8.8 获取环境变量
      • 命令行第三个参数
      • 通过第三方变量 environ 获取
      • 通过系统调用获取或设置
        • getenv
        • putenv

8.1 命令行参数

main函数其实是有参数的,main函数的参数个数最多有3个

参数类型含义
argc(argument count)int命令行参数的个数(包括程序名本身)。
argv(argument vector)char *argv[]char **argv指向字符串数组的指针,每个字符串是一个命令行参数,最后一个元素为NULL
envp(environment pointer)char *envp[]char **envp指向环境变量字符串数组的指针,每个字符串格式为"键=值",最后一个元素为NULL

命令行参数是为了实现,一个命令可以根据不同的选项,实现不同的子功能。这也是 Linux 中所有命令选项功能的实现方式。典型的声明形式例如:int main(int argc, char *argv[], char *envp[])

命令行参数的特点:

  • 命令行参数argc >= 1argv[0]一定有元素,指向的就是程序名。
  • 选项是以空格分隔的字符串,一个字符也是字符串。
  • argc个,argv[argc-1]是最后一个,argv[argc] == NULL

例如:

#include<iostream>#include<cstdio>intmain(intargc,char*argv[]){std::cout<<"argc: "<<argc<<std::endl;for(inti=0;argv[i];i++){printf("i: %d arg[v]: %s\n",i,argv[i]);}if(argv[argc]==nullptr){printf(" == nullptr\n");}if(argc!=2){printf("使用方法错误!示例:%s -a | -b | -c\n",argv[0]);exit(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 if (strcmp(argv[1], "-d") == 0)// {// printf("正在执行第4种功能\n");// }// else// {// printf("正在执行默认功能\n");// }return0;}// int argc : 参数的个数// char *argv[] : 存储命令行参数// char *envp[] : 环境变量表(传输给进程)

8.2 环境变量概念

环境变量(Environment Variables)⼀般是指在操作系统中⽤来指定操作系统运行环境的⼀些参数。环境变量通常具有某些特殊⽤途,不同的环境变量会有不同的应用场景。还有在系统当中通常具有全局特性

例如:在编写C/C++代码时,链接的时候,并没有指定所要链接的动静态库在哪个目录,可还是链接成功并生成可执行程序了,其原因就是存在相关的环境变量帮助编译器查找库的位置。

示例:

一开始发现无法执行,因为没有指明路径。

./标识当前路径,简单来说就是告诉OS,如果没有指明路径,用户要执行的程序就在当前路径下,而这个路径就存储在环境变量PATH中。

8.3 常见环境变量

常见环境变量作用
PATH可执行程序的搜索路径。
HOME指定用户的主⼯作目录。
SHELL当前Shell,它的值通常是/bin/bash
USER当前用户名。

8.4 查看环境变量

指令

echo $NAME// NAME:环境变量名称
#include<stdio.h>intmain(){for(inti=0;env[i];i++){printf("i: %d env[%d]: %s\n",i,i,env[i]);}}

测试 PATH

为什么有些指令可以直接执⾏,不需要带路径,⽽我们的⼆进制程序需要带路径才能执⾏?

将我们的程序所在路径加⼊环境变量PATH当中:

临时添加export PATH=$PATH:程序所在路径

结束会话后失效。

永久添加

  1. 针对当前用户

编辑~/.bashrc~/.bash_profile文件:

// 打开配置文件vim~/.bashrc// 在文件末尾添加export PATH=$PATH:/your/program/path// 保存后使配置生效source~/.bashrc
  1. 针对所有用户

编辑/etc/profile/etc/environment

// 打开配置文件sudo vim/etc/profile// 在文件末尾添加export PATH=$PATH:/your/program/path// 保存后使配置生效source/etc/profile
  1. /etc/profile.d/中创建脚本
// 创建自定义脚本sudo vim/etc/profile.d/myprogram.sh// 内容为export PATH=$PATH:/your/program/path// 保存后,该脚本会在下次登录时自动执行

8.5 环境变量相关命令

命令作用
echo显示某个环境变量值
export设置⼀个新的环境变量
env显示所有环境变量
unset清除环境变量
set显示本地定义的shell变量和环境变量

8.6 环境变量组织方式

每个程序都会收到⼀张环境表,环境表是⼀个字符指针数组,每个指针指向⼀个以\0结尾的环境字符串。

8.7 环境变量通常具有全局属性

环境变量独立于程序本身,具有全局属性,可以被子进程继承。

shell外壳bash的环境变量从哪里来?Linux系统的配置文件。

本地变量私有变量,只在当前脚本或Shell中有效,只具有局部属性。

#include<iostream>#include<cstdio>#include<cstdlib>intmain(intargc,char*argv[],char*env[]){char*myenv=getenv("MY_ENV");if(myenv){printf("%s\n",myenv);}return0;}

直接查看,发现没有结果,说明该环境变量根本不存在。

导出环境变量export MY_ENV="hello world"

再次运⾏程序,发现结果有了。说明:环境变量是可以被⼦进程继承下去的。

进程创建机制

当在shell中执行程序时,操作系统会使用fork + exec* 系列函数:

  • fork:创建当前进程的副本(包括环境变量)
  • exec:用新程序替换当前进程的内容,但环境变量通常被保留
环境变量的存储结构
// 每个进程都有这样的环境变量表char*envp[]={"PATH=/usr/bin:/bin","HOME=/home/user","MY_ENV=hello world",// 你设置的环境变量NULL// 结束标记};
代码执行流程
#shell进程┌─────────────────┐ │ PATH=...│ │ HOME=...│ │ MY_ENV=hello │ ← export在这里设置 └─────────────────┘ │ │fork()创建子进程 ▼ ┌─────────────────┐ │ PATH=...│ │ HOME=...│ │ MY_ENV=hello │ ← 子进程继承所有环境变量 └─────────────────┘ │ │exec()执行你的程序 ▼ ┌─────────────────┐ │ 你的C程序 │ │getenv("MY_ENV")│ ← 成功获取到值 └─────────────────┘
总结
  1. 继承机制: 子进程默认继承父进程的所有环境变量
  2. 单向性: 子进程对环境变量的修改不会影响父进程
  3. exec 保留: 即使程序被替换,环境变量表仍然保持
  4. 安全性: 这也是为什么敏感信息不应放在环境变量中的原因

8.8 获取环境变量

命令行第三个参数

#include<iostream>#include<cstdio>intmain(intargc,char*argv[],char*env[]){for(inti=0;env[i];i++){printf("i: %d env[%d]: %s\n",i,i,env[i]);}return0;}

通过第三方变量 environ 获取

libc中定义的全局变量environ指向环境变量表,environ没有包含在任何头⽂件中,所以在使⽤时要⽤extern声明。

#include<iostream>#include<cstdio>intmain(intargc,char*argv[]){externchar**environ;for(inti=0;environ[i];i++){printf("i: %d environ[%d]: %s\n",i,i,environ[i]);}return0;}

通过系统调用获取或设置

常用getenvputenv函数来访问特定的环境变量。

getenv
NAME getenv,secure_getenv-get an environment variable SYNOPSIS#include<stdlib.h>char*getenv(constchar*name);char*secure_getenv(constchar*name);RETURN VALUE Thegetenv()function returns a pointer to the value in the environment,orNULLifthere is no match.
#include<iostream>#include<cstdio>intmain(intargc,char*argv[],char*env[]){printf("PATH: %s\n",getenv("PATH"));printf("PWD:%s\n",getenv("PWD"));printf("HOME:%s\n",getenv("HOME"));return0;}

putenv
NAME putenv-change or add an environment variable SYNOPSIS#include<stdlib.h>intputenv(char*string);RETURN VALUE Theputenv()function returns zero on success.On failure,it returns a nonzero value,and errno is set to indicate the error.
#include<iostream>#include<cstdio>#include<cstdlib>intmain(intargc,char*argv[],char*env[]){// 设置新的环境变量putenv("NEW_ENV=hello");// 修改现有的环境变量printf("修改前PATH: %s\n",getenv("PATH"));putenv("PATH=/usr/local/bin:/usr/bin");printf("修改后PATH: %s\n",getenv("PATH"));// 验证设置char*ch=getenv("NEW_ENV");printf("NEW_ENV: %s\n",ch);return0;}

http://www.jsqmd.com/news/812226/

相关文章:

  • 在AI时代重新定义“软件测试”:从找Bug到质量架构师
  • 【DeepSeek+Grafana可视化实战指南】:20年SRE亲授5大避坑法则与实时指标监控黄金配置
  • 宠物胰岛素注射剂量安全指南:从单位与毫升混淆到规范操作
  • ARM PMSWINC寄存器解析与性能监控实践
  • macOS WPS文档工作流优化:基于Pandoc的预处理与兼容性解决方案
  • 一键安装器设计指南:从Shell脚本到自动化部署架构
  • Instagit:基于MCP协议,让AI编程助手精准分析Git仓库代码
  • 5G手机发展复盘:从技术挑战到市场现实的工程化演进
  • 2026年钢塑复合土工格栅可靠厂家TOP5精选排行:玻纤格栅、钢塑格栅、长丝土工布、高强涤纶土工格栅、pet焊接土工格栅选择指南 - 优质品牌商家
  • FPGA神经形态计算架构与Class 7实现详解
  • TimeIndex:专为海量时间序列数据设计的轻量级高效索引方案
  • CSS如何实现多种颜色的线性渐变_使用linear-gradient()按方向和色标填色
  • 交互式CLI工具开发指南:从原理到实战构建Node.js命令行应用
  • AI 术语通俗词典:链式法测
  • github拆分小批量上传文件
  • C#怎么实现Socket心跳包 C#如何在TCP Socket通信中设计心跳机制检测连接状态【网络】
  • Quantum Motion融资1.6亿美元,加速研发硅基量子芯片
  • 混合检索+重排序:当前 RAG 精度提升最成熟的工程路径
  • SoC验证自动化与硬件仿真:破解复杂芯片系统级验证难题
  • 基于NestJS的上下文管理:从AsyncLocalStorage到微服务架构实践
  • 索尼PSP中文游戏资源汇总 中文游戏全集+PS1转PSP+金手指+PSP模拟器
  • OnmyojiAutoScript:阴阳师全自动脚本终极指南,30+日常任务智能托管解放双手
  • AI 重构泳装产业,先智先行如何破解行业痛点
  • 3步搞定碧蓝航线Live2D模型提取:Unity资源解析实战指南
  • 科技与科学领域重点新闻摘要-2026年5月13日
  • 基于MCP协议构建Gemini CLI工具:标准化大模型集成实践
  • 2026特殊膳食招商优质平台推荐指南:外用产品招商、新药招商、特医食品招商、特殊膳食招商、生物制品招商、私域招商选择指南 - 优质品牌商家
  • AI编程助手规则生成器:自动化配置Cursor与Windsurf项目规范
  • 如何免费使用Cursor Pro:3步实现AI编程神器永久VIP指南
  • 2026在职考研管综初试辅导TOP5推荐:MPA辅导/在职考研管综初试培训/笔试EMBA培训/笔试EMBA辅导/选择指南 - 优质品牌商家