Linux环境变量

命令行参数

  1 #include
  2 
  3 int main(int argc,char*argv[])
  4 {
  5   int i = 0;                                                                                                                          
  6   for(;i

Linux环境变量_第1张图片

argc:从命令行接收到的参数个数

argv数组:每个成员都是从命令行读取的一个参数 

命令行参数,可以支持各种指令级别的命令行选项的设置,以往学习的指令与选项的关系正如上图

下面简单写一个计算器,来感受以下命令行参数吧 :

程序一定有4个命令行参数,第一个是程序名,第二个是加减乘除的字符串表示,第三个,第四个皆为数字

mytest.c:

  1 #include
  2 #include
  3 #include
  4 int main(int argc,char*argv[])
  5 {
  6   if(argc!=4)
  7   {
  8     printf("Use error\nUsage: %s op[-add|sub|mul|div] d1 d2\n", argv[0]);
  9     return 1;
 10   }
 11 
 12   int x = atoi(argv[2]);
 13   int y = atoi(argv[3]);
 14   int ret = 0;
 15 
 16   if(strcmp(argv[1],"-add")==0)
 17   {
 18     ret = x+y;
 19     printf("%d+%d=%d\n", x, y, ret);
 20   }
 21   else if(strcmp(argv[1],"-sub")==0)
 22   {
 23     ret = x-y;
 24     printf("%d-%d=%d\n", x, y, ret);
 25   }
 26   else if(strcmp(argv[1],"-mul")==0)
 27   {                                                                                                                                   
 28     ret = x*y;
 29     printf("%d*%d=%d\n", x, y, ret);
 30   }
 31   else if(strcmp(argv[1],"-div")==0)
 32   {
 33     if(y==0)
 34     {
 35       printf("%d/%d=error! div zero\n", x, y);
 36     }
 37     else 
 38     {
 39       printf("%d/%d=%d\n", x, y, x/y);
 40     }
 41   }
 42   else
 43   {
 44     printf("Use error, you should use right command line\nUsage: %s op[-add|sub|mul|div] d1 d2\n", argv[0]);
 45   }
 46 
 47    return 0;
 48 }

 

 Linux环境变量_第2张图片

 

基本概念

环境变量(environment variables)一般是指在操作系统中用来指定操作系统运行环境的一些参数

我们编写c/c++代码时,要链接时,并不知道静态库,动态库在哪里,但是链接一样是成功的,然后生成可执行程序,原因是因为有相关环境变量帮助编译器进行查找 

环境变量通常具有某些特殊用途,在系统当中通常具有全局特性

常见环境变量

PATH : 指定命令的搜索路径 (要执行一个命令,必须先要找到对应的可执行程序,此环境变量记录了系统可执行程序的默认搜索路径)

HOME : 指定用户的主工作目录(即用户登陆到Linux系统中时,默认的目录)

SHELL : 当前 Shell, 它的值通常是 /bin/bash

查看环境变量方法

echo $NAME (NAME:环境变量名称)

PATH

我们自己创建的源文件如myproc.c 编译链接所形成的可执行程序myproc为什么一定要是./myproc 才能运行起来,需要带上路径,但是如ls pwd 这些指令却不用加上./,无需带上路径,直接就可以运行?

这是因为如ls pwd等这样的指令所在路径早已加载在环境变量PATH中,但是我们自己写的程序,并没有添加路径到PATH中,所以需要我们指明路径

将我们的程序所在路径加入环境变量PATH当中, export PATH=$PATH:程序所在路径

我们自己写的程序想要不加./直接就可以运行,就要将当前程序所在路径添加到PATH环境变量里:PATH=$PATH:当前程序所在路径

Linux环境变量_第3张图片

 

Linux环境变量_第4张图片 将我们自己写的程序的路径添加到PATH环境变量中,就可以不用加./直接运行了

若是想要删除我们添加进去的路径,可以直接PATH=原有路径(直接覆盖)

实际上,以上对于PATH的修改,只是内存中的修改,即使你将PATH="",清空所有默认的搜索路径,只要我们关闭xshell重新登录,一切就恢复了

故而:默认更改环境变量,只限于本次登录,重新登录,环境变量自动被恢复 

若是我们不想要将当前程序所在路径添加到PATH中,也可以将当前程序拷贝到系统的指定搜索路径下,这样照样可以不加./直接运行起来,此过程也即安装程序

sudo cp mytest /usr/bin/

其中会涉及到权限问题,加上sudo即可

删除:此过程即卸载程序

sudo rm /usr/bin/mytest

HOME

Linux环境变量_第5张图片

为什么普通用户,默认所处家目录为:/home/xxx 

而root用户,默认所处家目录为:/root?

这是因为登录的时候

1 :输入用户名与密码

2 :认证

3:形成环境变量(不止一个,如PATH,PWD,HOME)

     根据用户名,初始化HOME=/root    HOME=/home/xxx

4 cd $HOME

要查看目前所有的环境变量:env

系统中会存在大量的环境变量,每一个环境变量都有它自己的特殊用途,用来完成特定的系统功能

Linux环境变量_第6张图片

获取环境变量

 使用getenv

Linux环境变量_第7张图片

printf("PATH: %s\n",getenv("PATH"));

Linux环境变量_第8张图片

下面的代码示例为--只允许root用户执行程序,普通用户不可以

  1 #include
  2 #include
  3 #include
  4 int main()
  5 {
  6   char*who = getenv("USER");
  7   if(strcmp(who,"root")!=0)
  8   {
  9     printf("%s,是一个非法用户\n", who);
 10     return 1;                                                                                                                         
 11   }                                                                                       
 12                                                                                           
 13    printf("my command!\n");                                                               
 14    printf("my command!\n");                                                               
 15   return 0;                                                                               
 16 } 

Linux环境变量_第9张图片 Linux环境变量_第10张图片

和环境变量相关的命令 

1. echo: 显示某个环境变量值
2. export: 设置一个新的环境变量
3. env: 显示所有环境变量
4. unset: 清除环境变量与本地变量
5. set: 显示本地定义的 shell 变量和环境变量

环境变量的组织方式

系统启动我们的程序时,可以选择给我们的进程(main)提供两张表:

1 命令行参数表 2 环境变量表

Linux环境变量_第11张图片

main函数的参数除却上方已提及的两个参数:argc argv数组外,还包括了env数组 

    1 #include 
    2 #include 
    3 #include                                                                                                                   
    4 int main(int argc,char*argv[],char*env[])
    5 {
    6   int i = 0;
    7   for(;env[i];i++)
    8   {
    9     printf("pid: %d, env[%d]: %s\n", getpid(), i, env[i]);
   10   }
        return 0;
   11 }

Linux环境变量_第12张图片

命令行启动的进程都是shell/bash的子进程,子进程的命令行参数与环境变量,都是父进程bash给它传递的

我们每次对环境变量进行修改,都是直接更改的bash进程内部的环境变量信息,每一次重新登录,都会给我们形成新的bash解释器,同时,新的bash解释器自动从where?(即.bash_profile)读取形成自己的环境变量表信息 

父进程的环境变量表信息从哪里来?

首先我们要了解:环境变量信息是以脚本配置文件的形式存在的

Linux环境变量_第13张图片

Linux环境变量_第14张图片 每一次登录的时候,bash进程都会读取

配置文件中的内容,为我们的bash进程形成一张环境变量表信息 

除了系统给定的环境变量外,我们也可以在bash进程的环境变量表中添加一些自己的环境变量

方法: export 环境变量

取消环境变量:unset 环境变量

 注意:直接设定环境变量,可以通过echo命令查看此环境变量,但是此环境变量被称作shell的本地变量,没有导入到shell/bash的环境变量表中,当执行:env | grep 你的环境变量时,则找不到,只有export 环境变量 才能真正导入bash进程的环境变量表中

 但是以上用export命令来添加我们设定的自定义环境变量,终归还是在内存中进行的,所以一旦我们关闭xshell,重新登录,那么我们用export添加进去的环境变量将不复存在

想要每次重新登陆,我们自定义的环境变量还存在,就要借助上文我们提过的脚本配置文件:

Linux环境变量_第15张图片

 

系统环境变量具有全局属性,父进程的环境变量会被所有子进程继承,代代相传(bash进程开始向后传递,父进程传子进程,子进程传孙子进程(子进程fork创建))

通过代码如何获取环境变量

1 getenv  2 main函数传参(命令行第三个参数) 3 extern char** environ

1 getenv

#include 
#include 
int main()
{
  printf("%s\n", getenv("PATH"));
  return 0;
}

命令行第三个参数

#include 
int main(int argc, char *argv[], char *env[])
{
  int i = 0;
  for(; env[i]; i++)
  {
     printf("%s\n", env[i]);
  }
  return 0;
}

3  environ 

全局变量environ指向环境变量表,environ没有包含在任何头文件中,所以在使用时 要用extern声明

Linux环境变量_第16张图片

Linux环境变量_第17张图片 

    4 int main()
    5 {
    6   extern char**environ;//全局变量environ指向环境变量表,environ没有包含在任何头文件中,所以在使用时 要用extern声明
    7   int i = 0;
    8   for(;environ[i];i++)
    9   {
   10     printf("%d: %s\n", i, environ[i]);
   11   }
   12   return 0;                                                                                                                         
   13 }

Linux环境变量_第18张图片

本地变量vs环境变量

 本地变量:只在bash进程内部有效,不会被子进程继承下去

  诸如 a=10  b=c 这种左侧名字=右侧内容的都是本地变量

Linux环境变量_第19张图片

 环境变量:通过让所有子进程继承的方式,实现自身的全局性

    3 #include
    4 #include                                                                                                                  
    5 int main()                           
    6 {                                           
    7   printf("MYENV_2: %s\n",getenv("MYENV_2"));
    8   return 0;                          
    9 }  

Linux环境变量_第20张图片

Linux环境变量_第21张图片

Linux环境变量_第22张图片 echo运行起来也是一个进程,即bash的子进程,为那么它能够获取本地变量,而上图演示的子进程无法获取本地变量?

原因:linux命令分类

1 常规命令:shell fork创建出子进程去执行

2 内建命令:shell命令行的一个函数,当然可以直接读取shell内部定义的本地变量

echo是内建命令,export也是内建命令

你可能感兴趣的:(Linux,linux)