【从浅学到熟知Linux】环境变量详谈(含使用程序获取环境变量的3种方法、如何查看环境变量)

在这里插入图片描述

🏠关于专栏:Linux的浅学到熟知专栏用于记录Linux系统编程、网络编程及数据库等内容。
🎯每天努力一点点,技术变化看得见

文章目录

  • 环境变量基本概念
  • 查看环境变量的方法
  • 环境变量相关命令
  • 环境变量组织方式及获取环境变量的3种方法
  • 验证环境变量的全局属性


环境变量基本概念

环境变量一般是指在操作系统中用来指定操作系统运行环境的一些参数。
环境变量通常具有某些特殊用途,在系统当中通常具有全局特性

【示例1】我们在系统中执行ls命令时,不需要./ls。而我们执行自己编写的C语言程序,并将它编译成test时,我们要执行它就需要./test才能够运行,这是为什么呢?

which命令后带上某个命令,就可以查看该指令的存储位置。如果执行which ls,可以看到ls存储在/usr/bin/目录中。

系统中维护了一个PATH环境变量,系统可以帮助我们在PATH环境变量保存的各个路径中查找命令。我们可以使用echo $[环境变量名]来查看某个环境变量的值,此时我们执行echo $PATH,结果如下图所示。可以发现,PATH环境变量种保存着/usr/bin目录。
在这里插入图片描述
也就是说,只要我们执行某个命令,系统默认从PATH环境变量下的各个目录进行搜索,如果存在该命令的可执行文件,则执行,否则就会报错。

而我们自己写的程序并没有保存PATH环境变量指定的目录下时,无法不带./就执行(或者是使用绝对路径的方式)。我们可以通过将该程序移动到PATH环境变量保存的某个目录中,这样就可以不带./运行了。但这种方式会污染系统命令,因为我们的程序并没有经过大量测试,可能存在大量错误,不建议将自己写的命令放入PATH变量的各个目录中。

【示例2】我们在编写C/C++代码的时候,在链接的时候,从来不知道我们的所链接的动态静态库在哪里,但是照样可以链接成功,生成可执行程序,原因就是有相关环境变量帮助编译器进行查找。

查看环境变量的方法

echo $[环境变量名]

在这里插入图片描述

下面我们来看一下常见的环境变量:
●PATH:指定命令的搜索路径
命令本质就是可执行文件,我们没有指定命令的可执行文件地址,但它会从PATH环境变量内的各个目录中查找该命令是否存在,存在则执行,不存在则报错。
在这里插入图片描述
●HOME:指定用户的主工作目录(即用户登陆到Linux系统中的默认目录)
当我以root用户身份登录时,我的HOME环境变量保存的是/root;但如果我以xiaoming用户身份登录时,我的HOME环境变量保存的/home/xiaoming。从这里可以发现,不同用户的HOME目录(也成为家目录)是不一样的。
在这里插入图片描述
●SHELL:当前Shell,它的值通常是/bin/bash
我们启动一个Linux命令行,本质就是执行一个bash程序。bash在执行用户程序、指令时,会fork子进程执行,即使子进程因程序问题而出错,也不会影响到bash的稳定运行,也就不会影响到用户的命令行使用了。
在这里插入图片描述

环境变量相关命令

  • echo:显示某个环境变量值(上面已经有介绍,这里不再赘述)

使用实例↓↓↓

echo $PWD

在这里插入图片描述

  • env:显示所有环境变量

使用实例↓↓↓

env

在这里插入图片描述

  • export:设置一个新的环境变量

使用实例↓↓↓

export jammingpro=666

在这里插入图片描述
在这里插入图片描述
要注意的是,export设置的环境变量仅在当前会话有效,当我们将整个会话关闭,重新打开Linux命令行时,这个环境变量就会消失。

在系统中,每次启动bash时,该bash都会从系统的环境变量配置文件中读取环境变量信息,export仅仅修改了本次启动的bash的环境变量,一旦关闭重启后,原来设置的环境变量不再存在,新启动的bash会重新从系统的环境变量配置文件中读取环境变量信息

如果我们想设置持久化的环境变量,可以修改/etc/profile添加环境变量,例如:下图中新增了jammingpro=666的环境变量↓↓↓(这样设置后,以后启动Linux的任何bash命令行中都会存在该环境变量)
在这里插入图片描述

  • set:显示本地定义的shell变量和环境变量

使用实例↓↓↓

set

在这里插入图片描述

我们可以在bash命令行直接定义变量,例如:baymaxPro=999(不需要使用export)。而set显示的除了环境变量外,还显示了本地自定义的shell变量。
在这里插入图片描述
那本地定义的变量和当前bash的环境变量有什么区别呢?当我们创建子进程时,当前bash的环境变量会被子进程继承,也就是说,bash执行的程序都有和bash相同的环境变量;但本地定义的变量不会被子进程继承。

  • unset:清除环境变量
unset [待清除的环境变量名]

在这里插入图片描述
由上图可以发现,unset既可以清除环境变量,也可以清除本地自定义的Shell变量。

环境变量组织方式及获取环境变量的3种方法

每个进程都有一张环境表,环境表是一个字符指针数组,每个指针指向一个以’\0’结尾的环境字符串
在这里插入图片描述
下面我们介绍3种可以从环境变量表获取环境变量的方法↓↓↓

  • getenv

在这里插入图片描述
使用getenv实现pwd命令↓↓↓

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

在这里插入图片描述

  • environ(第三方变量)

在这里插入图片描述
使用environ时,需要先对该变量进行声明,即extern char** environ。下面使用代码打印环境表种的所有内容↓↓↓

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

在这里插入图片描述

★ps:libc种定义的全局变量environ指向环境变量表,environ没有包含在任何头文件种,所以使用时要使用extern声明。

  • main的env参数(命令行第三个参数)

我们在使用命令执行某些可执行程序时,bash会帮助给该程序传入3个参数↓↓↓
在这里插入图片描述

以ls命令为例,ls -a -l,它的命令行参数有3个,分别时ls、-a、-l,因此argv保存的就是{“ls”, “-a”, “-l”, NULL},而第三个参数就是bash传递给它的子进程的环境变量。

下面我们使用main的env参数打印所有环境变量↓↓↓

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

在这里插入图片描述

下面我们自定义一个命令xm,该命令只允许用户带一个选项,如果带的选项是-a就输出"xiaoming say => you are nice!!“,带-b选项就输出"what are you doing now?”,用户选项输出与要求不符的提示用户如何使用该命令↓↓↓

#include <stdio.h>
#include <string.h>void Usage()
{printf("\r\tYou are supposed to use -a or -b\n");
}int main(int argc, char* argv[], char* env[])
{if(argc == 2 && strcmp("-a", argv[1]) == 0){printf("xiaoming say => you are nice!!\n");}else if(argc == 2 && strcmp("-b", argv[1]) == 0){printf("what are you doing now?\n");}else {Usage();}return 0;
}

在这里插入图片描述

验证环境变量的全局属性

环境变量具有全局属性,可以被子进程继承下去。子进程的环境变量是从父进程继承来的,默认所有的环境变量都会被子进程继承。

编写一个程序proc,用于获取名为jammingpro的环境变量↓↓↓

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

当前bash中开始时没有名为jammingpro的环境变量,此时使用export jammingpro=666设置环境变量,再指向proc程序时,proc程序可以获得该环境变量。说明子进程可以继承父进程的环境变量。
在这里插入图片描述
如果我们此时unset名为jammingpro的变量,并定义名为jammingpro的shell自定义变量,此时执行proc程序时会发送段错误。说明子进程不能继承bash中的shell自定义变量。
在这里插入图片描述

🎈欢迎进入从浅学到熟知Linux专栏,查看更多文章。
如果上述内容有任何问题,欢迎在下方留言区指正b( ̄▽ ̄)d

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

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

相关文章

Cesium.js--》探秘Cesium背后的3D模型魔力—加载纽约模型

今天简单实现一个Cesium.js的小Demo&#xff0c;加强自己对Cesium知识的掌握与学习&#xff0c;先简单对这个开源库进行一个简单的介绍吧&#xff01; Cesium 是一个开源的地理空间可视化引擎&#xff0c;用于创建基于 Web 的三维地球应用程序。它允许开发人员在网页上呈现高度…

Java基础第十一课——类与对象(2)

由于类与对象这一部分的知识点很多&#xff0c;而且操作方法也有很多&#xff0c;所以这次将继续深入讨论一下关于类与对象中方法传参、方法重载、构造方法以及this关键字使用方面的知识。 一、方法传参 1.return关键字 return关键字作用 作用场景&#xff1a;方法内 作用…

天猫精灵要会员,不能听歌,还能用来干什么呢?榨干它的剩余价值

目录 起因&#xff1a;以听歌为主要功能的设备&#xff0c;却不能听歌了 1.蓝牙音箱 2.控制智能家电 3.万能遥控器&#xff0c;需要一个外接设备 4.倒计时/提醒&#xff0c;闹钟提醒&#xff0c;整点提醒&#xff08;这功能有人不喜欢&#xff0c;闲吵&#xff0c;还不能关…

LeetCode题练习与总结:最小路径和--64

一、题目描述 给定一个包含非负整数的 m x n 网格 grid &#xff0c;请找出一条从左上角到右下角的路径&#xff0c;使得路径上的数字总和为最小。 说明&#xff1a;每次只能向下或者向右移动一步。 示例 1&#xff1a; 输入&#xff1a;grid [[1,3,1],[1,5,1],[4,2,1]] 输出…

UI设计规范

一套商城系统的诞生&#xff0c;除了代码的编写&#xff0c;UI设计也至关重要。UI设计关系到商城系统的最终呈现效果&#xff0c;关乎整体商城的风格展现&#xff0c;如果UI设计做不好&#xff0c;带来的负面影响也是不容小觑的。 1、在很多商城系统开发中&#xff0c;有时会有…

【Sql Server】锁表如何解锁,模拟会话事务方式锁定一个表然后进行解锁

大家好&#xff0c;我是全栈小5&#xff0c;欢迎来到《小5讲堂》。 这是《Sql Server》系列文章&#xff0c;每篇文章将以博主理解的角度展开讲解。 温馨提示&#xff1a;博主能力有限&#xff0c;理解水平有限&#xff0c;若有不对之处望指正&#xff01; 目录 前言创建表模拟…

运放噪声评估的来龙去脉

运放噪声评估的来龙去脉 友情提示&#xff0c;运放电路的噪声分析还是比较复杂的&#xff0c;不论是基础理论还是对应的推导过程&#xff0c;都不是特别容易。考虑到兄弟们的基础参差不齐&#xff0c;所以我还是尽量说清楚点&#xff0c;这样导致看起来就有点罗里吧嗦&#xff…

10 Php学习:循环

在 PHP 中&#xff0c;提供了下列循环语句&#xff1a; while - 只要指定的条件成立&#xff0c;则循环执行代码块do…while - 首先执行一次代码块&#xff0c;然后在指定的条件成立时重复这个循环for - 循环执行代码块指定的次数foreach - 根据数组中每个元素来循环代码块 当…

【Java EE】获取Cookie和Session

文章目录 &#x1f38d;Cookie简介&#x1f340;理解Session&#x1f333;Cookie 和 Session 的区别&#x1f332;获取Cookie&#x1f338;传统获取Cookie&#x1f338;简洁获取Cookie &#x1f334;获取Session&#x1f338;Session存储&#x1f338;Session读取&#x1f33b;…

Fence同步

在《Android图形显示系统》没有介绍到帧同步的相关概念&#xff0c;这里简单介绍补充一下。 在图形显示系统中&#xff0c;图形缓存GraphicBuffer可以被不同的硬件来访问&#xff0c;如CPU、GPU、HWC都可以对缓存进行读写&#xff0c;如果同时对图形缓存进行操作&#xff0c;有…

mysql8.0高可用集群架构实战

MySQL :: MySQL Shell 8.0 :: 7 MySQL InnoDB Cluster 基本概述 InnoDB Cluster是MySQL官方实现高可用读写分离的架构方案,其中包含以下组件 MySQL Group Replication,简称MGR,是MySQL的主从同步高可用方案,包括数据同步及角色选举Mysql Shell 是InnoDB Cluster的管理工具,用…

java项目之校园兼职系统(ssm框架+mysql数据库+文档)

项目简介 校园兼职系统的主要使用者分为&#xff1a;管理员&#xff1a;首页、个人中心、专业管理、商家管理、热门兼职管理、学生管理、兼职接单管理、学生咨询管理、兼职任务管理、完成评价管理、管理员管理、系统管理等模块信息的查看及相应操作&#xff1b;学生&#xff1…

OpenCV C++学习笔记

1.图像的读取与显示 1.1 加载并显示一张图片 #include<opencv2/opencv.hpp> #include<iostream>using namespace cv; using namespace std; int main(int argc,char** argv){Mat srcimread("sonar.jpg");//读取图像if(src.empty()){printf("Could…

超越传统Lambda函数:深入解析Out-of-line Lambdas的奇妙之处

超越传统函数&#xff1a;深入解析线外 Lambda函数 的奇妙之处 一、背景二、lambda 的捕获三、可能出现的警告四、lambda的广义捕获五、为每种情况进行重载六、总结 一、背景 Out-of-line Lambdas翻译过来就是“线外Lambda函数”或“离线Lambda函数”。Lambda 是使代码更具表现…

力扣 | 234. 回文链表

用到快慢指针&#xff01; /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode() {}* ListNode(int val) { this.val val; }* ListNode(int val, ListNode next) { this.val val; this.next next;…

ZooKeeper分布式服务与Kafka消息队列+ELKF整合方案

前言 ZooKeeper 是一个分布式的、开放源码的分布式应用程序协调服务&#xff0c;提供配置维护、命名服务、分布式同步、组服务等功能&#xff1b; Kafka 是一个开源的分布式流处理平台&#xff0c;它被设计用来处理实时数据流&#xff0c;包括发布和订阅消息系统、日志收集以…

叉车载货出入库AI检测算法介绍及应用

随着物流行业的快速发展&#xff0c;叉车作为物流运输的重要设备&#xff0c;其安全性和效率性越来越受到人们的关注。然而&#xff0c;在实际操作中&#xff0c;由于人为因素和操作环境的复杂性&#xff0c;叉车事故时有发生&#xff0c;给企业和个人带来了巨大的损失。为了提…

HarmonyOS开发实例:【app帐号管理】

应用帐号管理 介绍 本示例选择应用进行注册/登录&#xff0c;并设置帐号相关信息&#xff0c;简要说明应用帐号管理相关功能。效果图如下&#xff1a; 效果预览 使用说明参考鸿蒙文档&#xff1a;qr23.cn/AKFP8k点击或者转到。 1.首页面选择想要进入的应用&#xff0c;首次进…

JetBrains PhpStorm 2024.1 发布 - 高效智能的 PHP IDE

JetBrains PhpStorm 2024.1 发布 - 高效智能的 PHP IDE 请访问原文链接&#xff1a;JetBrains PhpStorm 2024.1 (macOS, Linux, Windows) - 高效智能的 PHP IDE&#xff0c;查看最新版。原创作品&#xff0c;转载请保留出处。 作者主页&#xff1a;sysin.org JetBrains PhpSt…

C语言: 字符串函数(下)

片头 在上一篇中,我们介绍了字符串函数。在这一篇章中&#xff0c;我们将继续学习字符串函数&#xff0c;准备好了吗&#xff1f;开始咯&#xff01; 1.strncpy函数 1.1 strncpy函数的用法 strncpy是C语言中的一个字符串处理函数&#xff0c;它用于将一个字符串的一部分内容…