第十一章 环境

环境

  1. 前面讲到,在 shell 会话调用环境 (environment) 期间, shell 会存储大量的信息。
  2. 程序使用存储在环境中的数据来确定我们的配置。尽管大多数系统程序使用配置文件 (configuration file) 来存储程序设置,但是也有一些程序会查找环境中存储的变量来调整自己的行为。
  3. 本章会讲解下述命令
  • printenv: 打印部分或者全部的环境信息
  • set: 设置 shell 选项
  • export: 将环境导出到随后要运行的程序中
  • alias: 为命令创建一个别名

环境中存储的是什么

基本介绍

  1. 尽管 shell 在环境中存储了两种基本类型的数据,但是在 bash 中,这两种类型基本上没有什么区别。这两种数据类型分别是环境变量 (environment variable) 和 shell 变量 (shell variable) 。
  2. shell 变量是由 bash 存放的少量数据,环境变量就是除此之外的所有其他变量。除变量之外,shell 还存储了一些编程数据 (programmatic data) ,也就是别名和 shell 函数。

检查环境

  1. 要了解环境中存储的内容,需要用到集成在 bash 中的 set 命令或 printenv 程序。

  2. 不同的是, set 命令会同时显示 shell 变量和环境变量,而 printenv 只会显示环境变量。

  3. 由于环境的内容可能会比较冗长,所以最好将这两个命令的输出以管道形式重定向到 less 命令中。

    1
    2
    3
    4
    5
    6
    7
    8
    [me@linuxbox ~]$ printenv | less
    KDE_MULTIHED=false
    SSH_AGENT_PID=6666
    HOSTNAME=linuxbox
    GPG_AGENT_INFO = /tmp/gpg-PdOt7g/S.gpg-agent:6689:1
    SHELL=/bin/bash
    TERM=XTERM
    USER=me
  4. 可以看到,输出结果是一系列的环境变量及其变量值。

  5. 例如,让我们来看一个名为 USER 的变量,其值为 me 。命令 printenv 也能够列出特定变量的值。

    1
    2
    [me@linuxbox ~]$ printenv USER
    me
  6. 在使用 set 命令时,如果不带选项或参数,那么只会显示 shell 变量,环境变量以及任何已定义的 shell 函数。

    1
    [me@linuxbox ~]$ set | less
  7. 与 printenv 命令不同的是,set 命令的输出结果是按照字母顺序排序的。

  8. 如果需要查看单个变量的值,我们也可以使用 echo 命令,如下所示

    1
    2
    [me@linuxbox ~]$ echo $HOME
    /home/me
  9. set 命令和 printenv 命令都不能显示的一个环境元素是别名。要查看别名,需使用不带任何参数的 alias 命令。

    1
    2
    3
    4
    5
    6
    [me@linuxbox ~]$ alias
    alias l.='ls -d .* --color=tty'
    alias ll = 'ls -l --color=tty'
    alias ls = 'ls --color=tty'
    alias vi = 'vim'
    alias which = 'alias | /usr/bin/which --tty-only --read-alias --show-dot --showilde'

一些有趣的变量

变量 说明
DISPLAY 运行图形界面环境时界面的名称。通常为:O ,表示由 X 服务器生成的第一个界面
EDITOR 用于文本编辑的程序名称
SHELL 本机 shell 名称
HOME 本机主目录的路径名
LANG 定义了本机语言的字符集和排序规则
OLD_PWD 先前的工作目录
PAGER 用于分页输出的程序名称,通常设置为 /usr/bin/less
PATH 以冒号分割的一个目录列表,当用户输入一个可执行程序的名称时,会查看该目录列表
PS1 提示符字符串 1 。定义了本机 shell 系统提示符的内容。在后面我们会看到,可以灵活地自定义该变量
PWD 当前工作目录
TERM 终端类型的名称。类 UNIX 系统支持很多种终端协议;此变量设定了本机终端模拟器使用的协议
TZ 用于指定本机所处的时区。大多数类 UNIX 系统以协调世界时 (UTC) 来维护计算机的内部时钟,而显示的本地时间是根据本变量确定的时差计算出来的
USER 用户名

环境是如何建立的

基本介绍

  1. 用户登录系统后,bash 程序就会启动并读取一系列被称为启动文件的配置脚本,这些脚本定义了所有用户共享的默认环境。
  2. 接下来, bash 会读取更多存储在主目录下的用于定义个人环境的启动文件。这些步骤执行的确切顺序是由启动的 shell 会话类型决定的。

login shell 和 non-login shell

  1. login shell 和 non-login shell 基本介绍
  • shell 会话存在两种类型,分别为 login shell 和 non-login shell 会话。
  • login shell 会话会提示用户输入用户名和密码,如虚拟控制台会话。而我们在 GUI 中启动的终端会话就是一个典型的 non-login shell 会话。
  1. login shell 启动文件
文件 说明
/etc/profile 适用于所有用户的全局配置脚本
~/.bash_profile 用户的个人启动文件。可扩展或重写全局配置脚本中的设置
~/.bash_login 若 ~/.bash_profile 缺失 ,则 bash 尝试读取此脚本
~/.profile 若在 ~/.bash_profile 与 ~/.bash_login 均缺失,则 bash 尝试读取此文件。在基于 Debian 的 Linux 版本中,这是默认值
  1. non-login shell 的启动文件
文件 内容
/etc/bash.bsahrc 适用于所有用户的全局配置脚本
~/.bashrc 用户的个人启动文件。可扩展或重写全局配置脚本中的设置
  1. login shell 和 non-login shell 补充说明
  • 在读取以上启动文件之外,non-login shell 还会继承父类进程的环境,父类进程通常是一个 login shell 。
  • 用户可查看本机系统有哪些启动文件,需要注意的是这些文件大多数以 . 开头(意味着这些文件是被隐藏的),所以用户在使用 ls 命令时,需要伴随使用 -a 选项。
  • 在普通用户看来, ~/.bashrc 可能是最重要的启动文件,因为系统几乎总是要读取它。
  • non-login shell 会默认读取 ~/.bashrc ,而大多数 login shell 的启动文件也能以读取 ~/.bashrc 文件的方式编写。

启动文件中有什么

  1. .bash_profile 启动文件
  • 一个典型的 .bash_profile 内容如下所示:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    # .bash_profile
    # Get the aliases and functions
    if [ -f ~/.bashrc ]; then
    . ~/.bashrc
    fi
    # User specific environment and startup programs

    PATH=$PATH:$HOME/bin
    export PATH
  • 文件中以 # 开始的行是注释行,而 shell 是不会读取注释行的,注释是为了提高用户可读性而存在的。一件有趣的是发生在第 4 行,如下所示
    1
    2
    3
    if [ -f ~/.bashrc ]; then
    . ~/.bashrc
    fi
  • 这段代码被称作 if 复合命令,会在本书的第四部分进行讲解,现在可以将这段代码理解为如下内容:
    1
    If the file "~/.bashrc" exists, then read the "~/.bashrc" file.
  • 可以看到这一段代码阐述了 login shell 读取 .bashrc 文件的机制。
  • 以上启动文件中另一个很重要的元素是 PATH 变量。
  • 在命令行输入一条命令后,你曾经疑惑过 shell 是怎样找到这些命令的吗?当用户输入命令 ls ,shell 不会搜索整个系统来寻找 /bin/ls ( ls 命令的完全路径名) ,而是会搜索 PATH 变量中存储的目录列表。
  • PATH 变量通常是由启动文件 /etc/profile 中的一段代码设定 (并不总是如此,这取决于系统的发行版本) 。
    PATH=$PATH:$HOME/bin
  • 这段代码将 $HOME/bin 添加到了 PATH 值的尾部。这是一个参数扩展的实例。
  • 以下代码可以帮助用户理解扩展的机理:
    1
    2
    3
    4
    5
    [me@linuxbox ~]$ foo="This is some"
    [me@linuxbox ~]$ echo $foo
    This is some
    [me@linuxbox ~]$ echo $foo" text."
    This is some text.
  • 使用参数扩展,用户可以将更多的内容添加到变量值的尾部。
  • 在字符串 $HOME/bin 添加到 PATH 值的尾部之后,当系统需要检索用户输入的命令时,$HOME/bin 这个路径就会处于被搜索的路径列表中。这就意味着当我们想在主目录下创建名为 bin 的目录,并在此目录中存放自己的私有程序时,shell 已经为我们准备好了,我们要做的就是将创建的目录称之为 bin 。
  • 很多 Linux 发行版本在默认情况下提供了该 PATH 设置。一些基于 Debian 的发行版本,如 Ubuntu ,会在登录时检查 ~/bin 目录是否存在,若存在,就会自动将其添加到 PATH 变量中。
  • 最后一行是如下代码:
    1
    export PATH
  • 该 export 命令告诉 shell ,将 shell 的子进程使用 PATH 变量的内容。

修改环境

基本介绍

  1. 现在用户已经知道了系统启动文件的位置和内容,就可以修改启动文件,来自定义我们的环境。

用户应当修改哪些文件

  1. 一般来说,在 PATH 中添加目录,或者定义额外的环境变量,需要将这些更改放入到 .bash_profile 文件中,其他的改变则应录入 .bashrc 文件中。
  2. 除非是系统管理员需要修改用户公用的默认设置,普通用户只需对主目录下的文件做出修改即可。
  3. 当然用户也可以修改其他目录下的文件。比如 /etc 下的 profile 文件,而且很多情况会需要用户这样做。

文本编辑器

  1. 为了编辑 shell 的启动文件,以及系统中的其他大多数配置文件,我们将用到一个称为文本编辑器的程序。
  2. 文本编辑器类似字处理器,它允许用户通过移动光标的方式来编辑屏幕中的文字。与字处理器不同的是,文本编辑器只支持纯文本,而且通常包含为编写程序而设计的特性。
  3. 文本编辑器是软件开发人员编写代码的主要工具,系统管理员也可以使用文本编辑器来管理系统的配置文件。
  4. 文本编辑器可大概分为两类:图形界面的和基于文本的。GNOME (GNU 网络对象模型环境) 和 KDE (K 桌面环境) 都配备有一些流行的图形界面编辑器。
  5. GNOME 配备的编辑器叫做 gedit ,在 GNOME 菜单中 gedit 通常被称为 Text Editor 。
  6. KDE 则配备了三种编辑器,分别是 kedit、kwrite 和 kate (复杂程度递增) 。
  7. 有很多种基于文本的编辑器,常见编辑器中较受用户欢迎的是 nano、vi 和 emacs 。
  8. nano 是一种简单易用的编辑器,最初是为了替代 pico (由 PINE 电子邮箱套件提供) 而出现的。 vi 是类 Unix 系统的传统文本编辑器 (在大多数 Linux 系统中已被 vim 所取代) 。
  9. emacs 仍然可用,但是大多数 Linux 系统很少默认安装 emacs 。

使用文本编辑器

  1. 基本介绍
  • 所有的文本编辑器都可以通过在命令行输入编辑器名称和需编辑的文件名称的方式启动。如果输入的文件不存在,编辑器会认为用户想要创建一个新的文件。
  • 下面是一个 gedit 的范例
    1
    [me@kinuxbox ~]$ gedit some_file
  • 如果 some_file 文件存在,这条命令将启动 gedit 编辑器,并载入 some_file 。
  • 接下来,我们将通过 .bashrc 文件的编辑过程来讲解 nano , nano 是一个基于文本的编辑器。
  • 但是在此之前,需要采取一些安全措施。在修改一些重要的配置文件时,先对配置文件进行备份是一个很好的习惯。
  • 我们可以使用以下代码备份:
    1
    [me@kinuxbox ~]$ cp .bashrc .bashrc.bak
  • 为备份文件取什么名字并不重要,只要备份文件的名称易于理解即可。扩展名 .bak、.sav、.old 和 .orig 是常用的标示备份文件的方法。
  • 需要说明的是,cp 命令会默默地覆盖现有的文件。
  • 备份文件完成之后,就可以启动文件编辑器。
    1
    [me@kinuxbox ~]$ nano .bashrc
  • nano 启动后,屏幕显示内容如下所示
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    GNU nano 2.0.3        File: .bashrc
    # .bashrc
    # Source global definitions
    if [ -f /etc/bashrc ];then
    . /etc/bashrc
    fi
    # User specific aliases and Fuctions
    [ Read 8 lines ]
    ^G Get Help^O WriteOut^R Read Fil^Y Prev Pag^K Cut Text^C Cur Pos
    ^X Exit ^J Justify ^W Where Is^V Next Page^U UnCut Te^T To Spell
  • 屏幕显示内容分为三个部分:顶端的标题 (header) 、中间的可编辑文本和底部的命令菜单。
  • 由于 nano 是替代电子邮件文本编辑器出现的,所以其编辑文本和底部的命令菜单中有相关的介绍。^X 代表了 Ctrl-X ,这是控制字符的常见表示法,很多程序中都使用它。
  • 我们需要了解的第二个命令就是如何保存我们的工作。就 nano 来说,按 Ctrl-O 完成保存。
  • 掌握这些知识之后,我们就可以进行文本编辑操作了。请使用向下箭头键或者向下翻页键使光标移动到文件的末尾,然后添加以下代码 .bashrc 文件中。
    1
    2
    3
    4
    5
    unmask 0002
    export HISTCONTROL=ignoredups
    export HISTSIZE=1000
    alias l.='ls -d .* --color=auto'
    alias ll='ls -l --color=auto'
  1. 用户系统的 .bashrc 文件可能已经写入了这些代码的一部分,但是不用担心,重复的代码不会造成什么危害。

  2. .bashrc 文件增加的代码

代码行 含义
Umask 0002 设置 umask 以解决第 9 章中讨论过共享目录的问题
Export HISTSIZE=1000 使命令历史记录规模从默认的 500 行增加到 1000 行
alias l.=’ls -d .* –color=aut0’ 创建新的命令: l. ,功能是显示所有以 . 开头的目录条目
alias ll=’ls -l -color=auto’ 创建新的命令: ll ,功能是以长格式来展示目录列表
  1. .bashrc 文件的注释
  • 可以看到,很多新增加的代码并不易于理解,所以就需要在 .bashrc 文件中添加一些注释来帮助用户理解代码含义。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    # Change umask to make directory sharing easier
    umask 0002

    # Ignore duplicates in command history and increase
    # history size to 1000 lines
    export HISTCONTROL=ignoredups
    export HISTSIZE=1000

    # Add some helpful aliases
    alias l. ='ls -d .* --color=auto'
    alias ll = 'ls -l --color=auto'
  • 这样一来就易懂多了。最后我们按 Ctrl-O 保存文档,按 Ctrl-X 退出 nano ,这样对 .bashrc 文件的修改就完成了。

激活我们的修改

  1. 因为只有在启动 shell 会话时才读取 .bashrc ,所以对 .bashrc 做出的修改只有在关闭 shell 终端会话并重启的时候才会生效。当然也可以使用以下命令强制命令 bash 重新读取 .bashrc 文件。
    1
    [me@linuxbox ~]$ source .bashrc

参考文章

  • 转载:Linux 命令行大全