目录
正文:
常见环境变量
和环境变量相关的的命令
通过代码获取环境变量
主函数参数
三个参数
参数调用
进程优先级
查看系统进程
PRI和NI
优先级修改
前言:
python
也是需要配置编码环境;而在我们的
Linux
中也有
环境变量
,由
环境变量
构成的集合称做
环境变量表
;我们还可以调整
进程
的优先级,使得
进程
运行更加灵活
通过上图我们可以发现环境变量其实是一组 K:V形式的变量。
正文:
常见环境变量
- PATH : 指定命令的搜索路径
- HOME : 指定用户的主工作目录(即用户登陆到Linux系统中时,默认的目录)
- SHELL : 当前Shell,它的值通常是/bin/bash。
我们可以通过 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需要包含头文件<stdlib.h>)
#include<iostream>
#include<stdlib.h> //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<iostream>
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<iostream>
#include<string.h>
#include<stdlib.h>
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 //查看进程优先级信息
PRI和NI
优先级修改
修改步骤
- 输入
top
指令进入任务管理器 - 输入
r
进入修改模式 - 再根据想要修改的进程,输入
PID
- 最后输入
NI
值,完成修改
虽然进程优先级可以被修改,我们只需要知道这个操作就可以,一般很少回去修改进程优先级。