# 第十一章 配置与环境
在shell会话调用环境期间,shell会存储大量的信息。程序使用存储在环境中的数据来确定我们的配置。尽管大多数程序会使用配置文件来存储程序设置,但是也有一些程序会查找环境中存储的变量来调整自己的行为。
知道这一点后,用户就可以使用环境来自定义shell。
# 环境中存储的数据类型
尽管shell在环境中存储了两种基本类型的数据,但在bash中,这两种类型基本没有区别。这两种数据类型分别是环境变量和shell变量。
- shell变量是由bash存放的少量数据
- 环境变量是除了shell变量之外的所有变量
除了变量以外,shell还存储了一些编程数据,即别名和shell函数。
# printenv
和set
和检查环境的两个程序
要了解环境中存储的内容,需要用到集成在bash中的set
命令或printenv
程序。由于环境的内容比较多,一般将这两个命令的输出重定向到less
命令中。
# printenv
-显示环境变量
- 输出所有环境变量机器值
printenv | less
得到如下结果
HOSTNAME=LAPTOP-2ESIRNKO
SHELL=/bin/bash
TERM=xterm-256color
HISTSIZE=1000
WSLENV=
USER=root
NAME=LAPTOP-2ESIRNKO
LS_COLORS=rs=0:di=38;5;27:ln=38;5;51:mh=44;38;5;15:pi=40;38;5;11:so=38;5;13:do=38;5;5:bd=48;5;232;38;5;11:cd=48;5;232;38;5;3:or=48;5;232;38;5;9:mi=05;48;5;232;38;5;15:su=48;5;196;38;5;15:sg=48;5;11;38;5;16:ca=48;5;196;38;5;226:tw=48;5;10;38;5;16:ow=48;5;10;38;5;21:st=48;5;21;38;5;15:ex=38;5;34:*.tar=38;5;9:*.tgz=38;5;9:*.arc=38;5;9:*.arj=38;5;9:*.taz=38;5;9:*.lha=38;5;9:*.lz4=38;5;9:*.lzh=38;5;9:*.lzma=38;5;9:*.tlz=38;5;9:*.txz=38;5;9:*.tzo=38;5;9:*.t7z=38;5;9:*.zip=38;5;9:*.z=38;5;9:*.Z=38;5;9:*.dz=38;5;9:*.gz=38;5;9:*.lrz=38;5;9:*.lz=38;5;9:*.lzo=38;5;9:*.xz=38;5;9:*.bz2=38;5;9:*.bz=38;5;9:*.tbz=38;5;9:*.tbz2=38;5;9:*.tz=38;5;9:*.deb=38;5;9:*.rpm=38;5;9:*.jar=38;5;9:*.war=38;5;9:*.ear=38;5;9:*.sar=38;5;9:*.rar=38;5;9:*.alz=38;5;9:*.ace=38;5;9:*.zoo=38;5;9:*.cpio=38;5;9:*.7z=38;5;9:*.rz=38;5;9:*.cab=38;5;9:*.jpg=38;5;13:*.jpeg=38;5;13:*.gif=38;5;13:*.bmp=38;5;13:*.pbm=38;5;13:*.pgm=38;5;13:*.ppm=38;5;13:*.tga=38;5;13:*.xbm=38;5;13:*.xpm=38;5;13:*.tif=38;5;13:*.tiff=38;5;13:*.png=38;5;13:*.svg=38;5;13:*.svgz=38;5;13:*.mng=38;5;13:*.pcx=38;5;13:*.mov=38;5;13:*.mpg=38;5;13:*.mpeg=38;5;13:*.m2v=38;5;13:*.mkv=38;5;13:*.webm=38;5;13:*.ogm=38;5;13:*.mp4=38;5;13:*.m4v=38;5;13:*.mp4v=38;5;13:*.vob=38;5;13:*.qt=38;5;13:*.nuv=38;5;13:*.wmv=38;5;13:*.asf=38;5;13:*.rm=38;5;13:*.rmvb=38;5;13:*.flc=38;5;13:*.avi=38;5;13:*.fli=38;5;13:*.flv=38;5;13:*.gl=38;5;13:*.dl=38;5;13:*.xcf=38;5;13:*.xwd=38;5;13:*.yuv=38;5;13:*.cgm=38;5;13:*.emf=38;5;13:*.axv=38;5;13:*.anx=38;5;13:*.ogv=38;5;13:*.ogx=38;5;13:*.aac=38;5;45:*.au=38;5;45:*.flac=38;5;45:*.mid=38;5;45:*.midi=38;5;45:*.mka=38;5;45:*.mp3=38;5;45:*.mpc=38;5;45:*.ogg=38;5;45:*.ra=38;5;45:*.wav=38;5;45:*.axa=38;5;45:*.oga=38;5;45:*.spx=38;5;45:*.xspf=38;5;45:
HOSTTYPE=x86_64
MAIL=/var/spool/mail/root
可以看到,输出结果是一系列环境变量及其变量值。当然,我们也可以指定输出特定的环境变量。例如,我们可以输出USER变量。
- 输出特定环境变量的值
printenv USER
由于我现在使用root
账号登录,因此USER变量值是root。
# set
-同时显示shell变量和环境变量
在使用set
命令时,如果不带选项和参数,那么结果中将包含shell变量、环境变量以及任何已定义的shell函数。
- 输出所有shell变量和环境变量以及shell函数
set | less
与printenv
命令不同的是,set
命令的输出结果是按照字母顺序排列的。
- 输出单个变量的值
若要查看单个变量的值,可以使用echo
命令
echo $HOME
输出结果是root账号的家目录\root。
set
命令和printenv
命令都不能显示别名,若想要查看别名,则需要使用不带任何参数的alias
命令。
alias
前面我们已经学习过这个命令,可以看到多个命令的别名
alias cp='cp -i'
alias egrep='egrep --color=auto'
alias fgrep='fgrep --color=auto'
alias grep='grep --color=auto'
alias l.='ls -d .* --color=auto'
alias ll='ls -l --color=auto'
alias ls='ls --color=auto'
alias mv='mv -i'
alias rm='rm -i'
alias which='alias | /usr/bin/which --tty-only --read-alias --show-dot --show-tilde'
# printenv
和set
两个命令的异同点
相同之处:
set
命令和printenv
命令都不能显示别名。
不同之处:
set
命令可以同时显示shell变量和环境变量,printenv
命令只可以显示环境变量。
# 一些重要的环境变量
变量 | 说明 |
---|---|
SHELL | 本机SHELL名称 |
HOME | 本机主目录的路径名 |
LANG | 本机语言的字符集和排序规则 |
PWD | 当前工作目录 |
USER | 用户名 |
PATH | 以冒号分割的一个目录列表,当用户输入一个可执行程序的名称时,会查找该目录列表 |
# 环境的建立过程
用户登录系统后,bash程序会启动并读取一系列称为启动文件的配置脚本,这些脚本定义了所有用户共享的默认环境。接下来,bash会读取更多存储在主目录下的用于定义个人环境的启动文件。这些步骤执行的确切顺序是由启动的shell会话类型决定的。
# shell会话的两种类型
shell会话存在两种类型,分别是login shell会话和non-login shell会话。login shell会话:这种会话会提示用户输入用户名和密码,如虚拟控制台会话。在GUI中启动的终端会话就是典型的non-login shell会话。
login shell会读取一个或多个文件。
- login shell的启动文件
文件 | 说明 |
---|---|
/etc/profile | 适用于所有用户的全局配置脚本 |
~/.bash_profile | 用户的个人启动文件,可扩展或重写全局配置脚本中的设置 |
~/.bash_login | 若~/.bash_profile缺失,则bash会尝试读取该脚本 |
~/.profile | 若~/.bash_profile和~/.bash_login都缺失,则bash尝试读取此文件 |
- non-login shell的启动文件
文件 | 内容 |
---|---|
/etc/bash.bashrc | 适合于所有用户的全局配置脚本 |
~/.bashrc | 用户的个人启动文件,可以扩展或重写全局配置脚本中的设置 |
在读取以上启动文件之外,non-login shell还会继承父类进程的环境,父类进程通常是一个login shell。
在普通用户看来,~/.bashrc可能是最重要的启动文件,因为系统几乎都要读取它。non-login shell会默认读取~/.bashrc,而大多数login shell的启动文件也能以读取~/.bashrc的方式来编写。
# 第十二章 vi编辑器简介
vi编辑器是Linux和Unix上最基本的文本编辑器,虽然我们已经有了各种各样可视化的编辑器,但是我们仍有学习它的必要。
- vi总是可用的,如果系统没有图形界面或图形界面不可用,则可以使用Linux自带的Vi编辑器编辑文本。
- vi是轻量级的软件,运行速度快。
大多数Linux发行版配备的并不是vi,而是vi加强版-vim。vim是传统UNIX系统中vi的改良版vi。通常vim的硬链接指向系统中的vi名称。
接下来,我们就来熟悉vi或vim的基本操作。
# 启动和退出vi
现在,我们先学习启动vi编辑器。
- 启动vi
输入以下命令,启动vi
vi
输出如下结果
~ VIM - Vi IMproved
~ ~ version 8.0.1453
~ by Bram Moolenaar et al.
~ Modified by pkg-vim-maintainers@lists.alioth.debian.org
~ Vim is open source and freely distributable
~ ~ Help poor children in Uganda!
~ type :help iccf<Enter> for information
~ ~ type :q<Enter> to exit
~ type :help<Enter> or <F1> for on-line help
~ type :help version8<Enter> for version info
- 退出vi
退出vi也很简单,输入
:q
即可退出vi编辑器。此时shell会返回初始的操作窗口。如果因为一些原因,vi不能退出(通常是因为没有保存修改过的文件),可以在命令后面加感叹号的方式强制退出vi。
:q!
TIP
如果不能确定vi所处的状态,可以按ESC键两次返回初始状态。
# vi查看文本内容
再次启动vi,并**向其传递一个不存在的文件名,就可以创建新文件。**这个新文件每行都是以波浪线开头,代表此行没有任何内容。
vi是一个模态编辑器。vi启动后进入的就是命令模式。在命令模式中,几乎键盘上的每一个按键都代表一条命令。所以如果要编辑文本,需要进入vi插入模式。
# vi进入插入模式
如果需要编辑文件内容,则首先需要按i键进入插入模式。若此时vim是在增强模式下正常运行,那么在屏幕底部会出现以下内容。
-- INSERT --
若我们编辑完文本内容,可以按ESC键退出插入模式并返回命令模式。
# 保存文本内容
若我们要保存修改过的文本文件,则需要在命令模式下,输入冒号键并在冒号后输入w。
:w
# 移动光标快捷键
在命令模式下,vi提供了很多移动光标的命令 ,其中有一些命令和less
命令是共用的。下面是比较重要的一些快捷键。
键 | 光标动作 |
---|---|
L或右方向键 | 右移一位 |
H或左方向键 | 左移一位 |
J或下方向键 | 下移一位 |
K或上方向键 | 上移一位 |
数字0 | 本行开头 |
shift-4($) | 本行结尾 |
Ctrl-F或Page Down | 下翻一页 |
Ctrl-B或Page Up | 上翻一页 |
Shift-G | 移动文件最后一行 |
# 编辑文本内容
# 插入文本内容
插入一行,若要在文件中插入一行,则可以在命令模式下按以下功能键。
- o:在当前行的上方插入文本
- O:当前行的下方插入文本
输入完成后,按ESC键退出插入模式。
# 删除文本内容
就像许多用户期待的那样,vi提供了许多删除文本的方式,下面是vi的一些删除命令,我们可以在命令模式下执行这些命令。
命令 | 删除内容 |
---|---|
x | 当前字符 |
3x | 当前字符和之后的2个字符 |
dd | 当前行 |
5dd | 当前行和之后的4行 |
d$ | 当前字符到当前行的末尾 |
d0 | 当前字符到当前行的起始 |
dG | 当前行到文件末尾 |
d20G | 当前行到文件第20行 |
# 剪切、粘贴、复制文本内容
剪切文本
在vi中
d
命令不仅仅能删除文本,还可剪切文本。用户每次使用d
命令之后,都会复制删除的内容进缓存。复制文本操作
命令 | 复制内容 |
---|---|
yy | 当前行 |
5yy | 当前行和之后4行 |
y$ | 当前字符到当前行的末尾 |
y0 | 当前字符到当前行的开头 |
yG | 当前行到文件末尾 |
y20G | 当前行到文件第20行 |
- 粘贴文本操作
命令 | 粘贴位置 |
---|---|
p(小写) | 将缓存中的内容粘贴到光标之后 |
P(大写) | 将缓存中的内容粘贴到光标之前 |
# 合并多行文本内容
vi在行的概念上非常严格,通常来说,将光标移动到行末并删除行的末尾字符并不能将此行和下一行合并。因此,vi专门提供了J
命令来合并行。
vi提供了在一行或整个文本根据搜索条件将光标移动到指定位置的功能。vi还可以执行替换文本的功能,用户可指定替换时是否需要用户确认。
# 搜索和替换文本内容
# 行内搜索文本内容
命令f
在行内进行搜索,并将光标移至搜索到的下一个指定字符。若已经执行过依次行内搜索之后,按分号将可以使vi重复上一次搜索。
# 搜索整个文件内容
当使用/
命令后,一个“/”符号将出现在屏幕底部。接下来,输入要搜索的单词或短语,以Enter结束。光标就会移动到下一处包含被搜索字符串的地方。使用n
命令可以重复此搜索。
# 全局搜索和替换
vi使用ex命令来执行几行之内或者整个文件中的搜索和替换操作。输入以下命令可以将文件中的Line替换为line。
:%s/Line/line/g
现在就来解析这条命令的每一部分。
组成 | 含义 |
---|---|
: | 冒号用于启动一条ex命令 |
% | 确定了操作动作的范围;%简介代表了从文件的第一行到最后一行。1,$ 意思是“从第一行到文件的最后一行”。如果不明确指出命令的作用范围,那么命令只会在当前行生效。 |
s | 指定了具体操作,本次是替换操作 |
/Line/line | 搜索和替换的文本 |
g | 代表global(全局),也就是对搜索到的每一行的每一个实例进行替换,若g缺失,则只替换每一行第一个符合条件的实例 |
# 编辑多个文件内容
实际操作中,我们经常遇到需要同时编辑多个文件的情况。可能是需要对多个文件做出修改,或者是拷贝文件的部分内容到另外一个文件。用户可以通过在命令行具体指定多个文件的方式使vi打开多个文件。
vi file1 file2 file3...
# 来回切换文件
在vi中,我们若需要来回切换打开的多个文件,可以使用以下两种方式
- 方式一:
若我们需要切换到下一个文件,则需要执行以下命令
:n
切换回上一个文件,则需要执行以下命令
:N
- 方式二:
可以使用:buffers
命令列出打开的多个文件,
:buffers
若需要切换文件,可以通过:buffer
命令切换到相应的文件。
:buffer filenumber
# 载入更多文件
有些时候我们载入更多文件,为了载入更多文件,我们可以在命令模式下输入以下命令来加载新文件
:e filename
需要注意的是,使用:e
命令载入的文件不会响应:n
或:N
命令,而需要使用:buffer
加文件编号来切换。
# 插入整个文件
通过vi可以将一个文件完全插入正在编辑的文件中,将光标移动到要插入的位置,输入命令
:r filename
命令:r
可以将指定的文件内容插入到光标位置之前。
# 第十三章 shell提示符
和Linux中的很多程序一样,shell提示符的可配置性很高。现在,我们来看一下系统默认的提示符。
[root@LAPTOP-2ESIRNKO ~]#
可以看到提示符中包含了用户名、主机名以及当前的工作目录。在Linux中,提示符是由名为PS1的环境变量定义的,我们可以用echo
命令查看环境变量的值。
echo $PS1
输出结果为[\u@\h \W]\$
。
可以看到,PS1中变量值中包含了一些特殊的字符,这些字符其实是由反斜杠转义的转义字符。下面是shell中常用的转义字符。
转义字符 | 含义 |
---|---|
\a | ASCII铃声,在遇到该字符时,计算机会发出哔哔声 |
\d | 当前日期,以星期、月、日的形式表示 |
\h | 本地机器的主机名,不带域名 |
\H | 完整的主机名 |
\n | 换行符 |
\r | 回车符 |
\s | shell程序的名称 |
$ | 在非管理员权限下输出$ ,在管理员权限下输出# |
! | 当前命令的历史编号 |
\V | shell的版本号和发行号 |
\v | shell的版本号 |
\w | 当前工作目录名 |
\W | 当前工作目录名称的最后一部分 |
\t | 当前时间(24小时制),格式为小时:分钟:秒 |
\T | 当前时间(12小时制) |
@ | 当前时间(12小时制,格式为AM/PM) |
\A | 当前时间(24小时),格式为小时:分钟 |
[ | 标志一个或多个非打印字符的开始。用于嵌入非打印的控制字符 |
] | 标志非显示字符序列的结束 |
通过这个字符列表,我们可以更改变量PS1来创建一个新的提示符。
当然,我们也可以通过其它转义字符来控制光标位置、字符属性(如颜色、粗体、文本闪烁)等内容,此处先略过,等以后有需要再补充。