## 12.3 善用判断式
在第十章中,我们提到过 [$?](../Text/index.html#returnvar) 这个变量所代表的意义, 此外,也通过 [&& 及 ||](../Text/index.html#redirect_com) 来作为前一个指令执行回传值对于后一个指令是否要进行的依据。第十章的讨论中,如果想要判断一个目录是否存在, 当时我们使用的是 ls 这个指令搭配数据流重导向,最后配合 $? 来决定后续的指令进行与否。 但是否有更简单的方式可以来进行“条件判断”呢?有的~那就是“ test ”这个指令。
### 12.3.1 利用 test 指令的测试功能
当我要检测系统上面某些文件或者是相关的属性时,利用 test 这个指令来工作真是好用得不得了, 举例来说,我要检查 /dmtsai 是否存在时,使用:
```
[dmtsai@study ~]$ test -e /dmtsai
```
执行结果并不会显示任何讯息,但最后我们可以通过 $? 或 && 及 || 来展现整个结果呢! 例如我们在将上面的例子改写成这样:
```
[dmtsai@study ~]$ test -e /dmtsai && echo "exist" || echo "Not exist"
Not exist <==结果显示不存在啊!
```
最终的结果可以告知我们是“exist”还是“Not exist”呢!那我知道 -e 是测试一个“东西”在不在, 如果还想要测试一下该文件名是啥玩意儿时,还有哪些标志可以来判断的呢?呵呵!有下面这些东西喔!
| 测试的标志 | 代表意义 |
| --- | --- |
| 1\. 关于某个文件名的“文件类型”判断,如 test -e filename 表示存在否 |
| -e | 该“文件名”是否存在?(常用) |
| -f | 该“文件名”是否存在且为文件(file)?(常用) |
| -d | 该“文件名”是否存在且为目录(directory)?(常用) |
| -b | 该“文件名”是否存在且为一个 block device 设备? |
| -c | 该“文件名”是否存在且为一个 character device 设备? |
| -S | 该“文件名”是否存在且为一个 Socket 文件? |
| -p | 该“文件名”是否存在且为一个 FIFO (pipe) 文件? |
| -L | 该“文件名”是否存在且为一个链接文件? |
| 2\. 关于文件的权限侦测,如 test -r filename 表示可读否 (但 root 权限常有例外) |
| -r | 侦测该文件名是否存在且具有“可读”的权限? |
| -w | 侦测该文件名是否存在且具有“可写”的权限? |
| -x | 侦测该文件名是否存在且具有“可执行”的权限? |
| -u | 侦测该文件名是否存在且具有“SUID”的属性? |
| -g | 侦测该文件名是否存在且具有“SGID”的属性? |
| -k | 侦测该文件名是否存在且具有“Sticky bit”的属性? |
| -s | 侦测该文件名是否存在且为“非空白文件”? |
| 3\. 两个文件之间的比较,如: test file1 -nt file2 |
| -nt | (newer than)判断 file1 是否比 file2 新 |
| -ot | (older than)判断 file1 是否比 file2 旧 |
| -ef | 判断 file1 与 file2 是否为同一文件,可用在判断 hard link 的判定上。 主要意义在判定,两个文件是否均指向同一个 inode 哩! |
| 4\. 关于两个整数之间的判定,例如 test n1 -eq n2 |
| -eq | 两数值相等 (equal) |
| -ne | 两数值不等 (not equal) |
| -gt | n1 大于 n2 (greater than) |
| -lt | n1 小于 n2 (less than) |
| -ge | n1 大于等于 n2 (greater than or equal) |
| -le | n1 小于等于 n2 (less than or equal) |
| 5\. 判定字串的数据 |
| test -z string | 判定字串是否为 0 ?若 string 为空字串,则为 true |
| test -n string | 判定字串是否非为 0 ?若 string 为空字串,则为 false。 -n 亦可省略 |
| test str1 == str2 | 判定 str1 是否等于 str2 ,若相等,则回传 true |
| test str1 != str2 | 判定 str1 是否不等于 str2 ,若相等,则回传 false |
| 6\. 多重条件判定,例如: test -r filename -a -x filename |
| -a | (and)两状况同时成立!例如 test -r file -a -x file,则 file 同时具有 r 与 x 权限时,才回传 true。 |
| -o | (or)两状况任何一个成立!例如 test -r file -o -x file,则 file 具有 r 或 x 权限时,就可回传 true。 |
| ! | 反相状态,如 test ! -x file ,当 file 不具有 x 时,回传 true |
OK!现在我们就利用 test 来帮我们写几个简单的例子。首先,判断一下,让使用者输入一个文件名,我们判断:
1. 这个文件是否存在,若不存在则给予一个“Filename does not exist”的讯息,并中断程序;
2. 若这个文件存在,则判断他是个文件或目录,结果输出“Filename is regular file”或 “Filename is directory”
3. 判断一下,执行者的身份对这个文件或目录所拥有的权限,并输出权限数据!
你可以先自行创作看看,然后再跟下面的结果讨论讨论。注意利用 test 与 && 还有 || 等标志!
```
[dmtsai@study bin]$ vim file_perm.sh
#!/bin/bash
# Program:
# User input a filename, program will check the flowing:
# 1.) exist? 2.) file/directory? 3.) file permissions
# History:
# 2015/07/16 VBird First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
# 1\. 让使用者输入文件名,并且判断使用者是否真的有输入字串?
echo -e "Please input a filename, I will check the filename's type and permission. \n\n"
read -p "Input a filename : " filename
test -z ${filename} && echo "You MUST input a filename." && exit 0
# 2\. 判断文件是否存在?若不存在则显示讯息并结束脚本
test ! -e ${filename} && echo "The filename '${filename}' DO NOT exist" && exit 0
# 3\. 开始判断文件类型与属性
test -f ${filename} && filetype="regulare file"
test -d ${filename} && filetype="directory"
test -r ${filename} && perm="readable"
test -w ${filename} && perm="${perm} writable"
test -x ${filename} && perm="${perm} executable"
# 4\. 开始输出信息!
echo "The filename: ${filename} is a ${filetype}"
echo "And the permissions for you are : ${perm}"
```
如果你执行这个脚本后,他会依据你输入的文件名来进行检查喔!先看是否存在,再看为文件或目录类型,最后判断权限。 但是你必须要注意的是,由于 root 在很多权限的限制上面都是无效的,所以使用 root 执行这个脚本时, 常常会发现与 ls -l 观察到的结果并不相同!所以,建议使用一般使用者来执行这个脚本试看看。
### 12.3.2 利用判断符号 [ ]
除了我们很喜欢使用的 test 之外,其实,我们还可以利用判断符号“ [ ] ”(就是中括号啦) 来进行数据的判断呢! 举例来说,如果我想要知道 ${HOME} 这个变量是否为空的,可以这样做:
```
[dmtsai@study ~]$ [ -z "${HOME}" ] ; echo $?
```
使用中括号必须要特别注意,因为中括号用在很多地方,包括万用字符与正则表达式等等,所以如果要在 bash 的语法当中使用中括号作为 shell 的判断式时,必须要注意中括号的两端需要有空白字符来分隔喔! 假设我空白键使用“□”符号来表示,那么,在这些地方你都需要有空白键:
```
[ "$HOME" == "$MAIL" ]
[□"$HOME"□==□"$MAIL"□]
↑ ↑ ↑ ↑
```
![鸟哥的图示](https://box.kancloud.cn/2016-05-13_5735736501917.gif "鸟哥的图示")
**Tips** 你会发现鸟哥在上面的判断式当中使用了两个等号“ == ”。其实在 bash 当中使用一个等号与两个等号的结果是一样的! 不过在一般惯用程序的写法中,一个等号代表“变量的设置”,两个等号则是代表“逻辑判断 (是与否之意)”。 由于我们在中括号内重点在于“判断”而非“设置变量”,因此鸟哥建议您还是使用两个等号较佳!
上面的例子在说明,两个字串 ${HOME} 与 ${MAIL} 是否相同的意思,相当于 test ${HOME} == ${MAIL} 的意思啦! 而如果没有空白分隔,例如 [${HOME}==${MAIL}] 时,我们的 bash 就会显示错误讯息了!这可要很注意啊! 所以说,你最好要注意:
* 在中括号 [] 内的每个元件都需要有空白键来分隔;
* 在中括号内的变量,最好都以双引号括号起来;
* 在中括号内的常数,最好都以单或双引号括号起来。
为什么要这么麻烦啊?直接举例来说,假如我设置了 name="VBird Tsai" ,然后这样判定:
```
[dmtsai@study ~]$ name="VBird Tsai"
[dmtsai@study ~]$ [ ${name} == "VBird" ]
bash: [: too many arguments
```
见鬼了!怎么会发生错误啊?bash 还跟我说错误是由于“太多参数 (arguments)”所致! 为什么呢?因为 ${name} 如果没有使用双引号刮起来,那么上面的判定式会变成:
> [ VBird Tsai == "VBird" ]
上面肯定不对嘛!因为一个判断式仅能有两个数据的比对,上面 VBird 与 Tsai 还有 "VBird" 就有三个数据! 这不是我们要的!我们要的应该是下面这个样子:
> [ "VBird Tsai" == "VBird" ]
这可是差很多的喔!另外,中括号的使用方法与 test 几乎一模一样啊~ 只是中括号比较常用在[条件判断式 if ..... then ..... fi](../Text/index.html#rule) 的情况中就是了。 好,那我们也使用中括号的判断来做一个小案例好了,案例设置如下:
1. 当执行一个程序的时候,这个程序会让使用者选择 Y 或 N ,
2. 如果使用者输入 Y 或 y 时,就显示“ OK, continue ”
3. 如果使用者输入 n 或 N 时,就显示“ Oh, interrupt !”
4. 如果不是 Y/y/N/n 之内的其他字符,就显示“ I don't know what your choice is ”
利用中括号、 && 与 || 来继续吧!
```
[dmtsai@study bin]$ vim ans_yn.sh
#!/bin/bash
# Program:
# This program shows the user's choice
# History:
# 2015/07/16 VBird First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
read -p "Please input (Y/N): " yn
[ "${yn}" == "Y" -o "${yn}" == "y" ] && echo "OK, continue" && exit 0
[ "${yn}" == "N" -o "${yn}" == "n" ] && echo "Oh, interrupt!" && exit 0
echo "I don't know what your choice is" && exit 0
```
由于输入正确 (Yes) 的方法有大小写之分,不论输入大写 Y 或小写 y 都是可以的,此时判断式内就得要有两个判断才行! 由于是任何一个成立即可 (大写或小写的 y) ,所以这里使用 -o (或) 链接两个判断喔! 很有趣吧!利用这个字串判别的方法,我们就可以很轻松的将使用者想要进行的工作分门别类呢! 接下来,我们再来谈一些其他有的没有的东西吧!
### 12.3.3 Shell script 的默认变量($0, $1...)
我们知道指令可以带有选项与参数,例如 ls -la 可以察看包含隐藏文件的所有属性与权限。那么 shell script 能不能在脚本文件名后面带有参数呢?很有趣喔!举例来说,如果你想要重新启动系统的网络,可以这样做:
```
[dmtsai@study ~]$ file /etc/init.d/network
/etc/init.d/network: Bourne-Again shell script, ASCII text executable
# 使用 file 来查询后,系统告知这个文件是个 bash 的可执行 script 喔!
[dmtsai@study ~]$ /etc/init.d/network restart
```
restart 是重新启动的意思,上面的指令可以“重新启动 /etc/init.d/network 这支程序”的意思! 唔!那么如果你在 /etc/init.d/network 后面加上 stop 呢?没错!就可以直接关闭该服务了!这么神奇啊? 没错啊!如果你要依据程序的执行给予一些变量去进行不同的任务时,本章一开始是使用 [read](../Text/index.html#ex_read) 的功能!但 read 功能的问题是你得要手动由键盘输入一些判断式。如果通过指令后面接参数, 那么一个指令就能够处理完毕而不需要手动再次输入一些变量行为!这样下达指令会比较简单方便啦!
script 是怎么达成这个功能的呢?其实 script 针对参数已经有设置好一些变量名称了!对应如下:
```
/path/to/scriptname opt1 opt2 opt3 opt4
$0 $1 $2 $3 $4
```
这样够清楚了吧?执行的脚本文件名为 $0 这个变量,第一个接的参数就是 $1 啊~ 所以,只要我们在 script 里面善用 $1 的话,就可以很简单的立即下达某些指令功能了!除了这些数字的变量之外, 我们还有一些较为特殊的变量可以在 script 内使用来调用这些参数喔!
* $# :代表后接的参数“个数”,以上表为例这里显示为“ 4 ”;
* $@ :代表“ "$1" "$2" "$3" "$4" ”之意,每个变量是独立的(用双引号括起来);
* $* :代表“ "$1<u>c</u>$2<u>c</u>$3<u>c</u>$4" ”,其中 <u>c</u> 为分隔字符,默认为空白键, 所以本例中代表“ "$1 $2 $3 $4" ”之意。
那个 $@ 与 $* 基本上还是有所不同啦!不过,一般使用情况下可以直接记忆 $@ 即可! 好了,来做个例子吧~假设我要执行一个可以携带参数的 script ,执行该脚本后屏幕会显示如下的数据:
* 程序的文件名为何?
* 共有几个参数?
* 若参数的个数小于 2 则告知使用者参数数量太少
* 全部的参数内容为何?
* 第一个参数为何?
* 第二个参数为何
```
[dmtsai@study bin]$ vim how_paras.sh
#!/bin/bash
# Program:
# Program shows the script name, parameters...
# History:
# 2015/07/16 VBird First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
echo "The script name is ==> ${0}"
echo "Total parameter number is ==> $#"
[ "$#" -lt 2 ] && echo "The number of parameter is less than 2\. Stop here." && exit 0
echo "Your whole parameter is ==> '$@'"
echo "The 1st parameter ==> ${1}"
echo "The 2nd parameter ==> ${2}"
```
执行结果如下:
```
[dmtsai@study bin]$ sh how_paras.sh theone haha quot
The script name is ==> how_paras.sh <==文件名
Total parameter number is ==> 3 <==果然有三个参数
Your whole parameter is ==> 'theone haha quot' <==参数的内容全部
The 1st parameter ==> theone <==第一个参数
The 2nd parameter ==> haha <==第二个参数
```
* shift:造成参数变量号码偏移
除此之外,脚本后面所接的变量是否能够进行偏移 (shift) 呢?什么是偏移啊?我们直接以下面的范例来说明好了, 用范例说明比较好解释!我们将 how_paras.sh 的内容稍作变化一下,用来显示每次偏移后参数的变化情况:
```
[dmtsai@study bin]$ vim shift_paras.sh
#!/bin/bash
# Program:
# Program shows the effect of shift function.
# History:
# 2009/02/17 VBird First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
echo "Total parameter number is ==> $#"
echo "Your whole parameter is ==> '$@'"
shift # 进行第一次“一个变量的 shift ”
echo "Total parameter number is ==> $#"
echo "Your whole parameter is ==> '$@'"
shift 3 # 进行第二次“三个变量的 shift ”
echo "Total parameter number is ==> $#"
echo "Your whole parameter is ==> '$@'"
```
这玩意的执行成果如下:
```
[dmtsai@study bin]$ sh shift_paras.sh one two three four five six <==给予六个参数
Total parameter number is ==> 6 <==最原始的参数变量情况
Your whole parameter is ==> 'one two three four five six'
Total parameter number is ==> 5 <==第一次偏移,看下面发现第一个 one 不见了
Your whole parameter is ==> 'two three four five six'
Total parameter number is ==> 2 <==第二次偏移掉三个,two three four 不见了
Your whole parameter is ==> 'five six'
```
光看结果你就可以知道啦,那个 shift 会移动变量,而且 shift 后面可以接数字,代表拿掉最前面的几个参数的意思。 上面的执行结果中,第一次进行 shift 后他的显示情况是“ one two three four five six”,所以就剩下五个啦!第二次直接拿掉三个,就变成“ two three four five six ”啦! 这样这个案例可以了解了吗?理解了 shift 的功能了吗?
上面这几个例子都很简单吧?几乎都是利用 bash 的相关功能而已~ 不难啦~下面我们就要使用条件判断式来进行一些分别功能的设置了,好好瞧一瞧先~
- 鸟哥的Linux私房菜:基础学习篇 第四版
- 目录及概述
- 第零章、计算机概论
- 0.1 电脑:辅助人脑的好工具
- 0.2 个人电脑架构与相关设备元件
- 0.3 数据表示方式
- 0.4 软件程序运行
- 0.5 重点回顾
- 0.6 本章习题
- 0.7 参考资料与延伸阅读
- 第一章、Linux是什么与如何学习
- 1.1 Linux是什么
- 1.2 Torvalds的Linux发展
- 1.3 Linux当前应用的角色
- 1.4 Linux 该如何学习
- 1.5 重点回顾
- 1.6 本章习题
- 1.7 参考资料与延伸阅读
- 第二章、主机规划与磁盘分区
- 2.1 Linux与硬件的搭配
- 2.2 磁盘分区
- 2.3 安装Linux前的规划
- 2.4 重点回顾
- 2.5 本章习题
- 2.6 参考资料与延伸阅读
- 第三章、安装 CentOS7.x
- 3.1 本练习机的规划--尤其是分区参数
- 3.2 开始安装CentOS 7
- 3.3 多重开机安装流程与管理(Option)
- 3.4 重点回顾
- 3.5 本章习题
- 3.6 参考资料与延伸阅读
- 第四章、首次登陆与线上求助
- 4.1 首次登陆系统
- 4.2 文字模式下指令的下达
- 4.3 Linux系统的线上求助man page与info page
- 4.4 超简单文书编辑器: nano
- 4.5 正确的关机方法
- 4.6 重点回顾
- 4.7 本章习题
- 4.8 参考资料与延伸阅读
- 第五章、Linux 的文件权限与目录配置
- 5.1 使用者与群组
- 5.2 Linux 文件权限概念
- 5.3 Linux目录配置
- 5.4 重点回顾
- 5.5 本章练习
- 5.6 参考资料与延伸阅读
- 第六章、Linux 文件与目录管理
- 6.1 目录与路径
- 6.2 文件与目录管理
- 6.3 文件内容查阅
- 6.4 文件与目录的默认权限与隐藏权限
- 6.5 指令与文件的搜寻
- 6.6 极重要的复习!权限与指令间的关系
- 6.7 重点回顾
- 6.8 本章习题:
- 6.9 参考资料与延伸阅读
- 第七章、Linux 磁盘与文件系统管理
- 7.1 认识 Linux 文件系统
- 7.2 文件系统的简单操作
- 7.3 磁盘的分区、格式化、检验与挂载
- 7.4 设置开机挂载
- 7.5 内存交换空间(swap)之创建
- 7.6 文件系统的特殊观察与操作
- 7.7 重点回顾
- 7.8 本章习题 - 第一题一定要做
- 7.9 参考资料与延伸阅读
- 第八章、文件与文件系统的压缩,打包与备份
- 8.1 压缩文件的用途与技术
- 8.2 Linux 系统常见的压缩指令
- 8.3 打包指令: tar
- 8.4 XFS 文件系统的备份与还原
- 8.5 光盘写入工具
- 8.6 其他常见的压缩与备份工具
- 8.7 重点回顾
- 8.8 本章习题
- 8.9 参考资料与延伸阅读
- 第九章、vim 程序编辑器
- 9.1 vi 与 vim
- 9.2 vi 的使用
- 9.3 vim 的额外功能
- 9.4 其他 vim 使用注意事项
- 9.5 重点回顾
- 9.6 本章练习
- 9.7 参考资料与延伸阅读
- 第十章、认识与学习BASH
- 10.1 认识 BASH 这个 Shell
- 10.2 Shell 的变量功能
- 10.3 命令别名与历史命令
- 10.4 Bash Shell 的操作环境:
- 10.5 数据流重导向
- 10.6 管线命令 (pipe)
- 10.7 重点回顾
- 10.8 本章习题
- 10.9 参考资料与延伸阅读
- 第十一章、正则表达式与文件格式化处理
- 11.1 开始之前:什么是正则表达式
- 11.2 基础正则表达式
- 11.3 延伸正则表达式
- 11.4 文件的格式化与相关处理
- 11.5 重点回顾
- 11.6 本章习题
- 11.7 参考资料与延伸阅读
- 第十二章、学习 Shell Scripts
- 12.1 什么是 Shell scripts
- 12.2 简单的 shell script 练习
- 12.3 善用判断式
- 12.4 条件判断式
- 12.5 循环 (loop)
- 12.6 shell script 的追踪与 debug
- 12.7 重点回顾
- 12.8 本章习题
- 第十三章、Linux 帐号管理与 ACL 权限设置
- 13.1 Linux 的帐号与群组
- 13.2 帐号管理
- 13.3 主机的细部权限规划:ACL 的使用
- 13.4 使用者身份切换
- 13.5 使用者的特殊 shell 与 PAM 模块
- 13.6 Linux 主机上的使用者讯息传递
- 13.7 CentOS 7 环境下大量创建帐号的方法
- 13.8 重点回顾
- 13.9 本章习题
- 13.10 参考资料与延伸阅读
- 第十四章、磁盘配额(Quota)与进阶文件系统管理
- 14.1 磁盘配额 (Quota) 的应用与实作
- 14.2 软件磁盘阵列 (Software RAID)
- 14.3 逻辑卷轴管理员 (Logical Volume Manager)
- 14.4 重点回顾
- 14.5 本章习题
- 14.6 参考资料与延伸阅读
- 第十五章、例行性工作调度(crontab)
- 15.1 什么是例行性工作调度
- 15.2 仅执行一次的工作调度
- 15.3 循环执行的例行性工作调度
- 15.4 可唤醒停机期间的工作任务
- 15.5 重点回顾
- 15.6 本章习题
- 第十六章、程序管理与 SELinux 初探
- 16.1 什么是程序 (process)
- 16.2 工作管理 (job control)
- 16.3 程序管理
- 16.4 特殊文件与程序
- 16.5 SELinux 初探
- 16.6 重点回顾
- 16.7 本章习题
- 16.8 参考资料与延伸阅读
- 第十七章、认识系统服务 (daemons)
- 17.1 什么是 daemon 与服务 (service)
- 17.2 通过 systemctl 管理服务
- 17.3 systemctl 针对 service 类型的配置文件
- 17.4 systemctl 针对 timer 的配置文件
- 17.5 CentOS 7.x 默认启动的服务简易说明
- 17.6 重点回顾
- 17.7 本章习题
- 17.8 参考资料与延伸阅读
- 第十八章、认识与分析登录文件
- 18.1 什么是登录文件
- 18.2 rsyslog.service :记录登录文件的服务
- 18.3 登录文件的轮替(logrotate)
- 18.4 systemd-journald.service 简介
- 18.5 分析登录文件
- 18.6 重点回顾
- 18.7 本章习题
- 18.8 参考资料与延伸阅读
- 第十九章、开机流程、模块管理与 Loader
- 19.1 Linux 的开机流程分析
- 19.2 核心与核心模块
- 19.3 Boot Loader: Grub2
- 19.4 开机过程的问题解决
- 19.5 重点回顾
- 19.6 本章习题
- 19.7 参考资料与延伸阅读
- 第二十章、基础系统设置与备份策略
- 20.1 系统基本设置
- 20.2 服务器硬件数据的收集
- 20.3 备份要点
- 20.4 备份的种类、频率与工具的选择
- 20.5 鸟哥的备份策略
- 20.6 灾难复原的考虑
- 20.7 重点回顾
- 20.8 本章习题
- 20.9 参考资料与延伸阅读
- 第二十一章、软件安装:源代码与 Tarball
- 20.1 开放源码的软件安装与升级简介
- 21.2 使用传统程序语言进行编译的简单范例
- 21.3 用 make 进行宏编译
- 21.4 Tarball 的管理与建议
- 21.5 函数库管理
- 21.6 检验软件正确性
- 21.7 重点回顾
- 21.8 本章习题
- 21.9 参考资料与延伸阅读
- 第二十二章、软件安装 RPM, SRPM 与 YUM
- 22.1 软件管理员简介
- 22.2 RPM 软件管理程序: rpm
- 22.3 YUM 线上升级机制
- 22.4 SRPM 的使用 : rpmbuild (Optional)
- 22.5 重点回顾
- 22.6 本章习题
- 22.7 参考资料与延伸阅读
- 第二十三章、X Window 设置介绍
- 23.1 什么是 X Window System
- 23.2 X Server 配置文件解析与设置
- 23.3 显卡驱动程序安装范例
- 23.4 重点回顾
- 23.5 本章习题
- 23.6 参考资料与延伸阅读
- 第二十四章、Linux 核心编译与管理
- 24.1 编译前的任务:认识核心与取得核心源代码
- 24.2 核心编译的前处理与核心功能选择
- 24.3 核心的编译与安装
- 24.4 额外(单一)核心模块编译
- 24.5 以最新核心版本编译 CentOS 7.x 的核心
- 24.6 重点回顾
- 24.7 本章习题
- 24.8 参考资料与延伸阅读