一、命令行参数
int main(int argc,char*argv[])
{
//...
return 0;
}
不知道有没有人见过这样的主函数,它带了两个参数,argv接收的参数就叫做命令行参数,因为它的参数是从命令行来的,给大家演示一下,大家就懂了
命令行中的命令会被按照空格分割成一个个字符串交给argv数组,args中存放数组的元素个数
那么我们就会发现,我们之前用的各种命令+选项,其实就是靠命令行参数实现的,我们可以根据不同的参数,实现不同的功能,下面写一个简易的命令行计算器程序
命令行参数可以支持各种指令级别的命令行选项的设置,所以我们如果有兴趣就可以模拟实现cat、ls、echo等简单的命令
二、环境变量
1.PATH
相信大家在一开始学Linux的时候都有一个困惑,那就是命令行上的指令本质就是程序,我写的也是程序,为什么像ls、cat、touch等等命令的执行不用加./,而自己的程序运行要加呢?
本质在于程序的运行,首先要找到这个程序的位置,而如果我们就只写程序名,操作系统只会在PATH中的路径上查找该程序,如果找到了就会执行,没找到就无法执行,而我们自己写的程序一般都不在PATH的路径上,所以我们的程序执行要自带路径./
当然我们可以将程序的路径加入PATH中
或者我们也可以将程序拷贝到PATH中的某个路径中,这个操作其实就相当于简易版的安装,而将程序从这些路径中删除,就相当于卸载操作,一般不建议这么做。
当然不用担心PATH被修改之后改不回来,这里的PATH是内存中的值,磁盘中的PATH并没有改变重启Linux后就会恢复。
2.PWD
我们有一个命令pwd能打印我们当前所在目录,本质是pwd命令读取了环境变量PWD中的值
3.HOME
不同的用户登录,会出现在各自的家目录,如root出现在/root,普通用户出现在/home/username为什么?
在登录时
1、输入了用户名和密码
2、认证是否匹配
3、形成环境变量(PATH/HOME/PWD等等),根据用户名,初始化HOME
系统中会存在大量的环境变量,每个环境变量都有它自己的特殊用途,其他的环境变量如下
我们还可以在代码中获取环境变量来完成一些特定的功能,比如限制用户的权限
我们还能通过给main函数传参,来获得环境变量
注意:main函数的三个参数的顺序不能改变。
我们会发现父子进程的环境变量的值一样,其实环境变量存放在下面的这样一张表中,和命令行参数类似。
两者都可以通过父进程传递给子进程,我们知道子进程的命令行参数是我们在命令行输入的命令转化来的,那么环境变量又是从哪里来的呢?
其实在操作系统启动的时候,会有相关的配置文件导入环境变量,可以理解为初始化的过程,我们在根目录下,能找到.bash_profile这样一个隐藏文件
这个文件里面存一些脚本,每一次登录的时候,你的bash进程会读取并执行该配置文件的内容,为bash进程形成一张环境变量表信息
所以我们之前修改的环境变量本质是在修改上面的那张表上的内容,也就是修改bash进程的环境变量(在内存中),不会影响磁盘中的配置文件,所以重启系统之后,环境变量就又恢复到默认的状态了。
如果我们想让每次打开系统都会有,我们可以将他写入这个配置文件中
我们也可以手动给bash进程加入一些环境变量
我们创建的变量只是本地变量,可以用echo查看,但是不在环境变量表中,得通过export命令将他们导入环境变量表中(再次强调这里的环境变量表只是内存中的)
本地变量只在bash进程内部有效,不会被子进程继承下去,环境变量通过让所有的子进程继承的方式,实现自身的全局性
在之前我们讲过父子进程数据共享,而环境变量也是属于进程的数据的,所以我们也可以不传参数来获取进程的环境变量,有一个全局的变量environ
上面这个本地变量,为什么能被echo打印,而不能被env打印?明明两个都是子进程,而本地变量不在环境变量中,所以子进程不应该能找到才对呀,那echo是怎么找到的?
其实Linux中的命令分为两个:
- 常规命令,shell fork创建子进程,让子进程去执行
- 内建命令,shell命令行的一个函数,当然可以直接读取shell内部定义的本地变量
而echo\export等就是内建命令,所以即使PATH="",它们也能执行
和环境变量有关的命令
1. echo: 显示某个环境变量值2. export: 设置一个新的环境变量3. env: 显示所有环境变量4. unset: 清除环境变量和本地变量5. set: 显示本地定义的shell变量和环境变量