目录
1.命令行参数
1.1.概念引入
1.2.命令行参数概念
2.环境变量
2.1.概念引入
2.2.环境变量概念
2.2.1常见的环境变量
2.3. 如何获取环境变量
2.3.1.Linux操作系统
2.3.2.代码获取
2.3.3.系统调用
2.4.环境变量的来源
2.5.环境变量的全局性
1.命令行参数
1.1.概念引入
注意当部分代码均在Linux下运行!
再讲环境变量前我们先引入一个概念:命令行参数,那什么是命令行参数呢?我们知道main()函数其实是可以带参数的,再给出定义之前下面我们用一段代码来体会一下什么是命令行参数。
#include<stdio.h>
int main(int argc, char* argv[])
{for(int i = 0; i < argc; i++){printf("%d: %s\n", i, argv[i]);} return 0;
}
如图:在Linux操作系统中我们跑这一段程序,发现结果分别打印了,程序名 + 我们写的一段话的每一部分(这里有以空格为分隔符,分割几份子串),数一数恰好从0-8一共有9份,我们再看回这一段代码,我们可以猜到argc = 9,也就是九个字符串,并且对应着这个指针数组,那么我们可以抽象出来
还是不理解的话,我们可以做一个小demo,命令行版本的计算器。
我们的输入规则为:
程序名 -add num1 num2
程序名 -sub num1 num2 (其中num1,num2计算的数据)
#include<stdio.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, char* argv[])
{if (argc == 4){int num1 = atoi(argv[2]);int num2 = atoi(argv[3]);if (strcmp(argv[1], "-add") == 0){printf("%d + %d = %d\n", num1, num2, num1 + num2);}else if (strcmp(argv[1], "-sub") == 0){printf("%d - %d = %d\n", num1, num2, num1 - num2);}else {printf("option illegal\n");printf("the right input is: process option(-add, -sub) num1 num2\n");}}else{printf("input illegal\n");printf("the right input is: process option(-add, -sub) num1 num2\n");}return 0;
}
1.2.命令行参数概念
命令行参数是在命令行界面中输入的一些额外信息,用于向程序传递参数或配置选项。通过命令行参数,我们可以在运行程序时指定不同的参数值,从而改变程序的行为。
命令行参数通常以空格分隔,并且以特定的格式传递给程序。在大多数操作系统中,命令行参数的格式通常是以"-“或”–"开头的选项,后面跟着选项的值。例如,在Linux系统中,可以使用以下格式传递命令行参数:
program_name -option1 value1 -option2 value2
在程序中,可以使用命令行参数来控制程序的执行逻辑、配置文件路径、调试模式等。通过解析命令行参数,程序可以根据用户的需求进行相应的操作。
再联系一下我们在Linux中学到的指令,比如最简单的 ls -a,ls -l这一些那我们就知道了命令行参数的作用了,便于一个大的模块转入一些不同的小模块。
2.环境变量
2.1.概念引入
在操作系统中“执行一条命令,需要找到可执行程序的位置”,我们在Linux操作系统中,运行一个自己写的可执行程序,一般都是通过“./程序名”来运行,而不能直接“程序名”来使用呢?。但是Linux的指令本质上也是一些可执行程序,那为什么他们可以直接ls、pwd、which直接使用呢?
根本原因就在于:Linux操作系统有一个叫做环境变量的东西,环境变量里添加着Linux内支持的指令,而我们自己写的可执行程序并不在环境变量里,也就是操作系统无法通过程序名来找到这个可执行程序。那么我们也可以通过把自己写的可执行程序写入环境变量中来实现程序名启动。
2.2.环境变量概念
环境变量(environment variables)一般是指在操作系统中用来指定操作系统运行环境的一些参数。
如:我们在编写C/C++代码的时候,在链接的时候,从来不知道我们的所链接的动态静态库在哪里,但 是照样可以链接成功,生成可执行程序,原因就是有相关环境变量帮助编译器进行查找。
环境变量通常具有某些特殊用途,还有在系统当中通常具有全局特性。
2.2.1常见的环境变量
PATH : 指定命令的搜索路径
HOME : 指定用户的主工作目录(即用户登陆到Linux系统中时,默认的目录)
SHELL : 当前Shell,它的值通常是/bin/bash。
2.3. 如何获取环境变量
2.3.1.Linux操作系统
通过输入 “echo $环境变量名 ” 指令查看
Linux下环境变量相关指令
1. echo: 显示某个环境变量值
2. export: 设置一个新的环境变量
3. env: 显示所有环境变量
4. unset: 清除环境变量
5. set: 显示本地定义的shell变量和环境变量
2.3.2.代码获取
#include <stdio.h>int main(int argc, char *argv[], char *env[])
{int i = 0;for(; env[i]; i++){printf("%s\n", env[i]);}return 0;
}
这段代码跟在Linux下运行跟输入env指令一致,都是打印全部的环境变量,这里的env[]指针数组本质上就是一个环境变量表
而实际上系统在启动我们的程序时,可以选择给我们的进程(main)提供“命令行参数表”、“环境变量表”
// 这一段代码也可以获取环境变量
#include <stdio.h>int main(int argc, char* argv[])
{extern char** environ;int i = 0;for (; environ[i]; i++){printf("%s\n", environ[i]);}return 0;
}
environ为指向环境变量表的指针
2.3.3.系统调用
通过系统提供的getenv()接口来获取
#include<stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{// 判断为root用户的demo,可以作为权限控制的小模块// getenv() 内填 环境变量名char* who = getenv("USER");if(strcmp(who, "root") != 0){printf("%s,是非法用户\n", who);return 1;}printf("当前为%s用户", who);return 0;
}
2.4.环境变量的来源
在操作系统中,子进程的命令行参数和环境变量是通过父进程的bash传递的。那么父进程的环境变量信息又是从哪里来的?并且我们在实际操作中,修改Shell中的环境变量,重启后,又恢复成原来的样子,这又是为什么呢?
答:首先环境变量里在系统中以“脚本配置文件”的形式存储,当我们启动时会重新生成对应的环境变量信息,也就是就算修改了bash的环境变量,也只是修改了加载在内存时的环境变量表,并不影响磁盘中存储的“脚本配置文件。
2.5.环境变量的全局性
我们在2.4中提到子进程的环境变量是通过父进程的bash传递的,也就是说环境变量可以被子进程继承下去,环境变量信息具有全局性。我们先来引入两个概念
本地变量(Local Variable): 本地变量是在程序中定义的、仅在特定作用域内可见和使用的变量。它们通常在函数或代码块内部声明,并且只能在声明它们的作用域内访问。本地变量的生命周期仅限于其所在的作用域,一旦超出作用域范围,本地变量将被销毁。本地变量的作用是存储临时数据,供当前作用域内的代码使用。
环境变量(Environment Variable): 环境变量是在操作系统中定义的、全局可见的变量。它们存储了一些系统级别的配置信息,如路径、用户名、操作系统版本等。环境变量可以在整个操作系统中被访问和使用,不同的程序可以通过读取环境变量来获取系统配置信息。环境变量通常由操作系统或用户自定义,并且可以在运行时进行修改。
在Linux中,我们可以通过以下指令实现,本地变量的创建,这里我们设定了本地变量MYENV
再通过这段代码尝试打印这个本地变量,发现这个本地变量无法被打印
#include <stdio.h> #include <stdlib.h>int main() {// 获取环境变量char* env = getenv("MYENV");if (env) {// 如果成功获取 那么打印printf("%s\n", env);}else{printf("can not find MYENV\n");}return 0; }
最终我们把本地变量导入环境变量中就可以输出这个MYENV,也就是本地变量只对当前bash有效(因为本地变量我们是通过命令行指令创建的,并未加载到全局),那么所以我们就能推出“环境变量具有全局性”
但是我们又发现为什么echo这个指令可以打印出MYENV对应的值10000呢?
这里涉及Linux的指令分类为“内建命令”和“常规命令
也就是我们如果想要在常规命令下访问我们的本地变量,就需要将本地变量通过export命令升级为环境变量,让bash的所有子进程继承下去。而对于内建命令如echo、pwd、export......是不受环境变量影响的指令,我们也可以实验一下将环境变量置为空,ls、which、who等命令无法使用但是内建命令任然可以使用。