首页 > 系统相关 >Linux系统编程·环境变量

Linux系统编程·环境变量

时间:2022-11-14 14:34:23浏览次数:68  
标签:Linux int 编程 argv mytest printf main 环境变量


Linux系统编程·环境变量_运维

你好,我是安然无虞。

文章目录

  • ​​自学网站​​
  • ​​基本概念​​
  • ​​常见环境变量​​
  • ​​相关命令​​
  • ​​获取环境变量​​
  • ​​环境变量·全局属性​​

自学网站

推荐给老铁们两款学习网站:
面试利器&算法学习:​​​牛客网​​​ 风趣幽默的学人工智能:​​人工智能学习​

基本概念

在谈环境变量的基本概念之前呢,我们先看下面这段程序:

//test.cpp文件下
#include<stdio.h>

int main()
{
printf("Hello Linux.\n");
return 0;
}

我们自己定义的Makefile文件:

mytest:test.cpp
g++ test.cpp -o mytest
.PHONY:clean
clean:
rm -f mytest

Linux系统编程·环境变量_环境变量_02

make之后生成可执行程序 mytest,我们运行看看效果:

Linux系统编程·环境变量_运维_03


很明显报错了,报错说没有想找到,如果像下面这样改动呢?

Linux系统编程·环境变量_linux_04


我们看到,带上路径之后运行成功了,上面没带路径却报没有找到的错误,这是为什么呢?而且我们知道,像ls, pwd, touch…这些系统指令,实际上也是可执行程序,为什么它们不用带路径也能直接执行呢?

Linux系统编程·环境变量_环境变量_05


有了上面的失败经验,我们知道,执行一个可执行程序,前提是要找到它

为什么系统的命令能找到,而我们自己的程序找不到呢?

因为系统中是存在相关的环境变量,保存了程序的搜索路径的。系统中搜索可执行程序的环境变量叫做PATH(像ls, pwd……这些指令可以在PATH中找到)

Linux系统编程·环境变量_环境变量_06


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

说到这里可能有老铁会好奇,怎么将我们自己生成的可执行程序 mytest 能像系统指令一样,不用带上路径也可以直接执行呢?
有两个方法:

方法1:
将 mytest 拷贝进 /usr/bin 路径下(极不推荐,易污染)
说明:系统的所有指令都在 /usr/bin 路径下。

//拷贝
sudo cp mytest /usr/bin
//删除
sudo rm /usr/bin/mytest

方法2:

将我们的程序所在的路径加入到环境变量PATH当中,export PATH=$PATH:mytest程序所在路径。

先查看程序当前路径:

Linux系统编程·环境变量_c++_07


执行下面命令:

export PATH=$PATH:/home/sl/code/linux-programming/TestProcess

Linux系统编程·环境变量_环境变量_08

常见环境变量

常见的环境变量有:

1.PATH:指定命令的搜索路径

Linux系统编程·环境变量_#include_09


2.HOME:指定用户的主工作目录

Linux系统编程·环境变量_linux_10


3.SHELL:当前SHELL,它的值通常是/bin/bash

Linux系统编程·环境变量_c++_11

相关命令

1.echo:显示某个环境变量值

Linux系统编程·环境变量_#include_09

echo $NAME //NAME为环境变量名称

2.export:设置一个新的环境变量

Linux系统编程·环境变量_linux_13


注意哦,命令行上是可以定义变量的哟。

Linux系统编程·环境变量_运维_14

val1=12; //定义变量val1,初始化为12

说明:命令行变量分为两种:

  • 普通变量(如val1)
  • 环境变量——全局属性(如testVal)

3.env:查看环境变量

4.set:显示本地定义的shell变量和环境变量

Linux系统编程·环境变量_linux_15

5.unset:清除环境变量

Linux系统编程·环境变量_环境变量_16

获取环境变量

在讲解获取环境变量之前,请老铁回答我一个问题:我们之前使用C语言时,经常写main函数,所以我要问的是main函数可以带参数吗,最多可以带几个?
按照我们以前的学习,可能我们会认为是可以带两个,好的,请看下面代码:

#include<stdio.h>

int main(int argc, char* argv[])
{
for(int i = 0; i < argc; i++)
{
printf("argv[%d] : %s\n", i, argv[i]);
}
return 0;
}

好,下面我们保存退出到命令行中运行:

Linux系统编程·环境变量_c++_17


argc 是 argv 数组的元素个数.

Linux系统编程·环境变量_c++_18


上面的 ./mytest 是程序名(可执行程序), -a -b -c -d 这样的字符串是选项.

我们给 main 函数传递的是 argc 和 argv数组, 而命令行参数传递的是, 命令行中输入的程序名和选项 .

这样传的意义是什么呢? 同一个程序, 通过传递不同的参数, 让同一个程序有不同的执行逻辑, 执行结果.

Linux 系统中会根据不同的选项, 让不同的命令, 可以有不同的表现, 指令中那么多选项的由来, 和起作用的方式.

Linux系统编程·环境变量_环境变量_19


好,下面我们做一个小实验:

写一个命令行计算器:

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

int main(int argc, char* argv[])
{
if(argc != 4)
{
//使用手册: 如./mycal -a 10 20
printf("Usage : %s [-a|-s|-m|-d] one_data two_data\n", argv[0]/*程序名*/);
return 0;
}

int x = atoi(argv[2]);//atoi()是将字符串转变成成整数
int y = atoi(argv[3]);

//根据传入不同的命令行参数,实现不同的功能
if(strcmp("-a", argv[1]) == 0)
{
printf("%d + %d = %d\n", x, y, x + y);
}
else if(strcmp("-s", argv[1]) == 0)
{
printf("%d - %d = %d\n", x, y, x - y);
}
else if(strcmp("-m", argv[1]) == 0)
{
printf("%d * %d = %d\n", x, y, x * y);
}
else if(strcmp("-d", argv[1]) == 0 && y != 0)
{
printf("%d / %d = %d\n", x, y, x / y);
}
else
{
printf("Usage : %s [-a|-s|-m|-d] one_data two_data\n", argv[0]/*程序名*/);
}
return 0;
}

Linux系统编程·环境变量_运维_20


好, 有了上面的铺垫之后, 想必老铁对于命令行参数有了一个新的认知, 再回到之前抛出的问题, main函数最多可以带几个参数, 其实是3个!

好,下面我们总结一下通过代码获取环境变量的三种方式:方式一 : 命令行第三个参数

其实我们的每一个程序都会收到一张环境表, 环境表示一个字符指针数组, 每个指针指向一个以 ‘\0’ 结尾的环境变量字符串.

Linux系统编程·环境变量_linux_21

#include<stdio.h>
//每个进程都会被传入环境变量参数的
int main(int argc, char* argv[], char* env[]/*第三个参数*/)
{
int i = 0;
for(i = 0; env[i] != NULL; i++)
{
printf("%s\n", env[i]);
}

return 0;
}

执行程序:

Linux系统编程·环境变量_#include_22


方式二 : 通过第三方变量environ获取

全局变量 environ 指向环境变量表, environ 没有包含在任何头文件中, 所以在使用时, 要用 extern 声明.

Linux系统编程·环境变量_linux_21

#include<stdio.h>

int main(int argc, char* argv[])
{
//环境变量的指针声明
extern char** environ;
int i = 0;
for(i = 0; environ[i] != NULL; i++)
{
printf("%s\n", environ[i]);
}

return 0;
}

方式三 : 调用getenv函数

第三种方式是调用 getenv 函数获取指定的环境变量.

Linux系统编程·环境变量_c++_24


比如:

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

int main()
{
printf("%s\n", getenv("PATH"));

return 0;
}

环境变量·全局属性

环境变量通常具有全局属性, 可以被子进程继承下去.

我们知道, 命令行中启动的进程, 父进程全部都是bash.

为什么环境变量具有全局属性呢?

因为环境变量要被子进程继承下去.

Linux系统编程·环境变量_运维_25


所谓的本地变量(不带export), 本质就是在 bash 内部定义的变量, 不会被子进程继承下去.

代码验证一下:

#include<stdio.h>
#include<sys/types.h>
#include<unistd.h>
#include<stdlib.h>

int main()
{
while(1)
{
printf("hello world, pid:%d, ppid:%d, myenv:%s\n", getpid(), getppid(), getenv("test_sl"));
sleep(1);
}
return 0;
}

首先设置 test_sl 为本地变量:

Linux系统编程·环境变量_运维_26


此时运行程序查看结果:

Linux系统编程·环境变量_环境变量_27


下面我们将 test_sl 设置成环境变量:

Linux系统编程·环境变量_环境变量_28


此时运行程序查看结果:

Linux系统编程·环境变量_linux_29


好的,上面的实验结果就说明了环境变量具有全局属性, 请老铁细品哦.

还有一个问题:

创建一个本地变量 local_val, 但是我们发现 echo 也是一条命令, 要通过子进程的方式执行, 与我们上面所说的"本地变量不会被子进程继承下去"相悖.

Linux系统编程·环境变量_环境变量_30


解释:

Linux下大部分命令都是通过创建子进程的方式执行的, 但是, 还有一部分命令, 不通过创建子进程的方式执行, 而是由 bash 自己执行(调用自己对应的函数来完成特定的功能), 我们把这种命令叫做内建命令.


标签:Linux,int,编程,argv,mytest,printf,main,环境变量
From: https://blog.51cto.com/u_15495449/5849095

相关文章

  • Linux系统编程·进程创建及终止
    你好,我是安然无虞。文章目录​​自学网站​​​​进程创建​​​​fork函数​​​​写时拷贝​​​​进程终止​​​​进程退出场景​​​​练习题​​自学网站推荐给老铁......
  • Linux系统编程·进程概念
    你好,我是安然无虞。文章目录​​自学网站​​​​上文回顾​​​​进程控制块—PCB​​​​查看进程​​​​初识系统调用​​​​初始fork函数​​​​练习题​​自学网站......
  • SELinux
    1.SELinux基本架构与原理 SELinux是典型的MAC-MandatoryAccessControls实现,对系统中每个对象都生成一个安全上下文(SecurityContext),每一个对象访问系统的资源都......
  • Linux系统编程·进程地址空间
    你好,我是安然无虞。文章目录​​自学网站​​​​三个验证​​​​虚拟地址引入​​​​进程地址空间​​​​练习题​​自学网站推荐给老铁们两款学习网站:面试利器&算法......
  • C基础学习笔记——01-C基础第02天(用户权限、VI操作、Linux服务器搭建)
    在学习C基础总结了笔记,并分享出来。01-C基础第02天(用户权限、VI操作、Linux服务器搭建) 打开终端:ctrl+alt+t清屏:ctrl+l或clear在终端中退出锁定:ctrl+c 目录3常用命令4......
  • Linux系统编程·进程优先级
    你好,我是安然无虞。文章目录​​自学网站​​​​基本概念​​​​查看系统进程​​​​PRIvsNI​​​​其他概念​​​​竞争性​​​​独立性​​​​并行​​​​并发......
  • 响应式编程(反应式编程)的来龙去脉(同步编程、多线程编程、异步编程再到响应式编程)
    响应式编程的来龙去脉(同步编程、多线程编程、异步编程再到响应式编程)文章目录​​响应式编程的来龙去脉(同步编程、多线程编程、异步编程再到响应式编程)​​​​简介​​​​......
  • 在安卓手机上运行arm汇编程序
      效果图手机安装gcc.datamsg:.asciz"hello,gnuasm\n"len=.-msg.text.globalmainmain:push{r0,r1,r2,lr}ldrr1,=msgmov......
  • Linux命令之sar命令用例
    一、命令简介  sar(SystemActivityReporter系统活动情况报告)命令用于收集、报告或保存系统活动信息。sar命令将操作系统中选定的累积活动计数器的内容写入标准输出。会计......
  • Linux sar命令详解:分析系统性能
    sar命令很强大,是分析系统性能的重要工具之一,通过该命令可以全面地获取系统的CPU、运行队列、磁盘读写(I/O)、分区(交换区)、内存、CPU中断和网络等性能数据。sar命令的基本......