硬核手搓解析!进程-内核分析:命令行参数及环境变量,重构main()

目录

命令行参数与环境变量

命令行参数

vim下的main()

环境变量

环境变量的应用举例

查询环境变量

全部查询

针对名称查询(常用的方式)

环境变量的更改

配置环境变量

进程:命令行参数及环境变量的关系

结论

获取环境变量

①getenv();

②environ();

本地变量

特性:

本地变量的删除:

本地变量->环境变量:

问题探讨(内建命令)

库函数与系统调用


重构了main()函数-参数、运行环境,基于Linux进程深度下的吐血整理~~

命令行参数与环境变量

命令行参数

一个命令可以通过 选项 来实现特定的功能。

像:ls -a 及ls -a -l

类似于以前使用的main()函数中你可能见过的l两种形态:

cpp 复制代码
int main(int argc, char *argv[]);
int main(int argc, char **argv);

main()作为程序的入口,实际上我们也可以通过外部指定选项传入并调用特定功能:

vim下的main()

vim内:

cpp 复制代码
int main(int argc, char *argv[])
{
    //......
    return 0;
}

在bash:

bash 复制代码
# 执行命令
./a.out -l -a hello world 123

本质就是将"-l -a hello world 123"分别分割并传入argv\[\]

|-----------|----------------------|
| argc | 5 |
| argv[0] | "./myprogram"(程序名) |
| argv[1] | "-l" |
| argv[2] | "-a" |
| argv[3] | "hello" |
| argv[4] | "world" |
| argv[5] | "123" |
| argv[6] | NULL(结束标志) |

运行代码:

cpp 复制代码
#include <stdio.h>

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

makefile内:

cpp 复制代码
  1 SRC=$(wildcard *.c)
  2 OBJ=$(SRC:.c=.o)
  3 CC=gcc -std=c99                                                                                                                 
  4 LFLAGS=-o
  5 FLAGS=-c
  6 RM=rm -f
  7 all:$(OBJ)
  8     $(CC) $^ $(LFLAGS) pc
  9 %.o:%.c
 10     $(CC) $(FLAGS) $< $(LFLAGS) $@
 11 .PHONY: clean
 12 clean:
 13     $(RM) pc $(OBJ)

运行:

环境变量

功能:环境变量是进程级**背景**配置。

|------|---------------------|
| 特性 | 说明 |
| 本质 | 键值对(HOME=/home/wzb) |
| 作用 | 配置环境运行环境,无需修改代码 |
| 继承性 | 子进程自动继承父进程的环境变量 |
| 作用范围 | 当前进程及其子进程 |

因此:环境变量具有全局特性,可被**++所有进程++ 继承**。

"进程级"配置又是一位程序新引入的执行逻辑,大大增加代码的复杂度。就像C中引入条件语句一般,是跨越性进步。

环境变量的应用举例

查询环境变量

全部查询

env

会打印显示全部已配置环境变量:

格式为环境变量名称=环境变量内容

针对名称查询(常用的方式)

echo \[名称\] #例如:echo PATH

环境变量的更改

原名称=新的绝对路径 #覆盖原路径

原名称=$原名称:拼接路径 #简便地路径拼接

配置环境变量

增加环境变量:

export 名称=内容

删除环境变量:

unset 名称

进程:命令行参数及环境变量的关系

无需多言:

我们在VS2022下运行

cpp 复制代码
#include<stdio.h>
int main(int argc, char* argv[], char* envp[])
{
	// envp是环境变量数组,格式为"KEY=val"
	for (char** env = envp; *env != NULL; env++)
	{
		printf("%s\n", *env);
	}
	return 0;
}

运行结果:

结果显而易见:环境变量全部显现。

结论

因此:自入进程开始我们就处于"命令行参数"+"环境变量"的配置环境。图示如下:

获取环境变量

①getenv();

头文件<stdlib.h>

函数原型:

cpp 复制代码
char* getenv(const char* name);

使用:

输入环境变量的名称来获取指向环境变量值的指针/NULL 。 // "指向目录路径"

cpp 复制代码
#include <stdio.h>
#include <stdlib.h>

int main() {
    char *path = getenv("PATH");
    char *home = getenv("HOME");

    printf("PATH: %s\n", path);
    printf("HOME: %s\n", home);
    
    return 0;
}

运行结果:

bash 复制代码
PATH: /usr/local/bin:/usr/bin:/bin
HOME: /home/wzb
②environ();

头文件:<stdlib.h>

函数原型:

cpp 复制代码
extern char** environ;

二级指针型访问数据可使用下标直接访问

代码实现:

输出同样的结果:


本地变量

本地变量是定义于vim外bash内的变量。

特性:

不会被子进程继承。

定义时"="++两侧不能加空格++ #否则会被当做命令进行查询 像:i=10正确而i = 10就是错误的!!

本地变量的删除:

像环境变量一样:

unset 本地变量名

本地变量->环境变量:

export 本地变量名称

问题探讨(内建命令)

众所周知:Linux指令是bash进程下执行文件的子进程。

假如export指令是一般性指令,怎么做到的子进程指令处理内容到父进程呢?

实际上:export别于一般性指令,其本质是"内建命令"(build-in command)。

++其不需要创建子进程,而是让bash自己操作++。

库函数与系统调用

指令"man"的指定页查询:

|-------|---------------|---------------------------------|
| 1 | 用户命令(可执行程序) | ls, cd, grep, find |
| 2 | 系统调用(内核提供的接口) | read, write, open, fork |
| 3 | 库函数(C 标准库) | printf, malloc, strcpy |

库函数与系统调用的对比

维度 系统调用 库函数
运行空间 内核态(Kernel Mode) 用户态(User Mode)
调用开销 大(需上下文切换) 小(普通函数调用)
实现者 操作系统内核 语言库(如 glibc)或应用程序
例子 read()write()open()fork() printf()scanf()fread()strcpy()
是否缓冲 无缓冲(直接操作内核) 通常有缓冲(如 stdio 缓冲)
执行速度

博主吐血回顾重构整理 求关注
o(╥﹏╥)o

相关推荐
田里的水稻7 小时前
FA_数字相机成像原理、分级和分类
运维·数码相机·机器人·自动驾驶
froyoisle7 小时前
CSP 真题解析:[CSP-J 2020-T3] 表达式
c++·算法·csp·信息学·信奥赛
Darkwanderor7 小时前
动、静态库相关内容的详细介绍
linux·c语言·开发语言·c++
文祐7 小时前
C++类之虚函数表没有虚继承的菱形继承
开发语言·c++·算法
w139548564228 小时前
AI 周报卡片:智能生成内容的 UI 呈现
后端
全堆鸿蒙8 小时前
天气药丸标签:Row + Text 组合实现品牌药丸
后端
sycmancia8 小时前
Qt——另一种创建线程的方式
开发语言·qt
HONG````8 小时前
HarmonyOS ArkUI Slider 与 Rating 实战:音量控制、亮度调节与星级评分
后端
醉城夜风~8 小时前
MyBatis 基础CRUD全套实战学习笔记
笔记·学习·mybatis
极客先躯8 小时前
高级java每日一道面试题-2026年04月18日-实战篇[Docker]-如何处理金融行业的时序数据容器化?
java·运维·docker·容器·金融·时序数据·高级面试