【Linux】深度解剖环境变量

> 作者简介:დ旧言~,目前大二,现在学习Java,c,c++,Python等

> 座右铭:松树千年终是朽,槿花一日自为荣。

> 目标:熟悉并掌握Linux的环境变量。

> 毒鸡汤:不为模糊不清的未来过分担忧,只为清清楚楚的现在奋发图强。

> 望小伙伴们点赞👍收藏✨加关注哟💕💕

🌟前言

咱们先抛出问题,不知道大家还记得我们使用java时需要安装环境变量,这里的环境变量就是我们今天所谈的环境变量,其实我们使用APP都需要配置环境变量,有些是不需要配置的,因为这些软件自己会配置环境变量,像我们使用的java编辑器就需要配置环境变量。基于这些情况我们来谈谈Linux下的环境变量。

⭐主体

我们从以下学习【Linux】深度解剖环境变量🥰🥰。

🌙浅谈基本概念

环境变量(environment variables)一般是指在操作系统中用来指定操作系统运行环境的一些参数,是操作系统为了满足不同的应用场景预先在系统内预先设置的一大批全局变量。

例如,我们编写的C/C++代码,在各个目标文件进行链接的时候,从来不知道我们所链接的动静态库在哪里,但是照样可以链接成功,生成可执行程序,原因就是有相关环境变量帮助编译器进行查找。选取:<Linux>环境变量_linux 环境变量-CSDN博客

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

要执行一个程序,那就需要先找到这个程序,如何去找是个问题🤔🤔,这里提供两个方案:

  • 第一种方法 (把文件拷贝到系统的默认路径下)
  1. 缺陷:指令没有经过测试,把代码安装在系统里,会污染系统指令池。
  2. 这种方法是能够找到,因为系统有环境变量🫢🫢:

比如在编写代码的时候,在链接的时候,我们不知道所链接的动态静态库在哪里,但是可以链接成功,生成可执行程序,原因就是有相关环境变量帮助编译器进行查找。

使用PATH查看:

  • 第二种方法 (把当前的路径添加到环境变量里面)

指令如下:

cpp 复制代码
export PATH=$PATH:加上路径

windows下的环境变量的查看,比如之前配置的jdk的环境变量:

🌙常见环境变量

  • PATH : 指定命令的搜索路径
  • HOME : 指定用户的主工作目录(即用户登陆到Linux系统中时,默认的目录)
  • LOGNAME:当前登录的用户名
  • HOSTNAME:主机名
  • SHELL : 当前Shell,它的值通常是/bin/bash

指令查看:

🌙获取环境变量

除去指令去获取环境变量,那我们就可以通过getenv获取环境变量🤗🤗。

1.创建文件mycmd.c和makefile

mycmd.c代码:

cpp 复制代码
#include <stdio.h>
#include <stdlib.h>

#define USER "USER"

int main()
{
	char *who = getenv(USER);
	printf("user:%s\n",who);
	return 0;
}

makefile代码:

cpp 复制代码
mycmd:mycmd.c
	gcc -o mycmd mycmd.c

.PHONY:clean

clean:
	rm -f mycmd.c

2.运行结果

3.总结

USER环境变量最大的意义就是可以标识当前使用Linux用户


我们可以也可以使用strcmp直接去判断是否为root用户

mycmd.c代码:

cpp 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define USER "USER"

int main()
{
	char *who = getenv(USER);
	if(strcmp(who,"root") == 0)
	{
		printf("user:%s\n",who);
	}
	else
	{
		printf("权限不足!\n");
	}

	return 0;
}

运行结果1:

运行结果2:

总结:

执行指令的时候,通过访问任何文件,文件上面有对应的拥有者和所属组,会根据环境变量user去进行对应,对身份进行认证,环境变量会在不同的应用场景被使用。

🌙设置环境变量

  • echo: 显示某个环境变量值
  • export: 设置一个新的环境变量
  • env: 显示所有环境变量
  • unset: 清除环境变量
  • set: 显示本地定义的shell变量和环境变量

echo:

env查环境变量并没有结果,要想找到结果,我们可以用export

export:

mycmd.c代码:

cpp 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define USER "USER"
#define MY_ENV "myval"

int main()
{
	char *who = getenv(USER);
	if(NULL == myval)
	{
		printf("%s not found\n",MY_ENV);
		return 1;
	}
	printf("%s = %s\n",MY_ENV,myval);

	return 0;
}

这时候用到export,把本地变量导成环境变量。

set:

set可以显示本地定义的shell变量和环境变量

unset:

清除取消我们的环境变量


抛出问题:我们的系统为什么知道我们当前的路径在哪里:如一开始学的ls,加上文件名就可以了,不需要加上路径,那ls为什么知道当前的路径是在哪里?PWD

环境变量在bash中维护当前所处的路径,路径发生变化时,shell会调整环境变量的值,而运行ls是在创建子进程,而环境变量会被子进程继承,所以ls拿到了当前路径,所以ls不需要带上路径

🌙命令行参数

抛出问题:main函数可以带参数吗?最多可以带多少?

  • main函数也是存在参数的(最多有三个)
  • main函数也会被系统调用。

下面我们先来看看这三个参数:

cpp 复制代码
int main(int argc, char* argv[], char* envp[])
{
    return 0;
}
  • int argc:数组里的元素个数
  • char argv :指针数组*
  • char*envp\[\] :环境变量

这个我们先演示前两个参数:

myproc.c代码:

cpp 复制代码
#include <stdio.h>
#include <unistd.h>

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

	return 0;
}

运行结果:

总结:

我们给main函数传递的argc,char* argv 是命令行参数,传递的内容是命令行中输入的程序名和选项,并且结尾以NULL束!!!


演示第三个参数:

char*envp\[\] 就是环境变量。也是一个字符指针数组,前面的argv是指向的命令行参数字符串,而这里envp指向的是一个一个环境变量字符串,最后也是以NULL结尾。结构图如下:

代码如下:

cpp 复制代码
#include <stdio.h>
#include <unistd.h>

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

运行结果:

  • 总结:一个进程是会被传入环境变量参数的。
  • 补充:一个函数在声明和定义的时候都没有参数,那么我实际传参的时候可以传参。

🌙代码获取环境变量

  • 命令行第三个参数(char*env\[\])获取环境变量

代码如下:

cpp 复制代码
#include <stdio.h>
#include <unistd.h>

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

运行结果:

  • 通过第三方变量environ获取 (extern char**environ)

代码如下:

cpp 复制代码
#include <stdio.h>
#include <unistd.h>

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

运行结果:

🌟结束语

今天内容就到这里啦,时间过得很快,大家沉下心来好好学习,会有一定的收获的,大家多多坚持,嘻嘻,成功路上注定孤独,因为坚持的人不多。那请大家举起自己的小手给博主一键三连,有你们的支持是我最大的动力💞💞💞,回见。

相关推荐
AlfredZhao7 小时前
vi 删除指定范围的行,不用再反复按 dd
linux·vi
用户97183563346613 小时前
银河麒麟 KY10 申威(SW64) 安装 nginx-1.16.1-2.p01.ky10.sw_64.rpm 详细步骤
linux
猪脚踏浪14 小时前
linux 拷贝文件或目录到指定的位置
linux
摇滚侠1 天前
Linux CentOS7 rpm 安装 MySQL 5.7
linux·运维·mysql
bush41 天前
嵌入式linux学习记录十四、术语
linux·嵌入式
载数而行5201 天前
Linux 11 动态监控指令top
linux
不会C语言的男孩1 天前
Linux 系统编程 · 第 8 章:进程基础
linux·c语言
古城小栈1 天前
Unix 与 Linux 异同小叙
linux·服务器·unix
凡人叶枫1 天前
Effective C++ 条款42:了解 typename 的双重意义
java·linux·服务器·c++
2601_961875241 天前
决战申论100题2026|最新|范文
linux·容器·centos·debian·ssh·fabric·vagrant