Linux之环境变量(内容由浅入深,层层递进)
一、概念介绍(来源:比特就业课)
-
环境变量一般是指在操作系统中用来指定操作系统运行环境的一些参数
-
环境变量通常具有某些特殊用途,并且在系统中通常具有全局特性
二、现象引入与解答
1.为什么像ls这样的系统指令可以直接执行,而我们生成的可执行程序不能像这样运行呢,而应该写成路径+文件名的形式呢?
解答:因为系统指令ls会自动默认的去环境变量PATH中去查找,若能够在众多路径下找到,便能够成功执行,否则报以上错误。可以见一见:
可以看到ls是可以找到的,PATH环境变量的值中路径用:分隔,查找时从左到右依次查找。(解决方法最后)
2.main函数有没有参数呢?
解答:其实是有的,那么参数有哪些呢?这里我把他们全部展示出来,见如下:
3.这些参数是由哪个传递的呢?
解答:其实是该程序的父进程Shell(bash)传递的。
4.前连个参数具体代表什么呢?
解答:我们在命令行中输入的任何指令,比如“ ls -a -l”都是以字符串(整体)的形式给到bash进程进行分割处理,得到“ls”, “-a”,“-l”,然后用一个char* argv[]把分割的字符串给管理起来,这样一张表就叫做“命令行参数表”,“ls”就是我们要执行的程序,“-a,“-l”是选项,用于实现该程序的不同的子功能,其中argc就是分割后字符串的个数,argv用NULL结尾,表示参数传递完毕。为了能够更形象,可见下图:
5.最后一个参数代表什么呢?
解答:首先我们需要明确,要执行一个程序,必须先找到它,其次系统中的环境变量(PATH)是用来帮助系统找到要执行的目标二进制文件,是系统中搜索指令的默认搜索路径!环境变量的形式为:名称=内容(这种类似键值的形式)。如何理解环境变量呢?需要从存储的角度,即bash会形成一张环境变量表,该环境变量表同命令行参数表一样也是char* argv[]类型的,那么环境变量,最开始是从哪里来的呢?答案是从系统的相关配置文件中来的,见图如下:
举例说明:比如执行ls命令就回到PATH中去找,又比如cd ~指令,就会找到HOME这个环境变量。
结论:bash会有两张表,一张叫命令行参数表argv,另一张叫环境变量表env。(重要)
推导:如果Linux系统有10个用户登录,就存在10个bash,那么每个bash都会有从配置文件中来的环境变量,形成一张环境变量表
三、获取环境变量的方法
指令方式:
①export 环境变量(需要注意的是,export属于内建命令,不会创建新进程,export会被bash直接执行,调用相关的系统调用)
②env(直接运行该指令便可以看到所有的环境变量,如果做了第一个操作,那么也可在看到)
③echo $环境变量(直接显示该环境变量的内容)
④unset 环境变量 (直接删除该环境变量)
代码方式:
①方法一:父进程(bash)的环境变量可以被子进程继承
②方法二:使用getenv()
③方法三:extern char** environ,使用全局指针(需声明)
四、理解环境变量的特性
①环境变量具有全局特性
②bash会记录两套变量:环境变量、本地变量(本地变量不会被子进程继承,只会在bash内部被使用)
五、认识更多的环境变量
常见的:
HOSTNAME:主机名
TREM:终端类型(如xterm、xterm-256color、screen、vt100等)
SHELL:命令行解释器的类型
USER:用户名
PATH:默认搜索路径
PWD:记录当前用户所在的路径
HOME:家目录
LOGNAME:登录用户名
OLDPWD:记录旧的路径(举例:cd -)
HISTSIZE:定义Shell历史命令巨鹿的最大条数
LANG:定义系统的默认语言和字符编码
六、解决方法
①方法一:直接将程序移动到PATH环境变量中的任何一个路径下
②方法二:直接将程序所在的路径追加到PATH环境变量值之后(例:export PATH=$PATH:想要添加的路径)
③方法三:修改配置文件.bash_profile(适用于登录Shell)/.bashrc(适用于交互式Shell)
echo 'export MY_VAR="value"' >> ~/.bash_profile
source ~/.bash_profile
echo 'export MY_VAR="value"' >> ~/.bashrc # 追加到文件末尾
source ~/.bashrc # 立即生效(无需重启)
方法四:使用export直接设置
export MY_VAR="value" # 设置环境变量
echo $MY_VAR # 检查是否生效
//特点:
//仅在当前 Shell 及其子进程(如新开的终端、脚本)中有效。
//重新连接 SSH 后会消失(因为新会话会重新加载 Shell 配置文件)。
七、相关代码
#include<stdio.h>
#include<stdlib.h>
//main有参数吗?有
#include<unistd.h>
int main(int argc,char* argv[],char* env[]){(void)argv;(void)argc;(void)env;extern char** environ;for(int i=0;environ[i];i++){printf("env[%d]=>%s\n",i,environ[i]);}return 0;
}//int main(int argc,char* argv[],char* env[]){
// (void)argv;
// (void)argc;
// (void)env;
// char* path=getenv("PATH");
// printf("PATH=%s\n",path);
// return 0;
//}//int main(int argc,char* argv[],char* env[]){
// (void)argv;
// (void)argc;
// for(int i=0;env[i];i++){
// printf("env[%d]=>%s\n",i,env[i]);
// }
// return 0;
//}//int main(int argc,char* argv[]){
// for(int i=0;i<argc;i++){
// printf("argv[%d]:%s\n",i,argv[i]);
// }
// return 0;
//}