进程的特性&环境变量&命令行参数
Posted 燕麦冲冲冲
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了进程的特性&环境变量&命令行参数相关的知识,希望对你有一定的参考价值。
环境变量与命令行参数
在Linux系统中,标识用户并不是通过用户名,而是uid。(可以类比QQ号码和QQ昵称)
原因是计算机更善于处理数字而不是字符。
进程的特性
并行:多个进程在多个cpu下同时运行。
并发:多个进程在一个cpu下采用进程切换的方式,在一段时间内使得多个进程推进。(进程切换时,保存进程上下文,每个进程开始在cpu上运行时,必须恢复上下文)
独立性:多进程运行,独享各种资源并互不干扰。(fork出子进程,代码共享,数据各自私有一份)
也是操作系统设计进程的一个原则。
利用僵尸进程验证独立性
1 #include<stdio.h>
2 #include<unistd.h>
3
4 int main()
5
6 pid_t id = fork();
7 if(id == 0)
8 //child
9 sleep(5);
W> 10 int a = 1 / 0; //除0出错终止进程
11
12 else
13 //father
14 while(1)
15
16 printf("father: I am alive!\\n");
17
18
19 return 0;
20
运行代码后启用监测脚本
while :; do ps -ajx | grep proc; sleep 5;echo "###################################"; done
可以看到父进程是S状态,子进程是Z状态,说明子进程死亡但不影响父进程的运行。
竞争性:进程和资源之间,进程永远是多数!为了高效完成任务,更合理竞争资源,便有了优先级。
环境变量
概念:操作系统启动后,环境变量的数据来源是通过某些配置文件来的,在系统当中承担着某些特殊作用。
打印出环境变量的路径:
//显示某一环境变量
echo $PATH //PATH为环境变量
//显示所有环境变量
env
程序、命令、指令、可执行程序……都是一个概念!
1、为什么运行一个我们编译生成可执行程序要带./
,而比如ls
等就无需使用呢?
./
是当前路径。如果不带这个直接运行可执行程序,则会报错:command not found
命令找不到?————》系统曾经找过————〉在PATH上找————》PATH辅助系统进行指令查找
:
作为分隔符,均为绝对路径。
如果把所有路径找完后,没有找到则报错,找到了则执行。
2、如何让我们自己编译生成的可执行程序不用./就能运行呢?
(1)将可执行程序::拷贝::至PATH中的任何一个路径里即可。
(2)将当前可执行程序路径::添加::至PATH中。
PATH=$PATH:当前可执行程序路径
如果不小心执行了
PATH=/
会导致大部分命令失效,但是在系统重新启动时都会给PATH环境变量赋值的。
3、为什么普通用户和root刚登录时所处的家目录不同?(登录时输入pwd查看)
echo $HOME
查看环境变量HOME,可以看到两者的初始家目录不同。
4、查看当前用户所使用的命令行解释器
echo $SHELL
我用的是bash。
5、查看历史命令
history
history |wc -l //查看历史命令数量,最大保存3000
echo $HISTSIZE //最大历史命令记录条数
6、获取环境变量的函数getenv
#include<unistd.h>
printf("I am a proc: pid:%d, ppid:%d\\n", getpid(), getppid());
运行后出现查看父进程的id,再查看父进程是谁
ps axj |head -1 && ps axj |grep (ppid)
在命令行上运行的大部分的指令,它的父进程都是bash,bash创建子进程(fork),子进程执行你的命令。
在命令行中我们可以定义两种变量:
(1)本地变量
MY_VAL=“you can see me”
使用getenv获取环境变量
int main()
printf(“%s\\n”, getenv(“PATH”);
printf(“%s\\n”, getenv(“MY_VAL”);
运行第一行代码没有问题,第二行会出现segmentation fault
段错误
原因MY_VAL是本地变量,只能够在当前shell命令行解释器内被访问,不可以被子进程继承。
解决方案:将本地变量MY_VAL导入环境变量
export MY_VAL
(2)环境变量
具有全局属性,可以被子进程继承。
set查看本地变量或环境变量
set | grep MY_VAL
7、内建命令
既然本地变量不可被子进程继承,那echo也是命令,大部分命令都会作为bash的子进程运行,echo会被bash创建的子进程运行,那么怎么也能看本地变量呢?
其实echo、set、env、export等是内建命令————是shell程序内部的一个函数,如果某个命令不是内建命令,bash才会为其fork一个子进程运行该命令。
8、清除变量
unset MY_VAL
命令行参数
1、main函数的参数
5 int main(int argc, char* argv[])
6
7 for(int i = 0; i < argc; i++)
8
9 printf("argv[%d]: %s\\n", i, argv[i]);
10
11
2、为什么存在命令行参数?
(1)利用main函数的参数实现一个加减法程序
1 #include<stdio.h>
2 #include<unistd.h>
3 #include<stdlib.h>
4 #include<string.h>
5
6 void Usage(const char* proc)
7
8 printf("Usage: %s -[a|s] x y\\n", proc);
9
10
11 //自定义命令行参数完成加减法./proc 1 + 2
12 int main(int argc, char* argv[])
13
14 if(argc != 4) //用法错误则写出提示
15
16 Usage(argv[0]);
17 return 1;
18
19 int x = atoi(argv[2]);
20 int y = atoi(argv[3]);
21 if(strcmp("-a", argv[1]) == 0)
22
23 printf("%d + %d = %d\\n", x, y, x + y);
24
25 else if(strcmp("-s", argv[1]) == 0)
26
27 printf("%d - %d = %d\\n", x, y, x - y);
28
29 else
30 Usage(argv[0]);
31
32 return 0;
33
这样就好理解命令参数了,如ls -l -a,后面的参数即为ls这个程序的参数。
可以根据不同的参数实现不同功能。
(2)命令行参数意义:帮助我们设计出,同一个程序,不同的业务功能。
3、main函数的第三个参数char* env[]
指针数组,每个元素指向的是一个一个的环境变量。结构和第二参数类似。
6 int main(int argc, char* argv[], char* env[])
7
8 for(int i = 0; env[i]; i++)
9
10 printf("env[%d]: %s\\n", i, env[i]);
11
12 return 0;
13
功能和env相似。
第三个参数的意义:继承环境变量,从而实现环境变量被子进程继承下去,从而拥有“全局属性”。
4、通过第三方变量获取环境变量
6 int main()
7
8 extern char** environ;
9 for(int i = 0; environ[i]; i++)
10
11 printf("%s\\n", environ[i]);
12
13 return 0;
14
以上是关于进程的特性&环境变量&命令行参数的主要内容,如果未能解决你的问题,请参考以下文章
如何将命令行参数传递给 unix/linux 系统上正在运行的进程?