【linux】-进程概念之环境变量的详解(命令行参数的介绍)

news2024/9/23 17:20:51

在这里插入图片描述
💖作者:小树苗渴望变成参天大树🎈
🎉作者宣言:认真写好每一篇博客💤
🎊作者gitee:gitee✨
💞作者专栏:C语言,数据结构初阶,Linux,C++ 动态规划算法🎄
如 果 你 喜 欢 作 者 的 文 章 ,就 给 作 者 点 点 关 注 吧!

文章目录

  • 前言
  • 一、常见的环境变量
    • 1.1PATH
    • 1.2HOME和SHELL
    • 1.3使用系统调用接口来获取环境变量
  • 二、命令行参数
  • 三、本地变量和内建命令
    • 3.1本地变量
    • 3.2内建命令
  • 四、总结


前言

今天我们来讲解一个之前陌生而又熟悉的知识—环境变量,有的同学听过,有的同学没有听过,之前学过java和python的应该配置过环境变量,但是还是不太了解,接下来这篇就带大家来重新认识什么是环境变量,环境变量有什么作用,我将先带大家认识几个常见的环境变量,然后再跟大家说明什么是环境变量,这样大家才能更好的理解,话不多说,我们开始进入正文的讲解


一、常见的环境变量

和环境变量相关的命令
1. echo: 显示某个环境变量值
2. export: 设置一个新的环境变量
3. env: 显示所有环境变量
4. unset: 清除环境变量
5. set: 显示本地定义的shell变量和环境变量

常见环境变量

PATH : 指定命令的搜索路径
HOME : 指定用户的主工作目录(即用户登陆到Linux系统中时,默认的目录)
SHELL : 当前Shell,它的值通常是/bin/bash。

1.1PATH

我们来写一个程序

  1 #include<stdio.h>
  2 
  3 int main()
  4 {
  5     int i=0;
  6     for(;i<5;i++)
  7     {
  8         printf("hello,%d\n",i);                                                                                                             
  9     }
 10     return 0;
 11 }

在这里插入图片描述

我们之前也说过,指令也是程序,和我们写的程序没什么区别,为什么我们自己写的程序需要加./来运行而指令却不需要,是因为什么,我们之前说过指令再指定路径下,系统会自动找到的,我们自己写的程序,系统是默认找不到的,原因就是因为PATH变量里面没有我们当前的查找路径,我们来看看PATH变量里面是什么:使用echo $PATH
在这里插入图片描述
我们PATH里面有许多好几个默认查找路径,以冒号进行分割的。我们看到我们的指令路径再我们的PATH下,所以可以查到,而我们自己写的程序却直接运行不了出现了not found说明他是搜索过的,只是没有查找到。


可以将我们写的程序放到默认的指令路径下,按照指令的模式一样运行,今天我们不使用这样的方式,我们把需要运行程序的路径放到PATH变量里面,是不是就可以像指令一样的运行了??
使用PATH=$PATH:路径这是追加路径
在这里插入图片描述

我们达到我们想要的效果了,等号两边不需要空格

使用PATH=路径这是覆盖原路径
在这里插入图片描述

我们发现我们的原来指令都跑不了了,但是pwd可以跑,这个后面再介绍原因,那我们应该怎么办,大家不要担心,这些修改都是bash进程下修改的,等退出登录的时候bash被销毁,下次再登录的时候就又恢复之前的样子了。

通过上面的介绍,我们写的程序还有系统的指令程序都是由路径的,使bash通过PATH变量里面路径帮助我们去查找,就算没有找到也是bash说没有找到,希望大家可以理解这个原理在这里插入图片描述

1.2HOME和SHELL

在这里插入图片描述

我们使用whoami的时候,系统怎么知道我们的的名字的,原因就是我们的HOME变量有我们对应的用户,我们来使用env查看一下所有环境变量:
在这里插入图片描述

我们只需要看看这几个我圈出来的这几个环境变量就行了,这下面还有一些环境变量在这里插入图片描述
OLDPWD这是上一次的用户目录
在这里插入图片描述
这是因为有了这个OLDPWD环境变量,我们可以实现使用**cd -**再两个用户直接来回切换,一会会介绍到怎么做到的,使用选项再里面由判断条件,对应不同的功能

所以我们的whoami、pwd 等一些指令为什么会达到我们想要的效果,就是因为有这样环境变量。

1.3使用系统调用接口来获取环境变量

getenv这个函数我们来看一下文档:
在这里插入图片描述
我们来修改第一次写的程序:

#include<stdio.h>
#include<stdlib.h>
int main()
{
    printf("PATh:%s",getenv("PATH"));
    return 0;
}

在这里插入图片描述
我们看到也可以用系统调用接口来获取此进程所拥有的环境变量。注意传参是传环境变量的字符串

接下来让大家再次理解权限的概念:看代码:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{
    char who[32];
    strcpy(who,"root");
    if(strcmp(who,getenv("USER"))==0)
    {
        printf("你可以做任何事情\n");
    }
    else 
    {
        printf("你是普通用户,受限制\n");
    }
    return 0;
}

在这里插入图片描述
相同的代码,再不同的用户登录去运行结果就是不一样的,我们权限也是类似于这样的设计。


上面我们介绍了常见的环境变量,也知道了环境变量的作用以及重要性,那什么是环境变量我还没有具体下定义:他是系统提供的一对name=value的
形式的变量,不同的用户具有不同的环境变量,环境变量通常具有全局性
,对于全局性我需要铺垫下面的知识,才能让大家更好的理解,命令行参数

二、命令行参数

相信大家对这个名词应该是非常的陌生的,但是对于这个东西可能见过,学过java的应该都有看过,但是没有具体使用过,为什么要有命令行参数以及怎么使用的一会都会介绍到。

我们一个程序是从主函数开始调用的,主函数也是函数,就存在调用和被调用关系,既然有参数肯定是通过别的函数调用主函数进行传参给主函数,才可以,接下来我们来看代码:

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

我们第一个参数是传了几个参数进来,第二个参数是一个指针数组,存放传进来的字符串,我们来看看运行效果:
在这里插入图片描述
在这里插入图片描述


按照上面说的,我们的结束条件也可以设置成下面这样: for(;argc[i];i++)

大家目前还是不懂什么意思,接下来再写一个代码大家就知道了:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int main(int argc,char*argv[])
{
    if(argc!=2)
    {
        printf("./cmd -[a|b|c]\n");//按照此格式进行运行
    }
    if(strcmp(argv[1],"-a")==0)
    {
        printf("功能1\n");
    }
    else if(strcmp(argv[1],"-b")==0)
    {
        printf("功能2\n");
    }
    else if(strcmp(argv[1],"-c")==0)
    {
        printf("功能3\n");
    }
    else 
    {
        printf("没有此功能\n");
    }

    return 0;
}

在这里插入图片描述

到这里我们的结论就出来了,命令行参数是为指令、工具软件提供命令行选项的支持


三参数的命令行参数:
大家有所疑问,我们不是再介绍环境变量吗,怎么说到这个了,他们有什么关系呢,真的有很大的关系,那第三个参数是什么呢?他是一个和第二个参数一模一样的类型,是一个指针数组的存放的环境变量,我们使用env看到许多环境变量,其实放在指针数组里面的,每一行其实都是使用双引号括起来的字符串,我们的getenv是获取一个环境变量,通过第三个参数我们可以获取所有的环境变量,我们来看代码:

#include <stdio.h>
int main(int argc, char *argv[], char *env[])
{
	 int i = 0;
	 for(; env[i]; i++)
	 {
		 printf("%s\n", env[i]);
	 }
 return 0;
}

在这里插入图片描述
我们通过第三个参数也可以把所有的环境变量给显示出来,不需要使用env了。

到这里给大家解释一个概念:
通过上面两个代码的演示,我们已经知道了第二个参数,以及第三个参数的作用了和效果,那这两个参数到底是什么,我们说过这两个参数都是指针数组,分别指向两个不同的数组,这两个数组一个是命令行参数表,一个是环境变量表

我们刚才运行的cmd程序原本是没有环境变量的,但是我们运行的时候形成了一个进程,此进程是bash进程的子进程,换句话说,子进程的环境变量是由父进程将自己的环境变量表和命令行参数表传给子进程,才打印出来的,子进程会继承父进程的环境变量表,而bash再启动的时候,也是os的子进程,他的环境变量信息是通过os的配置文件来获取的,我们参数不写也会直接继承。


怎么证明是继承下来了,通过env和子进程打印出来的都是一样的,是系统一开始就有的,那我们不确定是父进程继承下来的,还是系统的环境变量的?

此时我们就需要再bash进程里面添加一些特有的环境变量,看看此时子进程有没有这个特有的环境变量,是不是就达到验证了,那么问题来到我们怎么添加新的环境变量呢??
export name=value
在这里插入图片描述

我们不带export定义的变量是本地变量,不会被继承,一会说,我们需要使用export将环境变量进行导入,我们看到效果,确实被继承下来了,先要删除环境变量要通过unset name就可以删除了。

通过上面的一系列介绍,我们知道了每个进程的环境变量是怎么通过系统接口获取的,一旦bash进程没了那其他进程的环境变量也都没有了,还记得我们给出环境变量概念的时候,说过环境具有全局性,通过命令行参数的讲解,大家有没有理解环境变量具有全局性的特点。

三、本地变量和内建命令

3.1本地变量

再上面我们提到过不带export定义的变量叫做本地变量,我们来看看本地变量的是什么,为什么要定义本地变量,本地变量不会被继承怎么验证

  1. 本地变量是什么
    就是再命令行上直接定义的变量,不会出现再环境变量表里面的,使用env是看不到的,但是实际上是存在的
    在这里插入图片描述

  2. 为什么要有本地变量
    本地变量是给本地使用的,当前进程特有的一个功能,我们来看看bash的本地变量,使用set查看所有的环境变量以及本地变量
    在这里插入图片描述
    这是我截取的一部分有本地变量的。第一个是命令行提示符,这个只是bash自己使用就好了。

  3. 怎么验证没有被继承
    在这里插入图片描述
    我们只有使用export定义的变量才会被进程,没有导入就继承不了。

相信大家对这个本地变量应该有所了解了吧

3.2内建命令

在这里插入图片描述
我们定义了本地变量,我们所有的指令都是bash进程的子进程,刚才说过本地变量不会被继承,那我们echo指令式怎么获取定义的本地变量??换句话说echo到底有什么创建自己的进程??

有两批指令:

  1. 常规指令–创建子进程完成的
  2. 内建指令–不需要创建子进程,由bash自己去完成的,就是bash自己会调用自己内部的函数去完成的

bash也是一个程序,由自己的函数,接下来我就带大家来演示一个内建命令cd,这是求换目录的,我们来看看代码:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<unistd.h>
int main(int argc,char*argv[])
{
    sleep(30);
    printf("change begin\n");
    if(argc == 2)
    {
        chdir(argv[1]);//往里面传什么路径就切换到哪个路径
    }

    printf("change end\n");
    sleep(30);
    return 0}

在这里插入图片描述
我们的程序通过系统调用接口改变了路径,那我们的bash对于cd命令的时候采取的这样的方式去直接带哦有了这个系统调用接口

if(strcmp(argv[1], "cd")==0)//先判断,然后自己去调用
{
    chdir(argv[1]);
}

这样bash就不需要创建子进程给内建命令了。我们的pwd也是内建命令,他不再PATH里卖弄为空的情况,不像其他常规指令一样将环境变量继承下来,然后发现没有路径可以查找就使用不了,而内建命令式直接通过调用自己的函数去实现的,所有没有PATH也是可以直接运行的,而不是去找其他程序去运行别的程序函数去运行的。

到这里大家对于内建命令应该有所了解了。也明白了环境变量的作用以及重要性了

四、总结

说到这里我们对于环境变量的学习就到这里了,大家至少要掌握为什么要有环境变量,还由命令行参数,这个是非常重要的,希望大家下来自己可以很好的去理解,下一篇博主就会讲解关于进程概念的最后一个主题:进程地址空间,到时候会给大家解决之前留下来的问题,一个变量怎么保存不同的值,希望大家可以来支持博主,我们下篇再见。
请添加图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/855009.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

介绍另外一个容器技术, Apptainer

一说到容器&#xff0c;我们往往会脱口而出&#xff0c; Docker&#xff0c; 实际上Docker 仅仅是Linux 容器化的一种&#xff0c; 今天介绍的Apptainer 就是另外一种容器技术。 那么Apptainer 具体是一个什么东西呢&#xff1f; 跟Docker 有什么区别呢&#xff1f; 首先&#…

剑指 Offer !!56 - II. 数组中数字出现的次数 II

剑指 Offer 56 - II. 数组中数字出现的次数 II 在一个数组 nums 中除一个数字只出现一次之外&#xff0c;其他数字都出现了三次。请找出那个只出现一次的数字。示例 1&#xff1a;输入&#xff1a;nums [3,4,3,3] 输出&#xff1a;4 示例 2&#xff1a;输入&#xff1a;nums …

智慧停车场:城市出行新潮流,轻松驶入未来

在如今城市日益拥堵的交通环境下&#xff0c;停车难题成为人们日常生活中的一大困扰。然而&#xff0c;随着科技的不断进步&#xff0c;智慧停车场的建设正为我们带来更为便捷、高效的出行体验&#xff0c;成为现代城市发展的重要一环。 智慧停车场利用先进的技术手段&#xff…

Nginx安装以及LVS-DR集群搭建

Nginx安装 1.环境准备 yum insatall -y make gcc gcc-c pcre-devel #pcre-devel -- pcre库 #安装openssl-devel yum install -y openssl-devel 2.tar安装包 3.解压软件包并创建软连接 tar -xf nginx-1.22.0.tar.gz -C /usr/local/ ln -s /usr/local/nginx-1.22.0/ /usr/local…

windows 安装免费3用户ccproxy ubuntu 代理上网

Windows 上进行安装 ubuntu 上进行设置 方法一 (临时的手段) 如果仅仅是暂时需要通过http代理使用apt-get&#xff0c;您可以使用这种方式。 在使用apt-get之前&#xff0c;在终端中输入以下命令&#xff08;根据您的实际情况替换yourproxyaddress和proxyport&#xff09;。 终…

水果音乐制作软件fl studio汉化中文修改版下载,FL Studio哪个版本更合适新手

水果音乐制作软件fl studio汉化中文修改版下载由兔八哥爱分享小编精心为大家整理了fl studio软件所有版本合集。水果音乐制作软件fl studio汉化中文修改版下载其中包含了fl studio、以及fl studio汉化补丁、fl studio修改程序、fl studio注册机等等&#xff0c;fl studio是一款…

【某SH公E司IN 数据挖掘工程师-提前批笔试2023-8-8】

题目&#xff08;回忆版&#xff09;&#xff1a; 给一棵树&#xff0c;每个节点要么是白色要么是红色&#xff0c;并且有节点编号&#xff0c;要求查询每个节点所在子树中红色节点的数量。 先是一个正整数 n&#xff0c;表示树有 n 个节点。 第二行给出 n-1 个数字&#xff0…

标准的OSI七层模型(其实了解tcp足矣)

七层模型&#xff0c;亦称OSI&#xff08;Open System Interconnection&#xff09;。参考模型是国际标准化组织&#xff08;ISO&#xff09;制定的一个用于计算机或通信系统间互联的标准体系&#xff0c;一般称为OSI参考模型或七层模型。 它是一个七层的、抽象的模型体&#x…

Mermaid语法使用

Mermaid语法使用 1. 基础类1.1 流程图1.2 时序图 2. 工程图2.1 类图2.2 Git图 1. 基础类 1.1 流程图 graph TBid1(圆角矩形)--普通线-->id2[矩形];subgraph 子图id2粗线>id3{菱形}id3-. 虚线.->id4>右向旗帜]id3--无箭头---id5((圆形))end方向定义 用词含义TB从…

Spring(13) IOC的工作流程

目录 一、定义二、Bean的声明方式三、IOC的工作流程 一、定义 IOC&#xff1a;全称是 Inversion Of Control&#xff0c;也就是控制反转&#xff0c;它的核心思想是把对象的管理权限交给容器。应用程序如果需要使用某个对象的实例&#xff0c;那么直接从 IOC 容器里面去获取就…

Win10无法投影关闭3D模式

Win10不小心开启了3D模式&#xff0c;插上投影仪就一闪一闪的&#xff0c;无法正投影 解决办法&#xff1a; 1. 打开注册表工具regedit&#xff0c;删除以下注册表&#xff0c;重启电脑 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\GraphicsDrivers\Configurat…

PAT(Advanced Level) Practice(with python)——1023 Have Fun with Numbers

Code N int(input()) D_N 2*N # print(Yes)if len(str(D_N))>len(str(N)):print(No) else:for s in str(D_N):if s not in str(N) or str(D_N).count(s)!str(N).count(s):print("No")breakelse:print(Yes) print(D_N)

R语言5_安装Giotto

环境Ubuntu22/20, R4.1. 已开启科学上网。 第一步&#xff0c;更新服务器环境&#xff0c;进入终端&#xff0c;键入如下命令&#xff0c; apt-get update apt install libcurl4-openssl-dev libssl-dev libxml2-dev libcairo2-dev libgtk-3-dev libhdf5-dev libmagick9-dev …

第一百二十五天学习记录:C++提高:STL-deque容器(下)(黑马教学视频)

deque插入和删除 功能描述&#xff1a; 向deque容器中插入和删除数据 函数原型&#xff1a; 两端插入操作&#xff1a; push_back(elem); //在容器尾部添加一个数据 push_front(elem); //在容器头部插入一个数据 pop_back(); //删除容器最后一个数据 pop_front(); //删除容器…

flutter开发实战-TextPainter计算文本内容的宽度

flutter开发实战-TextPainter计算文本内容的宽度 最近开发过程中根据Text文本的大小判断是否需要进行显示跑马灯效果&#xff0c;获取文本的大小&#xff0c;需要TextPainter来获取Size 一、TextPainter TextPainter主要用于实现文本的绘制。TextPainter类可以将TextSpan渲染…

【从零开始学习JAVA | 第四十四篇】TCP协议中的握手与挥手

前言&#xff1a; TCP&#xff08;传输控制协议&#xff09;作为计算机网络中的重要协议&#xff0c;扮演着确保数据可靠传输的角色。在TCP的通信过程中&#xff0c;握手与挥手问题是不可忽视的关键环节。握手是指在建立连接时&#xff0c;客户端与服务器相互确认彼此的身份并…

Json简述(C++)

目录 1.介绍 2.格式 3.底层 3.1数据对象表示 3.2序列化接口 3.3反序列化接口 4.使用 1.介绍 Json&#xff08;JavaScript Object Notation&#xff09;是一种轻量级的数据交换格式&#xff0c;其最早是为JavaScript编程语言设计的格式。不过发发展至今&#xff0c;Jso…

[RoarCTF 2019Online Proxy]sql巧妙盲注

文章目录 [RoarCTF 2019Online Proxy]sql巧妙盲注解题脚本脚本解析 [RoarCTF 2019Online Proxy]sql巧妙盲注 解题 在源代码界面发现&#xff1a;Current Ip 我们会联想到&#xff1a;X-Forwarded-For来修改ip&#xff1a; 结果我们发现&#xff0c;response会讲Last Ip回显出…

基于协同过滤的电影推荐

基于协同过滤的推荐算法综述 - 知乎 (zhihu.com) # -*- coding: gbk -*- import pandas as pd_userID 1#电影评分排序 ratings pd.read_csv(ml-latest-small/ratings.csv) #打印前20行 #print(ratings.head(10))#电影所属类别 movies pd.read_csv(ml-latest-small/movies.cs…