嵌入式Linux系统编程 — 7.2 进程的环境变量

news2024/11/16 13:44:43

目录

1 什么是进程的环境变量

2 环境变量的作用

3 应用程序中获取环境变量

3.1 environ全局变量

3.2 获取指定环境变量 getenv

4 添加/删除/修改环境变量

4.1 putenv()函数添加环境变量

4.2 setenv()函数

4.3 unsetenv()函数


1 什么是进程的环境变量

每一个进程都有一组与其相关的环境变量, 这些环境变量以字符串形式存储在一个字符串数组列表中,把这个数组称为环境列表。 其中每个字符串都是以“名称=值(name=value)” 形式定义,所以环境变量是“名称-值”的成对集合。

譬如在 shell 终端下可以使用 env 命令查看到 shell 进程的所有环境变量,如下所示:

使用 export 命令还可以添加一个新的环境变量或删除一个环境变量:

export LINUX_TEST=123456 # 添加 LINUX_TEST 环境变量

使用"export -n LINUX_TEST"命令则可以删除 LINUX_TEST 环境变量。

2 环境变量的作用

环境变量主要有以下几个作用:

  • 配置应用程序:环境变量可以用于存储应用程序的配置信息,如文件路径、配置选项等。这使得应用程序可以在不同的环境中使用相同的代码,但根据环境变量的不同而表现出不同的行为。

  • 传递信息:在进程创建时,父进程的环境变量可以传递给子进程。这允许在不同程序之间共享信息,例如,用户的家目录路径通常通过环境变量 HOME 传递。

  • 控制shell行为:在shell中,环境变量控制着许多行为,如提示符的格式、别名、shell脚本的搜索路径等。

3 应用程序中获取环境变量

3.1 environ全局变量

应用程序当中也可以获取当前进程的环境变量,事实上,进程的环境变量是从其父进程中继承过来的,譬如在 shell 终端下执行一个应用程序,那么该进程的环境变量就是从其父进程(shell 进程)中继承过来的。新的进程在创建之前,会继承其父进程的环境变量副本。

环境变量存放在一个字符串数组中,在应用程序中,通过 environ 变量指向它, environ 是一个全局变量,在我们的应用程序中只需申明它即可使用,如下所示:

extern char **environ; // 申明外部全局变量 environ

编写应用程序,获取进程的所有环境变量。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

extern char **environ;

int main() 
{
    // 遍历环境变量数组
    while (*environ != NULL) {
        printf("%s\n", *environ);
        environ++;
    }

    return 0;
}

运行结果如下,可以看到和‘evn’命令行有相同的结果。

3.2 获取指定环境变量 getenv

如果只想要获取某个指定的环境变量,可以使用库函数 getenv(),其函数原型如下所示:

#include <stdlib.h>

char *getenv(const char *name);
  • name: 指定获取的环境变量名称。
  • 返回值: 如果存放该环境变量,则返回该环境变量的值对应字符串的指针;如果不存在该环境变量,则返回 NULL。

下面是一个使用 getenv() 函数获取这个环境变量的值的示例程序:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[]) 
{
    // 检查是否提供了环境变量名称作为命令行参数
    if (argc != 2) {
        printf("Usage: %s <environment-variable-name>\n", argv[0]);
        return 1;
    }

    // 获取环境变量的值
    const char *value = getenv(argv[1]);

    if (value != NULL) {
        printf("The value of '%s' is: %s\n", argv[1], value);
    } else {
        printf("The environment variable '%s' is not set.\n", argv[1]);
    }

    return 0;
}

 通过程序查看SHELL环境变量的值,

4 添加/删除/修改环境变量

C 语言函数库中提供了用于修改、添加、删除环境变量的函数,譬如 putenv()、 setenv()、 unsetenv()、clearenv()函数等。

4.1 putenv()函数添加环境变量

putenv() 函数用于添加或修改环境变量的函数。它接收一个字符串参数,该字符串应该包含环境变量的名称和值,两者之间用等号(=)连接。如果环境变量已经存在,putenv() 会更新它的值;如果不存在,它将添加一个新的环境变量。其函数原型如下所示:

#include <stdlib.h>

int putenv(char *string);
  • string: 参数 string 是一个字符串指针,指向 name=value 形式的字符串。
  • 返回值: 成功返回 0;失败将返回非 0 值,并设置 errno。

使用 putenv()函数为当前进程添加一个环境变量。

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
    if (2 > argc) {
        fprintf(stderr, "Error: 传入 name=value\n");
        exit(-1);
    }
    /* 添加/修改环境变量 */
    if (putenv(argv[1])) {
        perror("putenv error");
        exit(-1);
    }
    exit(0);
}

运行结果如下:

4.2 setenv()函数

setenv()函数可以替代 putenv()函数,用于向进程的环境变量列表中添加一个新的环境变量或修改现有环境变量对应的值,其函数原型如下所示:

#include <stdlib.h>

int setenv(const char *name, const char *value, int overwrite);
  • name: 需要添加或修改的环境变量名称。
  • value: 环境变量的值。
  • overwrite: 若参数 name 标识的环境变量已经存在,在参数 overwrite 为 0 的情况下, setenv()函数将不改变现有环境变量的值,也就是说本次调用没有产生任何影响;如果参数 overwrite 的值为非 0,若参数 name标识的环境变量已经存在,则覆盖,不存在则表示添加新的环境变量。
  • 返回值: 成功返回 0;失败将返回-1,并设置 errno。

setenv()与 putenv()函数有两个区别:

  • putenv()函数并不会为 name=value 字符串分配内存;
  • setenv()可通过参数overwrite控制是否需要修改现有变量的值而仅以添加变量为目的,显然putenv()并不能进行控制。

setenv()函数使用示例程序如下:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[]) 
{
    // 检查是否提供了环境变量名称和值
    if (argc != 3) {
        printf("Usage: %s <variable-name> <value>\n", argv[0]);
        return 1;
    }

    // 使用 setenv 函数添加或修改环境变量
    // setenv 返回 0 表示成功,非 0 表示错误
    if (setenv(argv[1], argv[2], 1) != 0) {
        perror("Failed to set environment variable");
        return 1;
    }

    // 打印环境变量的值以验证
    const char *value = getenv(argv[1]);
    if (value != NULL) {
        printf("%s is now set to: %s\n", argv[1], value);
    } else {
        printf("Failed to retrieve the set environment variable.\n");
    }

    return 0;
}

程序首先检查是否提供了正确的参数数量。如接下来,程序使用 setenv() 函数来设置环境变量。setenv() 的第三个参数设置为 1,表示如果环境变量已经存在,允许覆盖它的值。然后,程序使用 getenv() 函数来验证环境变量是否已正确设置,并打印出它的值。运行结果如下:

4.3 unsetenv()函数

unsetenv() 是 POSIX 标准中定义的一个函数,用于从当前进程的环境中删除指定的环境变量。这个函数的原型通常如下:

#include <stdlib.h>

int unsetenv(const char *name);
  • name :要删除的环境变量的名称。
  • 返回值:如果环境变量成功被删除,unsetenv() 会返回 0;如果发生错误,比如尝试删除不存在的变量,会返回非零值。

下面是一个使用 unsetenv() 函数的示例程序,它接受一个命令行参数(环境变量的名称),并尝试从当前进程的环境中删除这个变量:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char *argv[]) 
{
    // 检查是否提供了环境变量名称
    if (argc != 2) {
        printf("Usage: %s <environment-variable-name>\n", argv[0]);
        return 1;
    }

    // 尝试删除环境变量
    if (unsetenv(argv[1]) == -1) {
        perror("Failed to unset environment variable");
        return 1;
    }

    // 验证环境变量是否被删除
    const char *value = getenv(argv[1]);
    if (value == NULL) {
        printf("The environment variable '%s' has been unset.\n", argv[1]);
    } else {
        printf("The environment variable '%s' is still set to: %s\n", argv[1], value);
    }

    return 0;
}

运行结果如下: 



 

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

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

相关文章

Node.js 生成vue组件

在项目根目录下创建 create.js /*** 脚本生成vue组件* 主要是利用node自带的fs模块操作文件的写入* ===========================================* 准备步骤:* 1.输入作者名* 2.输入文件名* 3.输入菜单名* 4.输入文件地址* ============================================* 操…

【公益案例展】厦门大学附属成功医院——国产数据库在综合三甲医院核心系统的应用...

‍ 达梦数据公益案例 本项目案例由达梦数据投递并参与数据猿与上海大数据联盟联合推出的 #榜样的力量# 《2024中国数据智能产业最具社会责任感企业》榜单/奖项”评选。 大数据产业创新服务媒体 ——聚焦数据 改变商业 厦门大学附属成功医院是一所集医疗、教学、科研、保健、疗…

C++基础(八):类和对象 (下)

经过前面的学习&#xff0c;我们已经翻过了两座大山&#xff0c;类和对象入门知识就剩下这一讲了&#xff0c;加油吧&#xff0c;少年&#xff01; 目录 一、再谈构造函数 1.1 构造函数体赋值 1.2 初始化列表&#xff08;理解&#xff09; 1.3 explicit关键字&#xff08;C…

代码随想录算法训练营第13天|二叉树的递归遍历、二叉树的迭代遍历、二叉树的统一迭代法、102.二叉树的层序遍历

打卡Day13 1.理论基础2.二叉树的递归遍历3.二叉树的迭代遍历3.二叉树的统一迭代法4.102.二叉树的层序遍历扩展107. 二叉树的层序遍历 II199.二叉树的右视图637.二叉树的层平均值429.N叉树的层序遍历515.在每个树行中找最大值116.填充每个节点的下一个右侧节点指针117. 填充每个…

ctfshow web入门 web338--web344

web338 原型链污染 comman.js module.exports {copy:copy };function copy(object1, object2){for (let key in object2) {if (key in object2 && key in object1) {copy(object1[key], object2[key])} else {object1[key] object2[key]}}}login.js var express …

Python + 在线 + 文生音,音转文(中文文本转为英文语音,语音转为中文文本)

开源模型 平台&#xff1a;https://huggingface.co/ars-语言转文本: pipeline("automatic-speech-recognition", model"openai/whisper-large-v3", device0 ) hf: https://huggingface.co/openai/whisper-large-v3 github: https://github.com/openai/wh…

使用自动化测试确保接口正确性的详细指南!

引言&#xff1a; 随着软件开发的迅速发展&#xff0c;接口的正确性成为了确保应用程序质量的关键要素之一。自动化测试是一种强大的工具&#xff0c;可以帮助开发人员和测试人员减少错误&#xff0c;提高测试覆盖率&#xff0c;并加快测试过程。本文将详细介绍从零开始如何使…

探索LlamaIndex:如何用Django打造高效知识库检索

简介 LlamaIndex&#xff08;前身为 GPT Index&#xff09;是一个数据框架&#xff0c;为了帮助我们去建基于大型语言模型&#xff08;LLM&#xff09;的应用程序。 主要用于处理、构建和查询自定义知识库。 它支持多种数据源格式 excel&#xff0c;txt&#xff0c;pdf&…

ELK优化之Filebeat部署

目录 1.安装配置Nginx 2.安装 Filebeat 3.设置 filebeat 的主配置文件 4.修改Logstash配置 5.启动配置 6.kibana验证 主机名ip地址主要软件es01192.168.9.114ElasticSearches02192.168.9.115ElasticSearches03192.168.9.116ElasticSearch、Kibananginx01192.168.9.113ng…

测试人员如何管理项目与风险预警

在平时工作过程中&#xff0c;你有没有因项目延时&#xff0c;需求频繁变更&#xff0c;开发提测质量不高&#xff0c;以及漏测的情况下&#xff0c;背了不少锅的情况呢&#xff1f; 作为测试人员&#xff0c;我们应该如何发挥积极主动性&#xff0c;进行项目管理&#xff0c;有…

VuePress 的更多配置

现在&#xff0c;读者应该对 VuePress、主题和插件等有了基本的认识&#xff0c;除了插件&#xff0c;VuePress 自身也有很多有用的配置&#xff0c;这里简单说明下。 ‍ ‍ VuePress 的介绍 在介绍了 VuePress 的基本使用、主题和插件的概念之后&#xff0c;我们再来看看官…

CTS单测某个模块和测试项

1 &#xff0c;测试单个模块命令 run cts -m <模块名> 比如&#xff1a;run cts -m CtsUsbTests模块名可以从测试报告中看&#xff0c;如下&#xff1a; 2&#xff0c; 测试单个测试项 run cts -m <模块名> -t <test_name> 比如&#xff1a;run cts -m ru…

基于大象机器人UltraArm P340机械臂和传送带,实现教育场景中的自动化分拣系统!

引言 今天我们将展示一个高度自动化的模拟场景&#xff0c;展示多个机械臂与传送带协同工作的高效分拣系统。在这个场景中&#xff0c;机械臂通过视觉识别技术对物体进行分类&#xff0c;并通过精确的机械操作将它们放置在指定的位置。这一系统不仅提高了分拣的速度和准确性&am…

dotnet ef工具使用

设置工具安装目录 dotnet tool install dotnetsay --tool-path G:\dotnet-tools安装 dotnet tool install --global dotnet-ef更新 dotnet tool update --global dotnet-ef查看版本 dotnet ef --version创建迁移文件 # 只有一个dbcontext dotnet ef migrations add init #…

http读书笔记

持久化 HTTP/1.1 和一部分的 HTTP/1.0 想出了 持久连接&#xff08;HTTP Persistent Connections&#xff0c; 也称为 HTTP keep-alive 或 HTTP connection reuse&#xff09; 的方法。 持久连接的特点是&#xff0c; 只要任意一端 没有明确提出断开连接&#xff0c; 则保持 T…

mysql 9 新特新

mysql9新特性 新特性Audit Log NotesC API NotesCharacter Set SupportCompilation NotesComponent NotesConfiguration NotesData Dictionary NotesData Type NotesDeprecation and Removal NotesEvent Scheduler NotesJavaScript ProgramsOptimizer NotesPerformance Schema …

微机原理与单片机 知识体系梳理

单片机笔记分享 我个人感觉单片机要记的东西很多&#xff0c;也很琐碎&#xff0c;特别是一些位、寄存器以及相关作用等&#xff0c;非常难以记忆。因此复习时将知识点整理在了一起做成思维导图&#xff0c;希望对大家有所帮助。内容不是很多&#xff0c;可能有些没覆盖全&…

轻预压:滚珠丝杆精度与刚性的平衡点!

预压是指在所需的工作负荷下&#xff0c;使滚珠丝杆预先承受一定的负荷&#xff0c;从而使滚珠丝杆的轴向向心度和侧向偏差达到较小的偏差范围&#xff0c;保证了滚珠丝杆的准确性和稳定性&#xff0c;也确保机器的高精度和长期运作的可靠性。 预压是滚珠丝杆设计中的一个重要参…

基于Java技术的人事管理系统

你好&#xff0c;我是专注于计算机科学领域的小野。如果你对人事管理系统感兴趣或有相关需求&#xff0c;欢迎私信交流。 开发语言&#xff1a; Java 数据库&#xff1a; MySQL 技术&#xff1a; B/S模式、Java技术、SpringBoot 工具&#xff1a; Eclipse、MySQL、浏览…

Selenium 切换 frame/iframe

环境&#xff1a; Python 3.8 selenium3.141.0 urllib31.26.19说明&#xff1a; driver.switch_to.frame() # 将当前定位的主体切换为frame/iframe表单的内嵌页面中 driver.switch_to.default_content() # 跳回最外层的页面# 判断元素是否在 frame/ifame 中 # 126 邮箱为例 # …