Linux命令行与环境变量¶
约 2064 个字 54 行代码 13 张图片 预计阅读时间 8 分钟
命令行¶
前面写C语言时,很少关注过main
函数的参数,也没有考虑过main
为什么会有参数。
实际上在C语言中,main
函数一共有三个参数,在命令行部分先关注前两个参数:
argc
:表示main
函数接收到参数个数argv
:表示main
函数接收的参数
根据下面的代码观察这两个参数具体的效果:
C | |
---|---|
1 2 3 4 5 6 7 8 |
|
对应的Makefile
如下:
Makefile | |
---|---|
1 2 3 4 5 6 7 8 9 |
|
直接运行程序可以看到下面的结果:
如果在输入./test
后,再输入一些字符串可以看到下面的结果:
可以看到,argc
的值即为终端上包括./test
在内的所有字符串的个数,而argv
是一个字符串数组,存储着终端上包括./test
在内的以空格间隔的字符串,这个数组的最后一个元素就是NULL
。这就是main
函数的两个参数。
前面提到Linux下的命令都是文件,并且因为Linux是C语言编写的,所以所有命令所带有的选项即为存储在argv
数组中的字符串,而根据不同的参数值实现不同的功能就可以通过类似于下面的形式完成:
C | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 |
|
简单介绍命令如何传递¶
在Linux下输入的命令首先会被Shell拿到。
前面提到父进程和子进程的代码是共有的,但是二者数据是各自独立的,但是数据独立实际上只会建立在其中一个进程修改了数据,如果二者都是对变量进行只读不写,那么也没有必要单独为两个进程开辟两个数据空间
对于上面的情况亦是如此,直接在终端上执行的进程,其父进程都是Shell,并且父进程和子进程都只是以只读的方式访问main
函数的参数,所以就不会出现两个数据空间。
从上面的过程中也可以看出,在设计操作系统、编程语言等时,相互都是存在依赖关系的
环境变量¶
前面提到main
函数参数实际上有三个,而这第三个参数就是所谓的环境变量env
,与argv
一样,env
是一个字符串数组
使用下面的代码可以看到其中的内容:
C | |
---|---|
1 2 3 4 5 6 7 8 9 |
|
需要注意的是,因为argc
只能表示argv
中的参数个数,所以对于循环终止条件来说,因为env
的最后一个位置时NULL
,所以读取到NULL
即可停止
运行上面的代码,可以看到结果是一堆字符串,这些字符串就是所谓的环境变量
在Linux中,环境变量和对应的值都是键值对的形式,一共有三种方式查看系统中的环境变量:
- 程序中遍历
env
数组 env
指令- 使用
environ
指针访问
environ
本质是一个二级指针,其指向的是每一个环境变量的地址,所以通过下面的代码也可以访问到所有的环境变量:
C | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
环境变量PATH
¶
PATH
指定了命令默认搜索的位置,因为其值中默认是/.../bin
,所以命令执行是会默认去/bin
目录下找,所以前面将自己写的程序移动到/bin
路径下就可以运行是因为默认从/bin
路径下搜索
可以使用echo $PATH
查看当前用户的PATH
环境变量的值
Note
也可以使用echo ${PATH}
,此处的{}
表示限定变量的边界
如果需要修改PATH
值,可以使用PATH=指定的路径
,但是这种方式只是修改了位于内存的系统进程中对应的PATH
,而不会影响到本地配置文件中的PATH
,并且这种方式会覆盖当前系统进程中的PATH
值。
Note
通过上述方式修改只需要退出当前用户再重新登陆即可重新加载对应的配置文件中的PATH
如果需要修改PATH
对应的配置文件,可以到用户的家目录下找到.bash_profile
文件,修改其中的PATH
值为需要的值即可
环境变量HOME
¶
在Linux中,HOME
环境变量指定了每一个用户的家目录,对于root用户来说,其值即为/root
,对于普通用户该值即为/home/用户名
使用echo $HOME
查看结果如下:
普通用户:
root用户:
在用户登录时,首先bash
会从配置文件中加载对应的值到HOME
中,此时bash
进程中的cwd
就是家目录,因为HOME
的值为当前用户的家目录,而因为大部分运行在bash
进程之上的指令都是bash
进程的子进程,子进程会与父进程共用一块数据,所以子进程的cwd
与父进程的cwd
相同。所以如果直接在家目录运行一个普通的程序时,查看其cwd
值可以看到结果与父进程相同,例如下面的结果:
需要注意,并不是所有的命令都是bash
进程的子进程,例如cd
命令
cd
命令并不是一个单独的进程,而是一个内建(built-in)命令。所以如果使用cd
改变当前bash
的工作路径,cd
指令通过chdir
函数对bash
进程中的数据直接进行修改,从而达到直接改变bash
进程的cwd
,例如下面的效果:
Note
为了更加直观得看到当前bash
进程的PID
,可以使用echo $$
命令,其中的$$
就代表当前bash
的PID
环境变量PWD
¶
在Linux中,PWD
中的值为当前用户所处的工作路径,所以使用pwd
命令查看当前的工作路径实际上就是在读取PWD
中的值
PWD
一般用于进程在当前工作路径下创建一个文件,在标准库中提供了一个函数为getenv
,原型如下:
C | |
---|---|
1 |
|
只要获取到了当前路径,就可以在当前路径下创建文件
如果需要在程序中创建或修改一个环境变量,可以使用putenv
函数,原型如下:
C | |
---|---|
1 |
|
对应的还有一个OLDPWD
环境变量,该环境变量的值为上一次的工作路径,这也就是为什么使用cd -
可以切换为上一次工作路径的原因
环境变量SHELL
¶
在Linux中,SHELL
表示当前使用的终端:
理解环境变量¶
环境变量本质是系统提供的具有全局属性的变量,既然是全局属性,则证明所有进程都可以访问到环境变量,这个过程实际上就是通过进程之间的父子关系实现的,因为环境变量本质是被bash
进程从配置文件加载的,所以bash
进程和其子进程就都可以看到环境变量。在大部分情况下环境变量是不会被修改的,所以bash
进程和子进程实际上是共用一块环境变量空间
前面提到有一些指令时内建指令,另一部分是外部命令,常见的内建命令还有echo
和export
在Linux中,bash
是shell
脚本语言的一种实现,而shell
是一个命令行解释器,用户通过它与操作系统进行交互,它可以运行命令、脚本和程序,所以可以在命令行直接创建一个变量,这种变量也被称为本地变量,例如:
本地变量与环境变量基本一致,只是本地变量不具有全局属性,即父子进程不会共享
使用set
可以查看当前创建的本地变量和环境变量,如果想要清除指定的本地变量可以使用unset + 本地变量名
本地变量也可以使用echo
命令输出:
如果需要将本地变量添加到环境变量,可以使用export
命令,例如:
也可以直接将变量的初始化结合export
使用: