命令行参数&&环境变量

目录

前言:

命令行参数:

现象:

这些参数的意义:

为什么要这么做? 

这些事是谁做的呢?

环境变量

现象:

创建环境变量:

结合程序理解:


前言:

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

命令行参数:

现象:

        我们是否还记得,我们在刚开始学习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内部有效,无法被子进程继承下去。只要导成环境变量,此时才能够被获取。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

无双@

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值