当前位置: 首页 > news >正文

Linux环境变量

Linux环境变量

  • 孤儿进程
  • 进程优先级
  • 其他概念
  • 环境变量
    • 感性的理解环境变量
    • 常见的环境变量
    • 添加环境变量
    • 环境变量的组织形式
    • 通过代码如何获取环境变量
    • 再次理解环境变量
  • 命令行参数

孤儿进程

概念:父进程先于子进程结束,这样的子进程就叫做“孤儿进程”;

“孤儿”进程,真的就没有了父进程了吗?
答案是当然不是,当子进程原先的父进程先子进程一步“去”过后,会由os启动领养程序,该子进程会被init进程(也就是os)领养,此时init进程就是子进程的父进程;

那么为什么孤儿进程需要被init领养呢?
回答这个问题,也就是回答,如果不领养孤儿进程会怎么样?
如果没有进程领养孤儿进程的话,在孤儿进程结束后,由于没有父进程接受它的状态码,也就是没有父进程对其所占的空间进行回收,孤儿进程就会一直处于“僵尸”状态,白白的浪费内存,造成内存泄漏,为此为了回收孤儿进程结束过后的空间,os就安排自己充当了孤儿进程的父进程;
下面我们通过一段代码,来演示孤儿进程:

   #include<stdio.h>                                                                                                                                                                                             #include<unistd.h>int main(){pid_t id=fork();if(id==0){//childwhile(1){printf("我是子进程,我的pid:%d,我的ppid:%d\n",getpid(),getppid());sleep(1);}}else if(id>0){//fatherint sec=10;while(sec){printf("我是父进程,我的pid:%d,我的ppid:%d,我还有%ds死去!\n",getpid(),getppid(),sec--);sleep(1);}}else{printf("error!\n");}return 0;}

我们可以通过利用ps -axj命令来查看我们进程的pid和ppid:
在这里插入图片描述
此时子进程由原来的前台程序,变为了后台程序,我们可以通过ps命令输出的STAT哪一项来判断,状态带+号的就是前台程序,不带+号的就是后台程序;我们利用Ctrl+c的快捷键杀不死后台程序,但是我们可以利用命令kill -9 pid或者killall 进程名这两个命令来杀死进程;
在这里插入图片描述

进程优先级

什么是进程优先级:就是那个进程先执行,那么进程后执行;

为什么会有进程优先级?
因为CPU资源有限,为了使每个进程都合理的使用到CPU资源;

怎么使用优先级?
首先我们可以通过命令:ps -al来查看:
在这里插入图片描述
其中修改优先级的公式:PRI=PRI(默认值)+nice;
nice的取值范围:[-20,19];
nice值为什么是这个区间,因为一个进程的优先级必须有个度,不能过高也不能过低,过高或过低都会严重造成CPU资源的分配不合理;
如何修改优先级?
我们可以输入top命令->输入r->输入进程pid->输入nice值;
一般情况下,我们普通用户只能把优先级变大,不能把优先级变小,如果想要变小优先级,我们可以切换成root:
在这里插入图片描述
如果想要变小优先级的话,需要切换成root,因为普通用户权限不够;

其他概念

竞争性: 系统进程数目众多,而CPU资源只有少量,甚至1个,所以进程之间是具有竞争属性的。为了高效完成任务,更合理竞争相关资源,便具有了优先级.
独立性: 多进程运行,需要独享各种资源,多进程运行期间互不干扰.
并行: 多个进程在多个CPU下分别,同时进行运行,这称之为并行.
并发: 多个进程在一个CPU下采用进程切换的方式,在一段时间之内,让多个进程都得以推进,称之为并发.

环境变量

概念:环境变量(environment variables)一般是指在操作系统中用来指定操作系统运行环境的一些参数
说实话,这官方的概念,我们初学者理解起来比较困难;我来说说我对于这句话的理解吧:
我认为环境变量就是指定os在一些特定情况下该做什么的动态参数;
就比如:os应该把临时文件放在哪里?当我们运行一个程序时,并没有指定该程序的位置时,os应该去哪里寻找这个程序?在我们需要读取当前机器的用户名时,os应该去哪里拿?
我们可以通过设置环境变量,来告诉os,遇到这些情况时,应该去哪里寻找“答案”;

感性的理解环境变量

或许上面的一通概念,并没有让我们理解什么是环境变量,下面我们通过一个例子来更好的理解环境变量:

在Linux环境下,为什么在运行我们自己的可执行程序时需要带上./这样的相对路径,或者绝对路径?而在运行诸如:ls、cd、tree、cp等命令时不需要带上它们的路径?我们可不可以让自己的程序也能不带上路径就运行起来呢?
首先当我们在运行一个不带任何路径的程序时,os会去PATH环境变量下,寻找是否含有当前程序,找到了就执行,找不到就报错!而对于我们指定路径的程序,则去指定路径下搜索!
那么PATH环境变量里面到底装的是什么?
我们可以通过命令:echo $PATH来查看PATH环境变量下的内容:
在这里插入图片描述
我们可以发现PATH里面都是一些路径,这些路径以:作为分隔!
那么我们如何让我们自己的程序像ls等命令一样不用指定路径也能直接使用呢?
如果我们想要想要像:ls、pwd、tree等命令一样使用起来不带路径的话,我么只需要将我们的可执行程序添加到PTAH中任一一条目录下或者将我们的路径追加到PATH环境变量下面;
首先我们来实验一下第一种办法:
1、将我们的可执行程序添加到PATH环境变量下的任意一路径中去,比如我们可以将我们都程序添加到PATH下的/usr/bin/目录下去:
在这里插入图片描述
当然如果我们还是按照原来的方式./Code2-22来运行程序也是可以的:
在这里插入图片描述
2、直接将我们当前目录添加到PATH环境变量中去:
首先我们先来演示一种错误的添加方式:
PATH=路径
在这里插入图片描述
向上面这种添加方法,虽然我们的程序可以不带路径运行了,但是像ls这些命令就不能运行了,想要运行他们必须带上路径了:
在这里插入图片描述
可这终归不是万全之策,在后续的使用上极其不方便!这里主要有两个解决办法:
1、将原来PATH默认的路径重新赋值给PATH
2、重新登录shell就可以了;

既然上面的那种赋值方式不是正确的方式,那么该如何向PATH环境变量里面追加路径呢?
PATH=$PATH:路径
在这里插入图片描述
像这样,过后我们不仅可以不带路径的使用我们追加的路径下的可执行程序,同时也不会影响ls等命令的使用:
在这里插入图片描述

常见的环境变量

通过上面的例子我们对于环境变量有了一定的理解,接下来我们来看一看一些比较常见的环境变量:

PATH : 指定命令的搜索路径;
HOME : 指定用户的主工作目录(即用户登陆到Linux系统中时,默认的目录)
在这里插入图片描述
SHELL : 当前Shell,它的值通常是/bin/bash。
在这里插入图片描述
USER:当前登录机器的用户;
在这里插入图片描述
PWD:当前所在目录;
在这里插入图片描述
当然这都是一些比较常见的环境变量,我们如果想要查看所有环境变量的话,我们可以使用命令env
在这里插入图片描述

添加环境变量

那么如何添加环境变量?
我们可以通过命令export 环境变量我们也可以给这个环境变量赋值export 环境变量=100
在这里插入图片描述

环境变量的组织形式

首先我们知道环境变量是存储的有内容的,那么这些环境变量里面的内容是从哪里来的?
答:环境变量的内容一般是由os从特定的配置文件中读取到的,当我们的os启动完毕过后,os就会读取相关配置文件里面的数据放到环境变量里面;在Linux下环境变量一般都在家目录下的.bashrc和.bash_profile;
这些环境变量也是数据,os也会对这些数据进行管理,os利用一个字符指针数组来维护这个环境变量表
在这里插入图片描述
每个程序都会收到一张环境表,环境表是一个字符指针数组,每个指针指向一个以’\0’结尾的环境字符串;
这个环境变量表的最后一个元素是NULL,以此来表示环境表的长度;

通过代码如何获取环境变量

通过代码环境变量主要有3种方式:

1、通过main函数的参数获取;
我们都知道main函数是可以带参数的,而且最多可以带3个参数,比如:
int main(int argc,char*argv[],char*envp[]);
其中envp就是指向这个环境表的首元素指针,通过envp我们可以获取到环境变量:
下面我们通过代码测试:
在这里插入图片描述在这里插入图片描述
2、我们也可以不用main的参数,C语言给我们提供了一个全局的字符指针,用来指向环境表,我们也可以通过这个全局的环境表来访问环境变量,这个全局的字符指针也就是:environ,我们只需要声明一下即可使用:
在这里插入图片描述
在这里插入图片描述
3、通过getenv函数来获取;
上面的两种方法虽然可行,但是用起来实在是不方便,比如我向访问一下USER这个环境变量,还得我自己去写匹配算法去一个一个寻找,很是麻烦,而是用getenv函数则会省去我们自己写匹配算法查找的过程,我们只需要告诉getenv我们需要获取哪个环境变量即可,getenv就会返回对应环境变量的内容;如果没有找到对应环境变量则返回NULL;
在这里插入图片描述
接着我们利用getenv来测试一下:
在这里插入图片描述
在这里插入图片描述
的确是这样的,为此我们可以利用该函数实现一个只允许ikun使用的pwd命令!
测试代码:
在这里插入图片描述
为了保持我们的pwd指令能像系统的pwd指令那样执行,我们需要将我们的代码所形成的可执行程序添加到PATH其中一个默认目录下:
在这里插入图片描述
接着我们来使用一下自己的pwd:
在这里插入图片描述

再次理解环境变量

环境变量就是内存级的一张环境变量表,这张表由用户登录的时候,os根据用户形成用户自己环境变量表;每个用户的环境变量表都不一样!
环境变量表中的每个元素都有自己的作用和应用场景,有的是用来进行查看当前用户名的,有的是用来进行用户查找的,有的用来记录当前路径的等等……
每一个环境变量都有自己的应用场景;

那么如何理解环境变量是一张内存级的表呢?
你说一个int a=10;double b=20;这样的a、b变量我能理解,那么环境变量为什么说是内存级?
在os启动的时候,os会启动shell程序,然后将自己读取到的环境变量交给shell,当我们在命令行输入export MYPATH=1000,shell会认为你是在定义一个新的环境变量,然后shell就会去内存找块空间将"MYPATH=1000"这个字符串存起来(或者malloc一块空间),让后将该空间的指针添加到环境变量表里面!这样就完成了新增环境变量!环境变量是可以被子进程继承下去的,而我们启动的程序都是shell的子进程,因此我们的进程是可以拿到shell维护的环境变量表的!
同时我们需要注意一下,export定义的环境变量具有全局性,也就是export定义的环境变量是会进入环境变量表的,也就可以被所有子进程访问,但是没有用export定义的环境变量,是不具有全局性的,这种环境变量不会进入环境表,自然也就无法被子进程访问,只能在Shell本身进程访问!
比如我们现在创建一个本地的环境变量:我们的子进程是访问不到的:
在这里插入图片描述

我们再来通过我们的程序获取该变量:
在这里插入图片描述
在这里插入图片描述
我们的Code2-22作为shell的子进程并没有在从shell上继承下来的环境表中访问到MYPATH
同时我们也可以通过命令env来验证,该命令env只会显示出全局的环境变量,对于本地环境变量不显示:
在这里插入图片描述
我们发现依旧没有结果;
当时我们用set命令来找到我们设置的本地环境变量,set命令会显示出全局的和本地的环境变量;在这里插入图片描述
如果我们想要清除环境变量的值可以用unset命令:在这里插入图片描述

命令行参数

上面我们再介绍利用代码获取环境变量的时候,提到了可以利用main函数的参数来获取,其中我们介绍了envp参数,但是argc、argv参数没怎么讲,现在我们就来理解一下这两个参数的意义;
int main(int argc,char*argv[],char*envp[]),从结构上我们可以看到argv与envp是同一个类型,于是我们可以大胆的猜测一下,argv也可能表示的是一张表!其中argc是这个表的长度!
那么这个表里面有什么呢?我们可以打印出来看看:
在这里插入图片描述
在这里插入图片描述
我们可以发现argv似乎输出的是们在命令行输入的指令,我们命令行输入的什么,argv就输出什么;
我们现在来剖析一下我们在命令行输入的东西:
在这里插入图片描述
你看这和我们ls -a -l 的形式是不是一样的,实际上我们在命令行指令+选项的方式时,shell会读取到这一串字符串,然后以空格作为间隔,将指令和选项存在一张表里面,当Shell为我们的指令创建进程的时候就会将这张表传给子进程!子进程就可以根据选项表现出不同的功能;
在这里插入图片描述
因此argv的作用就是可以让我们的程序根据不同的选项执行不同的功能!

相关文章:

Linux环境变量

Linux环境变量孤儿进程进程优先级其他概念环境变量感性的理解环境变量常见的环境变量添加环境变量环境变量的组织形式通过代码如何获取环境变量再次理解环境变量命令行参数孤儿进程 概念:父进程先于子进程结束&#xff0c;这样的子进程就叫做“孤儿进程”&#xff1b; “孤儿”…...

Kotlin-委托、代理和单例对象

委托和代理 实现委托和代理&#xff0c;使用的是by关键字。 这里设计一个场景&#xff1a;假设某个演员被要求唱歌&#xff0c;但是不会唱歌&#xff0c;就委托一个会唱歌的歌手在后台唱歌。 如何实现这个需求&#xff0c;下面就开始直接写代码 首先定义一个唱歌能力接口 int…...

华为OD机试真题Python实现【报数】真题+解题思路+代码(20222023)

报数 题目 一百个人围成一圈,每个人有一个编码编号从一开始到一百。 他们从一开始依次报数,报道M的人自动退出圈圈, 然后下一个人接着从1开始报数一直到剩余人数小于M。 请问最后剩余人在原先的编码为多少? 🔥🔥🔥🔥🔥👉👉👉👉👉👉 华为OD机试(Py…...

MacOS:Error message “error:0308010C:digital envelope routines::unsupported“

命令行&#xff1a;export NODE_OPTIONS--openssl-legacy-provider 原帖&#xff1a;https://stackoverflow.com/questions/69692842/error-message-error0308010cdigital-envelope-routinesunsupported...

Java 异常处理,超详细整理,适合新手入门

目录 前言 抛出异常 捕获异常 处理异常 finally块 总结 前言 当Java程序中出现错误或异常时&#xff0c;通常会抛出一个异常。Java的异常处理机制使得我们可以在程序运行过程中捕获这些异常并采取相应的措施&#xff0c;以便程序能够正常运行或者优雅地停止。 抛出异常 在…...

23年了,GOPATH和go.mod 还在冲突!

现在 新配了 go环境 设置了GOROOT&#xff0c;GOPATH &#xff0c;发现引用别的包会出问题。一直会报 package XX not in GOROOT &#xff08;xxxx&#xff09;我的目录&#xff1a;我的开发目录&#xff1a; /home/fate/go_projects/老样子&#xff0c;下面有 /home/fate/go_…...

Could not connect to Redis at 127.0.0.1:6379: 由于目标计算机积极拒绝,无法连接。(极简解决办法)

一、遇到问题。 在需要启动Redis客户端的时候&#xff0c;会发现会报这个错误。报这个错误的原因就是Redis的服务端没有开启&#xff0c;那Redis的客户端是访问不了的 二、解决办法。 1.解决的办法就是要启动服务端&#xff0c;让这个客户端可以访问到。启动服务端最简单不会…...

华为OD机试 - 优雅数组(Python)【2023-Q1 新题】

华为OD机试300题大纲 参加华为od机试,一定要注意不要完全背诵代码,需要理解之后模仿写出,通过率才会高。 华为 OD 清单查看地址:blog.csdn.net/hihell/category_12199275.html 华为OD详细说明:https://dream.blog.csdn.net/article/details/128980730 优雅数组 | 华为…...

【概念辨析】数组指针指针数组

目录 一、数组指针 二、指针数组 三、 数组指针的数组名不是二级指针 再来说最关键的&#xff1a;数组指针为什么不是二级指针呢&#xff1f; 代码如下&#xff1a; 四、指针数组的数组名是二级指针 在复习&#xff0c;在考试&#xff0c;在焦虑。 又一次学习到了数组指针和指针…...

python实战应用讲解-【语法基础篇】字典的创建及建模(附示例代码)

目录 创建和使用字典 函数 dict 代码清单4-1列出了创建电话簿数据库的代码。...

华为OD机试真题Python实现【分糖果】真题+解题思路+代码(20222023)

分糖果 题目 小明从糖果盒中随意抓一把糖果 每次小明会取出一半的糖果分给同学们 当糖果不能平均分配时 小明可以从糖果盒中(假设盒中糖果足够)取出一个或放回一个糖果 小明至少需要多少次(取出放回和平均分配均记一次)能将手中糖果分至只剩一颗 🔥🔥🔥🔥🔥👉�…...

视频技术基础知识

一、视频图像基础 像素&#xff1a;图像的基本单元&#xff0c;即一个带有颜色的小块分辨率&#xff1a;图像的大小或尺寸&#xff0c;用像素个数来表示。原始图像分辨率越高&#xff0c;图像就越清晰位深&#xff1a;存储每位像素需要的二进制位数&#xff1b;位深越大&#…...

Windows应用之——设置定时关机

一 概述 本文介绍window设置自动关机的两种方式&#xff1a; cmd指令设置自动关机任务计划程序设置自动关机第三方定时关机软件 二 cmd指令设置自动关机—不推荐 2.1 自动关机-开启(管理员模式下) 依次点击‘“开始”&#xff0c;在“搜索程序和文件”中输入cmd&#xff0c…...

华为OD机试真题Python实现【 喊七】真题+解题思路+代码(20222023)

喊七 题目 喊 7,是一个传统的聚会游戏, N 个人围成一圈,按顺时针从1 - 7编号, 编号为1的人从1开始喊数, 下一个人喊得数字是上一个人喊得数字+1, 但是当将要喊出数字7的倍数或者含有7的话, 不能喊出,而是要喊过。 假定N个人都没有失误。 当喊道数字k时, 可以统计每…...

国产蓝牙耳机哪个好用?国产好用的蓝牙耳机推荐

现如今&#xff0c;国产蓝牙耳机越来越受到人们关注&#xff0c;国产蓝牙耳机近几年的发展愈发迅猛&#xff0c;配置上相对于非国产蓝牙耳机来说也毫不逊色。那么&#xff0c;国产蓝牙耳机哪个好用&#xff1f;下面&#xff0c;我来给大家推荐几款好用的蓝牙耳机&#xff0c;一…...

JAVA虚拟机JVM之内存模型

内存模型 java 内存模型 很多人将【java 内存结构】与【java 内存模型】傻傻分不清&#xff0c;【java 内存模型】是 Java Memory Model&#xff08;JMM&#xff09;的意思。 关于它的权威解释&#xff0c;请参考 https://download.oracle.com/otn-pub/jcp/memory_model-1.0…...

Java线程——常见方法

一、 常见方法 1.1 概述 ① start_vs_run&#xff1a;直接调用run方法并不会启动新的线程 import cn.itcast.n2.util.FileReader; import lombok.extern.slf4j.Slf4j;Slf4j(topic "c.Test") public class Test {public static void main(String[] args) {Thread t…...

机器学习:基于逻辑回归对某银行客户违约预测分析

机器学习&#xff1a;基于逻辑回归对某银行客户违约预测分析 文章目录机器学习&#xff1a;基于逻辑回归对某银行客户违约预测分析一、实验目的二、实验原理三、实验环境四、实验内容五、实验步骤1.逻辑回归2.业务理解3.读取数据4.数据理解5.数据准备6.逻辑回归模型训练7.模型评…...

MySQL数据库常用命令汇总(全网最全)

目录 数据库常用命令 数据库的创建 数据表的操作 表数据的增删查改 分组与函数查询 运算符&#xff1a;数学运算符 连接查询 多表查询 修改语句 删除语句 字符查询like MySQL练习 总结感谢每一个认真阅读我文章的人&#xff01;&#xff01;&#xff01; 重点&…...

Bulletproofs++

1. 引言 前序博客&#xff1a; Bulletproofs: Short Proofs for Confidential Transactions and More学习笔记Bulletproofs 代码解析Bulletproofs: Shorter Proofs for Privacy-Enhanced Distributed Ledger学习笔记Bulletproofs 代码解析 Liam Eagen 2022年3月论文《Bullet…...

日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻

在如今就业市场竞争日益激烈的背景下&#xff0c;越来越多的求职者将目光投向了日本及中日双语岗位。但是&#xff0c;一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧&#xff1f;面对生疏的日语交流环境&#xff0c;即便提前恶补了…...

【Linux】C语言执行shell指令

在C语言中执行Shell指令 在C语言中&#xff0c;有几种方法可以执行Shell指令&#xff1a; 1. 使用system()函数 这是最简单的方法&#xff0c;包含在stdlib.h头文件中&#xff1a; #include <stdlib.h>int main() {system("ls -l"); // 执行ls -l命令retu…...

AI书签管理工具开发全记录(十九):嵌入资源处理

1.前言 &#x1f4dd; 在上一篇文章中&#xff0c;我们完成了书签的导入导出功能。本篇文章我们研究如何处理嵌入资源&#xff0c;方便后续将资源打包到一个可执行文件中。 2.embed介绍 &#x1f3af; Go 1.16 引入了革命性的 embed 包&#xff0c;彻底改变了静态资源管理的…...

【Java学习笔记】BigInteger 和 BigDecimal 类

BigInteger 和 BigDecimal 类 二者共有的常见方法 方法功能add加subtract减multiply乘divide除 注意点&#xff1a;传参类型必须是类对象 一、BigInteger 1. 作用&#xff1a;适合保存比较大的整型数 2. 使用说明 创建BigInteger对象 传入字符串 3. 代码示例 import j…...

在Ubuntu24上采用Wine打开SourceInsight

1. 安装wine sudo apt install wine 2. 安装32位库支持,SourceInsight是32位程序 sudo dpkg --add-architecture i386 sudo apt update sudo apt install wine32:i386 3. 验证安装 wine --version 4. 安装必要的字体和库(解决显示问题) sudo apt install fonts-wqy…...

Netty从入门到进阶(二)

二、Netty入门 1. 概述 1.1 Netty是什么 Netty is an asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients. Netty是一个异步的、基于事件驱动的网络应用框架&#xff0c;用于…...

MFC 抛体运动模拟:常见问题解决与界面美化

在 MFC 中开发抛体运动模拟程序时,我们常遇到 轨迹残留、无效刷新、视觉单调、物理逻辑瑕疵 等问题。本文将针对这些痛点,详细解析原因并提供解决方案,同时兼顾界面美化,让模拟效果更专业、更高效。 问题一:历史轨迹与小球残影残留 现象 小球运动后,历史位置的 “残影”…...

【C++特殊工具与技术】优化内存分配(一):C++中的内存分配

目录 一、C 内存的基本概念​ 1.1 内存的物理与逻辑结构​ 1.2 C 程序的内存区域划分​ 二、栈内存分配​ 2.1 栈内存的特点​ 2.2 栈内存分配示例​ 三、堆内存分配​ 3.1 new和delete操作符​ 4.2 内存泄漏与悬空指针问题​ 4.3 new和delete的重载​ 四、智能指针…...

MFE(微前端) Module Federation:Webpack.config.js文件中每个属性的含义解释

以Module Federation 插件详为例&#xff0c;Webpack.config.js它可能的配置和含义如下&#xff1a; 前言 Module Federation 的Webpack.config.js核心配置包括&#xff1a; name filename&#xff08;定义应用标识&#xff09; remotes&#xff08;引用远程模块&#xff0…...

ubuntu系统文件误删(/lib/x86_64-linux-gnu/libc.so.6)修复方案 [成功解决]

报错信息&#xff1a;libc.so.6: cannot open shared object file: No such file or directory&#xff1a; #ls, ln, sudo...命令都不能用 error while loading shared libraries: libc.so.6: cannot open shared object file: No such file or directory重启后报错信息&…...