linux之《环境变量》

问题引入

在linux系统下,为什么我们编译好的文件要./+文件名才能运行,而指令,如ls,pwd...却可以直接运行?

想要解决这个问题,我们就需要学习一下环境变量。

一,执行路径

我们知道,在linux系统下,一切皆文件,无论是系统指令还是我们自己写的文件,本质上都是由程序编写成的文件。他们有的可以执行,有的不可以执行,而我们上面提到的系统指令和文件,都是可执行文件,在linux系统下,执行文件直接输入路径名即可,例如:系统指令的调用,执行可执行文件在这里插入图片描述
如图,为什么上述文件的执行方式有些不同呢?
其实,对于文件的执行,我们是有绝对路径和相对路径来执行的。

1. 相对执行路径

分析上图,执行process文件时,使用的是相对执行路径,.表示当前目录,/process表示文件名。这也验证了执行文件用路径名即可

相对执行路径:不完整的写完路径名,常用形式:./文件名

2. 绝对执行路径

讲完相对执行路径,我们来看看绝对执行路径。
绝对执行路径
如图,我们可以使用which指令来找寻ls指令的文件路径,然后输入完整的路径名。同样可以得到相同的结果。

绝对执行路径:完整的文件路径名。

二,环境变量——PATH

1. PATH

通过上述的例子,想必我们对文件的执行有一个进一步的了解,此时让我们回到开头的问题。为什么系统指令既没有输入绝对路径,又没有输入相对路径,但他仍然能够执行能?

这是因为linux系统中环境变量PATH的存在。

让我们来看看环境变量PATH是什么。
输入echo $PATH,查看PATH的内容。PATH的内容
可以看到,有很多个路径名,每个路径以:来区分。

/usr/local/bin:
/usr/bin:
/usr/local/sbin:
/usr/sbin:
/home/wk/.local/bin:
/home/wk/bin

原理:
这是系统针对每个用户提前准备好系统指令的完整路径名。我们在使用指令的时候,系统中的shell会自动对这个环境变量PATH的路径内容进行遍历,寻找正确且相符的系统指令的完整路径名,然后自动执行。

通过上述对原理的理解,现在算是知道为什么,我们编译好的可执行文件需要加上./才能执行,而系统指令却不用吧。说到底就是系统指令有环境变量PATH的支撑,可以找到路径来执行,而我们的可执行文件如果不加./就会找不到路径从而无法执行。

那如果我们也想像系统指令那样直接输入文件名就可以执行,是不是在PATH中配好正确路径就好了呢?答案是肯定的。

2.自定义配置PATH

我们利用下面这条指令export PATH=$PATH:文件路径将文件路径添加到PATH中
在这里插入图片描述
然后查看echo $PATH环境变量,发现多了一个路径
在这里插入图片描述
这样我们就可以像系统指令一样,直接通过文件名执行文件。
在这里插入图片描述

除此之外,我们还有另一种方式一样可以达到相同效果。那就是把文件拷贝到PATH中存在的任一路径这也就是linux下软件的安装大致实现原理

三,环境变量相关指令

ehco	显示某个环境变量的值
export	设置某个环境变量(本质是将本地变量添加到环境变量表里)
env		显示所以环境变量
set		显示本地定义的shell变量和环境变量
unset	清除环境变量

这里前两个都介绍过了,我们来看看第三个env
在这里插入图片描述
上面列出了我们所有的环境变量,我圈了几个常见的,大家可以重点认识一下。

四,用代码获取环境变量

1. main函数的形参

这里先提一个问题,我们所知的main函数能带参数吗?如果能带参数,那么有多少个呢?

main()函数能带参数,且最多能有三个
void main(int argc, char* argv[], char* envp[])

这里解释一下argc,argv,envp三个形参代表的意思

argc	表示 传入参数的个数
argv[]	表示 把传入参数的值存放在argv[]里
envp[]	表示 接受系统中环境变量表,无需传参,系统自己会传入

我们通过下面代码来实现一下,这几个形参的用法:

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

main函数形参使用
可以看到,argc表示形参个数,argv[]表示存储的形参值。
我们继续学习,修改一下代码

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

看看这回打印出来的是什么
envp[]
很好,和上面用echo $PATH出来的环境变量一模一样,充分说明envp[]就是接收到了系统传递过来的所有环境变量。

2. 利用environ获取

environ

每个程序都会收到一张环境表,环境表是一个字符指针数组,每个指针指向一个以’\0’结尾的环境字符串

下面我们使用另一种方式来获取到环境变量

int main(int argc, char* argv[], char* envp[])
{
    int i = 0;
    extern char** environ;
    for(i = 0; environ[i]; ++i)
    {
        printf("environ[%d] -> %s\n", i, environ[i]);
    }
    return 0;
}

在这里插入图片描述

3. 利用函数获取

利用函数获取环境变量,我们要先认识一下需要使用到的函数。
函数getenv("环境变量名");#include<stdlib.h>里面,当我们想要得到某个环境变量的值时,可以使用这个函数,输入环境变量的关键字,这样就可以取得了。下面是代码实例:

int main(int argc, char* argv[], char* envp[])
{
	char *str = getenv("PATH");
	printf("getenv = %s\n",str);
    return 0;
}

在这里插入图片描述

实用案例

a. 写一个自己的pwd指令
  1. 编写代码
int main(int argc, char* argv[], char* envp[])
{
	char *mypwd = getenv("PWD");
	printf("%s\n",mypwd);
    return 0;
}
  1. 配置PATH
    在这里插入图片描述
  2. 运行结果 在这里插入图片描述
b. 限定用户使用
int main(int argc, char* argv[], char* envp[])
{
	char* user = getenv("USER");
	if(strcmp(user, "wk") == 0)
		printf("用户所有者\n");
	else 
		printf("%s非法用户,无法访问...\n",user);
	return 0;
}

在这里插入图片描述
在这里插入图片描述

五,环境变量的本质

  • 环境变量本质就是一张内存级的表,这张表由用户在登录系统的时候,给特定用户形成属于自己的环境变量表。
  • 每个环境变量都有自己的用途,有的是进行路径查找,有的进行身份认证,有的进行动态库查找,有的是来确认当前路径…
  • 那么环境变量对应的数据是从哪里来的呢,从系统的相关配置文件(.bash_profile,.bashrc) 而来

六,环境变量的继承性

环境变量具有继承性
如:父进程的环境变量可以被子进程访问。

代码证明

  1. 先引入一个环境变量export username="wk"
  2. 然后执行代码程序
int main(int argc, char* argv[], char* envp[])
{
    char *myenv = getenv("username");
    printf("%s\n",myenv);
	return 0;
}

在这里插入图片描述

  1. 分析:process程序是bash程序的子程序。他里面能够获得在bash上面定义的环境变量,所以环境变量是有继承性的,具有全局属性。

提升问题

在这里插入图片描述
如图,var是bash里面的本地变量,不具有全局性,echo是指令,既然是指令,那就是文件,执行指令就是运行文件,需要开辟进程来运行,即echo也是bash的一个子进程,我们说环境变量才有全局性,而var不是环境变量却能被子进程echo读取到值呢?

预知原理如何,大家先自行百度(关键词:内建命令)

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值