命令行参数环境变量

news2024/11/25 20:35:31

目录

前言:

命令行参数:

现象:

这些参数的意义:

为什么要这么做? 

这些事是谁做的呢?

环境变量

现象:

创建环境变量:

结合程序理解:


前言:

        我们在前一章就开始学习与进程相关的部分知识,上一章是先学习到了进程优先级接下来就是补充一些额外知识。

命令行参数:

现象:

        我们是否还记得,我们在刚开始学习C语言的时候,对于main函数的写法我是介绍过的,我记得我说过main函数可以写成这样:int main(int argc, char* argv[]) 。我们当然是可以选择这样写也可以直接选择int main()这样直接完事。下面我们来看下列的代码:

输出结果:

        当然我们还可以再尝试一下:
        输入指令:./test -a -b -c -d

这些参数的意义:

        我们在通过点斜杠运行可执行程序后,通过添加-a或者-b这样的参数即可看到argc和argv的变化,其实这些是和该进程匹配的选项,这些选项以这些空格作为分隔符,把他们放进一个指针数组里。        

        其实作为区分的本质是将空格转换成'\0'加以区分的!

为什么要这么做? 

        可以通过输入不一样的选项,执行同一份代码的不同功能。以下通过代码举例子:

        命令行参数本质是交给我们程序不同的选项,用来定制不同的程序功能。命令中会携带很多选项。

这些事是谁做的呢?

        主要还是由我们的父进程bash(命令行解释器)管理,所以我们就可以得出以下结论:父进程的数据,默认能够被子进程看到并访问。命令行中启动的进程,都会变成进程,其实都是bash的子进程。
        所以对我们之前通过点斜杠运行的可执行程序,默认是输入给父进程bash的。
        因为子进程能看到父进程的数据,因此bash在识别几个-a -b -c后传递到argc,并再malloc出argv[],这些都是子进程能看到的。现在我们也能理解,为什么有些指令类似ls后面还会有一个-l或者-a这样的选项的意思了。

环境变量

        环境变量(environment variables)一般是指在操作系统中用来指定操作系统运行环境的一些参数,如:我们在编写C/C++代码的时候,在链接的时候,从来不知道我们的所链接的动态静态库在哪里,但是照样可以链接成功,生成可执行程序,原因就是有相关环境变量帮助编译器进行查找。
环境变量通常具有某些特殊用途,还有在系统当中通常具有全局特性。相信大家如果配置过java或者嵌入式stm环境得物时候为这个环境变量抓狂过,接下来我们就来了解下环境变量!

现象:

        在Linxu中,存在一些全局的设置,表明告诉bash(命令行解释器),应该在哪些路径下去寻找可执行程序。
        我们可以尝试输入指令:echo $PATH

        系统中有很多配置,在我们登录Linux系统的时候,就已经被加载到了bash进程中(在内存中的),默认查找到的环境变量是内存级的。

        PATH其实环境变量的一种,而我们$PATH无非就是将环境变量的内容存放地打印出来,我们将结果打印出来的内容:PATH=/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/ws/.local/bin:/home/ws/bin
        这一串就是表示了各个环境变量存放的位置,比如/usr/local/bin这个文件夹,里面的可执行程序在该文件夹中,就代表了环境变量。其中 “:” 表示分隔符,bash在执行命令的时候,需要先找到命令,因为未来要加载。

        刚刚我们讲命令行参数时,其实就有疑问了,运行test可执行程序时是要加点斜杠的,再加上-a -b之类的选项,然后我说这可以说明ls为什么有-l -a选项对应不同的功能。此时我们就会发现,ls这个指令就不用加点斜杠运行,  这又是为什么呢?
        其实这个就是讲解环境变量最好的例子,这是因为bash会先去各个地址找,然后发现了ls在/usr/bin目录中

        然后就会调用ls,所以在执行ls时就不用加点斜杠

创建环境变量:

        若是,我想要自己的可执行程序和系统指令一样,不带点斜杠该怎么办呢?目前我们介绍三种方法。

1、可以尝试使用cp命令,将自己的可执行程序拷贝到/usr/bin目录下。                

        首先我需要给我的test可执行程序改名字,因为/usr/bin目录下有test这个环境变量。目前我们单独使用my_test是不起作用的,which也没有结果。所以我们开始进行拷贝。

        演示成功啊,运行成功,和上面演示的一样。

2、也可以直接PATH =$PATH:"自己当前的目录",对于我的目录我就可以写成:

        当然这种方式慎用,但是也没关系。因为我们每一次重启,环境变量右会重新归为。这是因为最开始的环境变量并不是在内存中的,而是在系统的对应配置文件中(默认在配置文件中)。
        这个配置文件就在用户家目录下,.bash_profile文件、.bashrc文件和/etc/bashrc文件。其中前两个是用户的配置文件,最后一个是系统的配置文件。

        所以如果我们想要永久更改环境变量的路径,可以直接在.bash_profile里更改。 

见见更多的环境变量

        可以输入:env    查看全部的环境变量。

        这些环境变量都是极其准备好的。

        export "环境变量名" = “环境变量内容”   —— 添加
        unset "环境变量" —— 取消 

结合程序理解:

        环境变量默认是可以被子进程拿到的!因为环境变量们,默认实是在bash里的。
        

        而这些环境变量均是全局的!

        环境变量有那么多,bash内部是如何组织的呢?
        其本质是有一串代码组织的,extern char** environ;

接下来通过代码演示一下

         不难发现,通过代码发现和我们直接输入env这个指令没有区别的。
        bash再进程启动的时候,默认会给我子进程形成两张表:
                argv[ ]命令行参数表(从用户输入命令行获取),env[ ]环境变量表(从OS的配置文件获取),bash通过各种方式交给子进程。

        所以我们对于命令export XXX = XXX就是去env[ ]表里寻找NULL的地方,然后链入新的环境变量即可。

        环境变量具有系统级的全局属性,因为环境变量本身会被子进程继承下去

以下是获取环境变量的三种方法:

  1.         char* path = getenv("PATH")
  2.         通过main函数参数char* env[ ]
  3.         extern char** environ 

 在执行export添加新环境变量时不会创建子进程吗?

        子进程自己的数据bash看不到,但是export新的环境变量bash是可以看到的。当然执行export不会创建子进程,echo也不会创建子进程。这是因为export和echo是属于内建命令,这些命令是会有bash亲自执行。但是这只是一部分,因为80%的命令都是由bash创建子进程,子进程来执行的。
        对于内建命令,可以理解为bash内部的一个个void类型的函数,执行完就执行完,并没有返回值。

注意!!!

        如果你只是在输入指令:HELLO = 1234这样子输入,你本质只是创建了一个本地变量,而不是环境变量!你可以使用echo $HELLO打印出来

        但是你无法通过env|grep HELLO查找出来,通过main函数或者extern char** environ这两种方法也查找不到!

        本地变量只在ash内部有效,无法被子进程继承下去。只要导成环境变量,此时才能够被获取。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2035762.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

R语言里认识机器学习

下面内容摘录自: 1章2节:关于人工智能、机器学习、统计学连和机器学习、R 与 ChatGPT 的探究-CSDN博客文章浏览阅读1k次。在现代科技发展的浪潮中,人工智能(AI)、机器学习(ML)、统计学、R 编程…

网络通信(TCP/UDP协议 三次握手四次挥手 )

三、TCP协议与UDP协议 1、TCP/IP、TCP、 UDP是什么 TCP/IP协议是一个协议簇,里面包括很多协议的, UDP只是其中的一个, 之所以命名为TCP/IP协议, 因为TCP、 IP协议是两个很重要的协议,就用他两命名了,而TCP…

告别知云单一选择,这些文献翻译工具同样值得信赖!

在翻译领域,知云文献翻译以其专业度和便捷性赢得了众多用户的青睐,但市场上还有许多其他翻译工具同样值得关注。本文将为您推荐几款优秀的翻译工具。 Foxit在线翻译 链接: https://fanyi.pdf365.cn/ Foxit在线翻译以其高效的翻译速度和准…

创建第一个Qt项目

创建第一个QT项目 创建工程名称一般不要有特殊符号,不要有中文 项目工程保存路径可修改,路径不要带中文 Base class中的三个选项 QMainWindow:主窗口类,包括菜单栏、工具栏、状态栏。 QWidget:可以创建一个空白的窗口,是所有界…

嵌入式软件--数据结构与算法 DAY 13

在嵌入式中,对算法的要求不高,但顺序查找和冒泡排序是经典算法,必须掌握。 1.算法定义 算法是一个用于解决特定问题的有限指令序列(计算机可以执行的操作)。通俗的理解就是可以解决特定问题的方法。 2.时间复杂度 …

手动和torch.nn实现卷积神经网络、空洞卷积、残差网络

一、数据集 1. 分类问题 数据集——车辆分类数据 ⚫输入图片,输出对应的类别 ⚫共1358张车辆图片 ⚫分别属于汽车、客车和货车三类 ⚫汽车:779张 ⚫客车:218张 ⚫货车:360张 ⚫每个类别随机取20-30%当作测试集 ⚫各图片的大小不一,需要将图片拉伸到相同大小 汽车 …

three.js 安装方法、基础简介、创建基础场景

threejs简介 Three.js是一个基于JavaScript编写的开源3D图形库,‌利用WebGL技术在网页上渲染3D图形。‌ 它提供了许多高级功能,‌如几何体、‌纹理、‌光照、‌阴影等,‌使得开发者能够快速创建复杂且逼真的3D场景。‌ threejs提供了丰富的功…

云原生日志Loki

1. Loki简介 1.1 Loki介绍 Loki是 Grafana Labs 团队最新的开源项目,是一个水平可扩展,高可用性,多租户的日志聚合系统。它的设计非常经济高效且易于操作,因为它不会为日志内容编制索引,而是为每个日志流编制一组标签…

关于Vue项目npm快捷键,点击run启动报错,及npm i也报错的解决办法

1.配置idea的npm 2.点击运行按钮 3.结果 分析原因及问题: npm i npm run dev 由于是刚刚从gitlab新拉的前端代码,可能没有用命令install过类似于没有编译过,所以执行一下上面的命令 结果报错如下: F:\tbyf\qjyy\hip-manager-ui&…

SpringBoot整合MyBatis-Plus完整详细版(提供Gitee源码)

前言:本篇文章完整详细介绍了SpringBoot整合MyBatis-Plus的完整过程,这边我的SpringBoot版本是2.4版本、JDK1.8和Maven3.8.1版本,跟着文章一步步走就可以了,MyBatis-Plus整合非常方便,也是现在企业开发中经常会用的一个…

学习笔记第二十四天

1.exec族函数的区别 int exec l(const char *path, const char *arg, ...); int exec l p(const char *file, const char *arg, ...); int exec l e(const char *path, const char *arg,..., char * const envp[]); int exec v(const char *path, char *const argv[]); …

1011 World Cup Betting

题目 解释 题目讲的就是,给你三行数,每一行包含3个浮点小数,让你找到最大的那个小数,然后如果最后的小数是第一个,输出W,是第二个,输出T,是第三个,输出L,最后…

Day37 | 188.买卖股票的最佳时机IV 309.最佳买卖股票时机含冷冻期 714.买卖股票的最佳时机含手续费

语言 Java 188.买卖股票的最佳时机IV 买卖股票的最佳时机IV 题目 给你一个整数数组 prices 和一个整数 k ,其中 prices[i] 是某支给定的股票在第 i 天的价格。 设计一个算法来计算你所能获取的最大利润。你最多可以完成 k 笔交易。也就是说,你最多…

Broken: Gallery靶机复现

靶机设置 靶机设置为NAT模式 靶机IP发现 nmap 192.168.112.0/24 靶机IP为192.168.112.142 目录扫描 dirsearch 192.168.112.142 访问浏览器 发现文件页面 查看后发现都没什么用 getshell hydra -L rockyou.txt -P rockyou.txt 192.168.112.142 ssh 尝试爆破ssh账号密码…

互联网应用主流框架整合【Redis常用技术】

和其他大部分NoSQL不同,Redis是支持事务的,尽管没有数据库那么强大,但非常有用,在某些高并发但又要保证高度一致性的场景下,代替数据库事务非常有效;在Redis的机制中,允许通过流水线一次性发给R…

DATAX自定义KafkaWriter

因为datax目前不支持写入数据到kafka中,因此本文主要介绍如何基于DataX自定义KafkaWriter,用来同步数据到kafka中。本文偏向实战,datax插件开发理论宝典请参考官方文档: https://github.com/alibaba/DataX/blob/master/dataxPlug…

2024年TI杯E题-三子棋游戏装置方案分享-jdk123团队-第二弹 手搓机械臂

第一弹赛题的选择与前期方案的准备 opencv调用摄像头bug的解决 机械臂的组装 采用三个舵机,组成一个三自由度的机械臂。 并且利用电磁吸盘的方式,完成对棋子的抓取工作,后面的事实证明,在预算不足的情况下,队友手搓…

顺序表的实现——数据结构

线性表 文章目录 线性表线性表的定义和基本操作线性表的定义线性表的基本操作 线性表的顺序表示顺序表的定义顺序表的实现——静态分配顺序表的实现——动态分配顺序表的特点 线性表的定义和基本操作 线性表的定义 线性表(Linear List)的定义 ​ 线性…

多进程多线程

exec 系列函数 结束代码函数 atexec 函数 结束标志,从下往上 先出2再出1 void cleanup1() {printf("clean1"); }void cleanup2() {printf("clean2"); }atexec(cleanup1) atexec(cleanup2)

28. 找出字符串中第一个匹配项的下标【 力扣(LeetCode) 】

一、题目描述 给你两个字符串 haystack 和 needle ,请你在 haystack 字符串中找出 needle 字符串的第一个匹配项的下标(下标从 0 开始)。如果 needle 不是 haystack 的一部分,则返回 -1 。 二、测试用例 示例 1: 输…