5.1 什么时环境变量
bash shell用一个成为环境变量的特性来存储有关的shell回话和工作环境的信息,这是它们成为环境变量的原因。它允许你在内存中存储数据,以便运行在账户、系统、shell的特性以及任何其他你需要存储的数据
- 环境变量的分类
- 全局变量
- 局部变量
5.1.1 全局环境变量
- 全局环境变量不仅对shell会话可见,而且对所有shell创建的子进程也可见,局部变量只是对创建的他们的shell可见
- 这对全局环境变量对那些子进程中需要获得父进程信息的程序来说非常有用
- 系统环境变量一律使用全大写字母以区别普通用户的环境变量
- printenv:查看全局环境变量
- echo + $环境变量名:查看单个环境变量值
5.1.2 局部环境变量
- 局部变量只有在定义它们的进程中可见
- set命令:显示为某个特定进程设置的所有环境变量,包括全局环境变量和局部环境变量
$ set .
BASH=/bin/bash
EUID=500
IFS=$' \t\n'
...
5.2 设置环境变量
5.2.1 设置局部环境变量
一旦开启了bash shell(或者执行一个shell脚本),你就能创建在这个shell进程内可见的局部变量了
- 可以通过等号给局部变量设置,设置的值可以时数值或字符串
$ test=testing
$ echo $test
testing
$
- 如果要给变量赋一个含有空格的字符串值,必须用单引号来界定字符串的开始和末尾
$ test='testing a long string'
$ echo $test
testing a long string
$
- 局部变量一般用小写字母
- 注意:在环境变名称、等号和值之间没有空格
- 设置了环境变量之后就可以在shell进程中使用它了,如果在子进程中设置了环境变量,一旦退出了子进程,那个局部变量就不能用了
5.2.2 设置全局环境变量
- 设置一个全局环境变量的方法:先设置一个局部变量,然后再把它导出到全局环境中
- 通过export命令来完成导出任务
$echo $test
testing a long string
$export test
$bash
$echo $test
testing a long string
$
删除环境变量
- unset命令:删除一个环境变量
- 用法:unset + 环境变量名
- 注意不加$符号
$ unset test
$ echo test
$
- 注意:如果仅仅在子进程中删除了全部变量,那么仅仅对子进程有效,在父进程中依然有效
5.4 默认shell环境变量
默认情况下,bash shell 会用一些特定的环境变量来定义系统环境变量
bash shell时从Unix Bourne shell中衍生出来的,它保留有Unix Bourne shell里定义的那些环境变量
常见的shell支持的Bourne环境变量
- HOME:当前用户的主目录
- IFS:shell用来分隔文本字符串的一列字符
- PATH:冒号分隔的shell查找命令目录列表,同时显示了shell查找命令的顺序
- PS1:shell命令行界面的主提示符
- PS2:shell命令行界面的次提示符
不是所有的默认环境变量都会在运行set命令时列出来,尽管这些时默认的环境变量,但不是它们都必须有一个值
5.5 设置PATH环境变量
PATH环境变量定义了命令行输入命令的搜索路径,如果找不到,就会产生一个错误
$ myprog
-bash: myprog: command not found
$
- 解决上述问题的方法
- 保证PATH环境变量包含了所有存放应用的目录
- 添加新的搜索目录到现有的PATH环境变量,无需从头定义
- 应用原来的PATH值,然后再给字符串添加新目录进行了
PATH=$PATH:/home/user/test
- 通常将单点符也加入到PATH环境变量里
5.6 定位系统环境变量
- 启动bash shell的3种方式
- 登录时当默认登录shell
- 作为非登录shell的交互式shell
- 作为运行脚本的非交互式shell
5.6.1 登录shell
- 当登录Linux系统时,bash shell会作为登录的shell启动
- 登录的shell从4个不同的启动文件里读取命令,下面是bash shell处理这些文件的次序
- /etc/profile
- $HOME/.bash_profile
- $HOME/.bash_login
- $HOME/.profile
1. /etc/profile文件
- 这个文件时系统上默认的bash shell的主启动文件,只要登陆了Linux系统,bash就会执行该文件中的命令
- 不同的Linux发行版文件里的存放着不同的命令 - 文件中最后有一行:export PATH USER LOGNAME MAIL HOSTNAME …:保证这些环境变量能在所有登录这个shell创建的子进程中都有效
- 文件还有个复杂的特性:有个for语句逐一访问位于/etc/profile.d目录中的每个文件
- 它为Linux系统提供了一个集中存放用户登录时要执行的应用专属的启动文件的地方
- 大部分应用都会创建两个启动文件
- 一个给bash shell的(使用.sh扩展)
- 一个给c shell的(使用.csh扩展)
- lang.csh和.lang.sh文件会尝试去判断系统上所采用的默认语言文字集,然后正确地设置LANG环境变量
2. $HOME目录下的启动文件
- 剩下3个的启动文件都起着同样的作为:提供一个用户专属的启动文件来定义用户专有的环境变量
- 这3个启动文件都是以点开头的,是隐藏的文件
- 它们在用户的HOME目录下,所以每个用户都可以编辑这些文件并添加自己的环境变量来给他们启动的每个bash shell会话用
- .bash_forfile启动文件作用:
- 先去检查HOME目录中是否还有一个叫.bashrc的启动文件,有则先执行里面的命令
- 下一步,启动文件将一个目录加到了PATH环境变量,在HOME目录下提供了一个放置可执行文件的通用位置
交互式shell
如果启动的shell不是登录系统时启动的shell,该shell就是交互式shell
- 如果bash shell是作为交互式shell,他就不回去访问/etc/profile文件,而会去用户的HOME目录检查.bashrc是否存在
- .bashrc文件的两个作用:
- 查看/etc目录下的共用bashrc文件
- 通用的/etc/bashrc启动文件会被系统文件上每个启动交互式shell会话的用户执行
- 为用户提供了一个定制自己的命令别名和私有脚本函数的地方
- 查看/etc目录下的共用bashrc文件
- .bashrc文件的两个作用:
- 默认的/etc/bashrc文件会设置一些环境变量,但是没有执行export命令让它们成为全局的
- 交互式shell的启动文件只会在每次有新的交互式shell启动的时候才运行,因此任何子shell都会自动执行这个交互式shell的启动文件
5.6.3 非交互式shell
系统执行shell脚本时用的就是非交互式shell,不用担心它没有命令行提示符
但当每次在系统上运行脚本时仍要运行特定的启动命令
- bash shell提供了BASH_ENV环境变量来处理这种情况
- 当shell启动一个非交互式shell进程时,它会检查这个环境变量来查看要执行的启动文件,如果有指定的,shell会执行文件里的命令
- 在Linux发行版里,默认情况这个环境变量并未设置
可变数组
- 环境变量可以作为数组使用,数组是能够存储多个值得变量
- 这个值可按照单个值或整个数组来引用
- 要给多个环境变量设置多个值,可以把值放在括号里,值与值之间用空格分隔
$ mytest=(one two three four five)
$
- 要引用一个单独的数组元素,需要用代表它在数组中位置的数值索引值,数值要用括号括起来
$ echo $(mytest[2])
three
$
- 要显示整个数组变量,可用星号作为通配符放在索引值的位置
$ echo ${mytest[*]}
one two three four five
$
- 改变某个索引值位置的值
$mytest[2]=seven
$echo ${mytest[*]}
one two seven four five
$
- 删除数组中的元素:unset,但注意一些问题
$ unset mytest[2]
$ echo ${mttest[*]}
one two four five
$ echo ${mytest[2]}
$ echo ${mytest[3]}
four
$
- 删除整个数组:unset + 数组名
$ unset mytest
$ echo ${mytest[*]}
$
5.8 使用命令别名
- 命令别名允许为通用命令(和他们的参数一起)创建一个别名
- 查看已有的别名列表:alias -p
- 用alias定义自己的用户别名,一旦定义了别名,就可以在任何时候在shell中使用,包括shell脚本
$ alias li='ls -il'
$ li
...
$
- 命令别名的行为和定义局部环境变量差不多,只在定义它的shell进程中有效
- 解决方法:在$HOME/,bashrc启动文件中定义,因为bash shell作为交互式shell时总会读取这个文件