Linux中环境变量的逐步理解

mian函数的参数

假设在Linux中有如下代码:

c 复制代码
#include<stdio.h>
int main(int argc, char *argv[]) {
	printf("argc: %d\n", argc);
	int i = 0;
	for (; i < argc; ++i) {
		printf("argc[%d]->%s\n", i, argv[i]);
	}
	return 0;
}

argv是一个存放字符串的数组、argc是字符串的数量。当执行以下操作:

1)为什么要有参数?

当假设有这样的代码:

命令行的本质应用,是为了实现一个命令,可以根据不同的选项,实现不同的子功能!也是Linux中所有命令选项功能的实现方式!!!

注意:

**1)**命令行参数,至少是1,argc>=1,argv[0]一定会有元素,指的就是程序名;

**2)**选项,是以空格分隔的字符串,一个字符,也是字符串!

3) argc个,argv[argc - 1]是最后一个,argv[argc]等于NULL。(所以for (; i < argc; ++i)这个循环也可以写成for (; argv[i]; ++i)。)

环境变量

1)为什么自己写的程序需要有./main呢?不能像其他命令那样直接用命令名字就能运行?

系统命令一般都存在/usr/bin目录下,命令执行时,一般就会去/usr/bin目录下去找

那么如果我们将自己的创建的命令存到/usr/bin目录下,是不是也可以直接用名字执行呢?

答案肯定的!

在目录下删除了就失效了

2)为什么会去/usr/bin/路径下去找?

Linux中,存在一个系统级的环境变量PATH,内容是以冒号分隔的多串路径。

作用:告诉系统,如果用户执行一个没有指明路径 的的可执行文件,就会依次根据PATH里的地址去查找

所以除了问题(1)中的操作,那样会污染系统命令池,不建议;我们还可以将我们自己的可执行文件的路径,添加到PATH里呀。注意:添加时不要覆盖,要追加

总而言之,PATH是环境变量中的一个,系统中也会有其他的环境变量 ,通过命令env,能显示所有的环境变量:

  • HISTSIZE(history size):系统会记录用户执行的命令,HISTSIZE=1000指的是只会记录最近的1000条命令;
  • OLDPWD:记录上一次所在文件路径,cd -命令会回到上一次所在路径,利用的就是这个OLDPWD环境变量;
  • SSH_TTY:记录的当前终端的编号/dev/pts/1;
  • SHELL:记录当前操作系统外壳的具体体现/bin/bash。

3)环境变量和我们C/C++代码和进程之间的关系?

用代码获取环境变量

main函数的参数可以有三个,除了上面提过的两种,还有一个char* env[],存放字符串的数组:其中存放的是,系统给当前程序提供的环境变量表!本质是把环境变量表传递给进程!

c 复制代码
#include <stdio.h>
int main(int argc, char *argv[], char *env[]) {
	void(argc);	// 防止不用参数时警报
    void(argv);
    int i = 0;
	for(; env[i]; i++) {
	printf("%s\n", env[i]);
	}
return 0;
}

还有其他方式获取环境变量:

c 复制代码
int main() {
	extern char** environ;
	int i = 0;
	for (; environ[i]; ++i) {
		printf("environ[%d]->%s\n", i, environ[i]);
	}
	return 0;
}

当然,我们利用环境变量肯定不是这样全部看完,C语言stdlib.h提供了一个函数char* getenv(const char* name),可以通过传入对应的变量名来获取变量内容。

c 复制代码
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<string.h>
int main() {
	char* whoami = getenv("USER");
	printf("用户:%s\n", whoami);
	if (whoami == NULL) {
		printf("无法执行我,不认识用户\n");
	}
	else if (strcmp(whoami, "root") == 0) {
		printf("root也不能执行!\n");
	}
	else if (strcmp(whoami, "zincsweet") == 0) {
		printf("你是合法用户,可执行!\n");
	}
	else {}
	return 0;
}

切换其他用户测试代码时,需要su - [用户名],要带杠-,将环境变量更新为对应用户的,不然执行此程序还是会显示zincsweet可执行。

环境变量由谁传递?

环境变量默认在**bash内部,据我们所知bash就是一个 进程**,进程在内存 中,所以环境变量表是临时的,内存级。

内存级!内存级!内存级!内存级!内存级!

一些命令 都是bash进程的子进程 ,子进程代码和数据是可以共享 的,所以也就能拿到父进程bash里面的环境变量

总之,环境变量是父进程给的!!!可以延续继承 ,所以环境变量具有全局性!

bash进程的环境变量是从Linux系统配置文件 来的,每次系统运行bash,都会先从系统配置文件中读取信息,将环境变量加载到bash中。

**配置文件是什么?**用户家目录下都有一个.bashrc隐藏文件,他就是配置文件,其中包含许多配置信息

本地变量

本地变量不属于环境变量

  • 无法被子进程继承;
  • 不具备全局性;
  • 只在bash内部可以访问。

但是可以取这个变量打印出来

可以通过命令export [变量名],将本地变量导出到环境变量中:

还可以直接将现成的变量导出到环境变量:

怎么从环境变量表中去掉 呢?要用命令:unset [变量名];

ort 变量名`,将本地变量导出到环境变量中:

外链图片转存中...(img-izVQ3sXk-1779024573187)

还可以直接将现成的变量导出到环境变量:

外链图片转存中...(img-l4EZtryJ-1779024573187)

怎么从环境变量表中去掉 呢?要用命令:unset [变量名];

相关推荐
jaronho12 分钟前
【脚本】 【Linux】启动所有网卡
linux·运维·服务器
草莓熊Lotso13 分钟前
【C++ 基于微服务的即时通讯系统】基建三件套:gflags + gtest + spdlog 源码编译安装与实战入门
linux·网络·数据库·c++·微服务·log4j
H.莓飛24 分钟前
【C++】类与对象(末):static、友元与拷贝优化
linux·开发语言·c++·visual studio
程序员-Benothing9 小时前
Vim编辑器从入门到精通:模式、快捷键、配置、插件
linux·运维·服务器
‎ദ്ദിᵔ.˛.ᵔ₎9 小时前
linux 进程信号 (上)
linux·服务器
15Moonlight9 小时前
Linux网络(02):Socket 编程 UDP
linux·网络·udp
wuminyu10 小时前
ForkJoinPool窃取线程在扫描其他WorkQueue时的随机采样算法与Phase线程挂起唤醒机制解析
java·linux·c语言·jvm·c++
liulilittle10 小时前
Linux 下 select 测试函数
linux·服务器·网络·数据库·c++·select·c
DongQiShanRen11 小时前
玄龙(上):TICK 主循环——意识心跳怎么跳
linux·jvm·数据库·人工智能·数据挖掘·rust
小此方11 小时前
Linux网络(二十一):深入理解 TCP 异常处理:网线断开、Keepalive 保活机制与 Linux 内核传输层协议源码剖析
linux·网络·tcp/ip