环境变量
当我们要执行一个程序的时候,先要找到这个程序。
./mytest----->./---->当前路径----->找到程序。
ls就没有指定路径,可以直接运行。
明明ls和mytest都是可执行程序,这是为什么呢?
其实ls也需要找,但是系统帮我们默认去指定路径下去找。
解决方法1:(不推荐)
powershell
sudo cp mytest /usr/bin/
拷贝到系统安装的指令的路径中。(污染指令池)
powershell
sudo rm /usr/bin/mytest
删除
解决方法2
把mytest放到系统默认去搜索的路径中(PATH)
powershell
echo $PATH //查看路径信息
路径以冒号相隔开。
powershell
export PATH=新路径
虽然执行mytest,不用在加路径了,但是这里有个问题。
ll和ls却找不到。这里退出重新登录xshell就解决了
所以正确添加路径如下
powershell
export PATH=$PATH:/home/wdl/linux/test_9_9
1.自己写的程序在运行时,无法直接执行是因为自己程序所在的路径,并没有在系统默认搜索路径下,默认搜索路径(PATH)
2.系统当中的指令能被找到,是因为环境变量,PATH里默认带了系统对应的路径搜索。
which 搜索命令,就是去PATH路径下搜索。
环境变量的配置
系统默认帮我们配置好环境变量。
shell在登录时,系统默认让当前shell进程把.bash_profile中内容执行一次(把对应的环境变量导到当前shell中)。
1.基本概念
环境变量(environment variables)一般是指在操作系统中用来指定操作系统运行环境的一些参数
如:我们在编写C/C++代码的时候,在链接的时候,从来不知道我们的所链接的动态静态库在哪里,但是照样可以链接成功,生成可执行程序,原因就是有相关环境变量帮助编译器进行查找。
环境变量通常具有某些特殊用途,还有在系统当中通常具有全局特性。
操作系统为了满足不同的应用场景而预先在系统内设置的一大批全局变量。
2.查看环境变量的方法
powershell
echo $NAME
powershell
echo $HOME //查看用户工作目录
echo $HOSTNAME //主机名
echo $LOGNAME //当前登录用户
echo $HISTSIZE //查看记住历史命令个数
history //查看历史命令
history | wc -l //查看记录历史命令个数
powershell
env //查看系统内所有环境变量
3.获取环境变量
当我们是普通用户和超级用户,查看对应的工作目录是不一样的。
我们查看环境变量,对比一下
是因为USER不一样,结果才不一样。USER环境变量最大的意义,可以标识当前使用linux用户。
除了可以用echo $HOME 读取USER。我们也可以使用函数来获得环境变量。
3.1代码获得环境变量三种方法
3.1.1getenv()函数
c
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#define USER "USER"
int main()
{
char* user=getenv(USER);
if(user)
{
printf("%s\n",user);
}
else
{
printf("%s no found\n",user);
}
return 0;
}
在命令行也能定义一个变量
使用getenv看看能不能得到这个变量。
c
int main()
{
char* a=getenv("a");
if(a)
{
printf("%s\n",a);
}
else
{
printf("%s no found\n",a);
}
return 0;
}
getenv得不到这个变量。
我们使用env去查环境变量,发现a不再环境变量里面。
其实在命令行定义的变量是本地变量
set显示本地变量和环境变量
如果想让getenv得到这个变量,需要本地变量变成环境变量
环境变量其实就是一个个字符串。
这样我们就可以把本地变量变成环境变量了。
总结:
bash是一个系统进程,mytest也是一个进程,不过是bash的子进程。其实我们的环境变量是定义给bash的,具有全局属性。具有全局属性的原因,是因为环境变量会被子进程继承下去,为什么要继承呢?主要是为了不同的应用场景。
本地变量只会在当前进程(bash内)有效
并且环境变量是在bash内维护的,
两次pwd不同,是因为环境变量在bash内维护,pwd也是子进程,环境变量可以被子进程继承。
如果我们再次使用env,就可以在环境变量中发现a了。
和环境变量相关的命令
1. echo: 显示某个环境变量值
2. export: 设置一个新的环境变量
3. env: 显示所有环境变量
4. unset: 清除环境变量
5. set: 显示本地定义的shell变量和环境变量
3.1.2命令行参数
c
//argv是一个指针数组,里面存放的是char类型,
//今天我们认为里面存放的是字符串
int main(int argc,char* argv[])
{
return 0;
}
这样形式的main函数,大家肯定都见过。
我们看看传的是什么。
c
int main(int argc,char* argv[])
{
for(int i=0;i<argc;++i)
{
printf("argv[%d]----->%s\n",i,argv[i]);
}
return 0;
}
命令行中输入的内容不断变多时,我们数组的内容也在不断变多。
./mytest -a -d -l 与 ls -a -l 其实是一样的。第一个是程序,后面是选项。
命令行参数本质上是把程序和选项,传给我们的argv数组。
那么这么做的意义是什么呢?
c
int main(int argc,char* argv[])
{
if(argc != 2)
{
printf("Usage: \n\t%s [-a/-b/-c/-ab/-bc/-ac/-abc]\n", argv[0]);
return 1;
}
if(strcmp("-a", argv[1]) == 0)
{
printf("功能a\n");
}
if(strcmp("-b", argv[1]) == 0)
{
printf("功能b\n");
}
if(strcmp("-c", argv[1]) == 0)
{
printf("功能c\n");
}
if(strcmp("-ab", argv[1]) == 0)
{
printf("功能ab\n");
}
if(strcmp("-bc", argv[1]) == 0)
{
printf("功能bc\n");
}
return 0; }
~
命令行参数最大意义,让同一个程序,根据选项不一样,执行不一样的功能。
c
int main(int argc,char* argv[],char* env[])
还有一种这样的形式。把环境变量参数带上。
c
int main(int argc,char* argv[],char* env[])
{
for(int i=0;env[i];++i)
{
printf("env[i]:%s\n",i,env[i]);
}
return 0;
./mytest是子进程,我们可以认为环境变量通过命令行参数传给子进程。
其实main函数也可以不带参数获得上述环境变量
3.1.3environ指针
我们可以通过environ二级指针来获得环境变量
c
int main()
{
extern char** environ;
for(int i=0;environ[i];++i)
{
printf("%d : %s \n",i,environ[i]);
}
return 0;
3.2总结或许环境变量的方式
上面内容总结了三种获得环境变量的方式。
1.getenv()
2.char* env[]
3 extern char* environ
getenv()是最推荐的