Linux 环境变量

目录

一、环境变量的基本概念

 1.常见环境变量

 2.查看环境变量方法

​3.几个环境变量

环境变量:PATH

 环境变量:HOME

环境变量:SHELL

二、和环境变量相关的命令  

三、库函数getenv,setenv

四、环境变量和本地变量

 五、命令行参数

1.main 函数可以带参数吗?能带几个参数呢?

2.命令行参数的意义 

六、环境变量的组织方式

 1、通过 main 的第三个参数获取环境变量

2、通过全局变量 environ 获取环境变量


一、环境变量的基本概念

在我们学习JAVA,Python我们都要在windows上配置环境变量。

环境变量的概念

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

 1.常见环境变量

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

 2.查看环境变量方法

echo $NAME //NAME:你的环境变量名称

 3.几个环境变量

环境变量:PATH

我们先先创建一个文件:test.c,并写入代码。

 #include <stdio.h>int main(){printf("打印\n");                                                                                                                                                                                           return 0;}

我们生成的可执行程序是不是一条命令呢?

 

是一条命令,每一个可执行文件都具有(X)执行权限。

像我们常说的命令,指令,可执行程序 都是同一个概念。

那竟然mytest是一条命令,那为什么会出现无法找到mytest这个指令呢?而是要./mytest呢?

 

我们上面说PATH环境变量是指令的搜索路径

这些都是绝对路径,如果在这些路径下找不到该指令的话,就会报错! 

如果我们想直接用mytest让程序运行起来该怎么办呢?

我们可以将该可执行程序的路径添加到环境变量PATH中

这样我们就可以直接用mytest运行了。 

 环境变量:HOME

分别在 root 和普通用户下执行 cd ~ 和 pwd 查看家目录,分别是 /root 和 /home/xyl,为什么得到的结果不一样呢?

因为不同用户的家目录中的配置文件不一样,所以不同用户下的环境变量 HOME 也是不一样的。

环境变量:SHELL

  • 我们在命令行上运行的大部分命令,它们的父进程都是 bash。
  • bash 创建子进程,然后由子进程执行用户输入的命令。

二、和环境变量相关的命令  

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

 

三、库函数getenv,setenv

getenv:char *getenv(const char *name); 获取环境变量。

setenv:int setenv(const char *name, const char *value, int overwrite);更改或添加环境变量。

getenv() 和setenv()

1 #include <stdio.h>2 #include <stdlib.h>3 int main()4 {5   printf("%s\n",getenv("PATH"));6   char* env;7   env=getenv("HOME");8   printf("HOME:%s\n",getenv("HOME"));9   setenv("HOME","haha",1);10 11   printf("HOME:%s\n",getenv("HOME"));                                                                                                                            12   return 0;13 }

setenv()用来改变或增加环境变量的内容。参数name为环境变量名称字符串。参数 value则为变量内容,参数overwrite用来决定是否要改变已存在的环境变量。如果没有此环境变量则无论overwrite为何值均添加此环境变量。若环境变量存在,当overwrite不为0时,原内容会被改为参数value所指的变量内容;当overwrite为0时,则参数value会被忽略。返回值 执行成功则返回0,有错误发生时返回-1。

四、环境变量和本地变量

上面我们说环境变量具有全局属性,也就是说环境变量可以被子进程继承。

1 #include <stdio.h>2 #include <stdlib.h>3 int main()4 {5   char* env=getenv("MYENV");6   if(env)7   {8     printf("%s",env);                                                                                                                        9   }                                                                                                                                    10   return 0;                                                                                                                            11 } 

运行发现没有结果,因为我自己创建的MYENV不是环境变量。

当我们用export导出环境变量时,发现程序运行并打印了。

这说明环境变量是可以被子进程继承下去的。 

  • 本地变量(只能在当前 shell 命令行解释器内被访问,不可以被子进程继承)

这说明本地变量不能被子进程继承 

我们该如何查看本地变量呢? 

其实和环境变量是一样的。

 上面说到,我们在命令行上运行的大部分命令,都是 bash 创建子进程来执行的,而本地变量不能被子进程继承,那为什么使用 echo 命令,却可以访问本地变量呢?

因为echo是一个内建命令,是shell程序内部的一个函数,可以直接访问shell内定义的本地变量,这并没有fork创建子进程。

 五、命令行参数

main函数,我们很少见到像这样的类型。

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

1.main 函数可以带参数吗?能带几个参数呢?

main 函数可以带参,但大部分都是缺省。

  • argc:命令行参数的个数。
  • argv:字符指针数组(指向各个命令行参数的字符指针所构成的数组)。
int main(int argc, char* argv[]) // 接收命令行参数
{for (int i = 0; i < argc; i++){printf("argv[%d]: %s\n", i, argv[i]); // 遍历字符指针数组argv}return 0;
}

 运行结果:字符数组中只有一个元素,就是我们输入的命令。

如果我们多输入几个参数 

实际上我们输入的命令行参数,就是一个个的 C 字符串: "./proc"、"arg1"、"arg2"、"arg3",传给了 main 函数: 

2.命令行参数的意义 

为什么要存在命令行参数呢?

帮助我们能够给同一个程序,设计出不同的业务功能。

举个小例子,比如我想要实现这样一个计算器:

  • 如果输入 ./cal,则会提示该程序的正确用法:Usage:./cal -[a|s] x y;
  • 输入 ./cal -a 1 2,cal 程序可以输出 1 + 2 的结果;
  • 输入 ./cal -s 4 2,cal 程序可以输出 4 - 2 的结果。
#include <stdio.h>
#include <stdlib.h> // atoi -- 函数原型:int atoi(const char *nptr); // 将C字符串转换成整数
#include <string.h> // strcmp// cal命令的用法手册
void Usage(const char* cal)
{printf("Usage: %s -[a|s] x y\n", cal);
}int main(int argc, char* argv[]) // 接收命令行参数
{// 输入的参数个数不为4if (argc != 4){Usage(argv[0]);return 1; // 退出程序}// 保存第3个和第4个参数                                                      int x = atoi(argv[2]);int y = atoi(argv[3]);// 根据不同参数,执行不同功能,然后输出结果if (strcmp(argv[1], "-a") == 0){                                            printf("%d + %d = %d\n", x, y, x + y); }else if (strcmp(argv[1], "-s") == 0){printf("%d - %d = %d\n", x, y, x - y); }else{Usage(argv[0]);return 1; // 退出程序}return 0;
}

 

命令行参数可以让同一个命令,通过带上不同的选项表现出不同的功能和作用。

比如:ls -l、ls -l -a、ls -l -a -i。这就是命令行参数的意义。

总结:我们运行的进程,都是子进程,bash本身在启动时,会从操作系统的配置文件读取环境变量信息,子进程会继承父进程的环境变量 

可以通过 main 函数的参数,可以传递命令行参数和环境变量

六、环境变量的组织方式

main 函数除了可以传递两个和命令行参数相关的参数 argc 和 argv 以外,还可以传递第 3 个参数 env

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

这也是 main 函数获取环境变量的方式。

通过给 main 函数第三个参数传参,把一个个环境变量传递给当前程序,当前程序运行起来变成进程,就意味着当前这个进程获取到了这些环境变量。

 每个被 bash 创建的子进程都会接收到一张环境表,环境表是一个字符指针数组,每个指针指向一个以 ’\0’ 结尾的环境字符串(环境变量)。

 1、通过 main 的第三个参数获取环境变量

// proc.c
#include <stdio.h>
#include <string.h>int main(int argc, char* argv[], char* env[]) // 通过第三个参数接收环境变量
{for (int i = 0; env[i]; i++) // 循环结束条件为env[i],遍历到NULL停止{printf("env[%d]: %s\n", i, env[i]); // 遍历字符指针数组env}return 0;
}

我们获取了bash进程的所有环境变量,因为子进程mytest继承了bash进程的环境变量。

2、通过全局变量 environ 获取环境变量

C/C++ 提供了一个全局二级指针变量 char** environ,指向存放环境变量地址的字符指针数组 char* env[ ]。

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

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

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

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

相关文章

Redis实战(黑马点评)——涉及session、redis存储验证码,双拦截器处理请求

项目整体介绍 数据库表介绍 基于session的短信验证码登录与注册 controller层 // 获取验证码PostMapping("code")public Result sendCode(RequestParam("phone") String phone, HttpSession session) {return userService.sendCode(phone, session);}// 获…

MYSQL数据库 - 启动与连接

MYSQL数据库的启动&#xff1a; 一 在cmd控制界面以管理员身份运行 执行语句: net start mysql80 net stop mysql80 二 MYSQL数据库客户端建立连接&#xff1a; 1 该种方法是使用windows系统的cmd界面&#xff0c;需要配置相关路径path 2 使用MYSQL自带的

【Salesforce】审批流程,代理登录 tips

审批流程权限 审批流程权限问题解决方案代理登录代理登录后Logout 审批流程权限 前几天&#xff0c;使用审批流程&#xff0c;但是是两个sandbox&#xff0c;同样的配置&#xff0c;我有管理员权限。但是profile不是管理员&#xff0c;只是通过具备管理员权限的permission set…

RDMA 工作原理 | 支持 RDMA 的网络协议

注&#xff1a;本文为 “RDMA” 相关文章合辑。 英文引文机翻未校。 图片清晰度受引文所限。 Introduction to Remote Direct Memory Access (RDMA) Written by: Dotan Barak on March 31, 2014.on February 13, 2015. What is RDMA? 什么是 RDMA&#xff1f; Direct me…

hexo + Butterfly搭建博客

Hexo‌是一个基于Node.js的静态网站生成器&#xff0c;主要用于快速搭建博客和个人网站。它使用Markdown语法编写文章&#xff0c;能够迅速生成静态页面并部署到服务器上。 配置node 使用nvm安装node(v16.13.2)后配置镜像 安装并使用node&#xff1a; nvm install 16.13.2 n…

手撕B-树

一、概述 1.历史 B树&#xff08;B-Tree&#xff09;结构是一种高效存储和查询数据的方法&#xff0c;它的历史可以追溯到1970年代早期。B树的发明人Rudolf Bayer和Edward M. McCreight分别发表了一篇论文介绍了B树。这篇论文是1972年发表于《ACM Transactions on Database S…

【2025年数学建模美赛F题】(顶刊论文绘图)模型代码+论文

全球网络犯罪与网络安全政策的多维度分析及效能评估 摘要1 Introduction1.1 Problem Background1.2Restatement of the Problem1.3 Literature Review1.4 Our Work 2 Assumptions and Justifications数据完整性与可靠性假设&#xff1a;法律政策独立性假设&#xff1a;人口统计…

【FreeRTOS 教程 四】队列创建与发布项目到队列

目录 一、FreeRTOS队列&#xff1a; &#xff08;1&#xff09;队列介绍&#xff1a; &#xff08;2&#xff09;用户模型说明&#xff1a; &#xff08;3&#xff09;阻塞队列&#xff1a; 二、队列管理 API&#xff1a; &#xff08;1&#xff09;uxQueueMessagesWaiti…

如何在data.table中处理缺失值

&#x1f4ca;&#x1f4bb;【R语言进阶】轻松搞定缺失值&#xff0c;让数据清洗更高效&#xff01; &#x1f44b; 大家好呀&#xff01;今天我要和大家分享一个超实用的R语言技巧——如何在data.table中处理缺失值&#xff0c;并且提供了一个自定义函数calculate_missing_va…

基于OpenCV实现的答题卡自动判卷系统

一、图像预处理 🌄 二、查找答题卡轮廓 📏 三、透视变换 🔄 四、判卷与评分 🎯 五、主函数 六、完整代码+测试图像集 总结 🌟 在这篇博客中,我将分享如何使用Python结合OpenCV库开发一个答题卡自动判卷系统。这个系统能够自动从扫描的答题卡中提取信…

C++ list 容器用法

C list 容器用法 C 标准库提供了丰富的功能&#xff0c;其中 <list> 是一个非常重要的容器类&#xff0c;用于存储元素集合&#xff0c;支持双向迭代器。<list> 是 C 标准模板库&#xff08;STL&#xff09;中的一个序列容器&#xff0c;它允许在容器的任意位置快速…

docker部署jenkins

环境&#xff1a; centos7.9 jenkins/jenkins:lts-jdk11 1、拉去jenkins镜像&#xff0c;请指明版本号 [rootlocalhost ~]# docker pull jenkins/jenkins:lts 开始拉取 拉取完成 [rootlocalhost ~]# docker pull jenkins/jenkins:lts lts: Pulling from jenkins/jenkins 0a9…

沃尔玛 礼品卡绑定 分析

声明: 本文章中所有内容仅供学习交流使用&#xff0c;不用于其他任何目的&#xff0c;抓包内容、敏感网址、数据接口等均已做脱敏处理&#xff0c;严禁用于商业用途和非法用途&#xff0c;否则由此产生的一切后果均与作者无关&#xff01; 逆向分析 部分代码参考 func doPost…

【2024年华为OD机试】 (A卷,100分)- 整理扑克牌(JavaScriptJava PythonC/C++)

一、问题描述 题目描述 给定一组数字,表示扑克牌的牌面数字,忽略扑克牌的花色,请按如下规则对这一组扑克牌进行整理: 步骤1:分组形成组合牌 炸弹:当牌面数字相同张数大于等于4时。葫芦:3张相同牌面数字 + 2张相同牌面数字,且3张牌与2张牌不相同。三张:3张相同牌面数…

Arduino大师练成手册 --控制 OLED

要在 Arduino 上使用 U8glib 库控制带有 7 个引脚的 SPI OLED 显示屏&#xff0c;你可以按照以下步骤进行&#xff1a; 7pin OLED硬件连接 GND&#xff1a;连接到 Arduino 的 GND 引脚。 VCC&#xff1a;连接到 Arduino 的 5V 引脚。 D0&#xff08;或 SCK/CLK&#xff09;…

单片机基础模块学习——按键

一、按键原理图 当把跳线帽J5放在右侧&#xff0c;属于独立按键模式&#xff08;BTN模式&#xff09;&#xff0c;放在左侧为矩阵键盘模式&#xff08;KBD模式&#xff09; 整体结构是一端接地&#xff0c;一端接控制引脚 之前提到的都是使用了GPIO-准双向口的输出功能&#x…

AWScurl笔记

摘要 AWScurl是一款专为与AWS服务交互设计的命令行工具&#xff0c;它模拟了curl的功能并添加了AWS签名版本4的支持。这一特性使得用户能够安全有效地执行带有AWS签名的请求&#xff0c;极大地提升了与AWS服务交互时的安全性和有效性。 GitHub - okigan/awscurl: curl-like acc…

初识MySQL

文章目录 1.数据库2.查看数据库3.创建数据库4.字符集编码和排序规则6.修改数据库7.删除数据库 1.数据库 MySQL是一款使用率高且免费的数据库&#xff08;使用率仅仅低于Oracle&#xff09; 关系数据库和 NoSQL 数据库管理系统知识库(DB-Engines Ranking -) (此图数据于2025-1…

flutter_学习记录_00_环境搭建

1.参考文档 Mac端Flutter的环境配置看这一篇就够了 flutter的中文官方文档 2. 本人环境搭建的背景 本人的电脑的是Mac的&#xff0c;iOS开发&#xff0c;所以iOS开发环境本身是可用的&#xff1b;外加Mac电脑本身就会配置Java的环境。所以&#xff0c;后面剩下的就是&#x…

[b01lers2020]Life on Mars1

打开题目页面如下 看了旁边的链接&#xff0c;也没有什么注入点&#xff0c;是正常的科普 利用burp suite抓包&#xff0c;发现传参 访问一下 http://5edaec92-dd87-4fec-b0e3-501ff24d3650.node5.buuoj.cn:81/query?searchtharsis_rise 接下来进行sql注入 方法一&#xf…