“这里是云端源想IT,帮你轻松学IT”
嗨~ 今天的你过得还好吗?
风可以吹起一大张白纸
却无法吹走一只蝴蝶
因为生命的力量在于不顺从
- 2023.07.21 -
环境变量(environment variables)一般是指在操作系统中用来指定操作系统运行环境的一些参数,如:临时文件夹位置和系统文件夹位置等。
每次在安装开发环境的时候,比如上期我们安装JDK工具时,经常需要配置环境变量。对于很多新手来说,环境变量往往是难以理解和上手的,给实际开发带来一定的困难。今天小编就来给大家讲一讲环境变量到底是什么。
一、基本概念
环境变量是在操作系统中一个具有特定名字的对象,它包含了一个或者多个应用程序所将使用到的信息。例如Windows和DOS操作系统中的path环境变量,当要求系统运行一个程序而没有告诉它程序所在的完整路径时,系统除了在当前目录下面寻找此程序外,还应到path中指定的路径去找。用户通过设置环境变量,来更好的运行进程。
当我们在使用Linux系统时,使用的命令实质上都是一些可执行程序。但是你有没有发现一个问题?
我们在执行这条命令时并不知道这个可执行程序在哪,并且执行这条命令时不需要带路径。可是我们自己编写的代码生成的可执行程序运行时,需要带上路径。这就是环境变量在起作用。
- 环境变量一般指在操作系统中用来指定操作系统运行环境的一些参数。
- 环境变量通常具有某些特殊的用途,在系统中通常具有全局特性。
说白了,环境变量是在系统中具有一定全局性质的变量,通常是为了满足某些系统的需求。指明操作系统的某些重要目录在哪。
先来看一下linux下的环境变量:
我们发现,环境变量里存在的是一些变量,后面的内容是一些路径和值。
常见的环境变量
- PATH:指定可执行程序的搜索路径
- HOME:指定用户的主工作目录(即登录到Linux系统中时,默认工作目录)
- SHEEL:当前的命令行解释器,它的值在centos中通常时/bin/bash
二、命令
1、查看环境变量的方法
命令"echo $NAME",NAME环境变量名。
2、其它相关指令
- export:设置一个新的环境变量
- env:显示所有环境变量
- unset:清除环境变量
- set:显示本地定义的shell变量和环境变量
3、测试PATH
创建一个源文件test.c
#include<stdio.h>
int main(){
printf("hello test1\n");
return 0;
}
环境变量是如何实现调用系统命令不需要加路径,而我们编写的可执行程序需要加路径?
我们编写的生成的程序一般和PATH环境变量有关,系统提供的那些路径保存在了PATH环境变量的某个路径下了。当执行一条命令时,系统会在PATH环境变量的路径下找,找到这个可执行程序,就执行这条命令,没找到就会报错。
环境变量不只PATH一个环境变量,说明它还有其它很多功能。
如何实现我们写的程序可以像命令一样不加路径执行?
1)将可执行程序的绝对路径加到PATH路径下。(linux特有,重新启动加的路径就没了)
2)将可执行程序加到PATH的某个路径的目录下。(不推荐,污染系统下的命令)
这些系统命令是如何到环境变量中的?
安装软件时,会把对应软件的可执行程序拷贝到PATH的某个路径下,PATH只是环境变量之一,系统还有很多环境变量又来解决不同场景。
修改环境变量
命令范式:export 环境变量名称=$[环境变量名称]:[新添加的环境变量的内容]
先查看一下PATH这个环境变量目前的状态,我们一会儿将对它进行修改:
两种方式修改一下PATH环境变量:
我们是在命令行当中直接进行修改的,这种修改有一个很值得注意的特点,就是它是临时生效的,只在当前终端生效。
在命令行当中修改:如果是新增某个环境变量,可以不要$ [环境变量名称],直接export 环境变量名称=[新添加的环境变量的内容];如果是修改原来的环境变量,必须加上$[环境变量名称],否则之前的环境变量的值就找不到了。
在文件当中修改:修改完后不会立即生效,需要配合source [环境变量文件名称],永久生效。如果是新增某个环境变量,在文件末尾直接添加:export 环境变量名称=[新添加的环境变量的内容];如果是修改原来的环境变量,在原来的后面添加“[新添加的环境变量的内容]”。
在文件当中修改是永久生效的,因为每次登录都会加载环境变量文件。
我们一般执行自己的可执行程序的时候,都是需要在前面加上./的,为什么要这样子呢?因为我们要告诉bash,要执行的可执行程序到底在哪里,./就是告诉bash,执行的可执行程序在当前路径下。那我们可不可以不加./呢?当然可以,只是需要我们将可执行程序的路径配置到PATH环境变量当中。
三、环境变量的组织方式
环境变量实际是一个字符指针数组,每一个字符指针指向一个环境字符串。这个指针数组以NULL结尾。
四、通过代码获取环境变量
这里说明一下,其实我们的main函数有三个参数,由两部分组成。第一部分是命令行参数:命令行参数的个数、命令行参数的值,也就是前两个参数;第二部分是环境变量的值,也就是第三个参数。
ps补充:可执行程序后面加命令行参数
//显示命令行参数
#include<stdio.h>
int main(int argc,char *argv[],char *env[]){
for(int i=0;i<argc;i++){
printf("argv[%d]: %s\n",i,argv[i]);
}
return 0;
}
命令行参数实际也是一个字符指针数组,不以空结尾。指向一个个命令行参数的字符串。如上:
所以那些ls -a指令是可以通过判断来实现不同操作:
#include<stdio.h>
#include<string.h>
int main(int argc,char *argv[],char *env[]){
char *s=argv[1];//必须传一个命令行参数
if(strcmp(s,"-a")==0){
printf("hello -a\n");
}
else{
printf("hello other\n");
}
return 0;
}
注意:即使main函数没有参数传入,这三个参数仍然存在,值系统获取调用的。
通过main函数的第三个参数获得:
#include<stdio.h>
#include<string.h>
int main(int argc,char *argv[],char *env[]){
for(int i=0;env[i];i++){
printf("%s\n",env[i]);
}
return 0;
}
和命令env显示的一样。
通过第三方变量获取
libc(c库函数)中定义全局变量environ指向环境变量表,envron没有包含在任何头文件中,所以要extern证明。
#include<stdio.h>
#include<string.h>
int main(int argc,char *argv[],char *env[]){
extern char **environ;
for(int i=0;environ[i];i++){
printf("%s\n",environ[i]);
}
return 0;
}
仍然可以得到相同结果。
五、通过系统调用获取环境变量
getenv(存在头文件stdlib.h中),访问特定环境变量,查找失败返回0。
#include<stdio.h>
#include<stdlib.h>
int main(){
printf("%s\n",getenv("PATH"));
return 0;
}
六、环境变量通常具有全局属性
环境变量通常具有全局属性,可以被子进程继承下去。
#include<stdio.h>
#include<stdlib.h>
int main(){
char *env=getenv("MYVAL");
if(env){
printf("%s\n",env);
}
return 0;
}
直接运行,
当我在bash进程加入MYVAL环境变量。
原因:在bash加入的环境变量,它的子进程test1也可以访问,具有全局性是这样体现的。
七、windows系统中的环境变量
这个在咱们上期安装jdk就有讲过配置环境变量,所以你是不是还有点印象呢?
不管在windows里还是liunx里都少不了环境变量的配置,一键Copy是解决不了问题的,还可能会出现各种各样的问题,如果我们搞清楚原理,就会方便许多。
总之Java基础的学习不是单纯的复制教程就ok,搞懂原理才能让我们的学习事半功倍哦!
我们下期再见!
END
文案编辑|云端学长
文案配图|云端学长
内容由:云端源想分享