shell环境
摘要:从本章开始,进入本书的第二部分——配置文件和shell环境。本章讲述shell的环境变量,也就是shell的环境配置等内容。
shell环境
shell 在 shell 会话中保存着大量信息。这些信息被称为 (shell 的) 环境。程序获取环境中的数据(即环境变量)来了解本机的配置。
本章将会用到以下命令:
- printenv - 打印部分或所有的环境变量
- set - 设置shell选项
- export - 导出环境变量,让随后执行的程序知道。
- alias - 创建命令别名
什么存储在环境变量中
shell在环境中存储了两种基本类型的数据:环境变量和shell变量。shell变量是bash存放的少量数据,剩下的都是环境变量。除了变量,shell还存储了一些可编程的数据,即别名和shell函数。
检查环境变量
- set - bash内建命令,用来显示shell变量或环境变量。
- printenv - 只显示环境变量。
xuxg@xuxg-ubuntu:~$ printenv | less
执行上述命令,我们会看到环境变量及其数值的列表。例如,其中有一个叫做USER的变量,其变量值为xuxg。
printenv
也可以列出特定变量的数值:
xuxg@xuxg-ubuntu:~$ printenv USER
xuxg
当使用没有带选项和参数的 set 命令时,shell 变量,环境变量,和定义的 shell 函数都会被显示。不同于 printenv 命令,set 命令的输出很友好地按照首字母顺序排列:
xuxg@xuxg-ubuntu:~$ set | less
也可以通过echo
命令来查看一个变量的内容,像这样:
xuxg@xuxg-ubuntu:~$ echo $HOME
/home/xuxg
别名无法通过使用 set
或printenv
来查看。用不带参数的alias
来查看别名:
xuxg@xuxg-ubuntu:~$ alias
alias alert='notify-send --urgency=low -i "$([ $? = 0 ] && echo terminal || echo error)" "$(history|tail -n1|sed -e '\''s/^\s*[0-9]\+\s*//;s/[;&|]\s*alert$//'\'')"'
alias egrep='egrep --color=auto'
alias fgrep='fgrep --color=auto'
alias grep='grep --color=auto'
alias l='ls -CF'
alias la='ls -A'
alias ll='ls -alF'
alias ls='ls --color=auto'
一些有趣的环境变量
shell 环境中包含相当多的变量。可能会看到以下的环境变量:
变量 | 内容 |
---|---|
DISPLAY | 如果你正在运行图形界面环境,那么这个变量就是你显示器的名字。通常,它是”:0”,意思是由 X 产生的第一个显示器。 |
SHELL | shell 程序的名字。 |
HOME | 用户家目录。 |
LANG | 定义了字符集以及语言编码方式。 |
PATH | 由冒号分开的目录列表,当你输入可执行程序名后,会搜索这个目录列表。 |
PS1 | Prompt String 1. 这个定义了你的 shell 提示符的内容。随后我们可以看到,这个变量内容可以全面地定制。 |
PWD | 当前工作目录。 |
TERM | 终端类型名。类 Unix 的系统支持许多终端协议;这个变量设置你的终端仿真器所用的协议。 |
USER | 你的用户名 |
如何建立shell环境
当我们登录系统后,bash 程序启动,并且会读取一系列称为启动文件的配置脚本,这些文件定义了默认的可供所有用户共享的 shell 环境。然后是读取更多位于我们自己家目录中的启动文件,这些启动文件定义了用户个人的 shell 环境。确切的启动顺序依赖于要运行的 shell 会话类型。有两种 shell 会话类型:一个是登录 shell 会话,另一个是非登录 shell 会话。
登录 shell 会话会在其中提示用户输入用户名和密码,例如,我们启动一个虚拟控制台会话。非登录 shell 会话通常当我们在 GUI 下启动终端会话时出现。
登录 shell 会话会读取一个或多个启动文件,正如下表所示:
文件 | 内容 |
---|---|
/etc/profile | 应用于所有用户的全局配置脚本。 |
̃/.bash_profile | 用户个人的启动文件。可以用来扩展或重写全局配置脚本中的设置。 |
̃/.bash_login | 如果文件 ̃/.bash_profile 没有找到,bash 会尝试读取这个脚本。 |
̃/.profile | 如果文件 ̃/.bash_profile 或文件 ̃/.bash_login 都没有找到,bash 会试图读取这个文件。这是基于 Debian 发行版的默认设置,比方说 Ubuntu。 |
非登录 shell 会话会读取以下启动文件:
文件 | 内容 |
---|---|
/etc/bash.bashrc | 应用于所有用户的全局配置文件。 |
̃/.bashrc | 用户个人的启动文件。可以用来扩展或重写全局配置脚本中的设置。 |
除了读取以上启动文件之外,非登录 shell 会话也会继承它们父进程的环境设置,通常是一个登录 shell会话。
一个启动文件的内容
看一下我系统中的.profile
文件(来自Ubuntu18.04):
# ~/.profile: executed by the command interpreter for login shells.
# This file is not read by bash(1), if ~/.bash_profile or ~/.bash_login
# exists.
# see /usr/share/doc/bash/examples/startup-files for examples.
# the files are located in the bash-doc package.
# the default umask is set in /etc/profile; for setting the umask
# for ssh logins, install and configure the libpam-umask package.
#umask 022
# if running bash
if [ -n "$BASH_VERSION" ]; then
# include .bashrc if it exists
if [ -f "$HOME/.bashrc" ]; then
. "$HOME/.bashrc"
fi
fi
# set PATH so it includes user's private bin if it exists
if [ -d "$HOME/bin" ] ; then
PATH="$HOME/bin:$PATH"
fi
# set PATH so it includes user's private bin if it exists
if [ -d "$HOME/.local/bin" ] ; then
PATH="$HOME/.local/bin:$PATH"
fi
以
#
开头的行是注释,shell 不会读取它们。
看一下第一个程序段:
if [ -n "$BASH_VERSION" ]; then
# include .bashrc if it exists
if [ -f "$HOME/.bashrc" ]; then
. "$HOME/.bashrc"
fi
fi
这叫做一个 if 复合命令,我们将会在后边章节详细地介绍它,现在我们对它翻译一下:
如果变量$BASH_VERSION的值是非空的,就继续向下执行:
如果文件$HOME/.bashrc存在,就继续向下执行:
读取文件$HOME/.bashrc的内容
结束
结束
我们可以看到这一小段代码就是一个登录 shell 会话得到.bashrc
文件内容的方式。
shell中,利用
-n
判定字符串非空;利用-f
判定文件存在。
下一个程序段与PATH变量有关。当我们输入一个命令时,shell不会在整个计算机系统中查找该命令的位置;而是在一个目录列表中查找,这些目录包含在PATH变量中。
PATH变量通过这行代码设置:
PATH="$HOME/bin:$PATH"
修改 PATH 变量,添加目录 $HOME/bin
到目录列表的末尾。这是一个参数展开的实例。
修改 shell 环境
既然我们知道了启动文件所在的位置和它们所包含的内容,我们就可以修改它们来定制自己的shell 环境。
我们应该修改哪个文件?
通常,添加目录到你的 PATH 变量或者是定义额外的环境变量,要把这些更改放置到.bash_profile
文件中(或者其替代文件中,根据不同的发行版。例如,Ubuntu 使用.profile
文件)。对于其它的更改,要放到.bashrc
文件中。除非你是系统管理员,需要为系统中的所有用户修改默认设置,否则限定你只能对自己家目录下的文件进行修改。
文本编辑器
为了编辑shell 的启动文件以及系统中大多数其它配置文件,我们使用一个叫做文本编辑器的程序。
文本编辑器分为两种基本类型:
-
图形化文本编辑器
GNOME自带了一个叫gedit的编辑器,也就是Text Editor。
KDE 通常自带了三种编辑器,分别是(按照复杂度递增的顺序排列)kedit,kwrite,kate。
-
基于文本的编辑器
vi 编辑器:类 Unix 操作系统的传统编辑器。在大多数 Linux 系统中被 vim 替代。
emacs 编辑器:一个庞大、多用途的,可做任何事情的编程环境。GNU项目创始人编写的。
nano 编辑器:一个简单易用的编辑器,用于替代随 PINE 邮件套件提供的 pico 编辑器。
使用文本编辑器
所有的文本编辑器都可以通过在命令行中输入编辑器的名字,加上你所想要编辑的文件来唤醒。如果所输入的文件名不存在,编辑器则会假定你想要创建一个新文件。
图形化文本编辑器很简单,不再赘述。下边我们介绍一下nano编辑器,并用它来编辑文件.bashrc
。
为了避免在编辑文件时弄乱bash配置,先备份一下.bashrc
:
xuxg@xuxg-ubuntu:~$ cp .bashrc .bashrc.bak
备份文件的名字无关紧要,只要选择一个容易理解的文件名。扩展名
.bak
、.sav
、.old
和.orig
都是用来指示备份文件的流行方法。哦,记住cp
命令会默默地覆盖已经存在的同名文件。
现在可以放心的来编辑.bashrc
了:
xuxg@xuxg-ubuntu:~$ nano .bashrc
nano编辑器启动后,我们会看到下面这样的屏幕:
GNU nano 2.9.3 .bashrc
# ~/.bashrc: executed by bash(1) for non-login shells.
...(省略)
^G Get Help ^O Write Out ^W Where Is ^K Cut Text ^J Justify ^C Cur Pos
^X Exit ^R Read File ^\ Replace ^U Uncut Text^T To Spell ^_ Go To Line
这个屏幕由上面的标头,中间正在编辑的文件文本和下面的命令菜单组成。
nano的设计初衷是代替电子邮件客户端提供的编辑器,所以nano并不好用。
下面的命令菜单说明了
^X
代表Exit,也就是Ctrl+X
可以退出nano。
使用下箭头按键或下翻页按键,移动鼠标到文件的最后一行,然后添加以下几行到文件.bashrc
中:
umask 0002
export HISTCONTROL=ignoredups
export HISTSIZE=1000
alias l.='ls -d .* --color=auto'
alias ll='ls -l --color=auto'
下表是所添加行的意义:
文本行 | 含义 |
---|---|
umask 0002 | 设置掩码来解决共享目录的问题。 |
export HISTCONTROL=ignoredups | 如果相同的命令已被记录,使得 shell 的历史记录功能忽略该命令。 |
export HISTSIZE=1000 | 增加命令历史的大小,从默认的行数改到1000 行。 |
alias l.=‘ls -d .* --color=auto’ | 创建一个新命令,叫做l. ,这个命令会显示所有以点开头的目录项。 |
alias ll=’ls -l --color=auto’ | 创建一个叫做ll 的命令,这个命令会显示长格式目录列表。 |
添加注释可以帮助人们理解。使用编辑器,更改我们添加的代码,让它们看起来像这样:
# 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
来保存我们修改的.bashrc
文件,输入Ctrl-x
退出 nano。
记住:
添加注释是个好习惯。
Shell 脚本和 bash 启动文件都使用
#
符号来开始注释。
激活我们的修改
我们对于文件.bashrc
的修改不会即刻生效。直到我们关闭终端会话,再重新启动一个新的会话,修改才会生效。因为.bashrc
文件只是在刚开始启动终端会话时读取。
但是,我们可以强迫 bash 重新读取修改过的.bashrc
文件,使用下面的命令:
xuxg@xuxg-ubuntu:~$ source .bashrc
运行上面命令之后,我们就应该能够看到所做修改的效果了。试试其中一个新的别名ll
:
xuxg@xuxg-ubuntu:~$ ll
total 52
drwxrwxr-x 6 xuxg xuxg 4096 Feb 17 19:56 baidunetdisk
drwxrwxr-x 3 xuxg xuxg 4096 Feb 23 10:43 baidunetdiskdownload
drwxr-xr-x 3 xuxg xuxg 4096 Mar 12 16:28 codecraft2020
drwxr-xr-x 2 xuxg xuxg 4096 Mar 10 15:27 Desktop
drwxr-xr-x 4 xuxg xuxg 4096 Mar 10 09:50 Documents
drwxr-xr-x 4 xuxg xuxg 4096 Mar 13 11:34 Downloads
drwxr-xr-x 4 xuxg xuxg 4096 Mar 12 16:55 Music
drwxr-xr-x 8 xuxg xuxg 4096 Mar 14 15:19 MyHexoBlog
drwxr-xr-x 2 xuxg xuxg 4096 Mar 7 13:01 Pictures
drwxr-xr-x 2 xuxg xuxg 4096 Feb 6 18:49 Public
drwxr-xr-x 5 xuxg xuxg 4096 Feb 19 18:45 snap
drwxr-xr-x 2 xuxg xuxg 4096 Mar 10 15:27 Templates
drwxr-xr-x 2 xuxg xuxg 4096 Mar 10 16:48 Videos
总结
在这一章中,我们学到了用文本编辑器来编辑配置文件的基本技巧。在随后的章节里面,我们将会学习 shell 函数,一个很强大的特性,你可以把它包含在 bash 启动文件里面,以此来添加你自定制的命令宝库。