深入学习Linux: 命令行参数与环境变量详解
文章目录
- 1. 命令行参数
- 1.1 main函数的参数
- 1.2 命令行参数的作用
- 2. 环境变量
- 2.1 理解一个问题
- 2.2 PATH环境变量
- 2.3 其他环境变量
- 3. C/C++代码与进程之间的关系
- 3.1 用代码获取环境变量
- 3.1.1 main函数最多有几个参数?
- 3.1.2 shell外壳里的环境变量是哪里来的?
- 3.2 获取环境变量的若干种方法
- 3.3 环境变量、本地变量、内建命令
- 3.3.1 创建自己的环境变量
- 3.4 内建命令
1. 命令行参数
1.1 main函数的参数
main函数是可以有参数的。main函数的参数由bash和系统自动传递。命令行参数的本质是一个字符串,shell以空格为分割符号,切成了若干的子串。
细节一:命令行参数至少是1,argc>=1,argv[0]一定会有元素,指向的就是程序名。
细节二:选项是以空格分割的字符串,一个字符也是字符串。
细节三:argv的本质是一张表,元素由argc决定,argv[argc]是最后一个,且始终为NULL。
1.2 命令行参数的作用
为什么要有命令行参数?命令行参数的本质应用,是为了实现一个命令可以根据不同的选项,实现不同的子功能。也是Linux中所有命令选项功能的实现方式。问题:VS2022有没有命令行参数?有的。cat file.txt和cat < file.txt如何打印出文件内容?本质是通过命令行参数,将文件打开,打开后读文件,打印内容。
2. 环境变量
2.1 理解一个问题
环境变量具有全局属性的根本原因是:环境变量可以被bash进程的子进程继承,所有在Linux下的子进程都会拥有对应的环境变量。
./的本质是相对路径,本质是告诉OS,用户要执行的bin,就在当前路径下。
2.2 PATH环境变量
Linux怎么知道我应该去哪一个路径下找可执行程序?除了去/usr/bin路径下去找,还会不会去其他路径下去找?Linux系统,会存在所谓的环境变量的东西。
PATH是该环境变量的变量名:
echo$PATH以冒号为分割符的多串路径,告诉Linux系统,如果用户执行一个可执行文件,没有指明路径,去哪几个路径下去找?
PATH的本质是协助Linux进行指令查找的环境变量。
如何将路径配置到环境变量里?就可以执行的时候不带有./:
PATH=[你的路径]你这么写就直接覆盖了:
PATH=$PATH:[你想要添加的路径]总结:
PATH:指定命令的搜索路径。
PATH环境变量是全局的。
2.3 其他环境变量
系统级的变量,变量名和变量内容,往往具有全局属性。
还有没有其他环境变量?查询:
env介绍其余环境变量:
echo$HISTSIZE记忆你之前使用过的命令,默认是1000,统计最近使用的1000条命令。
echo$OLDPWD记忆用户在运行时上一次所存在的工作路径。
echo$SSH_TTY记录终端文件,终端窗口不一样,输入重定向对内容进行重新输入。
PATH:指定命令的搜索路径。当你在命令行输入一个命令时,系统会按照 PATH 中列出的目录顺序依次查找对应的可执行文件。
HOME:当前用户的主目录路径。执行cd ~或cd不带参数时,就会跳转到该目录。不同用户的 HOME 不同,例如/home/zhangsan或/root。
SHELL:当前用户所使用的 Shell 解释器的路径。常见的有/bin/bash、/bin/zsh等,决定了你在终端中使用的命令解释器类型。
3. C/C++代码与进程之间的关系
3.1 用代码获取环境变量
3.1.1 main函数最多有几个参数?
三个参数,拿到系统的环境变量表,本质是将环境变量表传递给进程。
有什么用?不同的环境变量有不同的用途。
是谁传递的?怎么传递的?
环境变量在bash没有拿到的时候在哪里?
是谁传递给你的?默认是在bash内部的,bash本质是一个进程,是存储在内存中的,是临时表,内存级的。我的程序都是bash进程的子进程,子进程代码和数据是可以共享的,是父进程传递的。
所以环境变量具有全局属性。
存在两张环境变量表,当我们运行程序时,bash会fork出一个子进程,子进程可以看到父进程的参数。所以说,不传参数也能看到环境变量的原因是,子进程进行了继承。
不传参数怎么获取环境变量?
子进程都是bash的子进程,你可以获得bash的表,子进程天然可以继承父进程的数据。
语言会默认提供全局变量,全局的指针可以指向环境变量表。获取环境变量的第二种方式。
需要记住的是,环境变量可以被获取。
bash有两张表,一张是命令行参数表,一张是环境变量表。
3.1.2 shell外壳里的环境变量是哪里来的?
bash的环境变量是哪里来的?是从Linux系统的配置文件里面来的,启动时会把配置文件加载进来,所以当时你改的是内存级的数据,你关掉Xshell又打开会重新从配置文件中加载。
什么是配置文件,配置文件又是哪里来的?
家目录存在两个配置文件:.bashrc.bash_profile
上面的两个文件其实是相关的。
bash在启动时,会访问
.bashrc文件,会将配置文件载入,修改一下就可以看到bash被执行,echo一行字就可以了。
root怎么不执行?每一个人都会有自己的家目录,改的不是root的配置文件。
为什么会给每个用户都搞一个bash?
while:;dopsaxj|grepbash;sleep1;donewhile:;dopsaxj|grepbash;sleep1;echo"#############";done每开一个窗口就会有一个bash,每个子进程都会加载一个环境变量。
最常见:
mangetenv原理是,根据名字查找环境变量的内容,根据环境变量名遍历这张表,并依次比较,遍历成功将右边返回,失败返回NULL。
如何用C/C++获取环境变量:
char *whoami = getenv("USER");3.2 获取环境变量的若干种方法
环境变量的作用是限制程序的执行。
获取环境变量的三种做法:
- main函数参数:
char* env[] - C语言全局变量:
char** environ - 最佳实践:
getenv(name)
测试:限制访问用户名。
3.3 环境变量、本地变量、内建命令
3.3.1 创建自己的环境变量
我想创建一个自己的环境变量怎么办?
test_env=12344env|grepTEST_ENV存在但env不到,这个叫本地变量。
导出成环境变量:本质是在将本地变量放到环境变量表里,你就可以查到了:
exportTEST_ENV再次查询就有了。
如果这个本地变量本来就没有,可以用export直接导也可以:
exportAAA=asdfghj能不能被自己的C语言程序获得?
getenv("TEST_ENV");子进程是可以获得父进程环境变量的,环境变量是全局的本质:环境变量是可以被子进程继承的。
如何删除环境变量:
unset[环境变量名]取消命令行的环境变量:本质就是将环境变量,从环境变量表中删除。
其实,这些也都是内存级的,关掉重新打开就好了。
本地变量和环境变量的区别:本地变量无法被子进程继承,不具备全局性,只在bash内部可以访问!!
类比于局部变量和全局变量。
为什么要有本地变量?
cnt=0;while[$cnt-le100];doecho$cnt;letcnt++;doneshell当中的本地变量是为了支持语法的,用于保存一些临时信息。
set可以查询系统变量和环境变量。
如果我想让我的环境变量关掉打开后还有,打开.bash_profile,在里面export导入一个环境变量。
3.4 内建命令
提出问题:
本地变量只能在shell内部运行,不能被子进程继承。
echo子进程看不到本地变量是如何被打印的?
- echo这个进程是怎样能打印本地变量的?
命令和命令是不一样的,存在二进制文件级别的命令:
普通命令:
内建命令:在shell内部自己定义,bash自己内部的一次函数调用,不依赖第三方路径。
内建命令是shell自己的,意味着内建命令的执行不需要环境变量。
欢迎大家批评指正!!!