命令行参数和环境变量

命令行

命令行就是终端上输入的字符串,如 ls -l

命令行参数

命令行参数是命令行字符串按空格分割的子字符串

环境变量

环境变量是一个格式为''Val=value''的字符串

命令行解释器

命令行解释器又称shell,是用来解析和执行命令行的进程,比如 linux的bash进程

main函数的三个参数

int main(int argc, char **argv, char **envp)

  • argc:命令行参数的个数(包括程序名本身)。
  • argv:指向一个字符指针数组,每个字符指针指向一个命令行参数字符串
    • argv[0] 指向程序名。
    • argv[1] 到 argv[argc-1] 指向的是用户输入的参数。
    • argv[argc] 是 NULL,也就是数组最后一个char*为NULL。
  • envp:envp也是指向一个char*数组,每一个char*指向一个环境变量字符串。
    • envp指向的指针数组的最后一个char*为NULL。

命令行参数和环境变量的存放

1.命令行参数和环境变量存放在虚拟地址空间里栈的栈顶

高地址

+-------------------+

| "PATH=/usr/bin" | <-- envp0 指向的字符串

| "USER=root" | <-- envp1 指向的字符串

| "ls" | <-- argv0 指向的字符串

| "-l" | <-- argv1 指向的字符串

+-------------------+

| envp0 | → 指向环境变量字符串

| envp1 | → ...

| NULL |

| argv0 | → 指向命令行参数字符串

| argv1 | → ...

| NULL |

+-------------------+

| argc (2) |

+-------------------+

| 返回地址 | → _start

低地址

2.elf文件中没有保存命令行参数和环境变量

3.clib会用一个char** environ的全局变量来指向栈里面的envp,假如进程要修改环境变量,那栈里面的envp字符串和指针数组作废,会去堆上开字符数组保存字符串,开字符指针数组并用environ指向

fork()

fork系统调用会先创建子进程pcb,mm_struct 、files_struct 和父进程一样,也就是浅拷贝,于是代码、数据、环境变量子进程与父进程共享,并将子进程pcb加入运行队列。子进程重新调度,会从fork已经执行结束的位置开始运行。内核会将父进程中保存返回值的寄存器设为子进程pid,而子进程的设为0,然后才返回用户态。接下来父子进程共享代码,但却会因为返回值不同而执行流不同

命令行解释器运行流程

往终端里写入命令行,bash进程会解析命令行,将命令行参数字符串和指针数组存放在堆上,我假设是用一个char** argv指向指针数组,指针数组最后一个元素是NULL。然后接下来bash进程调用fork创建子进程,此时子进程共享父进程的environ全局变量,从而共享其环境变量,也就是说子进程根本不关心父进程此时environ指向栈还是堆。然后子进程调用execve,传入argv和environ,系统调用execve陷入内核,然后将堆上的环境变量和命令行参数字符串拷进内核缓冲区,用新程序的代码段和数据段替换原来的代码段和数据段,并重建堆栈,将缓冲区中的字符串存到新栈的栈顶,还要存进对应的字符指针数组和命令行参数个数,后面靠_start函数解析新栈来获取main函数的参数

相关推荐
Ruiery20 分钟前
Linux 6.6内核内存管理深度解析(十七):vmalloc — 内核要“虚拟连续“就够:物理页逐个凑,页表来连
linux·运维·服务器
Escalating_xu26 分钟前
【Linux 网络编程】ARP 的具体过程与 ARP 欺骗:一条 IP → MAC 映射,怎样改变数据的去向?
linux·网络·tcp/ip
坚定的共产主义生产设备永不宕机1 小时前
服务器从裸机开始搭建ESXI虚拟机
linux·服务器·网络
刚入门的大一新生1 小时前
Linux-线程封装
linux·运维·服务器
god_cvz1 小时前
实践:Linux环境构建CTB工具(cesium-terrain-builder)
linux·gis·ctb
Android系统攻城狮1 小时前
Linux FFmpeg深度解析之av_dump_format调用流程与实战(十一)
linux·运维·服务器·ffmpeg·1024程序员节·音视频进阶
Android系统攻城狮1 小时前
Linux FFmpeg深度解析之avcodec_find_decoder调用流程与实战(十二)
linux·运维·服务器·ffmpeg·1024程序员节·音视频进阶
小白的码BUG之路2 小时前
K8s -- 启动一主二从节点
linux·运维·服务器
Escalating_xu2 小时前
【Linux 网络编程】IP 分片与重组:3000 字节的数据报,怎样拆开又拼回来?
linux·网络·tcp/ip
小相会自律2 小时前
全平台远程控制软件推荐2026:Win/Mac/Linux/手机/鸿蒙互通哪款好
linux·macos·智能手机·todesk·teamviewer·向日葵