Linux系统编程:详解环境变量_char **environ-程序员宅基地

技术标签: Linux系统和网络  运维  linux  服务器  

目录

一. 环境变量的基本概念

1.1 什么是环境变量

1.2 环境变量的功能测试

二. 与环境变量相关的操作 

三. 环境变量的组织方式

四. 通过代码获取环境变量的值

五. 总结


一. 环境变量的基本概念

1.1 什么是环境变量

环境变量是用于指定操作系统相关参数的、全局的变量。通过env指令,可以查看系统中全部的环境变量。

下面是几个常见的环境变量:

  • PATH:指令的搜索路径
  • HOME:特定用户的家目录,即:用户登录时默认所在的路径。
  • SHELL:当前的shell外壳,一般为/bin/bash

查看环境变量值的方法:echo $环境变量名

环境变量有如下几点特性:

  • 某个进程环境变量是从它的父进程中继承下来的。
  • 默认所有的环境变量都会被子进程继承。
  • 环境变量具有全局属性。

1.2 环境变量的功能测试

  • 测试PATH

PATH表示指令的默认搜索路径,我们首先通过echo $PATH,获取当前的PATH值,如图1.1所示,我们看到所有的路径被:分割,OS会依次从PATH的路径中搜索用户输入的指令,直到找到指令为止,如果到了最后一个路径还没有找到,那么OS就认为指令不存在,无法执行。

图1.1 环境变量PATH的值

我们创建编译下面的代码,生成可执行程序mytest.exe,分别在命令行中输入./mytest.exe和mytest.exe,前者成功运行,后者运行失败,详见图1.2。这是因为mytest.exe并不是一条指令,mytest.exe文件所在的路径不包含在PATH值内。

结论:Linux系统内置的指令不需要路径,输入指令名称就可以运行。用户自主编译生成的可执行程序,需要加上路径./XXX才可以运行。

图1.2 加路径和直接输入可执行程序名称时的运行结果

接下来,通过指令 export PATH=$PATH:(pwd)  修改修改环境变量PATH的值,然后再次在命令行中直接输入mytest.exe,可见这次程序运行成功了(详见图1.3)!此时通过echo $PATH查看PATH的值,可见当前路径被加入到了PATH中,因此直接输入mytest.exe可以成功运行程序。

图1.3 改变环境变量PATH的值
  • 测试HOME 

在两个终端下,分别使用普通用户zhangHHH和root用户登录,分别使用echo $HOME指令在不同用户登录的情况下查看环境变量HOME的值,可以看到HOME就是用户的家目录。

图1.4 在普通用户和root用户下测试HOME的值

二. 与环境变量相关的操作 

  • echo $ -- 获取环境变量值 

语法:echo $val_name,可以输出环境变量的值。这里的$不能省略,如果省略,那么输出的就是环境变量本身了,如echo PATH输出PATH。

  • export -- 定义环境变量 

语法:export 环境变量名称=值,如:export VAL=1234,就定义了一个名称为Val,值为1234的环境变量,这个变量具有全局属性。 

  • env -- 获取系统中的所有环境变量

如果我们通过export设定了环境变量,那么使用env同样能够查到。

  • unset -- 清除环境变量

语法:unset [环境变量名称]

图2.1 环境变量相关操作
  • putenv -- 在程序中导入环境变量 

语法:putenv("[valName]=VAL") 

putenv是C语言提供的函数,被包含在头文件<stdlib.h>中

如:putenv("MYVAL=1234"),就导入了名为MYVAL,值为1234的环境变量。导入父进程环境变量的子进程,也会接收到这个环境变量。

三. 环境变量的组织方式

一个main函数,最多可以有三个形参。即:main(int argc, char* argv[], char* env[]),其中argc为运行可执行程序时命令行参数的个数,argv为指向命令行参数列表的指针数组,env为指向环境变量列表的指针数组。

env指向一个存有若干char*类型变量的指针数组,数组以NULL结尾,数组中的每个数据指向一个环境变量的值,见图3.1。argv的组织方式与env基本完全相同,只不过不会以NULL结尾,但会有argc来获取记录选项的个数。

图3.1 环境变量的组织

四. 通过代码获取环境变量的值

  • 方法1:通过main函数的第三个参数获取

main(int argc, char* argv[], char* env[]))函数的第三个参数为指向环境变量列表的指针数组,通过evn[i],可以依次获取每个环境变量。代码4.1通过for循环,以env[i] != NULL为循环条件,依次打印每个环境变量的值。程序运行结果见图4.1。

代码4.1:通过main函数第三个参数获取环境变量

#include<iostream>    
      
main(int argc, char* argv[], char* env[])    
{    
    for(int i = 0; env[i]; ++i)    
    {    
        printf("env[%d] = %s\n", i, env[i]);                                                                                       
    }   
 
    return 0;    
}   
图4.1 通过代码4.1的运行结果
  •  方法2:通过第三方变量char **environ获取

变量char **environ被包含在头文件<unistd.h>中,在使用时,需要显示的包含头文件<unistd.h>或者在程序中声明外部变量extern char **environ。代码4.2展示了environ的用法。

代码4.2:通过第三方变量environ获取环境变量  

#include<iostream>    
#include<unistd.h>    
    
int main()                                                                                                                           
{                                                         
    for(int i = 0; environ[i]; ++i)                       
    {                                                     
        printf("environ[%d] = %s\n", i, environ[i]);      
    }                                                     
    return 0;                                             
} 
  • 方法三:通过函数getenv获取

语法:char* env_name = getenv("环境变量名称")

如果企图获取不存在的环境变量,那么程序会在运行期间报错Segmentation fault。

代码4.3:通过getenv函数获取环境变量值

#include<iostream>    
int main()                                                                                                                           
{             
    char* path = getenv("PATH");    
    char* home = getenv("HOME");    
    printf("PATH:%s\n", path);      
    printf("home:%s\n", home);    
    return 0;                     
} 
图4.2 代码4.3的运行结果

补充知识:

我们可以直接在命令行中使用  val_name=val 类似的指令来定义局部变量的值,但是,这并不属于全局变量,如果我们企图使用getenv获取它们的值,会在运行期间报错Segmentation fault。

这里由于提到了main函数的三个参数,因此也顺便对int argc和char* argv[]进行解读。argv表示可执行程序运行时命令行参数的个数,如果仅输入./XXX运行,那么命令行参数的个数就为1。

命令行参数的主要功能是让同一个函数,根据输入的选项,执行不同的代码。如代码4.4所示,我们要求至少有两个命令行参数,如果只输入一个(argc < 2),那么程序报错退出,如果输入选项-a,那么就执行function1,如果输入选择-b,那么就执行function2。

结论:选项 + 命令行参数可以实现同一份代码执行不同工作。

代码4.4:通过命令行参数让同一份代码执行不同工作

  #include<iostream>    
  #include<string.h>    
      
  int main(int argc, char *argv[], char *env[])    
  {    
      //至少有两个命令行参数(一个选项)    
      if(argc < 2)    
      {    
          std::cout << "至少两个命令行参数" << std::endl;    
      }    
      
      if(strcmp(argv[1], "-a") == 0)    
      {    
          std::cout << "function1" << std::endl;    
      }    
      else if(strcmp(argv[1], "-b") == 0)                                                                                                                                                                                                                                     
      {    
          std::cout << "function2" << std::endl;    
      }    
      
      return 0;    
  }  
图4.3 代码4.4的运行结果

五. 总结

  • 环境变量是用于定义操作系统相关参数的全局变量,主要有PATH、HOME、SHELL等,每个进程的环境变量从它的父进程中继承。
  • 通过echo $、export、unset、env等指令,可以实现对环境变量的增删查改。
  • 环境变量是通过指针数组来组织的,char* env[]可作为main函数的第三个参数。
  • 有三种方法可以实现在代码中获取环境变量的值:通过main函数的第三个参数char* env[]、通过第三方变量extern char **environ、通过getenv函数。
  • main函数的第一个参数argc表示命令行参数的个数,第二个参数为指向命令行参数存储地址的指针数组,通过 命令行参数+选项 的组合使用,可让一份代码根据用户需要实现不同的功能。
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_43908419/article/details/131405194

智能推荐

React学习记录-程序员宅基地

文章浏览阅读936次,点赞22次,收藏26次。React核心基础

Linux查磁盘大小命令,linux系统查看磁盘空间的命令是什么-程序员宅基地

文章浏览阅读2k次。linux系统查看磁盘空间的命令是【df -hl】,该命令可以查看磁盘剩余空间大小。如果要查看每个根路径的分区大小,可以使用【df -h】命令。df命令以磁盘分区为单位查看文件系统。本文操作环境:red hat enterprise linux 6.1系统、thinkpad t480电脑。(学习视频分享:linux视频教程)Linux 查看磁盘空间可以使用 df 和 du 命令。df命令df 以磁..._df -hl

Office & delphi_range[char(96 + acolumn) + inttostr(65536)].end[xl-程序员宅基地

文章浏览阅读923次。uses ComObj;var ExcelApp: OleVariant;implementationprocedure TForm1.Button1Click(Sender: TObject);const // SheetType xlChart = -4109; xlWorksheet = -4167; // WBATemplate xlWBATWorksheet = -4167_range[char(96 + acolumn) + inttostr(65536)].end[xlup]

若依 quartz 定时任务中 service mapper无法注入解决办法_ruoyi-quartz无法引入ruoyi-admin的service-程序员宅基地

文章浏览阅读2.3k次。上图为任务代码,在任务具体执行的方法中使用,一定要写在方法内使用SpringContextUtil.getBean()方法实例化Spring service类下边是ruoyi-quartz模块中util/SpringContextUtil.java(已改写)import org.springframework.beans.BeansException;import org.springframework.context.ApplicationContext;import org.s..._ruoyi-quartz无法引入ruoyi-admin的service

CentOS7配置yum源-程序员宅基地

文章浏览阅读2w次,点赞10次,收藏77次。yum,全称“Yellow dog Updater, Modified”,是一个专门为了解决包的依赖关系而存在的软件包管理器。可以这么说,yum 是改进型的 RPM 软件管理器,它很好的解决了 RPM 所面临的软件包依赖问题。yum 在服务器端存有所有的 RPM 包,并将各个包之间的依赖关系记录在文件中,当管理员使用 yum 安装 RPM 包时,yum 会先从服务器端下载包的依赖性文件,通过分析此文件从服务器端一次性下载所有相关的 RPM 包并进行安装。_centos7配置yum源

智能科学毕设分享(算法) 基于深度学习的抽烟行为检测算法实现(源码分享)-程序员宅基地

文章浏览阅读828次,点赞21次,收藏8次。今天学长向大家分享一个毕业设计项目毕业设计 基于深度学习的抽烟行为检测算法实现(源码分享)毕业设计 深度学习的抽烟行为检测算法实现通过目前应用比较广泛的 Web 开发平台,将模型训练完成的算法模型部署,部署于 Web 平台。并且利用目前流行的前后端技术在该平台进行整合实现运营车辆驾驶员吸烟行为检测系统,方便用户使用。本系统是一种运营车辆驾驶员吸烟行为检测系统,为了降低误检率,对驾驶员视频中的吸烟烟雾和香烟目标分别进行检测,若同时检测到则判定该驾驶员存在吸烟行为。进行流程化处理,以满足用户的需要。

随便推点

STM32单片机示例:多个定时器同步触发启动_stm32 定时器同步-程序员宅基地

文章浏览阅读3.7k次,点赞3次,收藏14次。多个定时器同步触发启动是一种比较实用的功能,这里将对此做个示例说明。_stm32 定时器同步

android launcher分析和修改10,Android Launcher分析和修改9——Launcher启动APP流程(转载)...-程序员宅基地

文章浏览阅读348次。出处 : http://www.cnblogs.com/mythou/p/3187881.html本来想分析AppsCustomizePagedView类,不过今天突然接到一个临时任务。客户反馈说机器界面的图标很难点击启动程序,经常点击了没有反应,Boss说要优先解决这问题。没办法,只能看看是怎么回事。今天分析一下Launcher启动APP的过程。从用户点击到程序启动的流程,下面针对WorkSpa..._回调bubbletextview

Ubuntu 12 最快的两个源 个人感觉 163与cn99最快 ubuntu安装源下包过慢_un.12.cc-程序员宅基地

文章浏览阅读6.2k次。Ubuntu 12 最快的两个源 个人感觉 163与cn99最快 ubuntu下包过慢 1、首先备份Ubuntu 12.04源列表 sudo cp /etc/apt/sources.list /etc/apt/sources.list.backup (备份下当前的源列表,有备无患嘛) 2、修改更新源 sudo gedit /etc/apt/sources.list (打开Ubuntu 12_un.12.cc

vue动态路由(权限设置)_vue动态路由权限-程序员宅基地

文章浏览阅读5.8k次,点赞6次,收藏86次。1.思路(1)动态添加路由肯定用的是addRouter,在哪用?(2)vuex当中获取到菜单,怎样展示到界面2.不管其他先试一下addRouter找到router/index.js文件,内容如下,这是我自己先配置的登录路由现在先不管请求到的菜单是什么样,先写一个固定的菜单通过addRouter添加添加以前注意:addRoutes()添加的是数组在export defult router的上一行图中17行写下以下代码var addRoute=[ { path:"/", name:"_vue动态路由权限

JSTL 之变量赋值标签-程序员宅基地

文章浏览阅读8.9k次。 关键词: JSTL 之变量赋值标签 /* * Author Yachun Miao * Created 11-Dec-06 */关于JSP核心库的set标签赋值变量,有两种方式: 1.日期" />2. 有种需求要把ApplicationResources_zh_CN.prope

VGA带音频转HDMI转换芯片|VGA转HDMI 转换器方案|VGA转HDMI1.4转换器芯片介绍_vga转hdmi带音频转换器,转接头拆解-程序员宅基地

文章浏览阅读3.1k次,点赞3次,收藏2次。1.1ZY5621概述ZY5621是VGA音频到HDMI转换器芯片,它符合HDMI1.4 DV1.0规范。ZY5621也是一款先进的高速转换器,集成了MCU和VGA EDID芯片。它还包含VGA输入指示和仅音频到HDMI功能。进一步降低系统制造成本,简化系统板上的布线。ZY5621方案设计简单,且可以完美还原输入端口的信号,此方案设计广泛应用于投影仪、教育多媒体、视频会议、视频展台、工业级主板显示、手持便携设备、转换盒、转换线材等产品设计上面。1.2 ZY5621 特性内置MCU嵌入式VGA_vga转hdmi带音频转换器,转接头拆解

推荐文章

热门文章

相关标签