【解锁创意之门:环境变量引领你的编程奇思妙想】(中)

简介: 【解锁创意之门:环境变量引领你的编程奇思妙想】

【解锁创意之门:环境变量引领你的编程奇思妙想】(上):https://developer.aliyun.com/article/1425748


当i++后,此时argv[i]就访问到了NULL,NULL对应的就是0,此时程序就会退出。通过上面我们知道main函数的两个参数是从命令行输入的,然后再由bash创建、维护并传参的,可是我们为什么要这么做呢???下面我们来写一个demo,来说明我们为什么要这么做。demo的功能是输入./myprocess -[number](1-3)可以实现不同的功能,只能传入两个参数。


我们来看一下程序的运行结果:


通过上面的demo,我们发现我们可以通过不同的选项,让我们的同一个程序执行它内部不同的功能!为什么呢?我们看一下下面这张图片。


我们发现我们平时使用的指令,后面跟着的都是我们的指令选项,这不就是和我们上面demo一样嘛,这些指令大部分也都是使用c语言去写的,选项的本质也就是命令行参数,所以我们平时使用的选项,最终都是以命令行参数的形式传递给我们main函数,然后我们可以根据选项去实现不同的指令功能。命令行参数,是Linux指令选项的基础!


3.2.环境变量 --- 初步并了解并使用环境变量



我们先来见见环境变量,我们运行我们的程序要运行就需要./myprocess或者找到这个可执行程序的绝对路径运行这个可执行程序,如果我们不以上面的两个方式,此时就会出现command not found的错误信息,这句话的潜在意思就是我们系统在执行myprocess的时候,系统没有找到这个可执行程序。


这里有一个问题,为什么执行我们的程序要./,而执行系统自带的指令就不用呢?比如ls,没见到我们用./ls呀!这是因为系统存在一个全局的环境变量PATH,我们可以通过echo $PATH打印出这个环境变量里面的内容。


所以上面的问题就能解决了,因为ls的执行路径默认就在/usr/bin/这个路径下,所以ls指令执行的时候就可以找到执行路径,而myprocess的路径是/home/whb/110/110/lesson12,没有被添加到环境变量PATH里,所以我们输入myprocess找不到执行路径,也就会给我们输出command not found的错误信息。PATH环境变量里面保存的是我们Lixnu系统搜索可执行程序时所对应的搜索路径。如果我们要想我们自己的程序也和ls一样直接执行,我们由两种方法:


1.将我们的mprocess拷贝到/usr/bin/这个路径下:


2.把自己的可执行程序添加到环境变量PATH里


此时我们再通过which就可以查到我们自己的可执行程序了


如果我们把之前的环境变量给覆盖了怎么办?很明显此时就只能我们自己的程序能够运行,系统提供的那些指令都不能使用了。


那怎么办?所有的基本的指令都不能使用了。不用担心此时,我们现在修改的环境变量它仅仅是在内存当中,由系统开辟的内存级的变量,此时我们重新打开Linux系统即可。我们再来看一下环境变量,当我们执行pwd的时候,它是怎么知道我们当前所处的路径的呢?是因为我们系统存在一个PWD的环境变量:


这个环境变量会时时刻刻观察当前用户的路径的变化,当用户切换了路径,PWD的环境变量也会相应的做出变化,进行同步更新。


我们再来看一下环境变量,当我们执行whoami的时候,它是怎么知道我们当前用户呢?是因为我们系统存在一个USER的环境变量:


当用户登录系统的时候,USER的环境变量会记录首次登录的用户是谁,然后将用户名记录在USER的环境变量中。还有其他环境变量我就不一一介绍了,我们可以通过env查看系统中已经存在的环境变量。


那这里我们就可以粗略的理解一下环境变量,环境变量是由bash提前在给每一个人在登录的时候,提前在内存里面开辟一块空间,开辟好之后,把这个人的基本信息写入到这块空间里,所以这个用户在使用Linux系统的过程中,系统直接可以通过环境变量认识用户,就好比入职公司之前,公司会提前把我们的工牌做好,此时领导或者公司同事就可以通过工牌认识你。所以预先给用户准备的一批变量就是我们的环境变量,也就是我们进入了Linux这个系统环境而提前准备的变量。


常见环境变量


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


3.3.环境变量 --- 特性 --- 命令行参数


和环境变量相关的命令


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


查看环境变量方法:

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


那我们想要自己定义一个环境变量呢?export: 设置一个新的环境变量


上面我们知道main函数有两个参数,实际上main函数还有一个参数char* env[];这个env和我们的argv一样,env也是一个数组指针,内部每个指针指向的就是环境变量。

环境变量的组织方式:


每个程序都会收到一张环境表,环境表是一个字符指针数组,每个指针指向一个以’\0’结尾的环境字符串。


运行结果:


此时我们就会发现系统会把环境变量以main函数的参数的形式传递给我们的进程.myprocess。然后我们再来改一下我们的代码。


运行结果:


通过上面的结论我们可以知道环境变量是默认是可以被子进程继承的,那我们的孙子进程呢?我们再来修改一下我们的代码。


这里的运行结果也显示了孙子进程,它也被我们的孙子进程所继承。因为我们创建子进程的时候,这个环境变量的数据本来也应该属于子进程,因为创建子进程的时候代码共享,数据以写时拷贝的方式各自私有一份。所以环境变量具有全局属性,环境变量会被所有的子进程包括孙子进程进行继承!!!也就意味着我们在bash命令行添加的任何环境变量,将来在我们的子进程都可以看到。


环境变量基本概念


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


3.4.环境变量 --- 代码获取和设置环境变量


除了上面的命令行第三个参数获得所有环境变量,我们还可以通过函数getenv去获得一个环境变量。

#include <stdio.h>
#include <stdlib.h>
int main()
{
    const char* username = getenv("USER");
    if(username)
        printf("username:%s\n", username);
    return 0;
}


运行结果:


此时我们就获得了环境变量。那么环境变量到底有什么用呢?


运行结果:


此时系统通过环境变量USER知道当前用户是whb,就让该用户运行核心的代码,当我们有另外一个用户root登录的时候,操作系统此时就会形成该用户的环境变量,USER就是root。然后以root的身份去执行代码,此时就没有权限了。


此时我们就可以通过不同的用户根据自己的环境变量执行自己相应的代码。比如通过环境变量做一些身份识别的功能 - 比如优酷的普通用户和VIP用户。除了通过上面的命令行第三个参数获取环境变量,还可以通过第三方变量environ获取。我们可以先来看看eviron是什么,我们可以通过手册查看:man eviron


现在我们来写一个代码来验证一下

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


第三方变量environ是一个二级指针,它在这里也指向一个char*的数组。


注意:libc中定义的全局变量environ指向环境变量表,environ没有包含在任何头文件中,所以在使用时要用extern声明,我们只能对它进行声明,不能进行定义。我们上面有一个结论:环境变量具有全局属性,那么现在我们在bash进程导入一个环境变量:export myenv=aaaaaaaaaaaaaaaaaaaaaa;当我们再次运行上面的程序时,此时这个程序是在bash运行的,那么父进程也就是bash,而我们上面的程序就是bash的子进程,同时子进程也会继承父进程的环境变量,所以当我们运行之后,我们也可以在子进程中看到刚刚设置的环境变量了。


除了环境变量,程序中还可以使用本地变量,我们来看一下


通过上面的图片我们可以知道设置本地变量不用加export,同时我们无法通过env查到本地变量,那我们该怎么查询本地变量呢?我们可以使用set查看,set会把bash所有的变量全部展示出来,包括环境变量和本地变量。


我们可以通过getenv获取一个变量。


运行结果:


如果我们获取本地变量呢?const char* myenv=getenv("hello");


我们在bash命令行输入echo $hello可以看到本地变量hello,但是当运行上面的程序就无法看到。所以我们就可以得出一个结论:本地变量只在bash内部有效,不能被子进程继承下去,即本地变量不是环境变量,本地变量只在bash内部有效。


设置变量有了,那怎么移除变量呢?使用unset + 变量名


【解锁创意之门:环境变量引领你的编程奇思妙想】(下):https://developer.aliyun.com/article/1425758

相关文章
|
12月前
|
机器学习/深度学习 人工智能 Java
学会用AI:释放创意,解放双手,工作再多也不慌
随着人工智能(AI)技术日渐成熟,AI在软件开发领域的应用也更加广泛。以前我们谈到AI时,常常会想到复杂的算法和深奥的理论,但如今,AI正在悄然改变着程序员的日常工作方式。从AI代码生成模型到AI编程助手应用,它们不仅仅是一小部分,更是未来程序开发的新趋势。
|
9天前
|
Java 数据库连接 数据库
Micronaut 响应式编程:乘科技热潮,解锁异步应用新境界,让你的软件快人一步!
【9月更文挑战第11天】在快速发展的软件开发领域,响应式编程凭借其处理异步事件和数据流的优势,逐渐成为构建高效应用的关键技术。Micronaut 作为现代化的 Java 微服务框架,提供了强大的工具和支持,如 Reactive Streams 和 RxJava,帮助开发者轻松构建高性能的异步应用。通过非阻塞的方式处理请求,Micronaut 能充分利用系统资源,提高应用的吞吐量和响应速度。此外,Micronaut 的反应式 Web 客户端和数据库访问模块进一步增强了其在高并发场景下的表现,为现代异步应用的开发提供了坚实的基础。
22 5
|
1月前
|
Swift iOS开发 UED
【绝妙创意】颠覆你的视觉体验!揭秘一款iOS应用中令人惊叹的自定义动画效果,带你领略编程艺术的魅力所在!
【8月更文挑战第13天】本文通过一个具体案例,介绍如何使用Swift与UIKit在iOS应用中创建独特的按钮动画效果。当按钮被按下时,其形状从圆形变化为椭圆形,颜色则从蓝色渐变为绿色;释放后,动画反向恢复原状。利用UIView动画方法及弹簧动画效果,实现了平滑自然的过渡。通过调整参数,开发者可以进一步优化动画体验,增强应用的互动性和视觉吸引力。
35 7
|
20天前
|
UED 存储 自然语言处理
【语言无界·体验无疆】解锁Vaadin应用全球化秘籍:从代码到文化,让你的应用畅游世界每一个角落!
【8月更文挑战第31天】《国际化与本地化实战:构建多语言支持的Vaadin应用》详细介绍了如何使用Vaadin框架实现应用的国际化和本地化,提升用户体验和市场竞争力。文章涵盖资源文件的创建与管理、消息绑定与动态加载、日期和数字格式化及文化敏感性处理等方面,通过具体示例代码和最佳实践,帮助开发者构建适应不同语言和地区设置的Vaadin应用。通过这些步骤,您的应用将更加灵活,满足全球用户需求。
30 0
|
20天前
|
IDE 开发工具 计算机视觉
解锁Ruby图像处理新技能!从零基础到大师级,你的照片即将焕发不可思议的魔力!
【8月更文挑战第31天】Ruby不仅在Web开发和脚本编写中表现出色,还能通过强大的库如RMagick实现图像处理。RMagick是ImageMagick的Ruby接口,支持几乎所有图像格式。只需简单安装,即可进行图像加载、显示、滤镜应用、大小调整及裁剪等操作。
21 0
|
1月前
|
Python
编程之禅的奇幻之旅:探寻代码世界与生活万象的惊世共鸣,颠覆你的认知!
【8月更文挑战第7天】编程不仅是技术活,更融汇艺术与哲学。它启示我们在生活里追求简洁高效,如Python列表推导式的优雅;教会我们面对挑战时冷静分析,正如调试代码;体现分工合作的重要性,像模块化设计;并鼓励持续优化,提升效能。编程所蕴含的生活智慧,能引导我们创造更美好、有序的人生。
36 1
|
28天前
|
JavaScript 前端开发 开发者
震撼揭秘!JS模块化进化史:从混沌到秩序,一场代码世界的华丽蜕变,你怎能错过这场编程盛宴?
【8月更文挑战第23天】在 Web 前端开发领域,JavaScript 模块化已成为处理日益复杂的 Web 应用程序的关键技术。通过将代码分解成独立且可重用的模块,开发者能够更有效地组织和管理代码,避免命名冲突和依赖混乱。从最早的全局函数模式到 IIFE,再到 CommonJS 和 AMD,最终进化到了 ES6 的原生模块支持以及 UMD 的跨环境兼容性。本文通过具体示例介绍了这些模块化规范的发展历程及其在实际开发中的应用。
29 0
|
29天前
|
数据处理 Python
解锁Python多线程编程魔法,告别漫长等待!让数据下载如飞,感受科技带来的速度与激情!
【8月更文挑战第22天】Python以简洁的语法和强大的库支持在多个领域大放异彩。尽管存在全局解释器锁(GIL),Python仍提供多线程支持,尤其适用于I/O密集型任务。通过一个多线程下载数据的例子,展示了如何使用`threading`模块创建多线程程序,并与单线程版本进行了性能对比。实验表明,多线程能显著减少总等待时间,但在CPU密集型任务上GIL可能会限制其性能提升。此案例帮助理解Python多线程的优势及其适用场景。
26 0
|
2月前
|
人工智能 机器人 智能硬件
一场科技与幽默的奇妙碰撞,高中生意外开启未来生活新纪元!
在一个晴朗午后,高中生李明偶然发现了祖父留下的日记与一顶复古帽。日记中记载了一个荒诞的想法——“人工智能征服厨房计划”,勾起了他对AI的好奇心。深入研究后,李明意识到AI已让生活更便捷有趣。参加AI创新大赛时,原本打算设计一个“不讲冷笑话的AI伴侣”,却意外加入幽默模块。演示时AI的一句玩笑赢得了大家的喜爱,也让李明在学校小有名气,同学们开始向他咨询AI趣事,甚至请求为宠物定制会讲笑话的AI项圈。李明意识到AI不仅能改变生活,还能带来欢笑。
38 0
|
4月前
|
存储 Shell Linux
【解锁创意之门:环境变量引领你的编程奇思妙想】(下)
【解锁创意之门:环境变量引领你的编程奇思妙想】