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

一、命令行参数

我们平时写的main函数都是没有参数的,但其实下面的写法也是正确的。在使用时它的参数可带可不带,如果带上我们要明白其含义。

int  main(int argc, char *argv[]);   //argv代表一个指针数组,argc代表指针数组中的元素个数

  1#include<stdio.h>
  2 #include<unistd.h>
  3 int main(int argc, char *argv[])
  4 {
  5  for(int i = 0; i < argc; i++)
  6  {
  7    printf("argv[%d] -> %s\n",i,argv[i]);
  8  }
  9 }                                                                                                                                                                 

 我们在命令行处输入以下内容结果如下:

 可以看出当在命令行处只输入路径+可执行程序名时,argc = 1,argv[0] -> 路径+程序名;当输入两个参数,数组就会有两个元素,0号下标仍指向程序名。

为什么要有命令行参数呢?本质就是交给我们程序的不同选项,用来定制不同的程序功能。命令行会携带很多的选项。

这样说可能还会有些不明白,看看下图。我们常用的ls指令也是如此,携带不同的后缀就显示出不同形式的信息。

谁做到的呢?--bash

由上图可以看出父进程的数据可以默认被子进程看到并访问。

验证代码如下:

  1 #include<stdio.h>
  2 #include<unistd.h>
  3 
  4 int g_val = 100;
  5 
  6 int main()
  7 {
  8   printf("I am father process,pid:%d,ppid:%d,g_val:%d\n",getpid(),getppid(),g_val);
  9   sleep(5);
 10   int id = fork();
 11   if(id == 0)
 12   {
 13     while(1)
 14     {
 15       printf("I am child process,pid:%d,ppid:%d,g_val:%d\n",getpid(),getppid(),g_val);
 16       sleep(1);
 17     }
 18   }
 19   else
 20   {
 21    while(1)
 22    {
 23     printf("I am father process,pid:%d,ppid:%d,g_val:%d\n",getpid(),getppid(),g_val);
 24     sleep(1);
 25    }
 26  }
 27 }

 为什么两次执行后父进程的ppid一直保持不变,我们使用指令查看一下ppid为11515的进程是谁。结果查出是bash。命令中启动的程序,都会变成进程,并且其实是bash的子进程。

二、环境变量

为什么我们执行自己的程序时需要加上路径呢?可不可以像系统指令一样不加路径使用呢?

        在Linux中,存在着一些全局的设置,这些设置表明,告诉命令行解释器,应该去哪些路径下去寻找可执行程序。                      

PATH就是一个环境变量,$PATH用来打印环境变量的内容。

系统中的很多配置,在我们登录Linux系统时就已经被加载到了bash进程中。bash在执行命令的时候,需要先找到命令,因为未来要加载。

上图可以看出PATH中并没有test.exe所在路径,所以并不能直接执行它。

要想像执行命令一样执行程序,只能修改配置文件。

//通过以下指令打开文件后将要添加的路径加入其中

vim .bash_profile

vim .bashrc

vim /etc/bashrc

env指令 --> 显示所有的环境变量

        1.HOME  --> 用户的家目录

        2.PWD  --> 用户当前所处路径

        3.SHELL --> 打印出bash进程的路径和程序名

        4.HISTSIZE --> Linux会默认记录用户输入的最新的1000条历史命令

echo $XXX --> 打印环境变量内容

export name=value --> 导入环境变量

        导入时不加export时,变量仍会被导入,但是使用env并不会显示出该变量,而使用echo $XXX却能查找的,将这种称为本地变量。

unset name --> 取消环境变量

理解:

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

我们获得环境变量的方式有两种

//方式一
 int main(int argc,int *argv[], char *env[])
 {
    extern char **environ;
    for(int i = 0; environ[i];i++)
    {
      printf("env[%d]->%s\n",i,environ[i]);
    }
 }
//方式二
 int main(int argc,int *argv[], char *env[])
 {
   extern char **environ;
   for(int i = 0; environ[i];i++)
   {
     printf("env[%d]->%s\n",i,environ[i]);
   }
 }

但是得到的结果都是env[0]->XDG_SESSION_ID=26753 、env[1]->HOSTNAME=iZ0jlec5mvndmhan316glmZ 这种形式,对我们来说看起来不方便,每次还要自己分解字符串。还有一种方式,通过函数getenv(环境变量名)来获得环境变量的内容,用例如下。

 int main()
 {
     char *path = getenv("PATH");
     if(path == NULL)
         return 1;
     printf("path:%s\n",path);
 }

        我们可以通过export指令来导入环境变量。export是指令,在执行的时候应该创建子进程,又因为进程具有独立性,父进程是不能看见子进程的定义的变量及对数据的修改的,那么这样的话echo $HELLO指令执行后应该什么也找不到的,即不应该被bash看到所导的变量。那为什么会有下面的结果呢?因为指令export和echo都被称为内建命令,由bash亲自执行。除内建命令外其余80%的命令都是通过bash创建子进程执行的。

验证:

将环境变量PATH置为空后,ls、touch等指令不能执行,export、echo指令仍可执行。

当我们在命令行直接建立一个变量时,使用echo指令可以查看其内容,为什么使用env指令却查找不到呢?

虽然这个变量不能查出来,但并不代表它真的没有,它仍在bash进程内部存在,只不过并没有被当做环境变量来看待。通过下面的代码发现也不能找到该变量。

 int main()
 {
    char *path = getenv("HELLO");                                                 
    if(path == NULL)
      return 1;
    printf("path:%s\n",path);
 }

我们知道子进程会继承父进程的环境变量表,运行结果表明HELLO不在环境变量表里。此时HELLO是本地变量

将HELLO导入为环境变量

export HELLO

再执行代码,便可查找出了。

本地变量(只能被内建命令找到)只在本bash内有效,无法被子进程继承下去。只有将本地变量导成环境变量才可能被获取。

  • 22
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

今天学习了吗•

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

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

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

打赏作者

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

抵扣说明:

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

余额充值