echo需要加上$符号才能打印出来环境变量
char *getenv(const char *name);
在代码中获取一个环境变量
bash怎么知道指令在哪里?
bash内部维护了PATH环境变量(指令的搜索路径)
which 是如何找到指令路径的?
对PATH进行搜索
PATH=/home/ljh //将PATH修改成只有/home/ljh,大部分指令无法使用
$PATH是内存级的环境变量,修改后重新登陆即可恢复
有没有权限得先知道你是谁,对权限理解进一步加深,不同用户根据环境变量不同受限制不同
环境变量是系统提供的一组name=value形式的变量,不同的环境变量有不同的用户,通常具有全局属性
int main(int argc,char* argv[])//指针数组,存的是char*,字符串
{}
c = count 个数
v = value
数组里有多少个元素
我们之前学的main函数从来没有参数,那这两个参数是什么呢?管他是啥我先打印出来看看
int i = 0;
for(; i<argc ;i++)
{
printf("argv[%d]->%s\n",i,argv[i]);
}
结果
打印出来这不是命令行参数吗?
为什么要这么干?
为指令、工具,软件等提供命令行选项的支持!!
例如ls -l 的实现
// if(argc != 2)
43 // {
44 // printf("Usage: %s -[a|b|c|d]\n",argv[0]);
45 // return 0;
46 // }
47 //
48 // if(strcmp(argv[1],"--help") == 0)
49 // {
50 // printf("Usage: %s -[a|b|c|d]\n",argv[0]);
51
52 // }else if(strcmp(argv[1],"-a") == 0)
53 // {
54 // printf("功能1\n");
55 // }else if(strcmp(argv[1],"-b") == 0)
56 // {
57 // printf("功能2\n");
58 // }else if(strcmp(argv[1],"-c") == 0)
59 // {
60 // printf("功能3\n");
61 // }else if(strcmp(argv[1],"-d") == 0)
62 // {
63 // printf("功能4\n");
64 // }else
65 // {
66 // printf("default\n");
67 // }
main函数被调用
你以为你写的./mycmd -a -b -c,其实输入的是字符串"./mycmd -a -b -c",然后以空格为分隔符打散放入的argv[ ]数组中,有几个字符串argc就是几,然后传入给main函数。
并且argv数组 最后一个位置是NULL
所以还可以不用argc遍历,直接利用最后一个是NULL来遍历
int i = 0;
for(; argv[i] ;i++)
{
printf("argv[%d]->%s\n",i,argv[i]); //命令行参数表
}
那这个命令行参数和环境变量有什么关系呢?
还真有点关系,因为main函数还有第三个变量env
int main(int argc,char* argv[],char* env[])
{
}
char* env[](环境变量表)和命令行参数表结构一摸一样
那就打印出来看看
int i = 0;
for(; env[i] ;i++)
{
printf("env[%d]->%s\n",i,env[i]); //环境变量表
}
结果
打印出来了环境变量
不要以为一个进程启动就是把程序加载到内存,而是当我们自己的程序变成进程再启动时,一定有人调用main函数,给main函数把这两张表传入
环境变量概念中的具有全局属性是什么意思?
我们所运行的进程,都是子进程,bash本身在启动的时候,会从操作系统的配置文件中读取环境变量信息,子进程会继承父进程交给我的环境变量!
思路:自己增加一个环境变量,子进程如果会继承就会被看到
MY_VAL=123456//本地变量
export MY_VAL=123456//导出环境变量
同样打印环境变量表
int i = 0;
for(; env[i] ;i++)
{
printf("env[%d]->%s\n",i,env[i]); //环境变量表
}
bash里面有自己定义的MY_VALUE,自己的mycmd子进程也查到了,验证完成。
子进程要修改环境变量不能影响父进程的环境变量,要发生写时拷贝
以前main函数从来没传入env,那么子进程是如何继承的?
第1种直接传入
第2种继承方式,到地址空间再谈
什么时候我的进程需要本地变量呢?
比如ps1搞出了命令行的格式 user hostname w工作目录 $
所以我们需要一些只在bash内部的符号,不要被子进程继承下去,所以有了本地变量的概念
问题:echo要不要创建子进程,如果创建,那么它无法继承bash的本地变量,但是这里却打印出来了,为什么呢?
王婆(bash)说媒 如果这个媒特别难说,那么就要创建子进程,但是如果这个媒很有把握,那王婆还是愿意自己上的
所以echo是内建命令
同样cd 也是内建命令 - 系统调用chdir()
sleep(15);
18 printf("change begin\n"); //目录切换,内建命令cd模拟
19 if(argc == 2)
20 {
21 chdir(argv[1]);
22 }
23
24 sleep(15);
25 printf("change end\n");
我们可以模拟cd命令,利用系统调用chdir()更改自己的工作目录,而不是创建子进程
如果我们今天自己写的mycmd是写的bash本身的话,他不给你创建子进程同样利用chdir改变工作目录cwd
注意
./mycmd / 更改本身的cwd
而pwd创建子进程继承了bash,bash又没改,所以还是原来的工作目录,所以只能ls /proc去看cwd
不同的环境变量用途不同,所以需要具体问题具体分析
进程 环境变量 进程地址空间 三位一体 进程的概念再也不是问题
通过第三方变量environ获取
int main(int argc,char* argv[])//指针数组
7 {
8 extern char** environ; //C语言提供的全局变量,形参中不用再传递env环境变量表了
9 int i = 0;
10 for(; environ[i] ;i++) //二级指针 指向char* 环境变量表 ,类似于形参char* env[]数组退化为指针char ** env
11 {
12 printf("%d : %s\n",i,environ[i]);
13 }
return 0;
}