【Linux】Linux中的环境变量及其意义

news2025/7/17 18:12:27


目录

一、环境变量的概念

1、让自己写的可执行程序无需路径即可执行的方法

1.1将可执行程序拷贝至/usr/bin/目录下

1.2将test的绝对路径添加至PATH中

二、环境变量相关的命令

三、getenv()(获取环境变量)

四、main函数命令行参数的解析及意义

1、main函数命令行参数的解析

2、main函数命令行参数的意义

五、本地变量和全局变量的区别

1、为什么该程序只能找到全局变量却找不到本地变量?

2、为什么执行指令时默认是当前路径

六、环境变量的作用

1、写一个自己的pwd命令

2、通过环境变量限制用户权限

3、通过main函数命令行参数设计指令


一、环境变量的概念

环境变量是操作系统为了满足不同的应用场景而预先在系统内设置的一大批全局变量。

./test
ls

我们自己写的可执行程序需要带上路径,而系统中ls指令不用路径即可执行。因为环境变量PATH中存放系统的默认搜索路径,我们的可执行程序不能直接执行,是因为可执行程序的路径不在PATH中。

1、让自己写的可执行程序无需路径即可执行的方法

1.1将可执行程序拷贝至/usr/bin/目录下

环境变量PATH中存在/usr/bin目录(这个目录其实是指令存放的目录)。我们可以把自己写的可执行程序添加到/usr/bin目录中,让用户的可执行程序无需指令也能运行。将可执行程序test拷贝至/usr/bin/目录下:

sudo cp test /usr/bin/
sudo rm /usr/bin/test

1.2将test的绝对路径添加至PATH中

错误的添加路径的方法:

export PATH=路径

注意,直接用等号的话原有路径是会被覆盖的,如果误操作,可以把Xshell重启一下。重启恢复的原因是家目录中有这两个配置文件,每次启动时会将对应的环境变量导入到bash的上下文环境中:

正确添加路径的方法:

export PATH=$PATH:路径

二、环境变量相关的命令

1、set:显示本地定义的shell变量和环境变量。

2、unset:取消环境变量。

3、export:将本地变量设置为全局变量。

export NEWVAL="123"

4、env:显示所有环境变量。

5、echo:显示某个环境变量的值

echo $PWD//查看PWD环境变量
echo $PATH//查看PATH中的路径

操作系统在启动的时候,存在一个叫PATH的环境变量,这个变量在系统内是全局有效的。查看PATH中的路径:

路径之间以冒号间隔(Windows中是分号),这些路径决定了shell去哪些目录中寻找命令或指令。

三、getenv()(获取环境变量)

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

不同的用户使用getenv函数获得当前name环境变量的内容不同。

getenv()是第一种获取环境变量的方式(最推荐)。

四、main函数命令行参数的解析及意义

1、main函数命令行参数的解析

我们在命令行输入命令的时候,本质上是输入了一个大的字符串,这些字符串会被单独拆开。指针数组char* argv[]中按顺序存储这些个被拆开的字符串的地址。bash负责字符串的解析和传参。

再看,main函数是有三个参数的,第三个变量就是环境变量指针数组:

有了第三个参数,环境变量就能被进程拿到了,char* env[]是第二种获取环境变量的方式

再看,为什么我们平常写代码main函数不传参数代码也能运行?他是怎么获取到环境变量的?

environ是系统中的一个全局的二级指针,它指向命令行参数表,作为参数传递给char* env[]。environ没有包含在任何头文件中,所以在使用时 要用extern声明。

int main() 
{ 
	extern char** environ; //声明
	for(int i = 0; environ[i]; i++)//environ[i]最后会走到NULL停止循环
    { 
    	printf("%d:%s\n", i, environ[i]); 
    }
	return 0;
}

char** environ是第三种获取环境变量的方式。

那么有人会问了,平常写代码我也没声明environ啊,为什么程序也能找到它的环境变量?那是因为环境变量本身是被加载到物理内存,再映射到进程的进程地址空间中,这样,每个程序即使不主动获取环境变量,这些环境变量也已经被加载到虚拟内存中了。

2、main函数命令行参数的意义

int main()
{
	if(argc != 2)
    {
        printf("Usage: \n\t%s [-a/-b/-c/-ab/-bc/-ac/-abc]\n", argv[0]);
        return 1;
    }
    if(strcmp("-a", argv[1]) == 0)
    {
        printf("功能a\n");
    }
    if(strcmp("-b", argv[1]) == 0)
    {
        printf("功能b\n");
    }
    if(strcmp("-c", argv[1]) == 0)
    {
        printf("功能c\n");
    }
    if(strcmp("-ab", argv[1]) == 0)
    {
        printf("功能ab\n");
    }
    if(strcmp("-bc", argv[1]) == 0)
    {
        printf("功能bc\n");
    }
    return 0;
}

指令的设计就是使用这种方式,在函数中对输入指令进行判断,再执行对应指令。无非就是使用C语言对具体功能进行封装。

五、本地变量和全局变量的区别

先创建一段本地变量:

myval=123456

写一段代码: 

#include <stdio.h>
#include <stdlib.h>
int main()
{
    char* val=getenv("myval");
    if(val==NULL)
    {
        printf("未找到myval\n");
    }
    else 
    {
        printf("%s\n",val);
    }
    return 0;
}

可以发现这个程序是找不到本地变量的。

那我们使用export修改一下本地变量myval为全局变量:

export myval

可执行程序便能找到myval这个全局变量了。

1、为什么该程序只能找到全局变量却找不到本地变量?

我们知道,bash是一个系统进程,mytest会通过fork()变成bash的子进程。环境变量具有全局属性,可以被子进程继承。我们可以通过这些全局变量找指令路径,进行身份认证等。

而本地变量仅当前进程(bash)有效,它的子进程无效。

2、为什么执行指令时默认是当前路径

因为有一个PWD的环境变量,它维护着用户当前所处的绝对路径,可以看到,当用户所处的路径变化时,PWD环境变量会自动更新,我们在执行的指令,这些指令本质上是bash的子进程,它们可以拿到这个全局变量,这些指令也就知道了目前所处的绝对路径。

六、环境变量的作用

1、写一个自己的pwd命令

#include <stdio.h>
#include <stdlib.h>
#define MYPWD "PWD"
int main()
{
    char* p=getenv(MYPWD);
    printf("%s",p);
    return 0;
}

写完后再命令行使用sudo cp mypwd /usr/bin/将可执行程序放入/usr/bin/目录下(/usr/bin/是PATH中的一个路径,用于存放指令)

所以该类指令本质上是通过C语言封装后的接口。

2、通过环境变量限制用户权限

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
    char* name=getenv("USER");
    if(strcmp(name,"root")==0)
    {
         printf("%s\n",name);
    }
    else 
    {
        printf("权限不足\n");
    }
    return 0;
}

可以发现,通过"USER"环境变量可以对不同角色进行权限的限制。

3、通过main函数命令行参数设计指令

见本文第四节。

广告别信:

《 符合学习规律的超详细linux实战快速入门》

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

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

相关文章

如何基于TS在React中使用Redux Toolkit

什么是Redux Redux 是 JavaScript 应用程序的状态容器&#xff0c;提供可预测的状态管理.可以帮助你开发出行为稳定可预测的、运行于不同的环境&#xff08;客户端、服务器、原生应用&#xff09;、易于测试的应用程序。不仅于此&#xff0c;它还提供超爽的开发体验&#xff0…

【Pytorch with fastai】第 3 章 :数据伦理

&#x1f50e;大家好&#xff0c;我是Sonhhxg_柒&#xff0c;希望你看完之后&#xff0c;能对你有所帮助&#xff0c;不足请指正&#xff01;共同学习交流&#x1f50e; &#x1f4dd;个人主页&#xff0d;Sonhhxg_柒的博客_CSDN博客 &#x1f4c3; &#x1f381;欢迎各位→点赞…

CentOS7安装MySQL(亲测版)

1 Yum Repository下载安装包文件 [rootlocalhost home]# wget https://dev.mysql.com/get/mysql57-community-release-el7-8.noarch.rpm2 使用yum安装mysql yum install mysql-server执行后报错&#xff0c;官方5.7版本默认没有GPG key, 需要在上述命令上 添加 --nogpgcheck …

图解计算机内部的高速公路 —— 总线系统

本文已收录到 GitHub AndroidFamily&#xff0c;有 Android 进阶知识体系&#xff0c;欢迎 Star。技术和职场问题&#xff0c;请关注公众号 [彭旭锐] 进 Android 面试交流群。 前言 大家好&#xff0c;我是小彭。 在之前的文章中&#xff0c;我们聊到了计算机的冯诺依曼计算…

2022-09-17青少年软件编程(C语言)等级考试试卷(五级)解析

​​​​​​T1. 城堡问题 【题目描述】 图1是一个城堡的地形图。请你编写一个程序,计算城堡一共有多少房间,最大的房间有多大。城堡被分割成mn(m≤50,n≤50)个方块,每个方块可以有0~4面墙。 【输入】 程序从标准输入设备读入数据。第1、2行每行1个整数,分别是南北向、东西…

MySQL数据库基础

文章目录一. 数据库的操作二. 数据库中常用的数据类型三.表的操作四. 总结一. 数据库的操作 1. 创建数据库 创建语法1 crate database [这里填入表名称]; 说明&#xff1a;当我们创建数据库没有指定字符集和校验规则时&#xff0c;系统使用默认字符集&#xff1a;utf8&#xf…

(十二)Jmeter测试dubbo接口

一、概览 先去https://github.com/thubbo/jmeter-plugins-for-apache-dubbo下载扩展jar包将下载的jar包复制到 jmeter/lib/ext/下重启Jmeter创建Dubbo取样器 二、实操 添加dubbo取样器 输入请求详情 参数类型可以在 https://github.com/thubbo/jmeter-plugins-for-apache-…

如何在Retail Link网站上与Walmart进行EDI连接测试?

本文主要介绍通过沃尔玛Walmart供应商平台Retail Link与沃尔玛Walmart建立EDI连接的流程。沃尔玛Walmart作为零售行业中最先使用AS2协议传输EDI数据的企业之一&#xff0c;其AS2经过多年的使用检验&#xff0c;具有安全连接、灵活数据传输等优点&#xff0c;使其经久不衰&#…

Qt Xml文件的创建和解析[xml和dom方式]

Qt Xml文件的创建和解析[xml和dom方式] 【1】Qt XML使用说明【2】Qt XML未来可期【3】Qt XML文件格式【4】Qt 读取XML文档的方法【5】Qt XML解析方式比较【6】QXmlStreamReader类说明【7】QXmlStreamWriter类说明【8】DOM说明【9】XML常用函数【10】DOM常用函数【11】XML和DOM源…

摊牌了,请各位做好一年内随时失业的准备

前两天跟一个HR朋友聊天&#xff0c;她表示刚在boss上发布了一个普通测试岗位&#xff0c;不到一小时竟然收到了几百份简历。而且简历质量极高&#xff0c;这是往年不敢想象的。岗位少&#xff0c;竞争激烈&#xff0c;这是今年软件测试就业的真实写照&#xff0c;也是所有岗位…

Python开发环境及常用Web框架

Python Python是一门易于学习、功能强大的编程语言。它提供了高效的高级数据结构&#xff0c;还能简单有效地面向对象编程。Python 优雅的语法和动态类型以及解释型语言的本质&#xff0c;使它成为多数平台上写脚本和快速开发应用的理想语言。 吉多范罗苏姆&#xff08;Guido…

基于Postmate实现的跨域通信

1、Postmate 介绍 是一款基于 postMessage 来处理父子页面通信的库&#xff0c;轻量且好用。一个强大的、简单的、基于 promise 的 postMessage iFrame 通信库。 postmate 官方地址 https://github.com/dollarshaveclub/postmate 2、Postmate 特性 基于 promise 的 API&…

如何将数字改为千分符且保留两位小数显示?toLocaleString()和toFixed(2)踩坑

前言 基于现代Web前端框架的应用&#xff0c;其原理是通过浏览器向服务器发送网络请求&#xff0c;获取必要的index.html和打包好的JS、CSS等资源&#xff0c;在浏览器内执行JS&#xff0c;动态获取数据并渲染页面&#xff0c;从而将结果呈现给用户。在这个过程中&#xff0c;…

【java学习】 static

文章目录成员变量static 工具类static 代码块设计模式继承重写成员变量 1&#xff0e;成员变量的分类和访问分别是什么样的? 静态成员变量&#xff08;有static修饰&#xff0c;属于类、加载一次&#xff0c;可以被共享访问)&#xff0c;访问格式 类名.静态成员变量(推荐) 对…

R语言七天入门教程六:文件相关操作

R语言七天入门教程六&#xff1a;文件相关操作 一、文件的读写 R 语言作为统计学编程语言&#xff0c;常常需要处理大量数据&#xff0c;而这些数据通常会从文件中进行读取&#xff0c;因此文件读写在R语言中是非常重要的操作。在R语言中&#xff0c;用到最多的文件格式是csv…

Carla安装记录

Carla安装记录 最近打算在做一些自动驾驶相关的东西&#xff0c;所以安装了一下Carla。在这里记录一些自己的安装过程中遇到的一些问题和解决的方法。 Carla release版本下载 想要安装Carla&#xff0c;可以选择release版本或者源码安装。在这里我主要介绍release版本的安装…

Vue3、vite项目页面自适应配置(postcss-plugin-px2rem、amfe-flexible)

文章目录前言&#xff1a;vite 如何处理 csspostcss项目配置下载相关包配置方案一方案二&#xff08;备选方案&#xff09;相关资料链接前言&#xff1a;vite 如何处理 css vite 天生就支持对css文件的直接处理 关于预处理器 ☀️目前&#xff0c;在工程化开发中&#xff0c;使…

AcWing-C/C++语法基础【合集2】

5.字符串 每个常用字符都对应一个-128~127的数字 &#xff0c;二者之间可以相互转化&#xff1a; (int)97 , (char)a 常用ASCII值&#xff1a;’A’-‘Z’ 是65~90&#xff0c;’a’-‘z’是97-122&#xff0c;’0’-‘9’是 48-57 字符可以参与运算&#xff0c;运算时会将其当…

2022年11月编程排行榜

2022年11月Tiobe编程排行榜已更新&#xff0c;研一的生涯也快结束&#xff0c;来看一下本月各大编程语言有何新进展&#xff1a; 目录&#xff1a;11月编程排行榜一、榜单情况二、榜单简单的分析一、榜单情况 这里只展示排名靠前的前15名&#xff1a; TOP 10编程语言TIOBE指数…

播放视频出现错误代码0xc00d36c4如何修复?

相信很多用户都遇到过视频无法播放的问题。比如将重要视频从旧电脑拷到U盘上&#xff0c;使用另一台电脑播放时&#xff0c;提示视频播放错误代码0xc00d36c4&#xff0c;不支持该视频播放。 其实&#xff0c;视频无法播放的问题是很常见的&#xff0c;不少用户将相机或者手机上…