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

常见环境变量
- PATH : 指定命令的搜索路径
- HOME : 指定用户的主工作目录(即用户登陆到Linux系统中时,默认的目录)
- SHELL : 当前Shell,它的值通常是/bin/bash。
PATH
问题引入:为什么我们写的程序,要用 ./程序名 来运行,而像 ls、pwd 这样的指令,直接输入名字就可以运行?
原因是:在运行 xshell 时,有一些环境变量就事先被创建了,比如 PATH(Linux 指令搜索路径)
如何在 Linux 下查看PATH的内容:

这个变量存储了多个路径,用 : 作为分割符。这些路径,就是系统查找我们输入的路径的默认查找路径。我们写的程序不在上面的任何一条路径,所以不能直接输入写的程序的程序名来运行程序。
如果要把我们写的程序也像 ls 指令那样直接输入名字就能执行,可以把程序所在的路径也加入到 PATH 环境变量:

注意:
1、等号两侧不能有空格
2、PATH=/home/hxh 会覆盖PATH之前的内容
3、退出重新登陆xshell,PATH 会恢复。
HOME
问题引入:为什么 root 用户登陆时,处于 /root 目录,而普通用户登陆时处于 /home/用户名 ?
原因是:登陆 Linux 时,shell 会识别登陆的用户,据此填充 HOME 环境变量


系统调用:getenv
我们不仅可以用 echo $环境变量名 获取环境变量的内容,也可以在程序中用 getenv 函数获取:
要包含头文件 #include <stdlib.h>



main 函数的命令行参数
main 函数也可以有参数:int main(int argc, char *argv[]),argc 是 argv(指向字符串的指针的指针数组)指向的字符串数组的字符串个数,argv 最后一个有效指针的下一个是 NULL。

编译运行:

其实,向 bash 命令行输入的,都是一个字符串,这些字符串,以空格为分割符,分别存储在 argv 数组里。这样做可以实现指令、工具、软件带不同的参数可以实现不同的功能(支持命令行选项)。


main 函数的参数其实还有一个:int main(int argc, char* argv[], char* env[]) ,即:两张核心的向量表:**命令行参数表argv和环境变量表env。**我们所运行的进程,都是 bach 进程的子进程,bach 在启动时,会从操作系统的配置文件中读取环境变量信息,子进程会继承父进程交给我们的环境变量。子进程如果再创建"孙子"进程,"孙子"进程又会继承子进程的环境变量,这就是为什么说环境变量具有全局性。
通过全局变量 environ 获取环境变量

libc中定义的全局变量environ指向环境变量表,environ没有包含在任何头文件中,所以在使用时 要用extern声明。
如何验证"子进程会继承父进程交给我们的环境变量"
要验证这个问题,首先要学会如何创建环境变量:
创建环境变量的方式:export 环境变量名=初始值(=两侧不能有空格)

在 bach 命令行创建的环境变量,与任何子进程无关,如果要求一个子进程打印环境变量,发现打印的环境变量有 MY_VALUE,就证明了这个问题。

可以发现打印的环境变量有 MY_VALUE:

删除环境变量:unset 环境变量名
补充知识:本地变量和内建命令
本地变量
上面创建的变量是环境变量,在创建时声明 export,如果不声明 export,直接用 变量名=初始值(=两侧不能有空格) 方式创建的变量,叫做本地变量

使用 set指令可以查看系统定义的所有变量,包括环境变量和本地变量
本地变量不会被子进程继承,只在本 bach 内部有效。
本地变量和环境变量可以相互转化 :把本地变量变成环境变量的方式:export 本地变量名, 把环境变量变成本地变量的方式:unset 环境变量名
内建命令

问题引入:
不是说好的 bach 都是创建子进程,让子进程去执行指令,自己继续继续命令行解释吗?不是说本地变量不会被子进程继承,那现在子进程打印出了本地变量,怎么解释?
原因是:
bach 指令可以分成两种:
1、常规指令:通过创建子进程完成
2、内建指令:bach 不创建子进程,而是自己亲自执行,类似于 bach 调用自己写到函数,或者系统提供的函数。(常见内建指令:cd、pwd、echo)