Linux-shell 学习笔记–环境变量
什么是环境变量
环境变量是描述系统运行环境的一系列变量,如PATH描述了应该去哪里查找命令,SHELL描述了默认的shell是哪个。
加载环境变量
当一个shell启动时会从某个文件读入环境变量,例如bash的环境变量就和~/.bashrc
文件密切相关。
普通变量
书上把shell里面的变量分为全局和局部,站在环境变量的角度,以我的理解我把shell里面的变量分为两种,普通变量和环境变量
我们在bash里面定义一个变量newvar看看它是否和环境变量性质一样
$set newvar 8
$echo $newvar
8
定义变量之后,使用env
这个命令查看环境变量,发现自己定义的变量并不包含在里面。这说明自己定义的变量和环境变量并不是一样的,他们是两种不同的变量。
两种变量的比较
- 两种变量都可以被set和unset,即被创建和删除
比如,我们尝试unset掉HOME这个环境变量
$echo $HOME
/home/user
$unset $HOME
$echo $HOME
我们发现HOME这个环境变量已经成功地被unset了。但是如果你此时另开一个shell你会发现这个HOME又回来了,这不难理解,因为shell每次启动都是从文件加载环境变量,而unset操作只是把导入shell里面的变量删除掉,而不会对导入环境变量的文件进行操作。
从属关系
环境变量属于当前shell及其子进程
比如你可以在
~/.bashrc
文件里自己加上一个变量myvar=9,那么bash启动时myvar就被加载成了环境变量,然后在bash里面再开一个bash,你会发现你放进文件里的myvar也会在子shell进程里。但是这里有个问题,你怎么知道子进程里的myvar是从它的父进程shell来的还是从文件来的?这个问题后文变量转换的时候可以解决。
普通变量只属于当前shell进程
普通变量不会出现在子shell进程中,如果想要它存在与子shell进程,需要将其转换成环境变量。
相关操作
env
env //显示当前环境变量
env -i NAME=value COMMAND
env -u NAME COMMAND
-i
参数表示不带环境变量启动,COMMAND是命令,可以是脚本或程序等
-u
参数表示从环境变量里面删除一个变量,然后运行COMMAND
更多命令去问男人吧man env
Talk is cheap. Show me the code!
user@myzone ~>env //显示全部,内容太多,略去
user@myzone ~>set a 5
user@myzone ~>echo $a
5
user@myzone ~>env -i PATH=mypath echo.sh
mypath
user@myzone ~>export a //将a设置为环境变量,详见下文
user@myzone ~>fish //这是子shell进程
user@myzone ~>echo $a
5
user@myzone ~>env -u a fish //子shell进程里面又开了一个shell进程
user@myzone ~>echo $a
user@myzone ~>exit
user@myzone ~>exit
echo.sh是自己写的一个脚本,功能是显示PATH的值
#!/bin/sh
echo $PATH
可以看到运行echo.sh 时PATH已被env修改
a是子shell里面的环境变量,env 加-u之后将其删除,所以在孙子shell(姑且这么说吧哈哈)就不存在a这个变量了
export
将一个变量a变成环境变量,但是只对子进程起作用,子进程中的a和PATH等环境变量无差别即如果再有子进程,a也是会被传递到子进程的,记住上文说的只有两种变量。有了这个命令我们就可以解释上文从属关系里面的问题了
user@myzone ~>set val 3
user@myzone ~>export val //转换成环境变量
user@myzone ~>fish //子shell进程
user@myzone ~>echo $val
3
由于export将val转换成了环境变量,子shell里面也有这个val,而文件里面没有val这个变量,因此子shell里的val是从调用它的那个shell来的
set/unset/echo
三个命令都比较简单,且看名字就知道是干嘛的,不详细叙述了。需要注意的是,不同的shell命令可能会不同,如fish没有unset
而有set -e
也没有NAME=VALUE
这种定义变量的写法,而只能set NAME VALUE
,具体区别,RTFM吧!