文章目录
前言:在Linux下,我们在命令行上执行一个可执行文件,一般用的是
./
+文件名。但是运行指令或命令前面却不需要加上
./
。指令和命令本质上也是可执行文件,为什么它们之前不用加
./
呢?还有一点,命令或者指令后面加上选项可以实现不同的功能,这又是怎么实现的?
1.环境变量的基本概念
- 环境变量(environment variables)一般是指在操作系统中用来指定操作系统运行环境的一些参数
- 如:我们在编写C/C++代码的时候,在链接的时候,从来不知道我们的所链接的动态静态库在哪里,但
是照样可以链接成功,生成可执行程序,原因就是有相关环境变量帮助编译器进行查找。- 环境变量通常具有某些特殊用途,还有在系统当中通常具有全局特性
1.1 解密如何输入程序名,即可执行程序
./
是为了帮助系统对应的程序在哪里,也不一定是./
,绝对路径和相对路径都可以。
比如:打印hollow world。
1 #include<stdio.h>
2 int main()
3 {
4 printf("hollow world\n");
5 return 0;
6 }
7
路径为/root/ly ,程序名为qq。
使用绝对路径找到可执行程序:
/root/ly/qq
使用相对路径找到可执行程序:
./qq
运行结果:
那么执行一个可执行文件,必须要找到它的路径(位置),那么指令,命令它们的路径是如何找到的呢?
环境变量,输入一个指令后,系统会自动查找环境变量中的PATH,它存的就是所有指令的路径,按个遍历PATH的存的路径,找到了那么指令运行成功,找不到那么会报命令找不到。
验证:
(1)查看环境变量PATH
(2)查看指令的路径是否在PATH中存着
用which指令查看指令的路径:
which 指令
ls和clear都在 /usr/bin 路径下,观察上面的PATH,不难发现确实有这个路径。
(3)自己配置环境变量PATH。
- 如果想要自己的程序和指令一样,不输入路径就能执行,很简单。只需要将程序的路径添加到PATH里就可以了。
- 我这里强烈不推荐将路径拷贝到 /usr/bin或者其他的指令路径下,虽然拷贝进去确实能和指令一样实现,但是会污染指令池,以后的某一天,可能输入一个指令,莫名其妙的打印了一句hollow world。毫无疑问,是指令池放了不该放的东西。
- 所以我的做法是,将程序路径加入到PATH里。
运行以下指令:
export PATH=$PATH:程序路径
- 上面的程序路径是/root/ly,我们来将其添加到PATH中。
- 已经将程序路径添加进PATH,现在我们来执行qq程序,发现就像指令一样,直接输入程序名即可。
1.2 环境变量的基本内容
PATH : 指定命令的搜索路径
HOME : 指定用户的主工作目录(即用户登陆到Linux系统中时,默认的目录)
SHELL : 当前Shell,它的值通常是/bin/bash。
环境变量的内容很多,上文只讲了PATH,常见的还有HOME和SHELL。
分别查看一下:
(1)HOME
这是用户登录到Linux的默认工作目录,很明显我是用root登录的。
切换到普通用户,查看HOME
(2)SHELL
一般情况下,当前shell都在/bin/bash下
1.3 查看所有的环境变量
(1)执行以下指令即可,env只能查看环境变量。
env
打开后,会看到所有的环境变量,这里我就不展示了。
(2)set指令
set
set可以查看shell和环境变量。
2.环境变量的组织方式
2.1 本地变量导入环境变量
在命令行上可以直接创建变量,但创建的是本地变量,重启之后,本地变量就会消失。
假如:我创建了一个My_val的变量。
My_val=111111
直接在命令行上定义
请问用env可以查看到My_val吗?
答案是不能。
请问用set可以查看到My_val吗?
答案是可以。
将本地变量导入环境变量,这样本地变量就不会重启后消失了。
export 变量名
导入后,可以用env查看了。
当然我们也可以删除环境变量。
unset 变量名
可以发现,删除成功。
2.2 程序如何实现带选项的功能
每个程序里都有main函数,main函数有三个参数。
int main(int argc, char *argv[], char *env[])
(1) argc
这个参数存的是选项的个数
1 #include<stdio.h>
2 int main(int argc, char *argv[], char *env[])
3 {
4 printf("%d\n",argc);
5 return 0;
6 }
直接运行不带选项,argc为1.
我带了一个-j 选项,发现argc为2、
再带一个-f 选项,发现argc为3
(2)char* argv[]
,这个参数存的是具体的选项
#include<stdio.h>
2 int main(int argc, char *argv[], char *env[])
3 {
4 for(int i=0;i<argc;i++)
5 {
6 printf("%s\n",argv[i]);
7 }
8 return 0;
9 }
这是一个打印选项的,小程序。
需要注意:第一个选项是运行的程序名。
据此我们就可以实现,根据选项来完成不同的功能。
假如:我要求输入一个选项,输入选项-j
打印“hollow -j” ,输入-f
打印“hollow -f”。
#include<stdio.h>
#include<string.h>
int main(int argc, char *argv[], char *env[])
{
if(strcmp(argv[1],"-j")==0)
printf("hollow -j\n");
else if(strcmp(argv[1],"-f")==0)
printf("hollow -f\n");
else
printf("nonono\n");
return 0;
}
运行结果:
(3)第三个参数是环境变量表,每个main函数都会导进去环境变量表
environ是个二级指针,指向了这个env[],env中又存指向环境变量指针。
2.3 用代码获得环境变量
(1)用main函数的第三个参数char *env[]
。
env[]最后指向null,具体可见上图。
#include<stdio.h>
int main(int argc, char *argv[], char *env[])
{
int i=0;
for(;env[i];i++)
{
printf("%s\n",env[i]);
}
return 0;
}
(2)利用第三方变量environ
#include<stdio.h>
int main(int argc, char *argv[], char *env[])
{
extern char **environ;
int i=0;
for(;environ[i];i++)
{
printf("%s\n",environ[i]);
}
return 0;
}
(3)调用库函数getenv()
上两种方法都不太银杏,打印出来的和用指令env没有区别。调用库函数getenv(),就可以具体的查看某个环境变量。
#include<stdio.h>
#include<stdlib.h>
int main(int argc, char *argv[], char *env[])
{
printf("%s\n",getenv("HOME"));
printf("%s\n",getenv("SHELL"));
printf("%s\n",getenv("PATH"));
return 0;
}
3.环境变量具有全局性的理解
环境变量会被子进程继承。假如我在父进程中创建了环境变量,子进程就会继承此环境变量。于是环境变量就有了全局性。简单理解就行了。
结尾语:以上就是环境变量的所有内容,在Linux环境下验证的。