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

【Linux课程学习】:环境变量:HOME,su与su - 的区别,让程序在哪些用户下能运行的原理,环境变量具有全局性的原因?

🎁个人主页:我们的五年

🔍系列专栏:Linux课程学习 

🌷追光的人,终会万丈光芒

🎉欢迎大家点赞👍评论📝收藏⭐文章

目录

HOME环境变量:

PWD环境变量:

USER和LOGNAME环境变量:

让我们的程序,指定某个用户运行:

su命令和su - 命令:

获得环境变量:

其他环境变量:

定义一个全局变量(shell维护的变量):

理解env,argv和export:

让子进程不被启动:

为什么子进程要继承父进程的环境变量?

获取环境变量的方式:


 

1.是先到家目录,然后再加载环境变量中的HOME?还是现有环境变量HOME,在根据这个到指定的目录呢?

是有环境变量HOME,环境变量先被加载。然后才能让工作路径到HOME目录。

2.bash也是一个进程,它的环境变量是根据用户和系统的配置文件来的。

3.所有的进程都是-bash的子进程。这些子进程的环境变量是从bash中拷贝的。

4.识别用户身份,不同的用户运行一个程序,不同用户的USER和LOGNAME是不同的,getenv又可以拿到这些环境变量,所以可以让哪些用户可以运行这个程序。

5.环境变量VS本地变量?

6.当创建一个子进程时,子进程会继承父进程的环境变量,这包括了操作系统级的环境变量,还有父进程设置的环境变量。

本地环境变量,默认不会传递给子进程。

子进程会继承父继承的环境变量。

7.为什么环境变量具有全局性?

因为子进程都会进程父进程的环境变量,所以子进程都能看到这些环境变量,也能进行操作。也可以传递给自己的子进程,让自己的子进程看到。

8.为什么要让子进程继承父进程的环境变量?

HOME环境变量:

表示当前用户的家目录,cd ~就是回到这样的目录。

刚刚登录shell的目录,就是该用户的家目录。


PWD环境变量:

当前进程的所在的工作路径。 


USER和LOGNAME环境变量:

 表示当前的用户。一般相同。

当我们用普通用户进行su切换到root时,没有真正登录root,所以USER和LOSNAME还是原来的普通用户。没有加载环境目标用户的环境变量,所以SUER和LOGNAME没有变化。

所以我们以后区分一个程序,就只要关注这两个环境变量就可以了。


让我们的程序,指定某个用户运行:

下面代码在root和kym用户下执行的结构如下:

要运行一个程序,就是操作系统要为这个程序开一个进程。我们这些进程全部都是-bash的子进程。当新建一个进程时,会继承父进程的环境变量。root用户进行登录shell和kym进行登录的环境变量USER和LOGNAME是不一样和。所以我们在getenv("USER")的时候,拿到的是不一样的字符串。所以执行就会发生区别。

#include <stdio.h>    
#include <stdlib.h>    
#include <string.h>    
    
int main()    
{    
    if(strcmp(getenv("USER"),"kym")==0)    
    {    
        printf("用户为kym,执行成功!\n");    
    }    
    else    
    {    
        printf("用户不匹配,请用kym用户进行执行!\n");    
    }                                                                                                  
    return 0;    
}   

su命令和su - 命令:

su命令:

如果不指定用户名,那么默认切换到超级用户(root)。如果指定了用户名,那么就切换到指定的用户。不管切换到那个用户,都不会加载该用户的环境变量,和启动该用户的脚本。

su - 命令:

会启动目标用户的脚本和加载环境变量。


获得环境变量:

头文件:

#include <stdlib.h>

函数原型:

char *getenv(const char *name);

进程可以通过系统调用获得当前的工作路径,后面新建文件就直接可以getenv("PWD")新建就行。

比如通过getenv获取PATH环境变量。 

#include <stdio.h>    
#include <stdlib.h>    
    
int main()    
{    
    char* s=getenv("PATH");    
    printf("%s\n",s);                                                                                                                                                                                              
    
    return 0;    
}    

其他环境变量:

LANG:UTF -8 表示语言是万国码,在不同的语言不会出现乱码。

LODPWD:最近一个路径。

所以cd - 的原理就是去环境变量中拿OLDPWD,就可以让路径切换回去。

cd -:返回最近一个路径。


定义一个全局变量(shell维护的变量):

他们不属于环境变量,通过env查看环境变量的时候,没有发现i=10,这个环境变量。

有shell内部进行维护。

set:显式本地的shell变量和环境变量。

unset (变量名):清除所有shell维护的环境变量。

export:将我们上面定义的全局变量,导入到环境变量中。

i=10;
set


理解env,argv和export:

每启动一个shell,操作系统就会启动一个-bash进程。开辟一块空间,存放一系列东西,里面包含了环境变量env,还有命令行参数列表,还有本地的环境变量。我们定义一个全局变量,比如i=10。其实就是在本地变量表中,有一个值存着"i=10"这个字符串起始位置。

export的效果就是,让env表指向"i=10"字符串。

 shell脚本:在shell命令行中衍生出来的一种语言。因为命令行可以定义变量,识别for等一系列关键词。


让子进程不被启动:

运行一个程序,就是让-bash帮我们创建一个子进程。但是子进程不会继承父进程的本地变量,只会继承父进程的环境变量。所以我们在父进程设置一个变量,就能控制该程序能不能运行。

可以设置为要有这个环境变量才能运行,也可以设置没有这个环境变量才能运行。

#include <stdio.h>    
#include <stdlib.h>    
#include <string.h>    
#include <unistd.h>                                                                                                                                                                                                
    
int main()    
{    
    char* is_running=getenv("ISRUNNING");    
    if(is_running==NULL)    
    {    
        while(1)    
        {    
            printf("程序被启动!\n");    
            sleep(1);    
        }    
    }    
    else    
    {    
        printf("程序启动失败!\n");    
    }    
    return 0;    
} 

这个程序就是:

1.没有ISRUNNING环境变量才能运行。

2.有ISRUNNING环境变量,getenv就返回NULL,打印"程序启动失败"


为什么子进程要继承父进程的环境变量?

a.系统的配置信息,尤其是具有指导性的配置信息。

我们给系统进行配置,就是让以后启动的任何进程都有这样的配置,而环境变量就是会把这些信息传递给以后的任何信息。而-bash的环境变量也是从bashrc和bash.profile文件中来的。所以在这些配置文件中配置一些信息,以后的进程都会有这些信息。

所以是配置信息生效的一种表现

b.进程是具有独立性的

所以如果父进程有数据要传给子进程。普通的数据是不会传递给子进程的,我们就可以通过环境变量进行传递。(只读数据)


获取环境变量的方式:

1.mian函数的第三个参数。

2.通过getenv函数获取。

3.通过environ全局变量获取。

extern:声明

#include <stdio.h>    
#include <stdlib.h>    
#include <string.h>    
#include <unistd.h>    
                                                                                                                                                                                                                   
extern  char** environ;    
int main()    
{    
    for(int i=0;environ[i];i++)    
        printf("env[%d]:%s\n",i,environ[i]);     
    return 0;    
}  


 


http://www.kler.cn/a/409719.html

相关文章:

  • ArcGIS应用指南:ArcGIS制作局部放大地图
  • 前端速通(CSS)
  • 用 Python 从零开始创建神经网络(九):反向传播(Backpropagation)
  • 网络安全,文明上网(5)注重隐私加密
  • P1 练习卷(C++4道题)
  • ValueError: bbox_params must be specified for bbox transformations
  • 【笔记】Linux下编译Python3.10.15为动态库同时正确处理OpenSSL3依赖
  • 搭建帮助中心,打造卓越的用户体验
  • 基于神经网络的流量异常检测
  • 【CSS】页面滚动到一定位置时,指定区域固定不变
  • Vue.js 组件开发实例分析
  • 基于基于DCT的数字水印算法
  • 【离散数学】特殊关系的矩阵表示
  • NLP论文速读(Apple出品)|迈向更好的多模态指令遵循能力评估
  • Vue.js --- Vue3中其他组合式API
  • 语言模型中的多模态链式推理
  • 【Linux】线程ID与互斥、同步(锁、条件变量)
  • 第4章 三个域对象
  • 深度解析:Vue 自定义指令到底是什么?快来了解
  • 鸿蒙面试题-某迈-2024年11月22日
  • 对于某些原型或UI软件的个人看法(2024/11)
  • 【Qt】控件LineEdit
  • MySql:库和表的操作
  • 在Kubernetes使用CronJob实现定时删除指定天数外的文件(我这里使用删除备份mysql数据库文件为例)
  • WPF——ICON按钮制作
  • Apache Spark