18 Linux-Shell基础
18.1 Shell概述
18.1.1 什么是Shell
现在我们使用的操作系统(Windows、Mac OS、Android、iOS 等)都是带图形界面的,简单直观,容易上手,对专业用户(程序员、网管等)和普通用户(家庭主妇、老年人等)都非常适用;计算机的普及离不开图形界面。
然而在计算机的早期并没有图形界面,我们只能通过一个一个地命令来控制计算机,这些命令有成百上千之多,且不说记住这些命令非常困难,每天面对没有任何色彩的“黑屏”本身就是一件枯燥的事情;这个时候的计算机还远远谈不上炫酷和普及,只有专业人员才能使用。
对于图形界面,用户点击某个图标就能启动某个程序;对于命令行,用户输入某个程序的名字(可以看做一个命令)就能启动某个程序。这两者的基本过程都是类似的,都需要查找程序在硬盘上的安装位置,然后将它们加载到内存运行。
然而,真正能够控制计算机硬件(CPU、内存、显示器等)的只有操作系统内核(Kernel),图形界面和命令行只是架设在用户和内核之间的一座桥梁。
由于安全、复杂、繁琐等原因,用户不能直接接触内核(也没有必要),需要另外再开发一个程序,让用户直接使用这个程序;该程序的作用就是接收用户的操作(点击图标、输入命令),并进行简单的处理,然后再传递给内核,这样用户就能间接地使用操作系统内核了。你看,在用户和内核之间增加一层“代理”,既能简化用户的操作,又能保障内核的安全,何乐不为呢?
用户界面和命令行就是这个另外开发的程序,就是这层“代理”。在Linux下,这个命令行程序叫做 Shell。
18.1.2 shell的分类
| Shell类别 | 易学性 | 可移植性 | 编辑性 | 快捷性 |
|---|---|---|---|---|
| Bourne Shell (sh) | 容易 | 好 | 较差 | 较差 |
| Korn Shell (ksh) | 较难 | 较好 | 好 | 较好 |
| Bourne Again (Bash) | 难 | 较好 | 好 | 好 |
| POSIX Shell (psh) | 较难 | 好 | 好 | 较好 |
| C Shell (csh) | 较难 | 差 | 较好 | 较好 |
| TC Shell (tcsh) | 难 | 差 | 好 | 好 |
Shell的两种主要语法类型有Bourne和C,这两种语法彼此不兼容。Bourne家族主要包括sh、ksh、Bash、psh、zsh;C家族主要包括:csh、tcsh (Bash和zsh在不同程度上支持csh 的语法)。
可以通过/etc/shells文件来查询Linux支持的Shell。命令如下:
18.2 Shell脚本的执行方式
18.2.1 echo命令
示例:
在echo命令中如果使用了“-e”选项,则可以支持控制字符,如表所示:
| 控制字符 | 作用 |
|---|---|
| \ | 输出\本身 |
| \a | 输出警告音 |
| \b | 退格键,也就是向左删除键 |
| \c | 取消输出行末的换行符。和“-n”选项一致 |
| \e | ESCAPE键 |
| \f | 换页符 |
| \n | 换行符 |
| \r | 回车键 |
| \t | 制表符,也就是Tab键 |
| \v | 垂直制表符 |
| \0nnn | 按照八进制ASCII码表输出字符。其中0为数字零,nnn是三位八进制数 |
| \xhh | 按照十六进制ASCII码表输出字符。其中hh是两位十六进制数 |
也就是说141这个八进制,在ASCII码中代表小写的“a”,其他的以此类推。
echo命令还可以进行一些比较有意思的东西,比如:
这条命令会把abcd按照红色输出。解释下这个命令\e[1是标准格式,代表颜色输出开始,\e[0m代表颜色输出结束,31m定义字体颜色是红色。echo能够识别的颜色如下:
30m=黑色,31m=红色,32m=绿色,33m=黄色,34m=蓝色,35m=洋红,36m=青色,37m=白色。
这条命令会给abcd加入一个绿色的背景。echo可以使用的背景颜色如下:
40m=黑色,41m=红色,42m=绿色,43m=黄色,44m=蓝色,45m=洋红,46m=青色,47m=白色。
18.2.2 Shell脚本的执行
Shell脚本写好了,那么这个脚本该如何运行呢?在Linux中脚本的执行主要有这样两种种方法:
-
赋予执行权限,直接运行
这种方法是最常用的Shell脚本运行方法,也最为直接简单。就是赋予执行权限之后,直接运行。当然运行时可以使用绝对路径,也可以使用相对路径运行。命令如下:
18.3 Bash的基本功能
18.3.1 历史命令
1)历史命令的查看
使用history命令查看的历史命令和~/.bash_history文件中保存的历史命令是不同的。那是因为当前登录操作的命令并没有直接写入~/.bash_history文件,而是保存在缓存当中的。需要等当前用户注销之后,缓存中的命令才会写入~/.bash_history文件。
如果需要把内存中的命令直接写入~/.bash_history文件,而不等用户注销时再写入,就需要使用“-w”选项了。命令如下:
这时再去查询~/.bash_history文件,历史命令就和history命令查询的一致了。 如果需要清空历史命令,只需要执行:
2)历史命令的调用
如果想要使用原先的历史命令有这样几种方法:
-
使用上、下箭头调用以前的历史命令
-
使用“!n”重复执行第n条历史命令
-
使用“!!”重复执行上一条命令
-
使用“!字串”重复执行最后一条以该字串开头的命令
-
使用“!$”重复上一条命令的最后一个参数
18.3.2 命令与文件的补全
输入命令或文件名前几位后,使用tab键可以将其补全
18.3.3 命令别名
示例:
既然说别名的优先级比命令高,那么命令执行时具体的顺序是什么呢?命令执行时的顺序是这样的:
-
第一顺位执行用绝对路径或相对路径执行的命令。
-
第二顺位执行别名。
-
第三顺位执行Bash的内部命令。
-
第四顺位执行按照$PATH环境变量定义的目录查找顺序找到的第一个命令。
为了让这个别名永久生效,可以把别名写入环境变量配置文件“~/.bashrc”。命令如下:
18.3.4 Bash常用快捷键
| 快捷键 | 作用 |
|---|---|
| ctrl+A | 把光标移动到命令行开头。如果我们输入的命令过长,想要把光标移动到命令行开头时使用。 |
| ctrl+E | 把光标移动到命令行结尾。 |
| ctrl+C | 强制终止当前的命令。 |
| ctrl+L | 清屏,相当于clear命令。 |
| ctrl+U | 删除或剪切光标之前的命令。我输入了一行很长的命令,不用使用退格键一个一个字符的删除,使用这个快捷键会更加方便 |
| ctrl+K | 删除或剪切光标之后的内容。 |
| ctrl+Y | 粘贴ctrl+U或ctrl+K剪切的内容。 |
| ctrl+R | 在历史命令中搜索,按下ctrl+R之后,就会出现搜索界面,只要输入搜索内容,就会从历史命令中搜索。 |
| ctrl+D | 退出当前终端。 |
| ctrl+Z | 暂停,并放入后台。 |
| ctrl+S | 暂停屏幕输出。 |
| ctrl+Q | 恢复屏幕输出。 |
18.3.5 输入输出重定向
1)Bash的标准输入输出
| 设备 | 设备文件名 | 文件描述符 | 类型 |
|---|---|---|---|
| 键盘 | /dev/stdin | 0 | 标准输入 |
| 显示器 | /dev/stdout | 1 | 标准输出 |
| 显示器 | /dev/stderr | 2 | 标准错误输出 |
2)输出重定向
| 类型 | 符号 | 作用 |
|---|---|---|
| 标准输出重定向 | 命令 > 文件 | 以覆盖的方式,把命令的正确输出输出到指定的文件或设备当中。 |
| 标准输出重定向 | 命令 >> 文件 | 以追加的方式,把命令的正确输出输出到指定的文件或设备当中。 |
| 标准错误输出重定向 | 错误命令 2>文件 | 以覆盖的方式,把命令的错误输出输出到指定的文件或设备当中。 |
| 标准错误输出重定向 | 错误命令 2>>文件 | 以追加的方式,把命令的错误输出输出到指定的文件或设备当中。 |
| 正确输出和错误输出同时保存 | 命令 > 文件 2>&1 | 以覆盖的方式,把正确输出和错误输出都保存到同一个文件当中。 |
| 正确输出和错误输出同时保存 | 命令 >> 文件 2>&1 | 以追加的方式,把正确输出和错误输出都保存到同一个文件当中。 |
| 正确输出和错误输出同时保存 | 命令 &>文件 | 以覆盖的方式,把正确输出和错误输出都保存到同一个文件当中。 |
| 正确输出和错误输出同时保存 | 命令 &>>文件 | 以追加的方式,把正确输出和错误输出都保存到同一个文件当中。 |
| 正确输出和错误输出同时保存 | 命令>>文件1 2>>文件2 | 把正确的输出追加到文件1中,把错误的输出追加到文件2中。 |
3)输入重定向
18.3.6 多命令顺序执行
| 多命令执行符 | 格式 | 作用 |
|---|---|---|
| ; | 命令1 ;命令2 | 多个命令顺序执行,命令之间没有任何逻辑联系 |
| && | 命令1 && 命令2 | 当命令1正确执行($?=0),则命令2才会执行 当命令1执行不正确($?≠0),则命令2不会执行 |
| || | 命令1 ||命令2 | 当命令1 执行不正确($?≠0),则命令2才会执行 当命令1正确执行($?=0),则命令2不会执行 |
18.3.7 管道符
1)行提取命令grep
示例:
2)find和grep的区别
find命令是在系统当中搜索符合条件的文件名,如果需要模糊查询,使用通配符进行匹配,搜索时文件名是完全匹配。
grep命令是在文件当中搜索符合条件的字符串,如果需要模糊查询,使用正则表达式进行匹配,搜索时字符串是包含匹配。
3)管道符
18.3.8 通配符
| 通配符 | 作用 |
|---|---|
| ? | 匹配一个任意字符 |
| * | 匹配0个或任意多个任意字符,也就是可以匹配任何内容 |
| [] | 匹配中括号中任意一个字符。例如:[abc]代表一定匹配一个字符,或者是a,或者是b,或者是c。 |
| [-] | 匹配中括号中任意一个字符,-代表一个范围。例如:[a-z]代表匹配一个小写字母。 |
| [^] | 逻辑非,表示匹配不是中括号内的一个字符。例如:0-9代表匹配一个不是数字的字符。 |
18.3.9 Bash中其他特殊符号
| 符号 | 作用 |
|---|---|
| '' | 单引号。在单引号中所有的特殊符号,如“$”和“`”(反引号)都没有特殊含义。 |
| "" | 双引号。在双引号中特殊符号都没有特殊含义,但是“$”、“`”和“\”是例外,拥有“调用变量的值”、“引用命令”和“转义符”的特殊含义。 |
| `` | 反引号。反引号括起来的内容是系统命令,在Bash中会先执行它。和$()作用一样,不过推荐使用$(),因为反引号非常容易看错。 |
| $() | 和反引号作用一样,用来引用系统命令。 |
| () | 用于一串命令执行时,()中的命令会在子Shell中运行 |
| {} | 用于一串命令执行时,{}中的命令会在当前Shell中执行。也可以用于变量变形与替换。 |
| [] | 用于变量的测试。 |
| # | 在Shell脚本中,#开头的行代表注释。 |
| $ | 用于调用变量的值,如需要调用变量name的值时,需要用$name的方式得到变量的值。 |
| \ | 转义符,跟在\之后的特殊符号将失去特殊含义,变为普通字符。如$将输出“$”符号,而不当做是变量引用。 |
1)单引号和双引号
2)反引号
3)小括号、中括号和大括号
在介绍小括号和大括号的区别之前,我们先要解释一个概念,那就是父Shell和子Shell。在我们的Bash中,是可以调用新的Bash的,比如:
这时,我们通过pstree命令查看一下进程数:
知道了父Shell和子Shell,我们接着解释小括号和大括号的区别。如果是用于一串命令的执行,那么小括号和大括号的主要区别在于:
-
()执行一串命令时,需要重新开一个子shell进行执行
-
{}执行一串命令时,是在当前shell执行;
-
()和{}都是把一串的命令放在括号里面,并且命令之间用;号隔开;
-
()最后一个命令可以不用分号;
-
{}最后一个命令要用分号;
-
{}的第一个命令和左括号之间必须要有一个空格;
-
()里的各命令不必和括号有空格;
-
()和{}中括号里面的某个命令的重定向只影响该命令,但括号外的重定向则影响到括号里的所有命令。
还是举几个例子来看看吧,这样写实在是太抽象了:
18.4 Bash的变量和运算符
18.4.1 什么是变量
在定义变量时,有一些规则需要遵守:
-
变量名称可以由字母、数字和下划线组成,但是不能以数字开头。如果变量名是“2name”则是错误的。
-
在Bash中,变量的默认类型都是字符串型,如果要进行数值运算,则必修指定变量类型为数值型。
-
变量用等号连接值,等号左右两侧不能有空格。
-
变量的值如果有空格,需要使用单引号或双引号包括。如:“test="hello world!"”。其中双引号括起来的内容“$”、“\”和反引号都拥有特殊含义,而单引号括起来的内容都是普通字符。
-
在变量的值中,可以使用“\”转义符。
-
如果需要增加变量的值,那么可以进行变量值的叠加。不过变量需要用双引号包含"$变量名"或用${变量名}包含变量名。例如:
-
-
环境变量名建议大写,便于区分。
18.4.2 变量的分类
-
用户自定义变量:这种变量是最常见的变量,由用户自由定义变量名和变量的值。
-
环境变量:这种变量中主要保存的是和系统操作环境相关的数据,比如当前登录用户,用户的家目录,命令的提示符等。不是太好理解吧,那么大家还记得在Windows中,同一台电脑可以有多个用户登录,而且每个用户都可以定义自己的桌面样式和分辨率,这些其实就是Windows的操作环境,可以当做是Windows的环境变量来理解。环境变量的变量名可以自由定义,但是一般对系统起作用的环境变量的变量名是系统预先设定好的。
-
位置参数变量:这种变量主要是用来向脚本当中传递参数或数据的,变量名不能自定义,变量作用是固定的。
-
预定义变量:是Bash中已经定义好的变量,变量名不能自定义,变量作用也是固定的。
18.4.3 用户自定义变量
1)变量定义
2)变量调用
3)变量查看
4)变量删除
18.4.4 环境变量
1)环境变量设置
2)环境变量查询和删除
env命令和set命令的区别是,set命令可以查看所有变量,而env命令只能查看环境变量。
3)系统默认环境变量
18.4.5 位置参数变量
| 位置参数变量 | 作 用 |
|---|---|
| $n | n为数字,$0代表命令本身,$1-$9代表第一到第九个参数,十以上的参数需要用大括号包含,如${10}. |
| $* | 这个变量代表命令行中所有的参数,$*把所有的参数看成一个整体 |
| $@ | 这个变量也代表命令行中所有的参数,不过$@把每个参数区分对待 |
| $# | 这个变量代表命令行中所有参数的个数 |
那么还有几个位置参数变量是干嘛的呢?我们在写个脚本来说明下:
那么“$”和“$@”有区别吗?还是有区别的,$会把接收的所有参数当成一个整体对待,而$@则会区分对待接收到的所有参数。还是举个例子:
18.4.6 预定义变量
| 预定义变量 | 作 用 |
|---|---|
| $? | 最后一次执行的命令的返回状态。如果这个变量的值为0,证明上一个命令正确执行;如果这个变量的值为非0(具体是哪个数,由命令自己来决定),则证明上一个命令执行不正确了。 |
| $$ | 当前进程的进程号(PID) |
| $! | 后台运行的最后一个进程的进程号(PID) |
我们先来看看“$?”这个变量,看起来不好理解,我们还是举个例子:
接下来我们来说明下“$$”和“$!”这两个预定义变量,我们写个脚本吧:
18.4.7 接收键盘输入
还是写个例子来解释下read命令:
18.4.8 Shell的运算符
1)数值运算的方法
那如果我需要进行数值运算,可以采用以下三种方法中的任意一种:
-
使用declare声明变量类型
既然所有变量的默认类型是字符串型,那么只要我们把变量声明为整数型不就可以运算了吗?使用declare命令就可以实现声明变量的类型。命令如下:
示例:数值运算
示例:数组变量类型
数组这个东东只有写一些较为复杂的程序才会用到,大家可以先不用着急学习数组,当有需要的时候再回来详细学习。那么数组是什么呢?所谓数组,就是相同数据类型的元素按一定顺序排列的集合,就是把有限个类型相同的变量用一个名字命名,然后用编号区分他们的变量的集合,这个名字称为数组名,编号称为下标。组成数组的各个变量成为数组的分量,也称为数组的元素,有时也称为下标变量。
一看定义就一头雾水,更加不明白数组是什么了。那么换个说法,变量和数组都是用来保存数据的,只是变量只能赋予一个数据值,一旦重复复制,后一个值就会覆盖前一个值。而数组是可以赋予一组相同类型的数据值。大家可以把变量想象成一个小办公室,这个办公室只能容纳一个人办公,办公室名就是变量名。而数组是一个大办公室,可以容纳很多人同时办公,在这个大办公室办公的每个人是通过不同的座位号来区分的,这个座位号就是数组的下标,而大办公室的名字就是数组名。
注意数组的下标是从0开始的,在调用数组值时,需要使用${数组[下标]}的方式来读取。
不过好像在刚刚的例子中,我们并没有把name变量声明为数组型啊,其实只要我们在定义变量时采用了“变量名[下标]”的格式,这个变量就会被系统认为是数组型了,不用强制声明。
示例: 环境变量
我们其实也可以使用declare命令把变量声明为环境变量,和export命令的作用是一样的:
示例:只读属性
注意一旦给变量设定了只读属性,那么这个变量既不能修改变量的值,也不能删除变量,甚至不能使用“+r”选项取消只读属性。命令如下:
不过还好这个变量只是命令行声明的,所以只要重新登录或重启,这个变量就会消失了。
示例:查询变量属性和取消变量属性
变量属性的查询使用“-p”选项,变量属性的取消使用“+”选项。命令如下:
使用expr命令进行运算时,要注意“+”号左右两侧必须有空格,否则运算不执行。
至于let命令和expr命令基本类似,都是Linux中的运算命令,命令格式如下:
-
这三种数值运算方式,大家可以按照自己的习惯来进行使用。不过我们推荐使用“$((运算式))”的方式
2)Shell常用运算符
| 优先级 | 运算符 | 说明 |
|---|---|---|
| 1 | =,+=,-=,*=,/=,%=,&=, ^=, |=, <<=, >>= | 赋值、运算且赋值 |
| 2 | || | 逻辑或 |
| 3 | && | 逻辑与 |
| 4 | | | 按位或 |
| 5 | ^ | 按位异或 |
| 6 | & | 按位与 |
| 7 | ==,!= | 等于、不等于 |
| 8 | < =, > =, < , > | 小于或等于、大于或等于、小于、大于 |
| 9 | << , >> | 按位左移、按位右移 |
| 10 | +, - | 加、减 |
| 11 | * , / , % | 乘、除、取模 |
| 12 | !, ~ | 逻辑非、按位取反或补码 |
| 13 | -, + | 单目负、单目正 |
运算符优先级表明在每个表达式或子表达式中哪一个运算对象首先被求值,数值越大优先级越高,具有较高优先级级别的运算符先于较低级别的运算符进行求值运算。
示例: 加减乘除
示例:取模运算
示例:逻辑与
18.4.9 变量的测试与内容置换
| 变量置换方式 | 变量y没有设置 | 变量y为空值 | 变量y设置值 |
|---|---|---|---|
| x=${y-新值} | x=新值 | x为空 | x=$y |
| x=${y:-新值} | x=新值 | x=新值 | x=$y |
| x=${y+新值} | x为空 | x=新值 | x=新值 |
| x=${y:+新值} | x为空 | x为空 | x=新值 |
| x=${y=新值} | x=新值 y=新值 | x为空 y值不变 | x=$y y值不变 |
| x=${y:=新值} | x=新值 y=新值 | x=新值 y=新值 | x=$y y值不变 |
| x=${y?新值} | 新值输出到标准错误输出(就是屏幕) | x为空 | x=$y |
| x=${y:?新值} | 新值输出到标准错误输出 | 新值输出到标准错误输出 | x=$y |
如果大括号内没有“:”,则变量y是为空,还是没有设置,处理方法是不同的;如果大括号内有“:”,则变量 y不论是为空,还是没有没有设置,处理方法是一样的。 如果大括号内是“-”或“+”,则在改变变量x值的时候,变量y是不改变的;如果大括号内是“=”,则在改变变量x值的同时,变量y的值也会改变。 如果大括号内是“?”,则当变量y不存在或为空时,会把“新值”当成报错输出到屏幕上。 示例:
和上表对比下,这个表是不是可以看懂了。这是变量y不存在的情况,那如果变量y的值是空呢?
那如果变量y有值呢?
示例:
那如果大括号内是“=”号,又该是什么情况呢?先测试下变量y没有设置的情况:
一旦使用“=”号,那么变量y和变量x都会同时进行处理,而不像例子1中只改变变量x的值。那如果变量y为空又是什么情况呢?
一旦在大括号中使用“:”,那么变量y为空或者不设定,处理方式都是一样的了。那如果y已经赋值了,又是什么情况:
示例:
再测试下大括号中是“?”的情况吧:
那如果变量y已经赋值了呢:
18.5 环境变量配置文件
18.5.1 source命令
18.5.2 环境变量配置文件
1)登录时生效的环境变量配置文件
在Linux系统登录时主要生效的环境变量配置文件有以下五个:
-
/etc/profile
-
/etc/profile.d/*.sh
-
~/.bash_profile
-
~/.bashrc
-
/etc/bashrc
环境变量配置文件调用过程
-
在用户登录过程先调用/etc/profile文件
在这个环境变量配置文件中会定义这些默认环境变量:
-
USER变量:根据登录的用户,给这个变量赋值(就是让USER变量的值是当前用户)。
-
LOGNAME变量:根据USER变量的值,给这个变量赋值。
-
MAIL变量:根据登录的用户,定义用户的邮箱为/var/spool/mail/用户名。
-
PATH变量:根据登录用户的UID是否为0,判断PATH变量是否包含/sbin、/usr/sbin和/usr/local/sbin这三个系统命令目录。
-
HOSTNAME变量:更加主机名,给这个变量赋值。
-
HISTSIZE变量:定义历史命令的保存条数。
-
umask:定义umask默认权限。注意/etc/profile文件中的umask权限是在“有用户登录过程(也就是输入了用户名和密码)”时才会生效。
-
调用/etc/profile.d/*.sh文件,也就是调用/etc/profile.d/目录下所有以.sh结尾的文件。
-
-
由/etc/profile文件调用/etc/profile.d/*.sh文件
这个目录中所有以.sh结尾的文件都会被/etc/profile文件调用,这里最常用的就是lang.sh文件,而这个文件又会调用/etc/sysconfig/i18n文件。
-
由/etc/profile文件调用~/.bash_profile文件
~/.bash_profile文件就没有那么复杂了,这个文件主要实现了两个功能:
-
调用了~/.bashrc文件。
-
在PATH变量后面加入了“:$HOME/bin”这个目录。那也就是说,如果我们在自己的家目录中建立bin目录,然后把自己的脚本放入“~/bin”目录,就可以直接执行脚本,而不用通过目录执行了。
-
-
由~/.bash_profile文件调用~/.bashrc文件
在~/.bashrc文件中主要实现了:
-
定义默认别名,所以超哥把自己定义的别名也放入了这个文件。
-
调用/etc/bashrc
-
-
由~/.bashrc调用了/etc/bashrc文件
在/etc/bashrc文件中主要定义了这些内容:.
-
PS1变量:也就是用户的提示符,如果我们想要永久修改提示符,就要在这个文件中修改
-
umask:定义umask默认权限。这个文件中定义的umask是针对“没有登录过程(也就是不需要输入用户名和密码时,比如从一个终端切换到另一个终端,或进入子Shell)”时生效的。如果是“有用户登录过程”,则是/etc/profile文件中的umask生效。
-
PATH变量:会给PATH变量追加值,当然也是在“没有登录过程”时才生效。
-
调用/etc/profile.d/*.sh文件,这也是在“没有用户登录过程”是才调用。在“有用户登录过程”时,/etc/profile.d/*.sh文件已经被/etc/profile文件调用过了。
-
这样这五个环境变量配置文件会被依次调用,那么如果是我们自己定义的环境变量应该放入哪个文件呢?如果你的修改是打算对所有用户生效的,那么可以放入/etc/profile环境变量配置文件;如果你的修改只是给自己使用的,那么可以放入~/.bash_profile或~/.bashrc这两个配置文件中的任一个。
可是如果我们误删除了这些环境变量,比如删除了/etc/bashrc文件,或删除了~/.bashrc文件,那么这些文件中配置就会失效(~/.bashrc文件会调用/etc/bashrc文件)。那么我们的提示符就会变成:
2)注销时生效的环境变量配置文件
在用户退出登录时,只会调用一个环境变量配置文件,就是~/.bash_logout。这个文件默认没有写入任何内容,可是如果我们希望再退出登录时执行一些操作,比如清除历史命令,备份某些数据,就可以把命令写入这个文件。
3)其他配置文件
还有一些环节变量配置文件,最常见的就是~/bash_history文件,也就是历史命令保存文件
18.5.3 Shell登录信息
1)/etc/issue
我们在登录tty1-tty6这六个本地终端时,会有几行的欢迎界面。这些欢迎信息是保存在哪里的?可以修改吗?当然可以修改,这些欢迎信息是保存在/etc/issue文件中,我们查看下这个文件:
可以支持的转义符我们可以通过man agetty命令查询,在表中我们列出常见的转义符作用:
| 转义符 | 作用 |
|---|---|
| \d | 显示当前系统日期 |
| \s | 显示操作系统名称 |
| \l | 显示登录的终端号,这个比较常用。 |
| \m | 显示硬件体系结构,如i386、i686等 |
| \n | 显示主机名 |
| \o | 显示域名 |
| \r | 显示内核版本 |
| \t | 显示当前系统时间 |
| \u | 显示当前登录用户的序列号 |
2)/etc/issue.net
/etc/issue是在本地终端登录是显示欢迎信息的,如果是远程登录(如ssh远程登录,或telnet远程登录)需要显示欢迎信息,则需要配置/etc/issue.net这个文件了。使用这个文件时由两点需要注意:
-
首先,在/etc/issue文件中支持的转义符,在/etc/issue.net文件中不能使用。
-
其次,ssh远程登录是否显示/etc/issue.net文件中的欢迎信息,是由ssh的配置文件决定的。
如果我们需要ssh远程登录可以查看/etc/issue.net的欢迎信息,那么首先需要修改ssh的配置文件/etc/ssh/sshd_config,加入如下内容:
这样在ssh远程登录时,也可以显示欢迎信息,只是不再可以识别“\d”和“\l”等信息了
3)/etc/motd
/etc/motd文件中也是显示欢迎信息的,这个文件和/etc/issue及/etc/issue.net文件的区别是:/etc/issue及/etc/issue.net是在用户登录之前显示欢迎信息,而/etc/motd是在用户输入用户名和密码,正确登录之后显示欢迎信息。在/etc/motd文件中的欢迎信息,不论是本地登录,还是远程登录都可以显示。
18.5.4 定义Bash快捷键
那么这些快捷键可以更改吗?可以啊,只要执行:
-
-
通过Bash调用执行脚本
-
变量值的叠加可以使用两种格式:“$变量名”或${变量名}
-
如果是把命令的结果作为变量值赋予变量,则需要使用反引号或$()包含命令。例如:
-
-
使用expr或let数值运算工具
要想进行数值运算的第二种方法是使用expr命令,这种命令就没有declare命令复杂了。命令如下:
-
expr命令和let命令大家可以按照习惯使用,不过let命令对格式要求要比expr命令宽松,所以推荐使用let命令进行数值运算。
-
使用“$((运算式))”或“$[运算式]”方式运算
其实这是一种方式“$(())”和“$[]”这两种括号按照个人习惯使用即可。命令如下:

