基本概念
环境变量
(environment variables)
一般是指在操作系统中用来指定操作系统运行环境的一些参数
如:我们在编写
C/C++
代码的时候,在链接的时候,从来不知道我们的所链接的动态静态库在哪里,但是照样可以链接成功,生成可执行程序,原因就是有相关环境变量帮助编译器进行查找。
环境变量通常具有某些特殊用途,还有在系统当中通常具有全局特性
常见环境变量
PATH :
指定命令的搜索路径
HOME :
指定用户的主工作目录
(
即用户登陆到
Linux
系统中时
,
默认的目录
)
SHELL :
当前
Shell,
它的值通常是
/bin/bash
。
查看环境变量方法
echo $NAME
//NAME:
你的环境变量名称
测试
PATH
1.
创建
hello.c文件
#include <stdio.h>
int main()
{
printf("hello world!\n");
return 0;
}
2.
对比
./hello
执行和之间
hello
执行
3.
为什么有些指令可以直接执行,不需要带路径,而我们的二进制程序需要带路径才能执行?
4.
将我们的程序所在路径加入环境变量
PATH
当中
,
export PATH=$PATH:hello
程序所在路径
5.
对比测试
6.
还有什么方法可以不用带路径,直接就可以运行呢?
测试
HOME
1.
用
root
和普通用户,分别执行
echo $HOME
,
对比差异
.
执行
cd ~
;
pwd
,
对应
~
和 HOME 的关系
和环境变量相关的命令
1. echo:
显示某个环境变量值
2. export:
设置一个新的环境变量
3. env:
显示所有环境变量
4. unset:
清除环境变量
5. set:
显示本地定义的
shell
变量和环境变量
通过代码如何获取环境变量
命令行第三个参数
通过第三方变量
environ
获取
环境变量通常是具有全局属性的
环境变量通常具有全局属性,可以被子进程继承下去
直接查看,发现没有结果,说明该环境变量根本不存在
导出环境变量
export MYENV="hello world"
再次运行程序,发现结果有了!说明:环境变量是可以被子进程继承下去的!想想为什么?
实验
如果只进行
MYENV
=
“helloworld”
,
不调用
export
导出,在用我们的程序查看,会有什么结果?为什么?
普通变量
程序地址空间
研究背景
kernel 2.6.32
32
位平台
来段代码感受一下
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int g_val = 0;
int main()
{
pid_t id = fork();
if(id < 0){
perror("fork");
return 0;
}
else if(id == 0){ //child
printf("child[%d]: %d : %p\n", getpid(), g_val, &g_val);
}else{ //parent
printf("parent[%d]: %d : %p\n", getpid(), g_val, &g_val);
}
sleep(1);
return 0;
}
输出
//
与环境相关,观察现象即可
parent[2995]: 0 : 0x80497d8
child[2996]: 0 : 0x80497d8
我们发现,输出出来的变量值和地址是一模一样的,很好理解呀,因为子进程按照父进程为模版,父子并没有对变
量进行进行任何修改。可是将代码稍加改动
:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int g_val = 0;
int main()
{
pid_t id = fork();
if(id < 0){
perror("fork");
return 0;
}
else if(id == 0){ //child,
子进程肯定先跑完,也就是子进程先修改,完成之后,父进程再读取
g_val=100;
printf("child[%d]: %d : %p\n", getpid(), g_val, &g_val);
}else{ //parent
sleep(3);
printf("parent[%d]: %d : %p\n", getpid(), g_val, &g_val);
}
sleep(1);
return 0;
}
输出结果:
//
与环境相关,观察现象即可
child[3046]: 100 : 0x80497e8
parent[3045]: 0 : 0x80497e8
我们发现,父子进程,输出地址是一致的,但是变量内容不一样!能得出如下结论
:
变量内容不一样
,
所以父子进程输出的变量绝对不是同一个变量
但地址值是一样的,说明,该地址绝对不是物理地址!
在
Linux
地址下,这种地址叫做
虚拟地址
我们在用
C/C++
语言所看到的地址,全部都是虚拟地址!物理地址,用户一概看不到,由
OS
统一管理
OS
必须负责将
虚拟地址
转化成
物理地址
。