环境:centos7.6,腾讯云服务器 Linux文章都放在了专栏:【 Linux 】欢迎支持订阅 🌹undefined 相关文章推荐: 【Linux】冯.诺依曼体系结构与操作系统 【Linux】进程理解与学习Ⅰ-进程概念 浅谈Linux下的shell--BASH 【Linux】进程理解与学习Ⅱ-进程状态
在学习之前我们要先搞清楚这个概念,就比如说【y=ab+cd】,在这里,等号左边的就是变量,等号右边的则是变量的内容。变量是bash中非常重要的一个存在,在Linux下变量又分为自定义变量以及环境变量。本次章节讲对此做相关理解。
由我们用户自己来直接定义的变量叫做自定义变量(也可以说时本地变量),上面说过等号左边为变量名,右边为变量的内容,我们便可以根据此特点直接定义一个自定义变量。(我们可以通过echo $变量名来查看该变量的内容)如下:
这里我们在定义变量时,有以下几点需要注意:
我们可以使用unset 变量名的指令来取消该变量的定义,如下:
什么是环境变量呢?相信学习Java、Python的老铁们应该会有一个更深刻的认识,因为在写Java之前,相信大家都会安装jdk,并在Windows下配置相关环境变量,配置完成后才能正常编写。如下图所示,这就是Windows下的环境变量:
Windows下的环境变量
说了这么多,还是没说到环境变量究竟是什么?
实际上环境变量一般是指在操作系统中用来指定操作系统运行环境的一些参数。Linux中同样也存在着相关的环境变量。
这里举个例子:我们在编写C/C++代码的时候,在链接的时候,从来不知道我们的所链接的动态静态库在哪里,但是照样可以链接成功,生成可执行程序,原因就是有相关环境变量帮助编译器进行查找。
不仅如此,环境变量通常还具有全局属性,并且一般都是以大写字符来表示。而由各个环境变量在一起构成的集合,一般我们称之为环境变量表,环境变量表可以被子进程继承。(先说结论)
以上所讲都只是一些概念层次的知识,接下来我们讲几个比较常见的环境变量,以便于大家能更好的理解。
我们在写完代码并编译,生成一个可执行程序时,为什么运行的时候要加./?实际上运行一个程序的前提是找到该程序。只有找到它,才能运行它,而./的含义大家应该知道,表示的是当前所在路径。
那么为什么我们输入ls的时候,则不用指定ls所在的具体位置呢?这里就涉及到了PATH,我们可以输入指令echo $PATH来查看PATH这个环境变量的内容,并且输入指令which ls:来查看ls所在的路径。就会发现原来ls所在的路径在PATH里。
而PATH的作用则是指定搜索路径,所以我们输入指令ls的时候,会自动去PATH中搜寻路径,发现PATH中有ls所在的路径,因此我们直接输入ls的时候,不用我们手动指定路径,也可以运行ls。但是如果我们不手动指定我们自己写的程序mytest,则会报错,因为环境变量中并没有mytest所在的路径。
那么我们可不可以像Windows一样,配置我们的环境变量呢?答案是可以的。
我们可以使用指令export PATH=PATH:自定义路径(上面在变量的定义中讲了 的作用就是保留PATH的原有内容,PATH中:是分隔符,所以我们这样来定义就相当于给PATH追加了一个内容。)如下:
我们可以直接输入指令env,便可以查看当前bash下的所有环境变量
实际上,我们的环境变量表是一个指针数组结构,而环境变量会被子进程所继承。我们便可以利用此特点来使用我们自己写的函数打印出环境变量。其实我们在写main函数时,实际上main函数有三个参数:int argc、char* argv[]、char*envp[]。而char*envp[]这个指针数组中的内容,就指向我们所说的环境变量表的内容的起始地址。如下:
我们可以通过代码来验证一下:
#include<stdio.h>
int main(int argc,char* argv[],char* envp[])
{
for(int i=0; envp[i]; ++i)
{
printf("envp[%d]:%s\n",i,envp[i]);
}
}
运行结果
#include<stdio.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]);
}
}
四、通过系统调用函数getenv()来获取我们想要的环境变量
我们可以通过系统调用函数getenv()来获取我们想要查看的环境变量,如下:
#include<stdio.h>
#include<stdlib.h>//头文件
int main()
{
printf("%s",getenv("PATH"));
}
先来看以下代码:
我们从中可以得出结论:
上面讲的有些零碎,这里做一个总结:
环境变量的相关配置文件部分内容
在上面我们讲到了main函数中的三个参数,为int argc、char* argv[]、char* envp[]。其中我们了解了第三个参数,也就是用来接收环境变量表的指针数组。那么前面两个呢?
当然,我们也可以写以下代码来验证:
#include<stdio.h>
//argc:传入的元素个数
//argv:用来存放元素内容起始位置的指针数组
int main(int argc,char* argv[])
{
printf("传入的元素个数为:%d\n",argc);
printf("传入的有效元素内容为:\n");
for(int i=0; i<argc; i++)
{
printf("argv[%d]:%s\n",i,argv[i]);
}
return 0;
}
运行结果
为什么我们输入ls -a 与ls -l 的功能不同,原理也在于此,即对命令行参数进行相关指令设置。我们也可以实现一个简单的任务:如下:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
void Utest(char* st)
{
printf("%s:-[a | b]\n",st);
}
int main(int argc,char* argv[])
{
//身份验证,只有qidunyan用户可以进行操作
if(strcmp(getenv("USER"),"qidunyan"))
{
printf("%s用户非法\n",getenv("USER"));
return 0;
}
//指令输入错误
if(argc!=2)
{
printf("指令错误,请重新输入:\n");
Utest(argv[0]);
}
// ./mytest -a
if(strcmp(argv[1],"-a")==0)
{
printf("执行A任务\n");
//...
sleep(3);
printf("执行完毕\n");
}
else if(strcmp(argv[1],"-b") == 0)
{
printf("执行B任务\n");
//...
sleep(3);
printf("执行完毕\n");
}
else
{
printf("指令错误,重新输入:\n");
Utest(argv[0]);
}
return 0;
}
运行结果
end.
生活原本沉闷,但跑起来就会有风!🌹