Linux学习笔记(8)

Posted 你算哪一个bug?

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux学习笔记(8)相关的知识,希望对你有一定的参考价值。

🌲进程优先级

🌴优先级和权限的区别

以CPU资源为例,优先级是一定能获得CPU资源,只是时间的长短

权限则不同,权限不够就不能获得资源

🌴优先级是什么?

优先级本质就是获得资源的先后顺序

🌴为什么要有优先级?

CPU的资源有限,所以进程需要根据优先级排队

🌴Linux里进程优先级由谁决定?

两个参数:PRI和NI

  • PRI可看作priority的简写,NI指的是nice值(新概念)

  • 更改nice值可以改变优先级

  • PRI越小,优先级越高,反之越低(一般创建的进程PRI默认是80)

  • NI的取值范围是-20到19(把NI设为100等同于设为19 把NI设为-100等同于设为-20),NI的值是可控状态

ps -al 看到PRI和NI

🌴更改优先级

优先级看PRI的值,PRI的值决定排名,NI的值可以更改PRI,进而影响优先级

PRI(新)=PRI(旧)+NI

注:这个PRI(旧)一般指80(PRI的值默认一般是八十)

设NI的值PRI(同一个进程)
080
1090
1393(不会变成103)

连续设定NI的值不会累加,80是一个基准,这是为了防止一个进程的优先级过高或者过低,进而保证CPU资源的公平分配。在设计上也比较简单

如果可以累加,用户操作时可能造成一个进程的优先级相当高,而别的进程优先级很低,导致资源的不公平分配,而CPU调度器的原则就是公平,所以过高和过低是不被允许的,正因为如此,NI的值不会被累加,每次调整的基准都是80

🌵设定nice的值

top命令

top -> r选项 ->输入PID -> 输入设定的renice (按q退出top)

注:改了两次NI,但是第二次改变的结果仍然是以80为基准得到的

🌴Linux标识用户

Linux标识用户是根据UID来的,而不是根据用户名

ll-n 可以看到uid

比如qq里标识我们的不是qq名,而是我们的qq号

随笔记录计算机善于处理数字数据

🌴进程补充

  • 独立性:每个进程相互独立

    fork创建子进程时,共享代码,私有数据,就是为了维护进程的独立性

  • 竞争性:资源是有限的,自然就有了竞争,为了高效的完成任务,合理竞争,也就产生了优先级,优先级高的先分配到CPU资源

🌲环境变量

🌴什么是环境变量?

环境变量(environment variables)一般是指在操作系统中用来指定操作系统运行环境的一些参数,如:临时文件夹位置和系统文件夹位置等。—百度百科🛡

例1,如果在Windows下配过Java的环境那肯定见过下面这张图

例2:C文件的编译与链接,链接时就需要库的参与,动态库静态库之类的,那编译器是怎么找到动态库或静态库的?就是借助了环境变量

例3:Linux下有一个名为 test 的可执行文件, ./test运行程序,其实"./test"也可以看作一条指令,我们为什么要在可执行程序前加 ./ ?(我们不用在ls,ll,pwd等等前面加 ==./==啊)

原因: “./” 可以帮助Linux找到当前的可执行文件的路径,Linux在执行可执行文件时默认在PATH(环境变量)里面去找文件路径,找到的第一条将被执行

因为ls,pwd这些命令本就在环境变量设置的目录下,所以不用加 “./” Linux系统也能找到ls,pwd然后执行

换句话说 ,如果我们在环境变量中移除了 ls,pwd 这些命令所在的目录,那我们就不能直接用ls,pwd这些命令,因为Linux找不到这些命令就会报错:-bash: xxx: command not found,此外,路径名中存在 ‘./’ ,则不搜索$PATH(一种环境变量)

windows默认带了查找路径 所以执行可执行文件不用加./

🌴环境变量种类

本地变量和环境变量

本地变量只能在shell内访问,不能被子进程继承

🌴常见的环境变量

  • PATH:指定命令的搜索路径

    PATH:辅助系统进行命令查找

    PATH下的路径以 :(冒号) 做分隔符

  • HOME:用户的工作目录

    用户通过登录 进入系统时所在的目录

  • SHELL:当前Shell

  • HISTSIZE:保存历史命令的数目

    history命令可以看到自己敲过的指令,一般是默认保存最近的3000条

    HISTSIZE的值默认就是3000

🌴查看环境变量

  • echo $变量名

echo $PATH

echo $HOME

echo $SHELL

echo $HISTSIZE

  • env

    可以看到所有的环境变量

  • set

    显示或设置shell特性及shell变量

🌴直接运行可执行程序的办法(不加./)

  1. 文件拷贝至PATH下

注:文件名别取test,不然会失败(我一开始文件名取了test,在PATH下的目录里面也能找到test,但是不能直接运行)

  1. 把当前目录添加到PATH下

PATH=$PATH:路径

$PATH代表原路径

关掉重启后环境变量又会恢复默认

记录PATH:怕玩崩了

/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/ck/.local/bin:/home/ck/bin

🌴环境变量具有全局性

全局属性:可以被子进程继承

🌵获取环境变量

通过全局属性 我们可以通过子进程获取父进程的环境变量(因为子进程继承了父进程的环境变量,所以父子的环境变量一样)

  • 通过C语言 getenv(变量名) 函数

test.c

#include<stdio.h>    
#include<stdlib.h>    
    
int main()    
    
  printf("PATH:%s\\n",getenv("PATH"));    //得到当前的PATH
  printf("HOME:%s\\n",getenv("HOME"));    
  printf("SHELL:%s\\n",getenv("SHELL"));   
  return 0;    
 

运行:

这个C程序加载到内存就是个进程,它的父进程就是bash(前面的Linux笔记有讲过,可以翻一下)

在命令行运行的大部分的指令,它的父进程都是bash,也即bash创建子进程,子进程执行你的指令

前面提过本地变量只能在shell内访问,不能被子进程继承

假定本地变量MY_VAL=15

C代码:getenv(“MY_VAL”);这种写法就是错误的,因为在子进程无法访问到本地变量

如何访问在子进程里访问本地变量?

加export

利用set测试

利用getenv函数测试

随笔小结:env只能看到环境变量 而set都可以看 可以利用这点来判断是否是环境变量

echo set env 等为内建命令,是shell程序内部函数 父进程不是bash

🌴补充命令

unset: 取消环境变量

如 unset MY_VAL

🌲命令行参数

 test.c                                                                                                                 
#include<stdio.h>    
#include<stdlib.h>    
      
int main(int argc,char* argv[])    
     
    for(int i=0;i<argc;i++)  
    //i<argc可以写成argv[i],因为argv数组最后一个元素为NULL
        
      printf("argv[%d]:%s\\n",i,argv[i]);    
             
    return 0;                                                               
 

上面的agrc,argv就是命令行参数

注:运行时得用C99标准 即 gcc -o test test.c -std=c99

运行:

此外main函数还有第三个参数 env ,可以通过env来获取当前环境

  #include<stdio.h>    
  #include<stdlib.h>    
      
int main(int argc,char* argv[],char* env[])    
      
    for(int i=0;env[i];i++)
   //env里放的就是env命令获取的内容                                            	
        
      printf("env[%d]:%s\\n",i,env[i]);    
             
    return 0;    
  

getenv()这个函数就是对env数组进行了信息筛选

上面程序等价于

  #include<stdio.h>    
  #include<stdlib.h>          
int main(int argc,char* argv[])    
      
    extern char** environ; //二级指针
    for(int i=0;environ[i];i++)//env里放的就是env命令获取的内容    
        
      printf("env[%d]:%s\\n",i,environ[i]);                                 
              
    return 0;    
     

environ是一个全局的外部变量 ,可以通过extern声明

这个变量在unistd.h中 所以也可以包含头文件使用

为什么要有命令行参数?

让一个程序可以实现不同功能

🌵示例:计算器功能

计算器源码:

#include<stdio.h>    
#include<stdlib.h>    
#include<string.h>    
int main(int argc,char* argv[] )    
    
  int num1=atoi(argv[2]);    
  int num2=atoi(argv[3]);    
  if(argc!=4)    
      
    printf("Usage:./cal -a(s) num num\\n");    
      
  if(strcmp(argv[1],"-a")&&strcmp(argv[1],"-s"))    
      
    printf("Usage:./cal -a(s) num num\\n");    
      
  else if(!strcmp(argv[1],"-a"))                                                                                                                         
      
    printf("%d+%d=%d\\n",num1,num2,num1+num2);    
      
  else    
      
    printf("%d-%d=%d\\n",num1,num2,num1-num2);    
      
  

以上是关于Linux学习笔记(8)的主要内容,如果未能解决你的问题,请参考以下文章

linux 学习笔记8

linux学习笔记8

Linux学习笔记第8章 Linux shell基础知识

2018-3-8 Linux学习笔记

2018-1-8 Linux学习笔记

linux学习笔记8--命令touch