深入了解Linux中的环境变量

在Linux系统中,环境变量(Environment Variables)是用于配置操作系统和应用程序运行环境的一种机制。它们储存在键值对中,可以控制程序的行为、路径查找和系统配置。本文将深入探讨环境变量的基本概念、常见类型、设置和管理方法,以及一些实用的技巧。

一、环境变量的基本概念

环境变量是在操作系统环境中定义的一些变量,用于存储信息,以便在系统中共享和使用。这些变量可以影响程序的行为和操作系统的功能。

  • 环境变量(environment variables)一般是指在操作系统中用来指定操作系统运行环境的一些参数
  • 如:我们在编写C/C++代码的时候,在链接的时候,从来不知道我们的所链接的动态静态库在哪里,但是照样可以链接成功,生成可执行程序,原因就是有相关环境变量帮助编译器进行查找。
  • 环境变量通常具有某些特殊用途,还有在系统当中通常具有全局特性

 首先在介绍环境变量前我们先介绍以下 “命令行参数”这一概念。

我们平常在Linux中输入命令时通常是这么使用的   ls -l    copy  test.c   /home/user

为什么后面可以跟后缀使用呢,这其实就跟我们的命令行参数有关

在C和C++编程中,命令行参数通过main函数的参数传递给程序。标准的main函数签名如下:

int main(int argc, char *argv[]) 

这个签名表明程序可以接受命令行参数,并通过argcargv这两个参数来访问这些输入。接下来,我们详细讲解这两个参数的作用和使用方法。

一、argcargv 的含义
  • argc(argument count):表示命令行参数的数量,包括程序名本身。
  • argv(argument vector):是一个指向字符数组的指针数组,每个元素指向一个命令行参数的字符串。

 

二、argcargv 的详细说明
1. argc 的作用

argc是一个整数,表示命令行参数的数量。例如,如果我们运行一个名为my_program的程序,并传递两个参数:

./my_program arg1 arg2

此时,argc的值为3,因为包括程序名在内总共有三个参数 

2. argv 的作用

argv是一个指向字符串数组的指针数组。每个元素是一个char*,指向一个命令行参数。假设上面的程序命令行如下

./my_program arg1 arg2

 那么,argv的内容如下:

  • argv[0]:指向字符串"./my_program"(程序名)。
  • argv[1]:指向字符串"arg1"(第一个参数)。
  • argv[2]:指向字符串"arg2"(第二个参数)。

argv[argc]是一个空指针(NULL),用于标记数组的结束。

三、实例讲解

下面是一个简单的C程序,它演示了如何使用argcargv来处理命令行参数:

#include <stdio.h>int main(int argc, char *argv[]) {// 打印命令行参数的数量printf("Number of arguments: %d\n", argc);// 遍历并打印每一个参数for (int i = 0; i < argc; i++) {printf("Argument %d: %s\n", i, argv[i]);}return 0;
}

 假设我们编译并运行该程序,传递一些命令行参数

./my_program arg1 arg2 arg3

 输出将是:

Number of arguments: 4
Argument 0: ./my_program
Argument 1: arg1
Argument 2: arg2
Argument 3: arg3

 

./my_program arg1 arg2 arg3

所以以上命令本质就是 程序的路径 + 名称   后面跟 和该进程匹配的选项

默认是交给父进程bash处理的! 命令中启动的程序都会变成进程,其实都是bash的子进程

那么为什么要有命令行参数呢?

本质:命令行参数本质是交给我们程序的不同选项,用来定制不同的程序功能

 下面是一个简单的例子

#include <stdio.h>
#include <stdlib.h>
#include <string.h>// 打印帮助信息
void print_help(const char *program_name) {printf("Usage: %s <command> [options]\n", program_name);printf("Commands:\n");printf("  help              Show this help message\n");printf("  add <num1> <num2> Calculate the sum of num1 and num2\n");printf("  sub <num1> <num2> Calculate the difference of num1 and num2\n");printf("  mul <num1> <num2> Calculate the product of num1 and num2\n");printf("  div <num1> <num2> Calculate the quotient of num1 and num2\n");
}// 计算两个数的和
void calculate_sum(int num1, int num2) {printf("Sum: %d\n", num1 + num2);
}// 计算两个数的差
void calculate_difference(int num1, int num2) {printf("Difference: %d\n", num1 - num2);
}// 计算两个数的积
void calculate_product(int num1, int num2) {printf("Product: %d\n", num1 * num2);
}// 计算两个数的商
void calculate_quotient(int num1, int num2) {if (num2 == 0) {printf("Error: Division by zero is not allowed.\n");return;}printf("Quotient: %d\n", num1 / num2);
}int main(int argc, char *argv[]) {if (argc < 2) {fprintf(stderr, "Error: No command provided.\n");print_help(argv[0]);return 1;}if (strcmp(argv[1], "help") == 0) {print_help(argv[0]);} else if (strcmp(argv[1], "add") == 0 && argc == 4) {int num1 = atoi(argv[2]);int num2 = atoi(argv[3]);calculate_sum(num1, num2);} else if (strcmp(argv[1], "sub") == 0 && argc == 4) {int num1 = atoi(argv[2]);int num2 = atoi(argv[3]);calculate_difference(num1, num2);} else if (strcmp(argv[1], "mul") == 0 && argc == 4) {int num1 = atoi(argv[2]);int num2 = atoi(argv[3]);calculate_product(num1, num2);} else if (strcmp(argv[1], "div") == 0 && argc == 4) {int num1 = atoi(argv[2]);int num2 = atoi(argv[3]);calculate_quotient(num1, num2);} else {fprintf(stderr, "Error: Invalid command or arguments.\n");print_help(argv[0]);return 1;}return 0;
}

编译并运行上述程序后,可以通过传递不同的命令行参数来执行不同的功能。例如:

./my_program sub 10 5

 那为什么内建命令不需要./呢,所以接下来我们继续讲解环境变量 

常见的环境变量包括:

  • PATH:存储可执行文件的目录路径列表,当你在终端输入命令时,系统会在这些目录中搜索可执行文件。
  • HOME:当前用户的主目录路径。
  • USER:当前登录的用户名。
  • SHELL:用户默认的Shell解释器。
  • LANG:系统的语言和区域设置。

二、查看环境变量

可以使用printenvenv和echo命令来查看当前的环境变量:

echo + $PATH/HOME 

 

 Linux中存在一些全局的设置,告诉命令行解释器应该去哪些路径下去寻找可执行程序

而系统中的很多配置,在我们刚刚登录到Linux中,就已经被加载到了bash进程(内存)中了,

所以我们默认查到的环境变量是内存级别的也就是说不会改变磁盘中的环境变量,当我们再次登录这个环境变量还是会重置!

所以最开始的环境变量不在内存中,而在对应的配置文件中

例如

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

当执行当前目录下的外部命令时,需要使用 ./ 进行路径指定。这是因为:

  1. 安全性考虑:为了避免安全隐患,默认情况下,当前目录 . 并不包含在 PATH 环境变量中。这防止了恶意可执行文件以常用命令名命名并被误执行。
  2. 明确路径:通过使用 ./ 明确指定当前目录,用户告诉 Shell 要在当前目录中查找并执行相应的可执行文件。

例如,当前目录下有一个名为 my_script.sh 的脚本:

./my_script.sh

如果没有 ./,Shell 会按照 PATH 中指定的目录查找 my_script.sh,而不是当前目录。

所以我们把这个可执行程序的路径加入到环境变量中以后就不需要带有路径了。 

 

 三、环境变量的组织方式

环境变量在 Bash 内部是以一个键值对(key-value pair)的形式存储的。这些键值对存储在一个全局变量中,该变量在 Bash 的整个生命周期内都可以访问。 

环境变量的存储实际上依赖于操作系统提供的环境表。每个进程都有一个环境表,这个环境表是一个字符串数组,其中每个字符串的形式为 KEY=VALUE。在 Bash 中,使用外部命令 printenv 或内建命令 export 可以查看和管理这些变量。

也就是说bash进程启动的时候会默认给子进程形成两张表,一个是argv[]命令行参数表,另一个是environ[]环境变量表。bash通过各种方式传递给子进程

 

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

命令行第三个参数 

#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;
}

 通过第三方变量来获取

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

五、内建命令 

内建命令(built-in commands)是由 Shell 自身实现和提供的一类命令。与外部命令(external commands)不同,内建命令不依赖于文件系统中的独立可执行文件,而是直接在 Shell 进程中执行。内建命令的设计和实现旨在提高效率、提供更紧密的 Shell 集成以及实现一些只有 Shell 可以处理的特殊功能。下面详细介绍内建命令的作用与用途。

一、内建命令的主要作用
1. 提高执行效率

由于内建命令直接由 Shell 处理,不需要创建新的进程,因此执行速度比外部命令更快。每次执行内建命令时,Shell 不需要通过文件系统查找命令或创建子进程,这减少了开销和延迟。

2. 提供关键的 Shell 功能

内建命令实现了许多核心的 Shell 功能和控制结构,例如:

  • 环境管理exportsetunset 等命令用于设置和管理环境变量。
  • 目录操作cd 用于改变当前工作目录。
  • Shell 控制exit 退出 Shell 会话,exec 替换当前 Shell 进程。
  • 条件和循环ifforwhile 等控制结构实现了脚本中的条件和循环逻辑。
3. 处理 Shell 内部状态

一些内建命令可以直接操作和修改 Shell 的内部状态,例如设置选项、启用或禁用特性等:

  • 选项设置set 命令可以打开或关闭 Shell 的各种选项,例如调试模式、命令别名等。
  • 历史记录管理history 命令用于查看和操作命令历史记录。
4. 实现复杂的命令组合和脚本

内建命令在脚本编写中起着至关重要的作用。它们提供了丰富的编程构造,使得复杂的命令组合和脚本实现成为可能:

  • 函数定义function 用于定义 Shell 函数。
  • 输入输出重定向read 命令用于从标准输入读取数据。
二、内建命令的实现原理

内建命令是 Shell 内部实现的一部分,通常用 C 语言编写,直接集成在 Shell 的源代码中。当用户输入一个命令时,Shell 按照以下顺序进行处理:

  1. 检查内建命令:首先检查输入的命令是否为内建命令。如果是,则直接在当前进程中执行该命令。
  2. 检查别名:如果不是内建命令,Shell 接下来检查是否有定义的别名。
  3. 检查函数:然后,Shell 检查是否有定义的 Shell 函数。
  4. 搜索外部命令:最后,如果上述都不是,Shell 在 PATH 环境变量指定的目录中搜索外部命令。

这种查找顺序确保了内建命令的高效执行和优先处理。

四、总结

内建命令在 Shell 中发挥着重要作用。它们提高了命令执行的效率,提供了许多关键功能和控制结构,并且能够直接操作 Shell 的内部状态。了解和熟练使用内建命令,可以显著提升使用 Shell 和编写脚本的效率和灵活性。

如果你有任何进一步的问题或需要详细解释的内容,欢迎在评论区留言讨论。

 

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

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

相关文章

Latex公式编辑:在矩阵内画横线与竖线

在LaTeX中&#xff0c;要在矩阵内绘制横线和竖线&#xff0c;我们通常使用array或matrix环境&#xff0c;并结合\hline&#xff08;用于横线&#xff09;和|&#xff08;用于竖线&#xff09;来实现。但需要注意的是&#xff0c;\hline通常用于表格环境中。 LaTeX中绘制分块矩阵…

idea配置ssh、sftp连接服务器,docker插件使用,极其方便,无需再开第三方软件去操作服务器了,集成用于Idea一体

目录 配置SSH连接服务器 配置SFTP文件传输 Docker插件使用 配置SSH连接服务器 Setting>Tools>SSHConfigurations,点击加号新建一个连接&#xff0c;认证形式选key pair 打开终端&#xff0c;连接服务器&#xff0c;就可以终端操作服务器了 配置SFTP文件传输 文件浏览窗…

ThreadLocal简介

Thread类中&#xff0c;有个ThreadLocal.ThreadLocalMap 的成员变量。 ThreadLocalMap内部维护了Entry数组&#xff0c;每个Entry代表一个完整的对象&#xff0c;key是ThreadLocal本身&#xff0c;value是ThreadLocal的泛型对象值 public void set(T value) {Thread t Thread…

装机必备——WinRAR安装教程

装机必备——WinRAR安装教程 软件下载 软件名称&#xff1a;WinRAR 软件语言&#xff1a;简体中文 软件大小&#xff1a;3.38M 系统要求&#xff1a;Windows7或更高&#xff0c; 32/64位操作系统 硬件要求&#xff1a;CPU2GHz &#xff0c;RAM4G或更高 下载通道①迅雷云盘丨下…

Linux线程:线程控制

目录 一、线程的退出与等待 1.1pthread_join线程等待 1.2线程异常 1.3线程如何退出和结束 ​编辑 二、线程切换 三、线程的优缺点 3.1优点 3.2缺点 3.3线程vs进程 四、多线程的使用及实操 4.1堆空间共享 一、线程的退出与等待 在Linux中线程具有如下的特点&#xf…

postman教程-4-发送post请求

领取资料&#xff0c;咨询答疑&#xff0c;请➕wei: June__Go 上一小节我们学习了postman发送get请求的方法&#xff0c;本小节我们讲解一下postman发送post请求的方法。 POST请求通常用于向服务器提交数据以创建新资源或执行某些操作。与GET请求不同&#xff0c;POST请求可…

景源畅信电商:做抖店的成本高吗?

在当今数字化时代&#xff0c;抖音不仅仅是一个分享短视频的平台&#xff0c;更是一个充满商机的市场。随着抖音用户量的激增&#xff0c;越来越多的商家和个人开始关注在抖音上开设店铺&#xff0c;即所谓的“抖店”。那么&#xff0c;做抖店的成本高吗?这个问题困扰着许多初…

【鱼眼镜头11】Kannala-Brandt模型和Scaramuzza多项式模型区别,哪个更好?

Kannala-Brandt模型和Scaramuzza多项式模型在描述鱼眼相机畸变时都有其特定的数学表示和应用&#xff0c;但它们之间存在一些区别。以下是对两者区别的分点表示和归纳&#xff1a; 数学表示&#xff1a; Kannala-Brandt模型&#xff1a;它假设图像光心到投影点的距离和角度的多…

Autodl如何进行实例使用(同区)

一、首先找到之前保存的实例 二、点击更多然后选择克隆实例 三、选择是否要保存之前的数据盘 四、选择空余的GPU进行创建即可

【Redis】持久化操作详解

Redis 持久化操作详解 Redis 实现持久化的时候&#xff0c;具体是按照什么样的策略来实现的呢&#xff1f; Redis支持两种方式的持久化&#xff0c;一种是RDB方式、另一种是AOF&#xff08;append-only-file&#xff09;方式&#xff0c;两种持久化方式可以单独使用其中一种&…

springcloud 之 Ribbon Hystrix Feign bus 动态修改配置

Ribbon 是微服务架构图中负责负载均衡的 组件。 BeanLoadBalancedpublic RestTemplate getRestTemplate() {return new RestTemplate();}测试如下&#xff1a; //微服务方式 Ribbon方式GetMapping("ribbon/{name}")public String RibbonTest(PathVariable String nam…

大模型所谓的参数是什么?大模型为什么需要训练?大模型训练到底干了什么?

“ 大模型的本质是机器学习&#xff0c;机器学习的本质就是一种数学模型。” 我们经常能听到这样的说法&#xff0c;某某大模型有多少参数&#xff0c;某某大模型参数量又提升了&#xff0c;这里所说的参数到底是什么&#xff1f; 我们知道大模型是训练出来的&#xff0c;那么…

中小学校活动怎样投稿给媒体报道宣传?

身为一名学校老师,同时承担起单位活动向媒体投稿的宣传重任,我深知每一次校园活动背后的故事,都承载着师生们的辛勤汗水与教育的无限可能。起初,我满怀着对教育的热情,希望通过文字传递校园的温暖与光芒,却在投稿的道路上遇到了前所未有的挑战。 最初,我选择了最传统的路径——…

【RSGIS数据资源】中国多时期土地利用遥感监测数据集(CNLUCC)

文章目录 数据基本信息摘要数据说明数据引用方式 数据基本信息 数据时间&#xff1a; 多时期(1970年代末期以来11期) 空间位置&#xff1a; 中国 数据格式&#xff1a; 矢量与栅格 空间分辨率&#xff1a; 30m 主题分类&#xff1a; 中国土地利用遥感监测数据 DOI标识&#xf…

UNION的使用

UNION的使用 给出将多条查询语句组合成单个结果集&#xff0c;两个表对应的列数和数据类型必须相同 UNION操作符&#xff1a; 返回两个查询结果集的并集&#xff0c;并去除重复记录 UNION ALL操作符 返回两个查询的结果集的并集。不去掉两个结果集的重复部分&#xff0c;重…

存储方式 - 前端学习

1. cookie是什么&#xff1f;你了解cookie吗&#xff1f; 在计算机领域中&#xff0c;特指一种由服务器发送到用户浏览器并保存在用户计算机上的小型文本文件。这个文件可以被服务器用来识别用户身份、跟踪用户活动、保存用户设置等。它通常由名称、值、域名、路径、过期时间等…

【漏洞复现】号卡极团分销管理系统 ue_serve.php 任意文件上传漏洞

0x01 产品简介 号卡极团分销 管理系统&#xff0c;同步对接多平台&#xff0c;同步订单信息&#xff0c;支持敢探号一键上架&#xff0c;首页多套U|商品下单页多套模板&#xff0c;订单查询支持实时物流信息、支持代理商自定义域名、泛域名绑定&#xff0c;内置敢探号、172平台…

CLIP源码详解:clip.py 文件

前言 这是关于 CLIP 源码中的 clip.py 文件中的代码带注释版本。 clip.py 文件的作用&#xff1a;封装了 clip 项目的相关 API&#xff0c;通过这些 API &#xff0c;我们可以轻松使用 CLIP 项目预训练好的模型进行自己项目的应用。 另外不太容易懂的地方都使用了二级标题强…

【机器学习300问】101、1x1卷积有什么作用?

卷积神经网络最重要的操作就是卷积层的卷积操作&#xff0c;之前文章中介绍过&#xff0c;卷积核filter往往都是3x3或者5x5什么的&#xff0c;但有一种非常特殊的卷积——1x1卷积。他在CNN中扮演着非常重要的角色。 一、通道维度的降维/升维 这是1x1卷积最显著的作用之一。通过…

AIGC 008-IP-Adapter文本兼容图像提示适配器用于文本到图像扩散模型

AIGC 008-IP-Adapter文本兼容图像提示适配器用于文本到图像扩散模型&#xff01; 文章目录 0 论文工作1 论文方法2 效果 0 论文工作 这篇论文介绍了 IP-Adapter&#xff0c;一种 高效地将预训练的图像到图像转换模型适应到新领域 的方法。它通过在预训练模型的 输入端 添加一个…