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

【Linux 系统】命令行参数和环境变量

文章目录

  • 前言
  • 1. 命令行参数
  • 2. 环境变量
    • 2.1 概念
    • 2.2 进程中获取环境变量
    • 2.3 环境变量的操作
    • 2.4 内建命令
  • 总结

前言

我在bash命令行上执行一些指令的时候,例如:ls指令。我们可以让我们的指令带上选项!从而实现出来不同的功能,可是我们有没有想过为什么指令带上不同的选项之后,就可以实现不同的功能了呢?

在这篇文章中,小编和大家了解认识两个东西:

  1. 命令行参数

  2. 环境变量

1. 命令行参数

  • 首先我们来看,main函数的函数原型:
int main(int argc, char* argv[])
{}

main函数也是有参数的:

  1. argc:是一个整型参数,代表数组的元素个数。
  2. argv:是一个指针,指向的是是一个char*一维数组的起始地址。

我们对于这两个参数还是保持着一种好奇心理,于是我们写出了下面这样的测试代码:

// 已经正确包含头文件
int main(int argc, char* argv[])
{for(int i = 0; i < argc; ++i){printf("[%d]: %s\n", i, argv[i]);}return 0;
}

我们编译运行一下,得到如下的结果:
在这里插入图片描述

  • 现象

    我们在命令行上的参数都被传给了我们启动的进程的main函数的参数(argv)

不妨现在,我们将我们的代码进行更改:

int main(int argc, char* argv[])
{if(strcmp(argv[1], "-a") == 0){printf("功能1...\n");//实现功能}else if(strcmp(argv[1], "-b") == 0){printf("功能2...\n");}else{printf("未实现该功能...\n");//...}return 0;
}

我们来看我们的测试结果
在这里插入图片描述

  • 结论

    命令行上的选项我们可以通过给main函数参数的形式交给程序。程序内部可以通过解析判断指令的选项类型是否正确,从而给我们实现不同的功能

  • 问题:那么我们在命令行上启动的程序是如何传参交给main函数的呢?

    这个问题,我们在命令行启动的进程大多都是bash进程的子进程。我们bash进程在接受到用户的命令的时候可以进行判断,从而创建子进程,采用系统调用exec*系列进程替换接口,详情在进程控制),从而将我们的输入的命令行选项传参给子进程。

  • 为什么需要main函数有这样的参数呢?

    就是为我们的指令、工具、软件等提供命令行选项的服务!

2. 环境变量

学习Linux系统,必然需要了解的一个知识点就是环境变量。在进程等中都比较重要。

2.1 概念

  • 是什么

    环境变量是系统提供的一组 name=value形式的变量,不同的环境变量有不同的用处,一般而言,环境变量具有全局性

  • 认识环境变量

    1. PATH:路径查找的环境变量

      来看这样一个示例,当我们在命令行上不指明路径执行我们自己的代码的时候:
      在这里插入图片描述
      对于我们的命令,报错信息是:not found也就是意味着,我们的bash一定是曾经去一个地方找过这条命令是否存在!这个地方就是环境变量的PATH

      查看一下:echo $PATH
      在这里插入图片描述
      所以想要我们的程序不通过指明路径指向特别简单:

      • 将我们的命令软连接/安装到环境变量的文件路径下。

      • 将我们当前文件安装的PATH中。

      我们采用第二种方式演示一下:
      演示更改PATH
      注意:这样更改环境变量PATH只是临时的,重新启动会话就会失效了。

    2. USER:表示用户身份的环境变量

      我们的bash命令行是如何识别一个用户的身份信息的呢?可以通过环境变量USER来识别,在代码级别做判断。

      • 首先我们来看一个接口:getenv

        在这里插入图片描述
        作用:根据传入的name获取value。

      • 那么一个用户的身份我们可以做如下的判断:

        在这里插入图片描述
        我们通过上面代码,可以认识到,bash在创建子进程之前(我们程序执行指令之前)可以对我们的身份信息做出判断的!!

  • 指令显示当前系统的环境变量env

    环境变量

2.2 进程中获取环境变量

  1. 第一种方法:我们刚刚已经谈到了,我们可以通过函数调用:getenv获取单条环境变量的value值。

  2. 第二种方法:main函数参数的第三个参数

    实际上,main函数还有第三个参数。原型如下:int main(int argc, char* argv[], char* env[])。最后一个参数就是指向的就是系统为每一个进程维护的一张环境变量表

我们可以尝试打印出来试试(一般最后一个参数为nullptr

// 正确包含头文件
int main(int argc, char* argv[], char* env[])
{for(int i = 0; env[i] != NULL; ++i){printf("[%d]:%s\n", i, env[i]);}return 0;
}

我们依然可以获得环境变量表

在这里插入图片描述

  • 上图有一个细节:此时我们设置的环境变量PATH还在!!

    在这里插入图片描述

    那么我们一定会有如下问题

    1. 我们在bash命令行上启动我们的进程,我们的进程环境变量表来自哪里?

      这个问题,上面的哪个示例也已经能窥探一二了:我们在bash上启动的进程都是子进程,所以当我们子进程在被启动的时候,环境变量表来源于我们的父进程bash。
      同样地,当我们的进程创建了一个子进程之后,我们创建的子进程就会得到来自我们父进程的环境变量表。为什么?因为环境变量表也是数据,子进程会共享父进程的代码和数据

    2. 环境变量表是谁传递参数的?编译器对这些参数是如何感知的?

      我们也能明白,在我们bash命令行启动进程的时候父进程就需要进行准备,当我们父进程创建子进程之后,采用函数调用exec*系列接口的时候,我们的Linux操作系统就会为我们传递参数!

      编译器(如 gcc)编译代码时,它不只是编译main函数。它会将一段特殊的启动代码 链接到可执行文件的开头。这段代码是用汇编和C语言写的,负责设置C程序运行所需的基本环境(在准备的时候就可以获取环境变量表的地址了,还有argc,argv等参数)。当我们通过exec*接口替换你的程序后,CPU指令指针首先指向的就是这段启动代码,而不是main函数。简单来说,main函数也是函数,也是在启动的时候被调用的

    3. 一般一个进程的环境变量表存储在进程地址空间的哪个位置?

      根据操作系统的视角来看,一般存储在一个进程地址空间的顶部。所以,环境变量表在进程的角度也是一个进程的数据
      在这里插入图片描述

  1. 第三种方法:采用全局变量extern char **environ。该全局变量被声明在:<unistd.h>

    在这里插入图片描述

  • 注意:在同一个进程中,第二三种方法获取到的表一定是同一个。在程序替换中会涉及到对环境变量表的替换。

2.3 环境变量的操作

我们也可以来了解一下如何设置环境变量和查看环境变量

  1. echo $name:显示环境变量名为name的value值。
  2. env:显示当前系统的所有环境变量。
  3. export:设置一个新环境变量。
  4. unset name:清除名为name的环境变量。
  5. set:显示本地自定义的shell变量和环境变量。
  • export

    在这里插入图片描述
    说明我们的环境变量已经设置成功了!

2.4 内建命令

  • 来看下面一个测试:

    在这里插入图片描述

原因也很简单,这涉及了一个命令的分类。

  • 常规命令:创建子进程完成的命令。
  • 内建命令: bash不创建子进程完成,而是自己完成。类似于自己调用了自己内部的函数!

很显然,上面的echo指令是一个内建命令!

总结

我们需要了解:

  1. 一个程序是有两张表的:

    • 命令行参数表

    • 环境变量表

    我们可以简单理解为:由操作系统维护的两张表。在进程启动的时候需要传给进程。

http://www.dtcms.com/a/434479.html

相关文章:

  • 如何用wordpress建一个网站太原建站模板搭建
  • DNS优选 2.6.3 |解锁专业版,优选最快DNS,享受快速且私密的互联网浏览体验
  • 云浮源峰网站建设工作室地址百度免费咨询
  • wordpress 公司网站有赞分销模式佣金
  • 冀icp 网站建设做seo哪些网站会好点
  • 基于YOLOv8-OBB的SAR图像目标检测系统
  • 《强化学习数学原理》学习笔记4——贝尔曼最优方程推理过程
  • 如何缩小物联网设备的 Docker 镜像
  • 513.找树左下角的值(二叉树算法题)
  • LeetCode:84.完全平方数
  • 《API网关性能优化指南:从请求拥堵到毫秒级响应,并发下的架构重构实践》
  • 免费p2p网站建设企业管理系统开发平台
  • 报告派研读:2025年电力设备及新能源行业深度报告
  • 站长之家源码垂直电商平台有哪些?
  • K8s中的ETCD存储机制
  • 【精品资料鉴赏】397页WORD详解智慧城市顶层设计方案
  • 16种粮食谷物分类数据集5300张17类别
  • 2025基于springboot的网上蛋糕销售系统
  • SSE是什么?SSE解决什么问题?在什么场景使用SSE?
  • 算法偏见的解药:将敏捷“灵魂”注入AI伦理
  • 基于前端+Node.js 的 Markdown 笔记 PDF 导出系统完整实战
  • lesson71:Node.js与npm基础全攻略:2025年最新特性与实战指南
  • 购买域名后 可以做网站么灰色关键词排名优化
  • 专业做家具的网站小程序注册方法
  • OWASP ZAP 工具安全测试介绍
  • Git介绍 常用命令
  • 教育机构作图:含拼团 / 课程封面模板,适配小程序
  • linux内核时间定时器延时
  • 远程安装vps相关软件记录
  • 山东高端网站建设方案宁波网站建设那家好