Linux——环境变量与本地变量

2023-12-24 16:35:48

环境变量与本地变量


本章思维导图:
在这里插入图片描述注:本章思维导图对应的 .xmind.png文件都已同步导入至 资源

1. 环境变量

在谈环境变量之前,我们先来看看命令行参数这一概念

1.1 命令行参数

一般来说,我们的主函数main都是不带参的:

int main(){}

但是相信不少小伙伴也见过这种带参形式的main函数:

int main(int argc, char* argv[]){}
  • argv是一个指向多个字符串的指针数组,最后一个元素为NULL
  • argc则表示指针数组argv有效元素的个数

我们可以来看一个例子:

#include <stdio.h>

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

  return 0;
}

形成可执行文件mybin后,我们执行命令:./mybin -l

output:

./mybin
-l

可以看到,这个程序将我们在命令行输入的命令./mybin -l,利用空格将其分为了两个字符串./mybin-l,并将其存放在了数组argv中,对于./mybin-l这种执行命令用到的参数,我们就叫作命令行参数,而对其进行存储的数组argv,就称为命令行参数列表

可能有小伙伴会问:命令行参数有什么用?

我们不妨来回忆一下以前学过的关于Linux命令的知识:

Linux的各种命令也是一个个的可执行程序,我们可以利用各种选项来实现不同的功能

例如,命令ls用来查看当前目录的内容。如果加上选项-l,就可以知道目录所属文件或目录的详细信息,加上选项-a就可以查看隐藏文件,其不同的选项都对应着不同的功能。

和上面的命令行参数做对比,我们惊奇的发现**ls的选项-a-l等不也是一个个命令行参数吗**?正是因为有了命令行参数,我们才可以让ls等命令根据不同的选项来执行不同的功能。

我们可以利用命令行参数来写一个能实现加、减、乘的简单计算器:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main(int argc, char* argv[])
{
  if (argc != 4)
  {
    printf("Usage:\n\t%s -[add|sub|mul] x y\n\n", argv[0]);
    return 1;
  }

  int x = atoi(argv[2]);
  int y = atoi(argv[3]);

  if (strcmp(argv[1], "-add") == 0)
    printf("%d\n", x + y);
  else if (strcmp(argv[1], "-sub") == 0)
    printf("%d\n", x * y);
  else if (strcmp(argv[1], "-mul") == 0)
    printf("%d\n", x - y);
  else 
    printf("unknown!\n");

  return 0;
}

效果如下:

1.2 环境变量PATH

尽管上面的命令已经和ls的执行方法很像,但细心的小伙伴还是能发现不同点:

虽然ls这个命令也是可执行程序,但是为什么我们运行使用的时候不需要./来运行,而是可以直接使用它的名字来运行呢?

  • 我们应该清楚,要执行一个可执行程序,首先就要知道这个程序具体在那个位置

  • 因此,./filename实际上是一个相对路径,表示当前目录的filename文件,用来告诉系统这个可执行程序在哪个地方

  • 既然可以用相对路径,绝对路径也同样可以执行一个可执行程序
    在这里插入图片描述

  • 因此,我们可以做出假设:既然执行ls命令不用输入它的路径,那么操作系统肯定已经提前知道了它的路径

上面的假设显然是成立的,像ls这种bash命令的路径都已经存放在了一个名为PATH的环境变量中

我们可以用命令:echo $PATH来进行查看:

在这里插入图片描述

同样,我么可以将自己写的可执行程序也加入PATH变量中来达到相同的效果

命令:

PATH=程序所在路径:$PATH

注意:

  • :$PATH一定不能省略将程序所在路径添加到PATH就变为了将PATH改为程序所在路径。这明显是不同的
  • 如果这么做了,bash命令很可能就不能使用了;但也不要过于紧张,重新启动一次bash环境变量就会和原来一样了

演示:

在这里插入图片描述

1.3 环境变量的概念和相关操作

概念:

  • 顾名思义,环境变量也是变量,是系统内置的具有特殊用途的变量
  • 环境变量不是一个,而是一堆。除了上面提到的PATH,还有USERHOME等环境变量

1.3.1 用命令查看环境变量

查看所有环境变量:

env

在这里插入图片描述

查看单个环境变量:

echo $name

在这里插入图片描述

1.3.2 用命令添加环境变量:

命令:

export name=

1.3.2 用命令删除环境变量

命令:

unset name

在这里插入图片描述

1.3.3 利用代码查看环境变量

方法一

利用main函数的形参int main(int argc, char* argv[], char* env[])

  • env也是一个字符指针数组,存储着所有的环境变量
  • env也是以NULL结尾的

例如:

#include <stdio.h>

int main(int argc, char* argv[], char* env[])
{
  //作用相当于命令"env",打印出所有的环境变量
  for (int i = 0; env[i]; i++)
    printf("%s\n", env[i]);
  return 0;
}

方法二

利用函数getenv()获取指定的环境变量

头文件:<stdlib.h>

函数原型:char *getenv(const char *name);

例如:

#include <stdio.h>
#include <stdlib.h>

int main()
{
  const char* ret = getenv("PATH");
  printf("%s\n", ret);

  return 0;
}

output:

/opt/rh/devtoolset7/root/usr/bin:/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/LWJ/.local/bin:/home/LWJ/bin

方法三

利用宏environ

需要包含头文件:<unistd.h>

如果要用,首先要对这个变量进行引用:extern char** environ

在这里插入图片描述

例如:

#include <stdio.h>
#include <unistd.h>

int main()
{
  extern char** environ;

  //和命令"env"一样,打印出所有的环境变量
  for (int i = 0; environ[i]; i++)
    printf("%s\n", environ[i]);

  return 0;
}

1.3.4 利用代码修改或添加环境变量

在代码中,我们也可以利用函数putenv()来修改或者添加环境变量:

头文件:<stdlib.h>

函数原型:int putenv(char *string);

注意:string的内容应该类似于name=value这种形式,以符合规范

例如:

#include <stdio.h>
#include <stdlib.h>

int main()
{
  putenv("TEST=6666666");
  printf("%s\n", getenv("TEST"));
    
  return 0;
}

output:

6666666

1.4 环境变量的特点

环境变量是可以被继承

  • 子进程以父进程为模板创建,因此子进程的环境变量也应该和父进程一样。例如上面的的main函数的参数中的环境变量就是继承的父进程bash
  • 又例如上面的函数putenv(),它会改变本进程和其所属子进程的环境变量但是不会影响它的父进程的环境变量

环境变量是内存级的

  • 作为一个变量,每一次关闭bash环境变量都会被作为一种资源被释放
  • 环境变量都存储在磁盘的文件中:每个用户都有一个.bash_profile隐藏文件用来记录环境变量
  • 每一次重新打开bash,系统都会从这个文件中读取环境变量,并写入内存
    在这里插入图片描述

我么可以直接向这个文件中写入需要的环境变量,这样当我们打开bash时,系统就会自动生成这个变量了。

2. 本地变量

在这里插入图片描述

2.1 本地变量的相关操作

设置本地变量

命令:

name=value

例如:

查看本地变量

命令:

set

  • 该命令用于查看所有的变量,包括环境变量和本地变量
  • env不能用于查看本地变量

演示:

在这里插入图片描述

2.2 本地变量的特性

  • 本地变量只能在bash内部使用
  • 本地变量不能被继承

本篇完

文章来源:https://blog.csdn.net/l315225/article/details/135182323
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。