logo资料库

how linux works 精通linux 中文版 第二版 非影.docx

第1页 / 共159页
第2页 / 共159页
第3页 / 共159页
第4页 / 共159页
第5页 / 共159页
第6页 / 共159页
第7页 / 共159页
第8页 / 共159页
资料共159页,剩余部分请下载后查看
第一章 概述
1.1 Linux 操作系统中的抽象级别和层次
图例 1-1 Linux系统的基本组成
1.2 硬件系统:理解主内存
1.3 内核
1.3.1 进程管理
1.3.2 内存管理
1.4 用户空间
1.5 用户
1.6 前瞻
第二章 基础命令和目录结构
2.1 The Bourne Shell: /bin/sh
2.2 使用Shell
2.2.1 Shell窗口
2.2.2 cat命令
2.2.3 标准输入输出
2.3 基本命令
2.3.1 ls
2.3.2 cp
2.3.3 mv
2.3.4 touch
2.3.5 rm
2.3.6 echo
2.4 浏览目录
2.4.1 cd
2.4.2 mkdir
2.4.3 rmdir
2.4.4 Shell基于通配符的模式匹配 (Shell Globbing/Wildcasts)
2.5 中间指令(Intermediate Commands)
2.5.1 grep
2.5.2 less
2.5.3 pwd
2.5.4 diff
2.5.5 file
2.5.6 find and locate
2.5.7 head 和 tail
2.5.8 sort
2.6 更改密码和Shell
2.7 配置文件(Dot Files)
2.8 环境变量和Shell变量
2.9 命令路径
2.10 特殊字符
2.11 命令行编辑
2.12 文本编辑器
2.13 在线帮助
2.14 Shell输入和输出
2.14.1 标准错误输出
2.14.2 标准输入重定向
2.15 了解错误信息
2.15.1 解析Unix中的错误信息
2.15.2 常见错误
2.16 Listing and Manipulating Processes
2.16.1 命令选项
2.16.2 终止(杀死)进程
2.16.3 工作调度(Job Control)
2.16.4 后台进程
2.17 文件模式和权限
2.17.1 更改文件权限
2.17.2 符号连接(Symbolic Links)
2.17.3 创建符号链接
2.18 归档和压缩文件
2.18.1 gzip
2.18.2 tar
解压缩
内容预览表模式
2.18.3 压缩归档文件
2.18.4 zcat
2.18.5 其他的压缩命令
2.19 Linux目录结构基础
2.19.1 根目录下的其他目录
2.19.2 /usr目录
2.19.3 内核目录
2.20 以超级用户的身份运行命令
2.20.1 sudo
2.20.2 /etc/sudoers
2.21 前瞻
第三章 设备管理
3.1 设备文件
3.2 sysfs 设备路径
3.3 dd命令和设备
3.4 设备名总结
3.4.1 硬盘: /dev/sd*
3.4.2 CD和DVD:/dev/sr*
3.4.3 PATA硬盘:/dev/hd*
3.4.4 终端设备:/dev/tty*, /dev/pts/*,和 /dev/tty
3.4.5 串行端口:/dev/ttyS*
3.4.6 并行端口:/dev/lp0和/dev/lp1
3.4.7 音频设备:/dev/snd/*,/dev/dsp,/dev/audio等
3.4.8 创建设备文件
3.5 udev
3.5.1 devtmpfs
3.5.2 udevd操作和配置
3.5.3 udevadm
3.5.4 设备监控
3.6 深入SCSI和Linux内核
3.6.1 USB存储设备和SCSI
3.6.2 SCSI和ATA
3.6.3 通用SCSI设备
3.6.4 访问设备的多种方法
第四章 硬盘和文件系统
4.1 为磁盘设备分区
4.1.1 查看分区表
4.1.2 更改分区表
4.1.3 磁盘和分区的构造
4.1.4 固态硬盘(SSDs)
4.2 文件系统
4.2.1 文件系统类型
4.2.2 创建文件系统
4.2.3 挂载文件系统
4.2.4 文件系统UUID
4.2.5 磁盘缓冲、缓存和文件系统
4.2.6 文件系统挂载选项
4.2.7 重新挂载文件系统
4.2.8 /etc/fstab文件系统表
4.2.9 /etc/fstab的替代者
4.2.10 文件系统容量
4.2.11 检查和修复文件系统
检查ext3和ext4文件系统
最坏的情况
4.2.12 特殊用途的文件系统
4.3 交换空间
4.3.1 使用磁盘分区作为交换空间
4.3.2 使用文件作为交换空间
4.3.3 所需交换空间的大小
4.4 前瞻:磁盘和用户空间
4.5 深入传统文件系统
4.5.1 查看inode细节
4.5.2 在用户空间中使用文件系统
4.5.3 文件系统的发展
第五章 Linux内核的启动
5.1 启动消息
5.2 内核初始化和启动选项
5.3 内核参数
5.4 引导装载程序
5.4.1 引导装载程序任务
5.4.2 引导装载程序概述
5.5 GRUB简介
5.5.1 使用GRUB命令行浏览设备和分区
设备列表
文件导航
5.5.2 GRUB配置信息
回顾Grub.cfg
生成新的配置文件
5.5.3 安装GRUB
在你的系统上安装GRUB
在外部存储设备上安装GRUB
使用UEFI安装GRUB
5.6 UEFI安全启动问题
5.7 链式加载其他操作系统
5.8 启动加载程序细节
5.8.1 MBR启动
5.8.2 UEFI启动
5.8.3 GRUB如何工作
第六章 用户空间的启动
6.1 init介绍
6.2 System V Runlevels
6.3 识别你的init
6.4 systemd
6.4.1 单元(units)和单元类型(unit types)
6.4.2 systemd中的依赖关系
依赖顺序
依赖条件
6.4.3 systemd配置
单元文件
开启单元和[Install]区段
变量(variables)和说明符(specifiers)
6.4.4 systemd操作
6.4.5 在systemd中添加单元
6.4.6 systemd进程追踪和同步
6.4.7 systemd的按需和资源并行启动
使用辅助单元(Auxiliary Units)优化启动
套接字单元和服务实例
实例和移交
6.4.8 systemd的System V兼容性
6.4.9 systemd辅助程序
6.5 Upstart
6.5.1 Upstart初始化过程
6.5.2 Upstart任务
查看任务
任务状态转换
6.5.3 Upstart配置
Service任务: tty1
进程跟踪和Upstart的expect节
6.5.4 Upstart操作
6.5.5 Upstart日志
6.5.6 Upstart Runlevel和System V 兼容性
6.6 System V init
respawn
ctrlaltdel
sysinit
6.6.1 System V init: 启动命令顺序
6.6.2 The System V init Link Farm
启动和停止服务
更改启动顺序
6.6.3 run-parts
6.6.4 控制System V init
6.7 关闭系统
6.8 初始RAM文件系统
6.9 紧急启动和单用户模式
第七章 系统配置:日志,系统时间,批处理任务,和用户
7.1 /etc目录结构
7.2 系统日志
7.2.1 系统日志
7.2.2 配置文件
设施和优先级
扩展语法
排错
日志:过去和未来
7.3 用户管理文件
7.3.1 /etc/passwd文件
7.3.2 特殊用户
7.3.3 /etc/shadow文件
7.3.4 用户和密码管理
7.3.5 用户组
7.4 getty和登录
7.5 设置时间
7.5.1 内核时间和时区
7.5.2 网络时间
7.6 使用cron来安排日常任务
7.6.1 安装Crontab文件
7.6.2 系统crontab文件
7.6.3 cron的未来
7.7 使用at为一次性任务安排日程
7.8 了解用户ID和用户切换
7.8.1 进程归属,有效UID,实际UID,和已保存UID
Setuid程序
相关安全性
7.9 用户标识(identification)和认证(authentication)
7.9.1 为用户信息使用库
7.10 PAM
7.10.1 PAM配置
功能类型
控制参数和入栈规则
模块参数
7.10.2 关于PAM的一些注解
7.10.3 PAM和密码
7.11 前瞻
第八章 深入进程和资源配置
8.1 进程跟踪
8.2 使用lsof查看打开的文件
8.2.1 lsof输出
8.2.2 lsof的使用
8.3 跟踪程序执行和系统调用
8.3.1 strace
8.3.2 ltrace
8.4 线程
8.4.1 单线程进程和多线程进程
8.4.2 查看线程
8.5 资源监控简介
8.6 测量CPU时间
8.7 调整进程优先级
8.8 平均负载
8.8.1 uptime的使用
8.8.2 高负载
8.9 内存
8.9.1 内存工作原理
8.9.2 内存页面错误
轻微内存页面错误
严重内存页面错误
查看内存页面错误
8.10 使用vmstat监控CPU和内存性能
8.11 I/O监控
8.11.1 使用iostat
8.11.2 使用iotop查看进程的I/O使用和监控
8.12 使用pidstat监控进程
8.13 更深入的主题
精通 Linux 2 http://www.amazon.com/dp/1593275676/ref=rdr_ext_tmb Review 注意事项: 1. 磁盘?硬盘? 2. 一些术语需要 google 确认 第一章 概述 Linux 这样的现代操作系统乍看起来都非常复杂,其内部有多得令人眼花缭乱的各种组件在同步 运行和相互通讯。比如:一个 Web 服务器可以联接到一个数据库服务器,他们之间可能使用了一 个很多其他程序也在使用的公共组件。这一切究竟是如何工作的? 理解一个操作系统的工作原理最好的方法是“抽象思维”,你可以暂时忽略大部分细节。就像坐车 一样,通常你不会去在意车内固定发动机的装配螺栓,也不会关心你正在经过的那条路是谁修筑 的。如果你是一个乘客的话,你可能只关心车要去哪、如何打开车门、怎样系好安全带。 但如果你在驾驶一辆汽车,你就需要了解更多的细节,比如:如何控制油门,怎样换挡,还有如 何处理意外情况。 如果我们觉得开车这个过程太复杂,就可以运用“抽象思维”来帮助理解。首先你可以将“一辆汽车 在路上行驶”抽象为三个部分:汽车,道路,以及你的驾驶操作。这样有助于将复杂的问题分解开 来。如果道路颠簸,你不会去埋怨车辆本身和你的驾驶技术。相反,你可能会想为什么这条路这 么烂,或者如果这是条新修的路的话,筑路工人的活干得可真够差劲的。 软件开发人员运用抽象思维来开发操作系统和应用程序。在计算机领域,我们用很多术语来描述 一个抽象的子系统,如:“子系统”,“模块”,和“包”。本书中我们使用“组件”这个相对简单的词。 在软件开发过程中,开发人员通常不太考虑他们需要使用的组件的内部结构,他们只关心能使用 哪些组件?怎么个用法? 本章概述了 Linux 操作系统涉及的主要组件。虽然每一个组件包含纷繁复杂的技术细节,我们将 暂时忽略这些细节,而专注于这些组件在系统中发挥的功能。 1.1 Linux 操作系统中的抽象级别和层次 在合理组织的前提下,通过抽象将系统分解为组件有助于了解其工作机制。我们将组件划分为层 (或者级别)。组件的层(或者级别)代表它在用户和硬件系统之间所处的位置。Web 浏览器、游 戏这些应用处于最高层,底层则是计算机硬件系统,如:内存.操作系统处于这两层之间。
Linux 操作系统主要分 3 层。如图 1-1 所示,最底层是硬件系统,包括内存和中央处理器(用于 计算和从内存中读写数据),此外硬盘和网络接口也是硬件系统的一部分。 硬件系统之上是内核,它是操作系统的核心。内核运行在内存中,向中央处理器发送指令。内核 管理硬件系统,是硬件系统和应用程序之间通讯的接口。 计算机中运行的所有进程(确切地说是用户进程,无论用户是否和它们有直接的交互)由内核统 一管理,它们组成了最顶层,称为用户空间。例如:Web 服务器就是以用户进程的形式运行的。 图例1-1 Linux 系统的基本组成 内核和用户进程之间最主要的区别是:内核运行在内核模式中,而用户进程运行在用户模式中。 在内核模式中运行的代码可以不受限地访问中央处理器和内存,这种模式功能强大,但也非常危
险,因为内核进程可以轻而易举地使整个系统崩溃。那些只有内核可以访问的空间我们称为内核 空间。 相对于内核模式,用户模式对内存和中央处理器有一定限度的访问权限,权限通常不是很大。用 户空间是那些用户进程能够访问的内存空间。如果一个用户进程出错并且崩溃的话,其导致的后 果也相对有限,并且能够被内核清除。例如:如果你的 Web 浏览器崩溃了,不会影响到你正在运 行的其他程序。 理论上来说,一个用户进程出问题并不会对整个系统造成严重的影响。当然这取决于我们如何定 义“严重的影响”,并且还取决于该进程拥有的权限。因为不同的进程拥有的权限可能不同,一些 进程能够执行一些别的进程无权执行的操作。举个例子,如果拥有足够的权限,用户进程可以将 硬盘上的数据全部清除,也许你会觉得这样太危险。操作系统提供了一些相关的安全措施,不过 大多数用户进程并没有这个权限。 1.2 硬件系统:理解主内存 主内存或许是所有硬件系统中最为重要的部分,主内存存储 0 和 1 这样的数据,我们称每一个 0 和 1 为一个比特(或字位)。内核和进程就在主内存里运行,它们由一系列 0 和 1 组成。所有外 围设备的输入和输出数据都通过主内存,同样是以一系列 0 和 1 的形式。中央处理器像一个操作 员一样处理内存中的数据,它从内存读取指令和数据,然后将运算结果写回到内存。 在我们谈论内存、进程、内核、和其他内容时你会经常看到“状态”这个词。严格说来,一个状态 就是一系列的比特值。例如:内存中 0110,0001 和 1011 三个比特值即表示三个不同的状态。 一个进程动辄由几百万个比特值组成,因而使用抽象词汇来描述状态可能比使用比特值更简单一 些。使用进程已经完成的任务或者当前正在执行的任务,如:“进程正在等待用户输入”或者“进程 正在执行启动任务的第二个阶段”。 注解:因为我们通常使用抽象词汇来描述状态,所以内存映像这个词则用来表示比特值在内存中 的排列。 1.3 内核 我们讨论主内存和状态的原因,是因为内核的几乎所有操作都和主内存相关。其中之一是将内存 划分为很多区块,并且始终保存这些区块的状态信息。每一个进程拥有自己的内存区块,内核必 须确保每个进程只使用它自己的那部分内存区块。 内核负责管理以下四个方面: 进程 - 内核决定哪个进程可以使用 CPU。
内存 - 内核管理所有的内存,哪一部分内存分配给了哪一个进程,哪些内存被多个进程共享, 哪些内存未被使用。 设备驱动程序 - 作为硬件系统和进程之间的接口,内核负责操控硬件设备。 系统调用和支持 - 进程通常使用系统调用和内核进行通讯。 下面我们详细介绍这四个方面。 注解:如果你对内核的详细工作原理感兴趣,可以参考《Operating System Concepts》, 9th edition, by Abraham Silberschalz, Peter B. Galvin, and Greg Gagne, Wiley, 2012 和《Moden Operating Systems》, 4th edition, by Andrew S. Tanenbaum and Herbert Bos, Prentice Hall, 2014 1.3.1 进程管理 进程管理涉及进程的启动,暂停,恢复和终止。启动和终止进程比较直观,但是要解释清楚进程 在执行过程中如何使用 CPU 则相对复杂一些。 在现代操作系统中,进程都是同步执行的。例如:你可以同时在桌面打开 Web 浏览器和电子表格 应用程序。虽然看上去是如此,实际上这些应用程序后面的进程并不是同步运行的。 我们设想一下在只有一个 CPU 的计算机系统中,可能会有很多进程使用该 CPU,但是在任何一 个特定的时间段内只能有一个进程可以使用该 CPU。所以实际上是多个进程轮流使用 CPU,每 个进程使用一段时间后就暂停,然后让另一个进程使用(通常是毫秒极),依次轮流。一个进程 让出 CPU 使用权给另一个进程的过程称为上下文切换。 进程在一个时间段内有足够的时间完成其主要的计算工作,通常进程在第一个时间段内就能完成 它当前的工作。由于时间段非常短,以至于我们根本察觉不到,所以在我们看来系统是在同时运 行多个进程。 内核负责上下文切换,我们来看一下下面的场景,以便理解它的工作原理: 1. CPU 为每个进程计时,到时即停止当前的进程,并切换至内核模式,由内核接管 CPU 控制 权。 2. 内核记录下当前 CPU 和内存的状态信息,这些信息在恢复当前被停止的进程时需要用到。 3. 内核执行上一个时间段内需要执行的任务。如:从输入输出设备获得数据,磁盘读写操作 等)。 4. 内核准备就绪可以执行下一个进程。内核从就绪进程列表中选择一个进程执行。 5. 内核为新进程准备 CPU 和内存。 6. 内核将新进程执行的时间段通知 CPU。 7. 内核将 CPU 切换至用户模式,将 CPU 控制权移交给新进程。
从以上步骤我们可以看出,内核是在进程的时间段间隙,上下文切换的时候运行的。 在多 CPU 系统中,情况要稍微复杂一些。如果新进程将在另一个 CPU 上运行,内核就不需要让 出当前 CPU 的使用权。不过为了最大化所有 CPU 的使用效率,内核会使用一些其他的方式来获 取 CPU 控制权。 1.3.2 内存管理 内核在上下文切换过程中管理内存,这个过程十分复杂,因为内核要保证以下所有条件: ● 内核需要自己的专有内存空间,其他的用户进程无法访问。 ● 每个用户进程有自己的专有内存空间。 ● 一个进程不能访问另一个进程的专有内存空间。 ● 用户进程之间可以共享内存。 ● 用户进程的某些内存空间可以是只读的。 ● 通过使用磁盘交换,系统可以使用比实际内存容量更多的“内存”空间。 新型的 CPU 提供了内存管理工具(MMU),MMU 使用了一种内存访问机制叫虚拟内存(virtual memory),即进程不是直接访问内存的实际物理地址,而是通过内核为进程设置好内存,使得进 程看起来可以使用整个系统的内存。当进程访问内存的时候,MMU 截获访问请求,然后通过内 存映射表将要访问的内存地址转换为实际的物理地址。内核不断初始化、维护和更新这个地址映 射表。例如:在上下文切换时,内核将内存映射表从移出进程转给移入进程使用。 注解:内存地址映射表通过页面表(page table)来实现。 关于内存性能,我们将在第 8 章详细介绍。 除了传统的系统调用,内核还为用户进程提供其他很多功能,最为常见的是:虚拟设备。虚拟设 备对于用户进程而言是物理设备,但是其实它们都是通过软件实现的。因此从技术角度来说,它 们并不需要存在于内核中,但是实际上它们很多 都存在于内核中。例如:内核的随机数生成器(/dev/random)这样的虚拟设备,如果由用户进程来 实现难度要大很多。 1.4 用户空间 前面提到过,内核分配给用户进程的内存我们称为用户空间。因为一个进程简单说就是内存中的 一个状态。用户空间也可以指所有用户进程占用的所有内存。(userland) Linux 中大部分的操作都发生在用户空间中。虽然所有进程从内核的角度都是一样的,但是实际 上它们执行的是不同的任务。相对于系统组件,用户进程存在于一个基础服务层中。图例 1-3,
最底层是基础服务层,工具服务在中间,用户使用的应用程序在最上层。图例 1-3 是一个简化版 本,你可以看到顶层距离用户最近(如:用户接口和 Web 浏览器)。中间一层中有邮件服务器这 样的组件,供 Web 浏览器使用。最下层的是一些更小的服务组件。 最下层通常是由一些小的组件组成,它们比较精巧,专注完成某一个特定功能。中间层的组件比 较大一些,如:邮件,打印和数据库服务。顶层组件完成用户交互和复杂的功能。组件之间也可 以相互调用。如果组件 A 调用了组件 B 的功能,我们可以视为组件 AB 在同一层级,或者 B 的层 级在 A 之下。 图示 1-3 只是一个粗略图,实际上用户空间里没有很明显的界限。例如:许多的应用程序和服务 会将系统调试信息写入日志,大部分程序使用标准的 syslog 服务来完成,但也有一些程序是自己 实现日志功能。 此外,很多用户空间组件比较难分类,象 Web 服务器和数据库服务器这样的服务组件你可以认为 它们是高级别组件,因为它们复杂度很高。然而,用户应用程序也会经常调用它们的功能,所以 你也可以将它们归入中级别组件。 1.5 用户 Linux 内核支持用户这一 Unix 的传统概念。一个用户代表一个实体,它有权限运行用户进程,对 文件拥有所有权。每个用户都有一个用户名,如:billyjoe。然而内核是通过用户 ID 来管理用户 的,用户 ID 是一串数字标识。(详见第 7 章) 用户机制主要用于权限管理。每一个用户进程都有一个用户作为所有者,我们称其为以该用户运 行的进程。在特定限制条件下,用户可以终止和改变他拥有的进程的行为。但是对其他用户的进 程无权干预。此外,用户可以决定是否将属于自己的文件和其他用户共享。 Linux 操作系统的用户包括系统自带用户和真实用户。详情见第 3 章。其中最关键的用户是 root。root 用户不受前面提到的种种权限的限制,它可以终止其他用户的进程,读取系统中的任 何文件。因此 root 也被称作超级用户。通常 Unix 的系统管理员拥有超级用户权限。 注解:使用 root 权限进行操作是一件很危险的事情,因为用户拥有最高权限,身份难以识别,如 果出错很难恢复。因此,系统设计者通常尽量避免使用 root 权限。而且,root 用户虽然权限很 高,但是还是运行在用户模式中,而非内核模式。 1.6 前瞻 到目前为止你对 Linux 系统的组成应该有了一个大致的了解。用户和用户进程交互,内核管理进 程和硬件系统。内核和进程都在内存中运行。
有了这些基础知识,如果想要了解更多的细节,你需要做一些实际的操作。下一章你会了解到一 些用户空间的基础知识,还有本章没有提及的永久存储(硬盘,文件等),就是存放应用程序和 数据的地方。
第二章 基础命令和目录结构 本章介绍了 Unix 系统的命令和工具,它们在整本书中经常会被使用到。也许你已经对这些基本知 识有所了解,不过我还是建议你花一些时间再浏览一遍,特别是 2.19 节关于目录结构部分。 你也许会问,为什么要介绍 Unix 命令?这本书不是有关 Linxu 的吗?一点没错,Linux 其实是 Unix 的一个变种,它的本质还是 Unix。Unix 这个词在本章中出现的频率甚至高于 Linux,并且你 可以将本章的知识直接应用到其他基于 Unix 的操作系统,如:Solaris 和 BSD。我们尽量再本章 避免介绍过多的只针对 Linux 的内容,一方面可以让你多了解一些其他基于的 Unix 系统,另一方 面也因为那些只针对 Linux 适用的扩展功能往往不太稳定。解了核心的通用命令行能够让你更快 地熟悉任何新的基于 Unix 的操作系统。 注解:Unix 初学者可以看这本书 The Linux Command Line (No Starch Press, 2012), UNIX for the Impatient (Addison-Wesley Professional, 1995), 以及 Learning the UNIX Operating System, 5th edition (O'Reilly, 2001)。 2.1 The Bourne Shell: /bin/sh The shell(命令行界面)是 Unix 操作系统中最为重要的部分之一。Shell 是一个应用程序,它运行 命令行,就像用户输入的那些命令。同时它为 Unix 程序员提供了一个编程环境,在这里 Unix 程 序员可以将一些通用的任务分解为一些小的组件,然后使用 shell 来管理和组织它们。 Unix 操作系统中很多重要的部分其实是 shell script(命令行脚本),它们是包含了一系列 shell 命令 的文本文件。如果你曾经使用过 MS-DOS,你可以将 shell script 理解为功能很强大的.bat 批处理 文件。我们将在第 11 章全面详细地介绍命令行脚本。 在你阅读这本书并且不断练习的过程中,你将会越来越熟练地使用命令行界面运行各种命令。它 的优点之一是,一旦你出现了误操作,你能够很容易地知道哪里出错了,然后改正。 命令行界面有很多种,但是它们都是基于 Bourne shell(/bin/sh),它是在贝尔实验室开发的标准命 令行界面,运行在早期的 Unix 系统上。所有基于 Unix 的操作系统都需要 Bourne shell。 Linux 使用了一个增强版本的 Bourne shell,我们叫做 bash 或者 Bourne-again shell。Bash 是大 部分 Linux 系统的默认 shell,通常/bin/sh 链接到 bash。你可以使用 bash 来运行本书的实例。 注解:你的 Unix 系统管理员为你设置帐号的时候,可能默认的 shell 并不是 bash,你可以请他为 你更改默认 shell。
分享到:
收藏