环境变量可以帮我们达到很多功能~包括主文件夹的变换啊、 提示字符的显示啊、 可执行文件搜寻的路径啊等等的, 还有很多很多啦! 那么, 既然环境变量有那么多的功能, 问一下,目前我的 shell 环境中, 有多少默认的环境变量啊? 我们可以利用两个指令来查阅, 分别是env 与 export 呢!

用 env 观察环境变量与常见环境变量说明

  1. 范例一: 列出目前的 shell 环境下的所有环境变量与其内容。
  2. [dmtsai@study ~]$ env
  3. HOSTNAME=study.centos.vbird <== 这部主机的主机名称
  4. TERM=xterm <== 这个终端机使用的环境是什么类型
  5. SHELL=/bin/bash <== 目前这个环境下, 使用的 Shell 是哪一个程序?
  6. HISTSIZE=1000 <== “记录指令的笔数”在 CentOS 默认可记录 1000
  7. OLDPWD=/home/dmtsai <== 上一个工作目录的所在
  8. LC_ALL=en_US.utf8 <== 由于语系的关系, 鸟哥偷偷丢上来的一个设置
  9. USER=dmtsai <== 使用者的名称啊!
  10. LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:
  11. or=40;31;01:mi=01;05;37;41:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:
  12. *.tar=01... <== 一些颜色显示
  13. MAIL=/var/spool/mail/dmtsai <== 这个使用者所取用的 mailbox 位置
  14. PATH=/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/dmtsai/.local/bin:/home/dmtsai/bin
  15. PWD=/home/dmtsai <== 目前使用者所在的工作目录 利用 pwd 取出!
  16. LANG=zh_TW.UTF-8 <== 这个与语系有关, 下面会再介绍!
  17. HOME=/home/dmtsai <== 这个使用者的主文件夹啊!
  18. LOGNAME=dmtsai <== 登陆者用来登陆的帐号名称
  19. _=/usr/bin/env <== 上一次使用的指令的最后一个参数( 或指令本身)

env 是 environment ( 环境) 的简写啊, 上面的例子当中, 是列出来所有的环境变量。 当然, 如果使用 export 也会是一样的内容~ 只不过, export 还有其他额外的功能就是了, 我们等一下再提这个 export 指令。 那么上面这些变量有些什么功用呢? 下面我们就一个一个来分析分析 !

HOME

代表使用者的主文件夹。 还记得我们可以使用 cd ~ 去到自己的主文件夹吗? 或者利用 cd 就可以直接回到使用者主文件夹了。 那就是取用这个变量啦~ 有很多程序都可能会取用到这个变量的值!

SHELL

告知我们, 目前这个环境使用的 SHELL 是哪支程序? Linux 默认使用 /bin/bash的啦!

HISTSIZE

这个与“历史命令”有关, 亦即是, 我们曾经下达过的指令可以被系统记录下来, 而记录的“笔数”则是由这个值来设置的。

MAIL

当我们使用 mail 这个指令在收信时, 系统会去读取的邮件信箱文件 ( mailbox) 。

PATH

就是可执行文件搜寻的路径啦~目录与目录中间以冒号( :) 分隔, 由于文件的搜寻是依序由 PATH 的变量内的目录来查询, 所以, 目录的顺序也是重要的喔。

LANG

这个重要! 就是语系数据啰~很多讯息都会用到他, 举例来说, 当我们在启动某些 perl 的程序语言文件时, 他会主动的去分析语系数据文件, 如果发现有他无法解析的编码语系, 可能会产生错误喔! 一般来说, 我们中文编码通常是 zh_TW.Big5 或者是zh_TW.UTF-8, 这两个编码偏偏不容易被解译出来, 所以, 有的时候, 可能需要修订一下语系数据。 这部分我们会在下个小节做介绍的!

RANDOM

这个玩意儿就是“随机乱数”的变量啦! 目前大多数的 distributions 都会有乱数产生器, 那就是 /dev/random 这个文件。 我们可以通过这个乱数文件相关的变量( $RANDOM) 来随机取得乱数值喔。 在 BASH 的环境下, 这个 RANDOM 变量的内容, 介于 0~32767 之间, 所以, 你只要 echo $RANDOM 时, 系统就会主动的随机取出一个介于 0~32767 的数值。 万一我想要使用 0~9 之间的数值呢? 呵呵~利用 declare 宣告数值类型, 然后这样做就可以了:

  1. [dmtsai@study ~]$ declare -i number=$RANDOM*10/32768 ; echo $number8 <== 此时会随机取出 0~9 之间的数值喔

大致上是有这些环境变量啦~里面有些比较重要的参数, 在下面我们都会另外进行一些说明的~

用 set 观察所有变量 ( 含环境变量与自订变量)

bash 可不只有环境变量喔, 还有一些与 bash 操作接口有关的变量, 以及使用者自己定义的变量存在的。 那么这些变量如何观察呢? 这个时候就得要使用 set 这个指令了。 set 除了环境变量之外, 还会将其他在 bash 内的变量通通显示出来哩! 信息很多, 下面鸟哥仅列出几个重要的内容:

  1. [dmtsai@study ~]$ set
  2. BASH=/bin/bash <== bash 的主程序放置路径
  3. BASH_VERSINFO=( [0]="4" [1]="2" [2]="46" [3]="1" [4]="release" [5]="x86_64-redhat-linux-gnu"
  4. BASH_VERSION='4.2.46( 1) -release' <== 这两行是 bash 的版本啊!
  5. COLUMNS=90 <== 在目前的终端机环境下, 使用的字段有几个字符长度
  6. HISTFILE=/home/dmtsai/.bash_history <== 历史命令记录的放置文件, 隐藏文件
  7. HISTFILESIZE=1000 <== 存起来( 与上个变量有关) 的文件之指令的最大纪录笔数。
  8. HISTSIZE=1000 <== 目前环境下, 内存中记录的历史命令最大笔数。
  9. IFS=$' \t\n' <== 默认的分隔符号
  10. LINES=20 <== 目前的终端机下的最大行数
  11. MACHTYPE=x86_64-redhat-linux-gnu <== 安装的机器类型
  12. OSTYPE=linux-gnu <== 操作系统的类型!
  13. PS1='[\u@\h \W]\$ ' <== PS1 就厉害了。 这个是命令提示字符, 也就是我们常见的
  14. [root@www ~]# [dmtsai ~]$ 的设置值啦! 可以更动的!
  15. PS2='> ' <== 如果你使用跳脱符号 \) 第二行以后的提示字符也
  16. $ <== 目前这个 shell 所使用的 PID
  17. ? <== 刚刚执行完指令的回传值。
  18. ...
  19. # 有许多可以使用的函数库功能被鸟哥取消啰! 请自行查阅!

一般来说, 不论是否为环境变量, 只要跟我们目前这个 shell 的操作接口有关的变量, 通常都会被设置为大写字符, 也就是说, “基本上, 在 Linux 默认的情况中, 使用{大写的字母}来设置的变量一般为系统内定需要的变量”。 OK! OK! 那么上头那些变量当中, 有哪些是比较重要的? 大概有这几个吧!

PS1: ( 提示字符的设置)

这是 PS1 ( 数字的 1 不是英文字母) , 这个东西就是我们的“命令提示字符”喔! 当我们每次按下 [Enter] 按键去执行某个指令后, 最后要再次出现提示字符时, 就会主动去读取这个变量值了。 上头 PS1 内显示的是一些特殊符号, 这些特殊符号可以显示不同的信息, 每个distributions 的 bash 默认的 PS1 变量内容可能有些许的差异, 不要紧, “习惯你自己的习惯”就好了。 你可以用 man bash [3]去查询一下 PS1 的相关说明, 以理解下面的一些符号意义。

  • \d : 可显示出“星期 月 日”的日期格式, 如: “Mon Feb 2”
  • \H : 完整的主机名称。 举例来说, 鸟哥的练习机为“study.centos.vbird”
  • \h : 仅取主机名称在第一个小数点之前的名字, 如鸟哥主机则为“study”后面省略
  • \t : 显示时间, 为 24 小时格式的“HH:MM:SS”
  • \T : 显示时间, 为 12 小时格式的“HH:MM:SS”
  • \A : 显示时间, 为 24 小时格式的“HH:MM”
  • \@ : 显示时间, 为 12 小时格式的“am/pm”样式
  • \u : 目前使用者的帐号名称, 如“dmtsai”;
  • \v : BASH 的版本信息, 如鸟哥的测试主机版本为 4.2.46( 1) -release, 仅取“4.2”显示
  • \w : 完整的工作目录名称, 由根目录写起的目录名称。 但主文件夹会以 ~ 取代;
  • \W : 利用 basename 函数取得工作目录名称, 所以仅会列出最后一个目录名。
  • : 下达的第几个指令。

  • $ : 提示字符, 如果是 root 时, 提示字符为 # , 否则就是 $ 啰~

    $: ( 关于本 shell 的 PID)

    钱字号本身也是个变量喔! 这个咚咚代表的是“目前这个 Shell 的线程代号”, 亦即是所谓的PID ( Process ID) 。 更多的程序观念, 我们会在第四篇的时候提及。 想要知道我们的 shell的 PID , 就可以用: “ echo $$ ”即可! 出现的数字就是你的 PID 号码。

    ?: ( 关于上个执行指令的回传值)

    虾密? 问号也是一个特殊的变量? 没错! 在 bash 里面这个变量可重要的很! 这个变量是: “上一个执行的指令所回传的值”, 上面这句话的重点是“上一个指令”与“回传值”两个地方。 当我们执行某些指令时, 这些指令都会回传一个执行后的代码。 一般来说, 如果成功的执行该指令, 则会回传一个 0 值, 如果执行过程发生错误, 就会回传“错误代码”才对! 一般就是以非为 0 的数值来取代。 我们以下面的例子来看看:
    1. [dmtsai@study ~]$ echo $SHELL
    2. /bin/bash <==可顺利显示! 没有错误!
    3. [dmtsai@study ~]$ echo $?
    4. 0 <==因为没问题, 所以回传值为 0
    5. [dmtsai@study ~]$ 12name=VBird
    6. bash: 12name=VBird: command not found... <==发生错误了! bash回报有问题
    7. [dmtsai@study ~]$ echo $?
    8. 127 <==因为有问题, 回传错误代码( 非为0
    9. # 错误代码回传值依据软件而有不同, 我们可以利用这个代码来搜寻错误的原因喔!
    10. [dmtsai@study ~]$ echo $?
    11. 0#
    12. 咦! 怎么又变成正确了? 这是因为 "?" 只与“上一个执行指令”有关,
    13. # 所以, 我们上一个指令是执行“ echo $? ”, 当然没有错误, 所以是 0 没错!

    OSTYPE, HOSTTYPE, MACHTYPE: ( 主机硬件与核心的等级)

    我们在第零章、 计算机概论内的 CPU 等级说明中谈过 CPU , 目前个人计算机的 CPU 主要分为 32/64 位, 其中 32 位又可分为 i386, i586, i686, 而 64 位则称为 x86_64。 由于不同等级的 CPU 指令集不太相同, 因此你的软件可能会针对某些 CPU 进行最优化, 以求取较佳的 软件性能。 所以软件就有 i386, i686 及 x86_64 之分。 以目前 ( 2015) 的主流硬件来说, 几乎都是 x86_64 的天下! 因此 CentOS 7 开始, 已经不支持 i386 相容模式的安装光盘了~哇呜! 进步的太快了!
    要留意的是, 较高阶的硬件通常会向下相容旧有的软件, 但较高阶的软件可能无法在旧机器上面安装! 我们在第二章就曾说明过, 这里再强调一次, 你可以在 x86_64 的硬件上安装i386 的 Linux 操作系统, 但是你无法在 i686 的硬件上安装 x86_64 的 Linux 操作系统! 这点得要牢记在心!

    export: 自订变量转成环境变量

    谈了 env 与 set 现在知道有所谓的环境变量与自订变量, 那么这两者之间有啥差异呢? 其实这两者的差异在于“ 该变量是否会被子程序所继续引用”啦! 唔! 那么啥是父程序? 子程序?这就得要了解一下指令的下达行为了。
    当你登陆 Linux 并取得一个 bash 之后, 你的 bash 就是一个独立的程序, 这个程序的识别使用的是一个称为程序识别码, 被称为 PID 的就是。 接下来你在这个 bash 下面所下达的任何指令都是由这个 bash 所衍生出来的, 那些被下达的指令就被称为子程序了。 我们可以用下面的图示来简单的说明一下父程序与子程序的概念:
    这个程序概念与变量有啥关系啊? 关系可大了! 因为子程序仅会继承父程序的环境变量, 子程序不会继承父程序的自订变量啦! 所以你在原本 bash 的自订变量在进入了子程序后就会消失不见, 一直到你离开子程序并回到原本的父程序后, 这个变量才会又出现!
    换个角度来想, 也就是说, 如果我能将自订变量变成环境变量的话, 那不就可以让该变量值继续存在于子程序了? 呵呵! 没错! 此时, 那个 export 指令就很有用啦! 如你想要让该变量内容继续的在子程序中使用, 那么就请执行:
    1. [dmtsai@study ~]$ export 变量名称
    这东西用在“分享自己的变量设置给后来调用的文件或其他程序”啦! 像鸟哥常常在自己的主文件后面调用其他附属文件( 类似函数的功能) , 但是主文件与附属文件内都有相同的变量名称, 若一再重复设置时, 要修改也很麻烦, 此时只要在原本的第一个文件内设置好“ export变量 ”, 后面所调用的文件就能够使用这个变量设置了! 而不需要重复设置, 这非常实用于shell script 当中喔! 如果仅下达 export 而没有接变量时, 那么此时将会把所有的“环境变量”秀出来喔! 例如:
    1. [dmtsai@study ~]$ export
    2. declare -x HISTSIZE="1000"
    3. declare -x HOME="/home/dmtsai"
    4. declare -x HOSTNAME="study.centos.vbird"
    5. declare -x LANG="zh_TW.UTF-8"
    6. declare -x LC_ALL="en_US.utf8"
    7. # 后面的鸟哥就都直接省略了! 不然....浪费版面~ ^_^
    那如何将环境变量转成自订变量呢? 可以使用本章后续介绍的 declare 呢!