命令行参数
在 Linux 命令行中,参数是用户在执行命令时提供的额外信息,用于修改命令的行为或指定操作对象
main函数可以有参数吗?当然可以
在 C 和 C++ 语言中,main 函数可以有以下几种参数形式:
标准参数形式
无参数形式
cpp
int main(void) { /* ... */ }
标准双参数形式
cpp
int main(int argc, char *argv[]) { /* ... */ }
这是最常用的形式,允许程序接收命令行参数


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

操作系统查找可执行命令是在环境变量PATH中查找的
cpp
echo $NAME //NAME:你的环境变量名称
我们可以用echo命令来查看环境变量

PATH中的路径以:分隔
我们平时在linux中输入命令时只需要输入命令的名称,不需要输入命令的所在路径,是因为PATH中存在那些命令的路径,我们执行命令时操作系统会自动在环境变量PATH中查找
而我们自己编写的可执行文件路径没有在PATH中,需要我们完整的输入路径,否则操作系统找不到

测试PATH
- 创建hello.c文件
cpp
#include <stdio.h>
int main()
{
printf("hello world!\n");
return 0;
}
-
对比./hello执行和之间hello执行
-
为什么有些指令可以直接执行,不需要带路径,而我们的二进制程序需要带路径才能执行?
-
将我们的程序所在路径加入环境变量PATH当中, export PATH=$PATH:hello程序所在路径
cpp
export PATH=$PATH:hello程序所在路径
- 对比测试

测试HOME
-
用root和普通用户,分别执行 echo $HOME ,对比差异
-
执行 cd
; pwd ,对应和 HOME 的关系

3 和环境变量相关的命令
-
echo: 显示某个环境变量值
-
export: 设置一个新的环境变量
-
env: 显示所有环境变量

- unset: 清除环境变量

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

4 查看环境变量方法
1 main函数(命令行第三个参数)
main函数可以有几个变量?实际是三个
main函数参数特殊扩展形式(非标准)
环境变量参数(UNIX/Linux 系统)
cpp
int main(int argc, char *argv[], char *envp[])
- envp:环境变量数组(Environment Pointers)
cpp
#include <stdio.h>
int main(int argc, char *argv[], char *envp[]) {
for (int i = 0; envp[i] != NULL; i++) {
printf("Env %d: %s\n", i, envp[i]);
}
return 0;
}


环境变量的组织方式

每个程序都会收到一张环境表,环境表是一个字符指针数组,每个指针指向一个以'\0'结尾的环境字符串
2 通过系统调用函数获取单个环境变量


cpp
char* getenv(const char* name);
功能:从环境变量中获取指定变量的值
- 参数 :
- name:要获取的环境变量的名称。
- 返回值 :
- 如果找到该环境变量,则返回其值的指针(字符串形式)。
- 如果未找到,则返回 NULL。
- 示例代码:
cpp
#include <stdio.h>
#include <stdlib.h>
int main() {
char* path = getenv("PATH");
if (path != NULL) {
printf("PATH: %s\n", path);
} else {
printf("PATH environment variable not found.\n");
}
return 0;
}

3 通过第三方变量environ获取
environ 是一个与环境变量相关的全局变量,通常用于存储当前进程的环境变量列表,其核心功能是提供对环境变量的访问
environ 的声明通常在 <unistd.h> 或 <stdlib.h> 中:
cpp
extern char **environ;
使用示例
以下是一个简单的示例,展示如何通过 environ 遍历所有环境变量:
cpp
#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;
}
libc中定义的全局变量environ指向环境变量表,environ没有包含在任何头文件中,所以在使用时 要用extern声明。
运行这个程序会输出当前进程的所有环境变量,例如:

此时,我们应该有一个疑问,我们的进程是怎么获得环境变量的
实际上,不是你的进程获得了环境变量,而是你的父进程获得了环境变量,形成环境变量表
在 Unix/Linux 系统中,进程的环境变量是通过父进程传递给子进程的。当一个进程创建子进程时,子进程会继承父进程的环境变量。这个机制确保了子进程可以访问父进程的配置信息,例如路径、语言设置等
环境变量通常是具有全局属性的
环境变量通常具有全局属性,可以被子进程继承下去
与之相对的是本地变量,只在父进程bash内有效

cpp
#include <stdio.h>
#include <stdlib.h>
int main()
{
char *env = getenv("MYENV");
if(env){
printf("%s\n", env);
}
return 0;
}
直接查看,发现没有结果,说明该环境变量根本不存在
• 导出环境变量
export MYENV="hello world"
• 再次运行程序,发现结果有了!说明:环境变量是可以被子进程继承下去的!

• 如果只进行 MYENV="helloworld" ,不调用export导出,在用我们的程序查看,会有什么结果

查看,发现没有结果,这是因为MYENV只是本地定义的普通shell变量,没有全局属性,只在父进程bash内有效
该变量不会被子进程继承,所以在子进程内无效
到此,命令行参数和环境变量就讲完了,怎么样,是不是感觉大脑里面多了很多新知识。
如果觉得博主讲的还可以的话,就请大家多多支持博主,收藏加关注,追更不迷路
如果觉得博主哪里讲的不到位或是有疏漏,还请大家多多指出,博主一定会加以改正
博语小屋将持续为您推出文章