-

变量是计算机系统用于保存可变值的数据类型。在Linux系统中,变量名称一般都是大写的,这是一种约定俗成的规范。我们可以直接通过变量名称来提取到对应的变量值。Linux系统中的环境变量是用来定义系统运行环境的一些参数,比如每个用户不同的家目录、邮件存放位置等。

细心的读者应该发现了,本节和上一节的标题名都分别加了形容词—重要的、常见的。原因其实不言而喻—要想让Linux系统能够正常运行并且为用户提供服务,需要数百个环境变量来协同工作,我们没有必要逐一查看、学习每一个变量,而是应该在有限的篇幅中精讲最重要的内容。

为了通过环境变量帮助Linux系统构建起能够为用户提供服务的工作运行环境,需要数百个变量协同工作才能完成。您当然没有必要去把每一个变量都看一遍,而应该在最宝贵的书籍中为读者精讲最重要的内容。为了更好地帮助大家理解变量的作用,刘遄老师给大家举个例子。前文中曾经讲到,在Linux系统中一切都是文件,Linux命令也不例外。那么,在用户执行了一条命令之后,Linux系统中到底发生了什么事情呢?简单来说,命令在Linux中的执行分为4个步骤。

第1步:判断用户是否以绝对路径或相对路径的方式输入命令(如/bin/ls),如果是的话则直接执行。

第2步:Linux系统检查用户输入的命令是否为“别名命令”,即用一个自定义的命令名称来替换原本的命令名称。可以用alias命令来创建一个属于自己的命令别名,格式为“alias 别名=命令”。若要取消一个命令别名,则是用unalias命令,格式为“unalias 别名”。我们之前在使用rm命令删除文件时,Linux系统都会要求我们再确认是否执行删除操作,其实这就是Linux系统为了防止用户误删除文件而特意设置的rm别名命令,接下来我们把它取消掉:

    [root@linuxprobe ~]# ls
    anaconda-ks.cfg Documents initial-setup-ks.cfg Pictures Templates
    Desktop Downloads Music Public Videos
    [root@linuxprobe ~]# rm anaconda-ks.cfg 
    rm: remove regular file ‘anaconda-ks.cfg’? y
    [root@linuxprobe~]# alias rm
    alias rm='rm -i'
    [root@linuxprobe ~]# unalias rm
    [root@linuxprobe ~]# rm initial-setup-ks.cfg 
    [root@linuxprobe ~]#

第3步:Bash解释器判断用户输入的是内部命令还是外部命令。内部命令是解释器内部的指令,会被直接执行;而用户在绝大部分时间输入的是外部命令,这些命令交由步骤4继续处理。可以使用“type命令名称”来判断用户输入的命令是内部命令还是外部命令。

第4步:系统在多个路径中查找用户输入的命令文件,而定义这些路径的变量叫作PATH,可以简单地把它理解成是“解释器的小助手”,作用是告诉Bash解释器待执行的命令可能存放的位置,然后Bash解释器就会乖乖地在这些位置中逐个查找。PATH是由多个路径值组成的变量,每个路径值之间用冒号间隔,对这些路径的增加和删除操作将影响到Bash解释器对Linux命令的查找。

    [root@linuxprobe ~]# echo $PATH
    /usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin
    [root@linuxprobe ~]# PATH=$PATH:/root/bin
    [root@linuxprobe ~]# echo $PATH
    /usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:/root/bin

这里有比较经典的问题:“为什么不能将当前目录(.)添加到PATH中呢? ” 原因是,尽管可以将当前目录(.)添加到PATH变量中,从而在某些情况下可以让用户免去输入命令所在路径的麻烦。但是,如果黑客在比较常用的公共目录/tmp中存放了一个与ls或cd命令同名的木马文件,而用户又恰巧在公共目录中执行了这些命令,那么就极有可能中招了。

所以,作为一名态度谨慎、有经验的运维人员,在接手了一台Linux系统后一定会在执行命令前先检查PATH变量中是否有可疑的目录,另外读者从前面的PATH变量示例中是否也感觉到环境变量特别有用呢。我们可以使用env命令来查看到Linux系统中所有的环境变量,而刘遄老师为您精挑细选出了最重要的10个环境变量,如表3-3所示。

表3-3 Linux系统中最重要的10个环境变量

>变量名称    作用
>HOME    用户的主目录(即家目录)
>SHELL   用户在使用的Shell解释器名称
>HISTSIZE    输出的历史命令记录条数
>HISTFILESIZE    保存的历史命令记录条数
>MAIL    邮件保存路径
>LANG    系统语言、语系名称
>RANDOM  生成一个随机数字
>PS1 Bash解释器的提示符
>PATH    定义解释器搜索用户执行命令的路径
>EDITOR  用户默认的文本编辑器

Linux作为一个多用户多任务的操作系统,能够为每个用户提供独立的、合适的工作运行环境,因此,一个相同的变量会因为用户身份的不同而具有不同的值。例如,我们使用下述命令来查看HOME变量在不同用户身份下都有哪些值(su是用于切换用户身份的命令,将在第5章跟大家见面):

    [root@linuxprobe ~]# echo $HOME
    /root
    [root@linuxprobe ~]# su - linuxprobe
    Last login: Fri Feb 27 19:49:57 CST 2017 on pts/0
    [linuxprobe@linuxprobe ~]$ echo $HOME
    /home/linuxprobe

其实变量是由固定的变量名与用户或系统设置的变量值两部分组成的,我们完全可以自行创建变量,来满足工作需求。例如设置一个名称为WORKDIR的变量,方便用户更轻松地进入一个层次较深的目录:

    [root@linuxprobe ~]# mkdir /home/workdir
    [root@linuxprobe ~]# WORKDIR=/home/workdir
    [root@linuxprobe ~]# cd $WORKDIR 
    [root@linuxprobe workdir]# pwd
    /home/workdir

但是,这样的变量不具有全局性,作用范围也有限,默认情况下不能被其他用户使用。如果工作需要,可以使用export命令将其提升为全局变量,这样其他用户也就可以使用它了:

    [root@linuxprobe workdir]# su linuxprobe
    Last login: Fri Mar 20 20:52:10 CST 2017 on pts/0
    [linuxprobe@linuxprobe ~]$ cd $WORKDIR
    [linuxprobe@linuxprobe ~]$ echo $WORKDIR
    [linuxprobe@linuxprobe ~]$ exit
    [root@linuxprobe ~]# export WORKDIR
    [root@linuxprobe ~]# su linuxprobe
    Last login: Fri Mar 20 21:52:10 CST 2017 on pts/0
    [linuxprobe@linuxprobe ~]$ cd $WORKDIR
    [linuxprobe@linuxprobe workdir]$ pwd
    /home/workdir