进程的特性&环境变量&命令行参数

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 系统上正在运行的进程?

如何利用shell脚本中的eval命令来构造&quot;智能&quot;命令

进程状态与环境变量的解析

将环境变量传递给多个命令

进程对应程序的命令行参数和环境变量

Linux详解 --- 进程管理2 (进程状态环境变量与命令行参数)