目录
正文:
常见环境变量
和环境变量相关的的命令
通过代码获取环境变量
主函数参数
三个参数
参数调用
进程优先级
查看系统进程
PRI和NI
优先级修改
前言:
通过上图我们可以发现环境变量其实是一组 K:V形式的变量。
我们可以通过 echo $NAME//NAME是环境变量名字 来查看环境变量
echo $ PATH
我们可以思考一下为什么我们写的程序编译完成后,我们需要执行./可执行文件 才可以将程序运行起来呢?但是我们平时使用的不需要加一个./呢?这是因为P
ATH
环境变量中有存储各种指令(程序)的路径,当我们直接输入指令时,OS会根据 PATH
提供的路径搜索程序,找到了就会直接运行对应指令(程序);而我们自己编写的程序则是需要通过 ./可执行程序
的方式运行,因为此时路径不被包含在 PATH
变量中。
如果我们想去掉./我们就要把我们的可执行程序的路径加入到系统的路径PATH变量中。
这就要用到export命令
//不能写成 export PATH=路径 这样会把path路径全部覆盖,我们要的是追加
export PATH=$PATH:/home/cmx-108/lesson8
这样我们就可以像命令行一样将我们的可执行程序直接运行起来。 需要注意的是作为普通用户,手动添加的环境变量只有本次登录才有效,下次登录环境变量会被重置(root用户除外)
除了使用export命令我们还可以将我们程序直接写在user/bin/目录下 也可以直接运行。
我们通过指令env看一下环境变量表
这里需要加入一个知识,main函数虽然是主函数的入口,但是第一个调用函数并不是main函数而是startup,而且这里会有条件编译如果我们传参 会有传参接收不传参就相应的有不传参接收。
我们在命令行创建的进程都是bash的子进程,我们都知道创建子进程的时候会继承父进程pcb,当执行不同模块发生写时拷贝,所以也会继承系统的环境变量表,这就是为什么环境变量具有全局属性就是因为继承了bash的环境变量表 在需要的时候可以添加需要的环境变量。
环境变量表是以指针数组的形式存储的
也可以通过 set
指令查看 环境变量表
,不过 set
指令显示的内容比 env
多得多,因为 set
还会显示 本地环境变量
信息。
environ
(char**
类型)获取getenv(NAME)
获取,这个比较常用main
函数中的第三个参数 char* envp[]
获取 我们通过下面程序将 第三方变量environ 和系统调用接口getenv查看环境变量进行演示(需要注意的是我们使用的系统调用接口getenv需要包含头文件
#include
#include //getenv 需要使用这个头文件
using namespace std;
extern char** environ; //声明使用
int main()
{
//cout << "Hello environment variable!" << endl; //你好环境变量!
int pos = 0;
while(pos < 5)
{
cout << environ[pos] << endl; //获取部分环境变量信息
pos++;
}
cout << endl << "========================" << endl << endl;
//通过函数获取
cout << "PWD=" << getenv("PWD") << endl;
return 0;
}
下面我们详细介绍一下主函数的参数
int argc
传入程序中的元素数,./程序名
算一个char* argv[]
传入程序中的元素表,由 bash
制作,传给 main
函数char* envp[]
环境变量表,所谓全局性就是指 main
函数可以通过此参数获取到环境变量表的信息我们除了环境变量表还要了解第二张核心向量表 叫命令行参数表,可以根据bash传入的选项然后形成字符串,然后将字符串按照空格解析成一个个命令 放入明亮行参数表,尾缀一个NULL(都是有bash完成)。
我们通过程序证明上面的解析,
#include
using namespace std;
int main(int argc, char* argv[], char* envp[])
{
cout << "现在传入的有效元素数为:" << argc << endl;
cout << "==========================" << endl;
cout << "通过元素表打元素信息" << endl;
int pos = 0;
while(pos < argc)
{
cout << argv[pos] << endl;
pos++;
}
cout << "==========================" << endl;
cout << "使用环境变量表获取前五个环境变量信息" << endl;
pos = 0;
while(pos < 5)
{
cout << envp[pos] << endl;
pos++;
}
return 0;
}
我们思考一下为什么要这么做呢?我们其实从输入的指令也能明白,这是为指令、工具软件提供选项的支持,来执行不同操作完成不同指令任务。
我们可以通过代码演示一下
#include
#include
#include
using namespace std;
//打印提示信息
void Usage(const char* str)
{
cout << str << " -[a | b | c]" << endl;
}
int main(int argc, char* argv[], char* envp[])
{
//首先进行身份检验
if(strcmp(getenv("USER"), "Yohifo") != 0)
{
cout << "当前用户为:" << getenv("USER") << endl;
cout << "非法使用他人程序,操作被拒绝!" << endl;
return 0;
}
//确保选项只有一个
if(argc != 2)
{
cout << "指令错误,尝试重新输入" << endl;
Usage(argv[0]);
return 0;
}
//验证成功后,进行选项分流
if(strcmp(argv[1], "-a") == 0)
{
cout << "执行 a 任务" << endl;
cout << "…………………………" << endl;
cout << "任务执行完成" << endl;
}
else if(strcmp(argv[1], "-b") == 0)
{
cout << "执行 b 任务" << endl;
cout << "…………………………" << endl;
cout << "任务执行完成" << endl;
}
else if(strcmp(argv[1], "-c") == 0)
{
cout << "执行 c 任务" << endl;
cout << "…………………………" << endl;
cout << "任务执行完成" << endl;
}
else
{
cout << "指令错误,尝试重新输入" << endl;
Usage(argv[1]);
return 0;
}
return 0;
}
通过不同的选项,调用不同的功能,这就是 main
函数参数存在的意义
选项会同程序名一起,构成一张表,传给 char* argv[]
参数
在 进程
的PCB
信息中,还包含了这些信息:
UID
身份标识PRI
进程优先级,默认为 80NI
进程修正值,这个只有 Linux
中有,配合修改优先级,范围为 [-20, 19]
我们可以通过ps指令查看系统进程,从而获取优先级相关信息
//注:其中的 myfile 是可执行程序名
$ ps -al | head -1 && ps -al | grep myfile //查看进程优先级信息
修改步骤
top
指令进入任务管理器r
进入修改模式PID
NI
值,完成修改虽然进程优先级可以被修改,我们只需要知道这个操作就可以,一般很少回去修改进程优先级。