跳转至

鸟哥的Linux私房菜(基础篇)

第0章 计算机概论

0.1 电脑

  • 电脑的硬件组成部分
    • 输入单元:包括键盘、鼠标、读卡器、扫描仪、手写板、触控屏幕等;
    • 主机部分:这个就是系统单元,被主机机箱保护着,里面含有一堆班子、CPU与内存等;
    • 输出单元:例如屏幕、打印机等。
  • CPU组成:算术逻辑单元、控制单元。
  • 电脑组成:输入单元、输出单元、CPU(控制单元、算术逻辑单元)与内存。


电脑组成

电脑组成图

0.2 CPU架构

  • 目前最常见的两种CPU架构

    1. 精简指令集(RISC)
    2. 复杂指令集(CISC)
  • “x86架构”名称的由来 > > - 这是因为最早的那块Inter研发出来的CPU代号为8086,后来依次又开发出了80286、80386等,因此这种架构的CPU又被称为x86架构了。 > - 后俩由于x86架构CPU由8位一直升级到新一代的64位,为了区别差异,因此称64位的个人电脑为x86-64架构。

  • 不同x86架构的CPU又什么差异? > 除了CPu的整体结构(如二级缓存、命令执行周期数等)之外,主要是在于指令集的不同。

0.3电脑上常用的计算单位(容量、速度)

  • 容量单元

    • 1字节 = 8位
    • 一般来说,数据容量使用的是二进制方式,而速度单则常使用十进制
      进制位KiloMegaGigaTeraPetaExaZetta
      二进制1024B1024K1024M1024G1024T1024P1024E
      十进制1000B1000K1000M1000G1000T1000P1000E
  • 速度单位

    • 网络传输使用的单位一般位每秒多少位,比如:10 Mbit/s
    • 我们常常见到的“20M/5M“指的是:下载2.5MB/上传625KB
  • 为什么购买了一块500GB的硬盘,但是格式化完毕后却只剩下460GB左右的容量? > 因为一般硬盘制造商会使用十进制的单位,所以500GB代表为 500*1000*1000*100*字节。转成数据的容量单位时使用二进制(1024为基数),所以就称为了466GB左右的容量了。

0.4 个人电脑架构与相关设备组件

  • 北桥 > 负责连接速度较快的CPU、内存与显卡等组件。
  • 南侨: > 负责连接速度较慢的设备接口,包括硬盘、USB设备、网卡等。

  • CPU工作频率

    • 外频 > CPU与外部组件进行数据传输时的速度。
    • 倍频 > CPU内部用来加速工作性能的一个倍数。
    • 工作频率 = 外频 * 倍频
  • 超线程(Hyper-Threading, HT)

    • 原理 > 将寄存器分成两组,并让程序分别使用两组寄存器

0.4.1 内存

  • 多通道设计:通过将多块内存拼接到一块使用,来达到增大位宽的效果

0.4.2 显卡

  • 显存:显卡又称为VGA(Video Graphics Array),存储颜色等。

  • 如果你的主机是用来玩3D游戏的,那么显卡选购很重要。如果你的主机是用来做网络服务器的,那么入门级显卡已经足够。

  • 常见的主要接口:

    • D-Sub(VGA接口) > 为模拟信号的传输所是使用.
    • DVI > 共有四种以上的接口,不过市面上比较常见的仅为提供数字信号的DVI-D,以及整合数字与模拟信号的DVI-I两种。DVI常见与液晶屏幕的连接,标准规格主要有:1920x1200px @60HZ2560x1600px @60Hz
    • HDMI > 可以传输影像与声音,因此被广泛用于电视屏幕中,电脑屏幕目前也常常有支持HDMI格式的.
    • DisplayPort(DP) > 可以传输影像与声音。

0.5 硬盘与存储设备

  • 碟片

    Hard Drive

    碟片组成示意图

    • 术语
      • 扇区:磁盘的最小物理存储单位。
      • 磁道:同一个同心圆的扇区组成的圆。
      • 柱面:所有碟片上面的同一个磁道的组合。
    • 由于外圈的扇区更多,因此单圈能读写的数据也较多,所以通常数据的读写都会由外圈开始往内写,这是默认方式。
  • 传输接口

    • 常见接口
      • 传统磁盘接口:SATA、SAS、IDE与SCSI等。
      • 外接磁盘:USB、eSATA等。
    • SATA接口
      • Serial Advanced Technology Attachment
    • SAS接口
      • Serial Attached SCSI
    • USB接口
      • Universal Serial Bus
  • 固态硬盘(Solid State Disk,SSD)

    • 机械硬盘:Hard Disk Drive(HDD)
    • 选购与使用须知
      • 选购须知
        • HDD或SSD > SSD作为系统盘,然后数据存储在HDD上。
        • 缓冲存储器(缓存) > 硬盘上面含有一个缓冲存储器,这个内存主要可以将硬盘内常使用的数据缓存起来,以加速系统的读写性能。通常这个缓冲存储器越大越好。
        • 转速 > 如果对高性能的数据存取有要求,那就越高越好。
      • 使用须知 > 由于硬盘内部机械手臂的磁头与碟片的接触是很细微的空间,如果有抖动或是污物附着在磁头与碟片之间就会造成数据的损坏或是物理硬盘整个损坏,因此,正确使用电脑的方式,应该是在电脑通电之后,就绝对不要移动主机,避免震动硬盘,而导致整个硬盘数据发生问题。另外,也不要随便将插头拔掉就以为是顺利关机。因为机械手臂必须要回归原位,所以使用操作系统的正常关机方式,才能够比较好地保护硬盘,因为它会让硬盘的机械手臂回归原位。
  • 选购须知 > NULL

0.6 参考资料与扩展阅读


第1章 Linux是什么与如何学习

操作系统的橘色

操作系统的角色

操作系统的角色图

概念

  • 软件移植 > > - 由于不同的硬件,它的功能函数并不相同,所以同一个操作系统是无法在不同硬件平台上面运行的。如果能够参考硬件的功能函数并以此修改你的操作系统程序代码,那经过改版后的操作系统就能够在另一个硬件平台上运行,这个过程我们称为“软件移植”。 > - Windows操作系统本来就是针对x86硬件架构进行的设计,所以它当然只能在x86的计算机上运行,在不同的硬件架构平台当然就无法运行。也就是说,每种操作系统都是在它们专门的硬件架构上面运行的,这带你得先了解。不过,Linux由于是开源的操作系统,所以它的程序代码可以被 修改成适合在各种硬件架构上面运行,也就是说,Linux是具有“可移植性”。

  • Unix历史

    1. 1969年以前:一个伟大的梦想——Bell,MIT与GE的“Multics”系统
    2. 1969年:Ken Thompson的小型file server system
    3. 1973年:UNIX的正式诞生,Richie等人用C语言写出第一个正式UNIX内核
    4. 1977年:重要的UNIX分之——BSD的诞生
    5. 1979年:重要的System V架构与版权声明
    6. 1984年之一:x86架构的Minix操作系统开始编写并于两年后诞生
    7. 1984年之二:GNU计划与FSF基金会的成立
  • Linux的内核版本 > 3.10.0-862.el7.x86_64

    • 奇数、偶数版本分类 > 在2.6x版本以前,托瓦兹将内核的发展方向分为两类,并根据这两类内核的发展分别给予不同的内核版编号: > > - 主、次版本为基数:开发中版本(development) > - 主、次版本为偶数:稳定版本(stable)

    • 主线版本、长期维护版本(longterm version) > 不过这种奇数、偶数的编号格式在3.0版退出之后就不再使用了。从3.0版开始,内核主要一句主线版本(MainLine)来开发,开发完毕后会往下一个主线版本进行。 > 而旧的版本在心的主线版本出现之后,会有两种机制来处理。一种机制为结束开发(End of Live,EOL)亦即改程序代码已经结束,不会有继续维护的状态。另一种机制为保持改版本的持续维护,亦即为长期维护版本(Longterm) > 所以,如果你想使用Linux内核来开发你的系统,那么当然要选择长期支持的版本才行。要判断你的Linux内核是否为长期支持的版本,可以使用“uname -r”来查看内核版本,然后对照下列连接来了解其对应值: > > - https://www.kernel.org/releases.html

  • Linux开发标准

如何学习Linux

  1. 从头学习Linux基础
    1. 计算机概论与硬件相关知识
    2. 先从Linux的安装与命令学起
    3. Linux操作系统的基础技能
    4. 无比学会vi文本编辑器
    5. Shell与Shell脚本的学习
    6. 一定要会软件管理(比如:Tarball, RPM, DPKG, YUM, APT等)
    7. 网络基础的建立
    8. 搭建网站:如果连网络基础都通过了,那么网站的搭建对你来说,简直就是“太简单”。
    9. 扩展
  2. 选择一本易读的工具书
  3. 实践再实践 实践经验分享网站Study-Area(http://www.study-area.org)
  4. 发生问题的处理方法
    1. 在自己的主机/网络资料库上查询HowTo或FAAQ
    2. 注意信息输出,自行解决疑难杂症
      • 如果是网络服务的问题,请到/var/log这个目录里面去查看一下log file(日志文件),这样可以几乎解决大部分问题。
    3. 查找过后,注意网络礼节,讨论区大胆的发言 > 提问前最好阅读一下提问的智慧这篇文章:http://phorum.vbird.org/viewtopic.php?t=96

      • 酷学员讨论区:http://phorum.study-area.org
      • 鸟哥私房菜馆讨论区:http://phorum.vbird.org
        1. Netman大大给的建议
      • 有系统地设计文件目录
      • 养成一个做记录的习惯
      • 如果网络上看到任何好文章,可以为自己留一份备份,同时定好题目,归类存盘(注意知识产权)
      • 作为一个用户,人要迁就机器;作为一个开发者,要机器迁就人。
      • 学写脚本的确没设置服务器那么好玩,不过以我自己的感觉是:关键是会得“偷”,透了会得改,改了会得变,变则通矣。
      • 在Windows里面,设置不好设备,您可以骂它;在Linux里面,如果设置好设备,您得感激它。
      • 鸟哥的建议
        • 学习的原动力:成就感、兴趣。

参考资料与扩展阅读


第2章 主机规划与磁盘分区

各硬件设备在Linux中的文件名

  • 在Linux系统中,每个设备都被当成一个文件来对待。比如STAT接口的硬盘的文件名即为/dev/sd[a-d],其中,括号内的字母为a-d当中的任意一个,亦即有/dev/sda、/dev/sdb、/dev/sdc即/dev/sdd这四个文件的意思。

  • 常见的设备在Linux中的文件名

    设备设备在Linux中的文件名
    SCSI、SATA、USB磁盘驱动器/dev/sd[a-p]
    U盘/dev/sd[a-p](与SATA相同)
    Virtio接口/dev/vd[a-p](用于虚拟机内)
    软盘驱动器/dev/fd[0-7]
    打印机/dev/lp[0-2](25针打印机)
    /dev/usb/lp[0-15](USB接口)
    鼠标/dev/input/mouse[0-15](通用)
    /dev/psaux(PS/2接口)
    /dev/mouse(当前鼠标)
    CD-ROM, DVD-ROM/dev/scd[0-1](通用)
    /dev/sr[0-1](通用,CentOS较常见)
    /dev/cdrom(当前CD-ROM)
    磁带机/dev/ht0(IDE接口)
    /dev/st0(SATA/SCSI接口)
    /dev/tape(当前磁带)
    IDE磁盘驱动器/dev/hd[a-d](旧式系统才有)

    • 时至今日,由于IDE接口的磁盘驱动器几乎已经被淘汰,因此现在连IDE接口的磁盘文件名也被模拟为/dev/sd[a-p]。此外,如果你使用的机器使用的是跟ISP申请的云端机器,这时候可能会得到的是虚拟机,其内部磁盘是模拟器产生的,磁盘文件名可能为/dev/vd[a-p

磁盘分区

正常的物理机器大概使用的都是/dev/sd[a-p]的磁盘文件名,至于虚拟机环境中,为了加速,可能就会使用/dev/vd[a-p]这种设备文件名。

  • 扇区的物理大小设计有两种,分别512字节与4K字节。
  • 所有碟片的同一个磁道我们称为柱面,通常那是文件系统的最小单位,也就是分区的最小单位。

MBR(MS-DOS)磁盘分区表

MBR

MBR磁盘分区表

早起的Linux系统为了兼容Windows的磁盘,因此使用的是支持Windows的MBR的方式来处理启动引导程序与分区表。而启动引导程序记录区与分区表则通通放在第一个扇区,这个扇区是512字节的大小(旧的磁盘扇区都是512字节),所以说第一个扇区的512字节主要会有这两种东西:

  • 主引导记录(MBR):可以安装启动引导程序的地方,有446字节。
  • 分区表(partition table):记录整块硬盘分区的状态,有64字节。
    • 由于分区表所在区块仅有64字节容量,因此最多仅能有四组记录区,每组记录区记录了该区段的起始与结束的柱面号。
    • 这四个分区的记录被称为主要(Primary)扩展(Extended)分区。
  • 我们可以得出

    • 其实所谓的分区只是针对那个64字节的分区表进行设置而已。
    • 硬盘默认的分区表仅能写入四组分区信息。
    • 这四组划分信息我们称为主要或扩展分区。
    • 分区的最小单位通常为柱面。
    • 当系统要写入磁盘时,一定会参考磁盘分区表,才能针对某个分区进行数据的处理。
  • 分区的原因

    1. 数据的安全性 > 因为每个分区的数据是分开的。所以,当你需要将某个分区的数据重新整理时,不会影响到其他分区里的数据。比如:C盘重装系统时,其他盘的数据不会受到影响。
    2. 系统的性能考虑 > 读取数据的时候只会专注于分区范围内的柱面,这样有助于数据读取的速度与性能。
  • 扩展分区

    • 通过扩展分区可以获得更多的分区,其中的每个分区都有对应的一个分区记录EBR,具体可以查看:https://en.wikipedia.org/wiki/Extended_boot_record
    • 目的是使用额外的扇区来记录分区信息,扩展分区本身并不能被拿来格式化。
    • 逻辑分区:由扩展分区切分出来的分区
  • 分区后的设备文件名 > 在磁盘设备后面增加号码,其中,[1-4]四个号码是保留给主分区和逻辑分区使用的,而逻辑分区则由5号开始,比如对sda磁盘分区: > > - P1: /dev/sda1 > - P2: /dev/sda2 > - L1: /dev/sda5 > - L2: /dev/sda6 > > 其中,3、4号不会被逻辑分区使用。

  • MBR主要分区、扩展分区与逻辑分区的特性

    • 主要分区与扩展分区最多可以有4个(硬盘的限制)
    • 扩展分区最多只能有一个(操作系统的限制)
    • 逻辑分区是由扩展分区持续划分出来的分区。
    • 能够被格式化后作为数据存取的分区是主要分区与逻辑分区,扩展分区无法格式化。
    • 逻辑分区的数量依操作系统而不同,在Linux系统中SATA硬盘已经可以突破63个以上的分区限制。
  • 问题 > 由于每组分区表仅有16字节而已,因此可记录的信息相当有限,因此常常会有如下问题: > - 操作系统无法使用2.2TB以上的磁盘容量。 > - MBR仅有一个区块,若被破坏后,经常无法或很难恢复。 > - MBR内的存放启动引导程序的区块仅446字节,无法存储较多的程序代码。

GPT磁盘分区表

GPT

GPT磁盘分区表


  • 因为过去一个扇区大小就是512字节,不过目前已经有4K的扇区出现了。为了兼容所有的磁盘,因此在扇区的定义上面,大多会使用所谓的逻辑区块地址(Logical Block Address, LBA)来处理。GPT磁盘所有区块以此LBA(默认为512字节)来规划,而第一个LBA称为LBA0(从0编号开始)。
  • 与MBR仅使用第一个512字节区块来记录不同,GPT使用了34个LBA区块来记录分区信息。同时与过去MBR仅有一个区块被干掉就死光光的情况不同,GPT除了前面34个LBA之外,整个磁盘的最后34个LBA也拿来作为另一个备份。
  • 图例解释

    • LBA0(MBR兼容区块)

      • 一部分分446字节,作为存储第一阶段的启动引导程序使用
      • 另一部分64字节,只存放一个特殊标记,用来表示此磁盘为GPT格式,不懂GPT分区表的磁盘管理程序不会认识这块磁盘。
    • LBA1(GPT表头记录) > 记录了分区表本身的位置与大小,同时记录了备份用的GPT分区放置的位置,同时放置了分区表的校验码(CRC32),操作系统可以根据这个校验码来判断GPT是否正确。若有错误可以通过这个记录区来获取备份的GPT来恢复。

    • LBA2-33(GPT实际记录分区信息处) > 从LBA2区块开始,每个LBA都可以记录4组分区记录,所以在默认的情况下,总共可以有:\(4{\times}32=128\) 组分区记录。因为每个LBA都有512字节,因此每组记录用到128字节的空间,除了每组记录所需要的标识符与相关记录之外,GPT在每组记录中分别提供了64位来记录开始/结束的扇区号码,因此GPT分区对于单一分区来说,它的最大容量限制就会在:\(\(2^{64} {\times} 512B = 2^{63} {\times} 1KB = 2^{33} {\times} 1TB = 8ZB\)\)

启动流程中的BIOS与UEFI启动检测程序

BIOS搭配MBR/GPT的启动流程
  • 流程

    1. BIOS:启动时主动执行的固件,会认识第一个可启动的设备。
      • 固件:写入到硬件上的一个软件程序。
    2. MBR:第一个可启动设备的第一个扇区内的主引导记录块、内含启动引导代码。
    3. 启动引导程序(Boot loader):一个可读取内核文件来执行的软件。
    4. 内核文件:开始启动操作系统。

      注意

      • 如果你的分区表为GPT格式的话,那么BIOS也能够从LBA0的MBR兼容区块读取第一阶段的boot loader代码,如果你的boot loader能够支持GPT的话,那么BIOS同样可以读取到正确的操作系统。
      • 由于LBA0仅提供第一阶段的启动引导程序代码,因此如果你使用类似grub的启动引导程序的话,那么就得要额外划分出一个“BIOS boot”的分区,这个分区才能够放置其他开机过程所需的程序,在CentOS当中,这个分区通常占用2MB左右而已。
  • Boot loader的主要任务

    • 提供选项:用户可以选择不同的启动选项,这也是多重引导的重要功能。
    • 加载内核文件:直接指向可使用的程序区段来启动操作系统。
    • 转交其他启动引导程序:将启动管理功能转交给其他启动引导程序负责。
      • 启动引导程序除了可以安装在MBR之外,还可以安装在每个分区的启动扇区(boot sector)——多系统

Boot Loader

启动引导程序的工作执行示意图

  • MBR的启动引导程序提供两个选项
    • M1:可以直接加载Windows的内核文件来开机
    • M2:将开机管理工作交给第二个分区的启动扇区。
      • 该boot loader只有一个选项,因此能够直接使用Linux的内核文件来启动。
  • 总结

    • 每个分区都拥有自己的启动扇区(boot sector)。
    • 图中的系统分区为第一及第二分区。
    • 实际可启动的内核文件是放置到各个分区中的。
    • 启动引导程序只会认识自己的系统分区内的可启动的内核文件,以及其他启动引导程序而已。
    • 启动引导程序可直接指向或是间接将管理权限转交给另一个管理程序。
  • 问题

    • 为什么人家常常说:“如果要只能装多重引导,最好先安装Windows再安装Linux”? > > - Linux在安装的时候,你可以选择将启动引导程序安装在MBR或各别分区的启动扇区,而且Linux的启动引导程序可以手动设置选项(就是途中的M1和M2),所以你可以在Linux的启动引导程序里面加入Windows启动的选项。 > - Windows在安装的时候,它的安装程序会主动地覆盖掉MBR以及自己所在分区的启动扇区,你没有选择的机会,而且它没有让我们自己选择选项的功能。
UEFI BIOS搭配GPT的启动流程
  • 传统BIOS与UEFI的差异
    比较项目传统BIOSUEFI
    使用程序语言汇编语言C语言
    硬件资源控制使用中断使用驱动程序与协议
    不可变的内存存取
    不可变的输入/输出存取
    处理器运行环境16位CPU保护模式
    扩充方式通过IRQ连接直接加载驱动程序
    第三方厂商支持较差较佳且可支持多平台
    图形能力较差较佳
    内置简化操作系统环境不支持支持

目录架构

  • 根目录:/
  • 挂载:利用一个目录当成进入点,将磁盘分区的数据放置在该目录下。

安装Linux(Centos)

  • 文件名的意思,比如:CentOS-7-x86_64-Everything-1503-01.iso

    • Centos-7:7.x版本
    • x86_64:64位操作系统
    • Everything:全功能版本
    • 1503:2015年3月发布版本
    • 01.iso则要与Centos-7搭配,意思是CentOS 7.1版本
  • 磁盘规划

    • 如果硬盘出现问题可以fsck来解决硬盘问题
    • 考虑到读写较频繁的地方出现问题的可能性较大,因此最好将频繁读写数据的地方与系统目录分开,以下是符合容量大且读写频繁的特征目录:
      • /boot
      • /
      • /home
      • /var
      • swap

参考资料与扩展阅读


第3章 安装CentOS 7.x

练习机规划

  • Linux主机的角色定位 > 主要目的在于练习Linux的相关技术,所以几乎所有的软件都要安装,因此连较消耗系统资源的X Window System也必须要安装。
  • 选择合适的Linux发行版 > 目前选择CentOS7.x
  • 计算机系统硬件设备
    • CPU等级类别 > 通过Linux原生的虚拟系统管理器,使用本季的CPU类型。
    • 内存 > 通过虚拟化技术提供大约1.2GB内存。
    • 硬盘 > 使用一块40GB的Virtio接口的磁盘,因此硬盘文件应该会是/dev/vda。同时提供一块2GB左右的IDE接口磁盘,这块磁盘作为测试使用,并不安装系统,因此还有一块/dev/sda。
    • 网卡 > 使用Bridge的方式设置了对外网卡,网卡同样使用Virtio接口还好CentOS本身就有提供驱动程序,所以可以直接识别网卡。
    • 显卡 > 使用在Linux环境下运行还算流畅的QXL显卡,给予60MB左右的显存。
    • 其他输入/输出设备 > 模拟光驱、USB鼠标、USB键盘以及17英寸屏幕输出等设备。
  • 磁盘分区的配置
    所需目录/设备磁盘容量文件系统分区格式
    BIOS boot2MB系统自定义主要分区
    /boot1GBxfs主要分区
    /10GBxfsLVM方式
    /home5GBxfsLVM方式
    交换分区1GBxfsLVM方式
  • 启动引导程序(boot loader) > 练习机的启动引导程序使用CentOS7.x默认的grub2,并且安装于MBR,也必须安装在MBR上面才行,因为我们的磁盘空间全部用在Linux上面。
  • 选择软件 > 作为服务器,同时又会用到图形用户界面,因此使用的是“带GUI的服务器”的软件方式来安安装。
  • 检查列表
    详细项目是与否,或详细信息
    01.是否已下载且刻录所需的Linux发行版?(DVD或CD)是,DVD版
    02.Linux发行版的版本是什么?(如CentOS 7.1 x86-64版本)CentOS 7.1, x64
    03.硬件等级是什么(如 i386、x86-64、SPARC等,以及DVD或CD-ROM)x86
    04.前三项安装媒介、操作系统、硬件需求,是否吻合?是,均为x86-64
    05.硬盘数据是否可以全部被删除?
    06.硬盘分区是否做好确认?(包括/与交换分区等容量)已确认分区方式
    硬盘数量:1块40GB硬盘,并使用GPT分区表
    BIOS boot(2MB)
    /boot(1GB)
    /(10GB)
    /home(5GB)
    交换区(1GB)
    07.是否具有特殊的硬件设备(如SCSI磁盘阵列卡等)有,使用Virtio
    08.若有上述特殊硬件,是否已下载驱动程序?CentOS已内置
    09.启动引导程序与安装的位置是什么?grub2,MBR
    10.网络信息(IP参数等)是否已取得?未取得IP参数
    未取得IP的情况下,可以套用如下的IP参数:
    是否使用DHCP:无
    IP:192.168.1.100
    子网掩码:255.255.255.0
    主机名:study.centos.vbird
    11.所需要的软件有哪些?Server with X

开始安装CentOS 7

制作启动U盘

  • # dd if=centos7.iso of=/dev/sdc

使用GPT分区

  1. Install CentOS 7选项按下tab键。
  2. (在末尾)输入inst.gpt后按下回车

设备类型

  • 标准分区 > 就是我们一直谈的分区,类似/dev/vda1之类的分区。
  • LVM > 这是一种可以弹性增加或缩小文件系统容量的分区。
  • LVM精简配置(Thin Provisioning) > LVM的高级版。可让你在使用多少容量才分配磁盘多少容量给你。

文件系统

  • ext2/ext3/ext4 > 这是Linux早期使用的文件系统类型。由于ext3/ext4文件系统多了日志功能,对于系统的恢复比较快速,不过由于磁盘容量越来越大,ext系列似乎有点挡不住了,所以除非你有特殊的设置需求,否则近来比较少使用ext4.
  • swap > 就是磁盘模拟为内存的交换分区,由于交换分区并不会使用到目录树的挂载,所以用交换分区就不需要指定挂载点。 > > - 功能:当有数据被存放在物理内存里面,但是这些数据又不是常被CPU所使用时,那么这些不常被使用的数据将会被扔到硬盘的交换分区当中,而将速度较快的物理内存空间释放出来给真正需要的程序使用,所以,如果你的系统不很忙,而内存又很大,自然不需要交换分区。

  • BIOS Boot > 就是GPT分区表可能会用到的东西,若你使用MBR,那就不需要这个东西。

  • xfs > 这个是目前CentOS 7默认的文件系统,最早是为大型服务器所开发。它对于大容量的磁盘管理非常好,而且格式化的时候速度相当快,很适合当今动不动就是好几个TB的磁盘的环境,因此我们主要用这玩意儿。
  • vfat > 同时被Linux与Windows所支持的文件系统类型。如果你的主机硬盘内同时存在Windows与Linux操作系统,为了数据的交换,确实可以创建一个vfat的文件系统。

注意

  • 自定义分区的时候需要手动修改**volume Group**,大小策略选择fixed,大小填入足够大以覆盖所有空闲容量,比如30G。
    • 这么做是为了不一次性分配完空间,这样后续可以在需要的时候从空闲的**volume group**中获取。
  • 最好建立一个日常登录系统的常用一般账号比较好(可以勾选管理员身份,以允许使用自己的密码来切换为root身份)。

  • 安装笔记本电脑或其他类PC计算机参数 > 由于笔记本电脑加入了非常多的省电功能或是其他硬件的管理功能,比如显卡常常是集成显卡,因此在笔记本电脑上面的硬件常常与一般台式计算机不怎么相同。所以当你使用适合于一般台式计算机的DVD来安装时,可能会出现一些问题,导致无法顺利地安装Linux到你的笔记本电脑中,此时可以如下操作: > > 1. DVD启动时,选择【Install CentOS 7】,然后按下【Tab】键。 > 2. 输入如下参数:nofb apm=off acpi=off pci=noacpi > - APM(Advanced Power Management)是早期的电源管理模块 > - ACPI(Advanced Configuration and Power Interface)则是最近的电源管理模块。 > - nofb是取消显卡上面的缓存检测。因为笔记本常常是集成型的。

多重引导安装步骤与管理

你可能会问:“既然虚拟机这么热门,应用面也广,那为什么不能安装Linux上面使用的Windows虚拟机?或反过来使用?”原因无它,因为“虚拟机的图形显示性能依旧不足”。所以,某些时刻你还是得要使用物理机器去安装不同的操作系统。

安装CentOS 7.x + Windows 7的规划

  • 计划通过虚拟机创建200GB的磁盘,然后使用传统BIOS搭配MBR分区表来实践多重引导的实验。预计创建CentOS 7.x以及一个Windows 7的多重操作系统,同时拥有一个共享的数据磁盘。
    • 由于没有UEFI的环境,因此不使用GPT分区。
Linux设备文件名Linux挂载点Windows设备实际内容文件系统容量
/dev/vda1/boot-Linux启动信息xfs2GB
/dev/vda2/-Linux根目录xfs50GB
/dev/vda3-CWindows系统盘NTFS100GB
/dev/vda5/datD共享数据磁盘VFAT其他剩余

高级安装 CentOS 7.x与Windows 7

  1. 在安装信息摘要时,按下ctrl+alt+F2来进入安装过程的Shell环境。
  2. 通过命令行来分区。

    # parted /dev/vda mklabel msdos                 # 建立 MBR
    # parted /dev/vda mkpart primary 1M 2G          # 建立 /boot
    # parted /dev/vda mkpart primary 2G 52G         # 建立 /
    # parted /dev/vda mkpart primary 52G 152G       # 建立 C
    # parted /dev/vda mkpart extended 152G 100%     # 建立扩展分区
    # parted /dev/vda mkpart logical 152G 100%      # 建立逻辑分区
    # parted /dev/vda print                         # 显示分区结果
    
    • mklabel:由于原本是MBR分区,因此使用此功能强制将MBR改为GPT后,所有的分区都死光光了。
    • 按下ctrl+alt+F6来回到原本的安装步骤中。
    • 进入到分区界面,然后依据设备名来重新格式化并填入合适的挂载点。
    • 接着及继续直到装好为止,然后重新启动后插入Windows 7的系统光盘并将其安装Windows的分区上(100G)。
    • 恢复回Linux的启动引导程序
    • 放入安装光盘并重启
    • 在启动界面中进入Troubleshooting,选择Rescue a CentOS system
    • 在出现的界面中,选择Continue后,能得到原本系统放置的位置(假设为/mnt/sysimage)。
    • 在出现的shell环境中做如下操作:

      # chroot /mnt/sysimage
      # grub2-install /dev/vda
      # exit
      # reboot
      
  3. 修改启动选项任务:

    1. 先以正常流程登入Linux,然后切换为root身份后进行如下操作:

      # vim /etc/grub.d/40_custom
      >>>>> 40_custom
      #!/bin/bash
      exec tail -n +3 $0
      # This file provides an easy way to add custom menu entries. Simply type the
      # menu entries you want to add after this comment. Be careful not to change
      # the 'exec tail' line above.
      menuentry "Windows 7" {
          set root='(hd0,3)'
          chainloader +1
      }
      <<<<< end
      
      # vim /etc/default/grub
      >>>>> grub
      GRUB_TIMEOUT=30 # 将5秒改成30秒长一些。
      ...
      <<<<< end
      
      # grub2-mkconfig -o /boot/grub2/grub.cfg
      
  4. 重新启动,选择想要的系统登录。

  5. 后续维护注意事项:
    • 在Windows的环境中最好将Linux的根目录与交换分区取消挂载(也就是删除其盘符),否则未来你打开文件管理器时,该软件回要求你“格式化”,如果一个不留神,你的Linux系统就毁了。
    • 你的Linux不可随便删除,因为grub回去读取Linux根目录下的/boot/目录的内容,如果你将Linux删除,你的Windows也就无法启动,因为整个启动选项都没了。

参考资料与扩展阅读


第4章 首次登录与在线求助

基础设置

  1. 设置电源选项汇总,修改屏幕锁定时间为从不
  2. 在终端中输入:gsettings set org.gnome.desktop.interface enable-animations false,这个操作回将GNOME默认界面切换的动画功能关闭,在虚拟机的环境下有助于提升界面的切换速度。
  3. 应用程序工具项目下的优化工具中,使用打字项目,并选择杀死X服务器的按键序列已禁用改成Control+Alt+Backspace的设置,这样可以让你按下三个按键就重启X窗口管理器。

X Window与命令行模式的切换

  • Linux默认的情况下会提供6个终端来让用户登录,切换的方式为使用:ctrl+alt+F1 ~ F6的组合键。
  • F1 ~ F6 分别对应这 tty1 ~ tty6 终端。
  • 在命令行下启动图形界面:执行startx命令

命令行模式下命令的执行

命令行模式登录后所运行的程序被成为壳(Shell),这是因为这个程序负责最外面跟用户(我们)沟通,所以才被戏称为壳程序。

  • 语言

    • 显示目前所支持的语系:locale
    • 更改语系或全部语系
      • export LANG=en_US.utf-8
      • export LC_ALL=en_US.utf-8
  • 基础命令操作

    • 显示日期与时间的命令:date
    • 显示日历的命令:cal
    • 计算器:bc
  • 重要的几个热键

    • tab: 补全
    • ctrl+c: 中断信号(SIGINIT)
    • ctrl+d: EOF

--help

  • 基本在Linux/Unix下都可以通过:command --help来查看命令帮助信息。

man page

  • 在Linux/Unix下可以通过man page来查看指定手册的信息,例如:man date man_date
  • 左上角的DATE(1)的意思是:date手册,手册代号为1。代号的意思如下:
    代号代表内容
    1用户在shell环境中可以操作的命令或可执行文件
    2系统内核可调用的函数与工具等
    3一些常用的函数(function)与函数库(library),大部分为C的函数库(libc)
    4设备文件的说明,通常在/dev下的文件
    5配置文件或是某些文件的格式
    6游戏(games)
    7惯例与协议等,例如Linux文件系统、网络协议、ASCII代码等的说明
    8系统管理员可用的管理命令
    9跟内核有关的文件
  • man page构成
    代号内容说明
    NAME间断的命令、数据名称说明
    SYNOPSIS简短的命令语法(syntax)简介
    DESCRIPTION较为完整的说明,这部分最好仔细看看
    OPTIONS针对SYNOPSIS部分中,有列举的所有可用的选项说明
    COMMANDS当这个程序(软件)在执行的时候,可以在此程序(软件)中执行的命令
    FILES这个程序或数据所使用或参考或链接到的某些文件
    SEE ALSO可以参考跟这个命令或数据有相关的其他说明
    EXAMPLE一些可以参考的范例
  • 一般man page所在位置:/usr/share/man目录下
    • 可以修改man page的查找路径,即修改配置文件:/etc/man_db.conf/etc/man.conf/etc/manpath.confman.config等。
    • 更多的信息可以执行命令man man查看。

info page

Info page是将文件数据拆成一个个的段落,每个段落用自己的页面来编写,并且在各个页面中还有类似网页的超链接来跳到不同的页面中,每个独立的页面也被称为一个节点(node)。

  • 执行info info命令: info_info
    • File: 代表数据来源是info.info这个文件。
    • Node: 代表目前的这个页面是属于**Top**节点,意思是info.info内含有很多信息,而**Top**仅仅是info.info文件内的一个节点内容而已。
    • Next: 下一个节点的名称为**Getting Started**,你也可以按N到下一个节点去。
    • Up: 回到上一层的节点总揽画面,你也可以按下U回到上一层。
    • Prev: 前一个节点。可以按P来回到前一个节点。
    • 注意:如果不知道怎么使用info,可以按下h来查看帮助信息。
  • 基本按键
    按键进行工作
    空格键向下翻一页
    DEL(Backspace)向上翻一页
    TAB在节点之间移动,有节点的地方通常会以*显示
    回车当光标在节点上面时,按下回车可以进入该节点
    b移动到当前节点的开头
    e移动到当前节点的结尾
    n下一个节点
    p前一个节点
    u上一层
    s(/)查找
    h(?)显示帮助选项
    q退出
    ctrl+x+0返回主窗口
  • info文件路径:/usr/share/info/

其他有用的文件

  • /usr/share/doc

正确的关机方法

  • 查看睡在线:who

  • 关机命令

    • 将数据同步写入磁盘:sync
      • 确保数据从内存中写入磁盘
    • 关机命令:shutdown
      • 可以自由选择关机模式:要关机或是重启均可;
      • 可以设置关机时间:可以设置成现在立刻关机,也可以设置某个特定时间才关机;
      • 可以自定义关机信息:在关机前可以将自己设置的信息发送给在线用户;
      • 可以仅发出警告信息:有时候可能你要进行一些测试,而不想让其他的用户干扰,或是明白地告诉用户某段时间要注意一下,这个时候可以使用shutdown来吓一吓用户,但是却不是真的要关机。
    • 重新启动、关机:reboothaltpoweroff
    • 其实所有命令都是通过systemctl来实现的。
      • systemctl halt
      • systemctl poweroff
      • systemctl reboot
      • systemctl suspend

参考资料与扩展阅读


第5章 Linux的文件权限与目录配置

用户与用户组

  • Linux用户身份与用户组记录的文件
    • 账户信息:/etc/passwd
    • 密码:/etc/shadow
    • 组名:/etc/group

Linux文件权限概念

Linux文件属性

  • 使用ls -alh来查看当前目录下的属性 ls_alh
    • 显示结果每列的意思为:权限 链接数 用户 用户组 文件大小 修改日期 文件名,以红框圈出为例:
      权限链接数用户用户组文件大小修改日期文件名
      drwxr-xr-x10wang_hongqistaff320BJul 9 10:06Mysql
  • 权限 file_type_and_priv
  • 链接数
    • 目录记录名称与inode的关系,链接数则是关联到同一个inode的名称数

修改文件属性与权限

  • chgrp:修改文件所属用户组
    • 要修改的组必须在/etc/group文件中存在才行,否则会报错
  • chown:修改文件拥有者
    • 要修改的拥有者必须在/etc/passwd文件中存在才行,否则会报错
    • 也可以一并修改用户组,例如:chown user:group filechown user.group file
    • 也可以只修改用户组,例如:chown :group filechown .group file
  • chmod:修改文件的权限,SUID、SGID、SBIT等的特性。

    命令身份动作权限被操作对象
    chmodu
    g
    o
    a
    +(加入)
    -(移除)
    =(设置)
    r
    w
    x
    文件或目录

    • 使用例子
    # 设置用户为"rwx(可读、可写、可执行)",组和其他为"rx"
    chmod u=rwx,go=rx .bashrc
    
    # 删除用户、组和其他中的可执行权限
    chmod a-x .bashrc
    
    # 设置用户为"rw",组为"wx",其他为"wx",等效于:chmod u=rw,go=wx .bashrc
    chmod 644 .bashrc
    

目录与文件的权限意义

  • 权限对于文件的重要性
    • 权限
      • r(read):可以读取此文件的实际内容,如读取文本文件的文字内容等。
      • w(write):可以编辑、新增或是修改该文件的内容等。
      • x(eXecute):该文件具有可以被系统执行的权限。
    • 注意 > 当你对一个文件具有w权限时,你可以具有修改文件内容的权限,但并不具有删除该文件本身的权限。对于文件的rwx来说,主要多是针对文件的内容而言,与文件名的存在与否没有关系,因为文件记录的是实际的数据。
  • 权限对于目录的重要性
    • r(read contents in directory):表示具有读取目录结构列表的权限,所以当你具有r权限时,你可以获取该目录下的文件名列表。
    • w(modify contents of directory):表示你具有改动该目录结构列表的权限,也就是具有如下权限:
      • 建立新的文件与目录;
      • 删除已经存在的文件与目录(无论该文件的权限是什么);
      • 将已存在的文件或目录进行更名;
      • 移动该目录内的文件、目录位置;
    • x(access directory):表示用户能否进入该目录使之成为工作目录。

Linux文件种类与扩展名

  • 文件种类

    • 常规文件 > 一般我们在尽心读写的类型的文件,在由ls -al所显示出来的属性访问,第一个字符问-,例如:-rwxrwxrwx。依照文件的内容,大概可以分为: > > - 纯文本文件(ASCII) > - 二进制文件(binary) > - 数据文件(data):有些程序在运行的过程中会读取某些特定格式的文件,那些特定格式的文件可以被成为称为数据文件。例如,我们的Linux在登录用户时,都会将登录的数据记录在/var/log/wtmp这个文件夹内,可以通过last命令读取。

    • 目录(directory)

      • 第一个属性为d
    • 链接文件(link)
      • 第一个属性为l
    • 设备与设备文件(device)
      • 通常集中在/dev目录下。
        • 区块(block):b
        • 字符(character):c
    • 数据接口文件(sockets)
      • 通常被用在网络上的数据交换。第一个属性为s,通常在/run/tmp目录下可看到。
    • 数据传送文件(FIFO,pipe)
      • FIFO是一种特殊的文件类型,是一个先进先出的管道,第一个属性为p
    • Linux文件扩展名
    • Linux下文件扩展名通常只是用来方便记忆,或则某些语法高亮会依据扩展名。
    • Linux文件名长度限制
    • 单一文件或目录的最大容许文件名为255字节,以一个ASCII英文占用一个字节来说,则大约可达255个字符长度。若是以每个汉字占用2字节来说,最大文件名就是大约在128个汉字之间。
    • Linux文件名的限制
    • 文件名最好避免如下特殊字符较好:

      * ? < > ; &  ! [ ] | \ ' " ` ( ) { }
      

      因为这些符号在命令模式下具有特殊意义。另外,文件名的开头为小数点时,代表这个文件为隐藏文件。由于执行命令经常会使用到-option之类的,所以最好也避免以-+开头来命名文件。

Linux目录配置

Linux目录配置的依据——FHS

  • Filesystem Hierachy Standard(FHS)
  • FHS依据文件系统使用的频繁与否和是否允许用户随意修改,而将目录定义为四种交互作用的形态:

    可分享(shareable)不可分享(unshareable)
    不变(static)/usr(软件存放处)/etc(配置文件)
    /opt(第三方辅助软件)/boot(启动与内核文件)
    可变动(variable)/var/mail(用户邮箱)/var/run(程序相关)
    /var/spool/news(新闻组)/var/lock(程序相关)

    • 可分享:可以分享给其他系统挂载使用的目录,所以包括执行文件与用户的邮件等数据,是能够分享给网络上其他主机挂载用的目录。
    • 不可分析:自己机器上运行的设备文件或是与程序有关的socket文件等,由于仅与自身机器有关,所以当然就不适合分享给其他主机。
    • 不变:有些数据是不会经常变动的,跟随这发行版而不变动。例如函数库、文件说明、系统管理员所管理的主机服务配置文件等。
    • 可变动:经常修改的数据,例如日志文件、一般用户可自行接收的新闻组等。
    • 事实上,FHS针对目录树架构仅仅定义出如下三层目录该放置什么数据:
    • /(root,根目录):与启动系统有关。
    • /usr(unix software resource):与软件安装/执行有关。
    • /var(variable):与系统运行过程有关。
    • 根目录(/)的意义与内容
    • 根目录是整个系统最重要的一个目录,因为它存放着与系统相关的所有程序,因此根目录不要放在非常大的分区内,因为越大的分区你会放入越多的数据,如此一来也会有较多发生错误的机会。
    • FHS建议:根目录分区应该越小越好,且应用程序所安装的软件最好不要与根目录放在同一个分区内,保持根目录越小越好,如此不但能性能较佳,根目录所在的文件系统也较不容易发生问题。
    • FHS建议目录划分如下:
      目录应该放置文件内容
      第一部分:FHS要求必须要存在的根目录
      /bin系统有很多存放执行文件的目录,但/bin比较特殊。因为/bin放置的是在单人维护模式下还能够被使用的命令。/bin下面的命令可以被root与一般账号所使用,主要有:cat、chmod、chown、date、mv、mkdir、cp、bash等常用的命令
      /boot这个目录主要放置启动会使用到的文件,包括Linux内核文件以及启动选项与启动所需配置文件等。Linux内核常用的文件名为:vmlinuz,如果使用的是grub2这个启动引导程序,则还会存在/boot/grub2这个目录
      /dev在Linux系统上,任何设备与接口设备都是以文件的形式存在于这个目录当中。你只要通过读写这个目录下的某个文件,就等于读写某个设备,比较重要的文件有/dev/null、/dev/zero、/dev/tty、/dev/loop*、/dev/sd*等
      /etc系统主要的配置文件几乎都放置在这个目录内,例如人员的账号密码文件、各种服务的启动文件等。一般来说,这个目录下的各文件属性是可以让一般用户查看的,但是只有root有权利修改。FHS建议不要放置可执行文件(binary)在这个目录中。比较重要的文件有:/etc/modprobe.d/、/etc/passwd、/etc/fstab、/etc/issue等。另外FFHS还规范几个重要的目录最好要存在/etc目录下:
      • /etc/opt(必要):这个目录在放置第三方辅助软件/opt的相关配置文件;
      • /etc/X11(建议):与X Window有关的各种配置文件都在这里,尤其是xorg.conf这个X Server的配置文件;
      • /etc/sgm(建议):与SGML格式有关的各项配置文件;
      • /etc/xml/(建议):与XML格式有关的各项配置文件
      /lib系统的函数库非常多,而/lib放置的则是在启动时会用到的函数库,以及在/bin或/sbin下面的命令会调用的函数库而已。另外FSH还要求下面的目录必须存在:
      • /lib/modules/:这个目录主要放置可抽换式的内核相关模块(驱动程序)
      mediamedia是媒体的英文,顾名思义,这个/media下面放置的就是可删除的设备,包括软盘、光盘、DVD等设备都暂时挂载于此。常见的文件名有:/media/floppy、/media/cdrom等
      /mnt如果你要想要暂时挂载某些额外的设备,一般建议你可以放置到这个目录中。在早些时候,这个目录的用途与/media相同。只是有了/media之后,这个目录机就暂时用来挂载
      /opt这个是给第三方辅助软件放置的目录。什么是第三方辅助软件?举例来说KDE这个桌面管理系统是一个独立的软件,不过它可以安装到Linux系统中,因此KDE的软件就建议放置到此目录下。另外,如果你想要自行安装额外的软件(非原本的发行版提供),那么也能够将你的软件安装到这里来。不过以前的Linux系统中,我们还是习惯放置在/usr/local目录下
      /run早期的FHS规定系统启动后所产生的各项信息应该要放置到/var/run目录下,新版的FHS则规范到/run下面,由于/run可以使用内存来模拟,因此性能上会好很多
      /sbinLinux有非常多命令是用来设置环境的,这些命令只有root才能够用来设置系统,其他用户最多只能用来查询而已。放在/sbin下面的为启动过程中所需要的,里面包括了启动、修复、还原系统所需要的命令。至于某些服务器软件程序,一般则放置到/usr/sbin/当中。至于本机自行安装的软件所产生的系统执行文件(system binary),则放置到/usr/local/sbin/当中了。常见的命令包括:fdisk、fsck、ifcnofig、mkfs等
      /srvsrv可以视为service的缩写,是一些网络服务启动之后,这些服务所需要使用的数据目录,常见的服务例如WWW、FTP等。举例来说,WWW服务器需要的网页数据就可以放置在/srv/www里面。不过,系统的服务数据如果尚未要提供给因特网任何人浏览的话,默认还是建议放置到/var/lib下面即可
      /tmp这是让一般用户或是正在执行的程序暂时放置文件的地方。这个目录是任何人都能够存取的,所以你需要定期地清理一下。当然,重要数据不可放置在此目录。因为FHS甚至建议在启动时,应该要将/tmp下的数据都删除
      /usr第二层FHS设置,后续介绍
      /var第二层FHS设置,主要为放置变动性的数据,后续介绍
      第二部分:FHS建议可以存在的目录
      /home这是系统默认的用户家目录(home directory)。在你新增一个一般用户账号时,默认的用户佳目录都会规范到这里来,比较重要的是家目录有两种代号:
      • :代表目前这个用户的加目录;
      • dmtsai:则代表dmtsai的家目录
      /lib<qual>用来存放与/lib不同的格式的二进制函数库,例如支持64位的/lib64函数库等
      /root系统管理员(root)的家目录,之所以放在这里是因为如果进入单人维护模式而仅挂载根目录时,该目录就能够拥有root的加目录,所以我们会希望root的家目录与根目录放置在同一个分区中
    • Linux下重要的目录:
      目录应放置文件内容
      /lost+found这个目录是使用标准的ext2、ext3、ext4文件系统格式才会产生的一个目录,目的在于当文件系统发生错误时,将一些遗失的片段放置到这个目录下,不过如果使用的是xfs文件系统的话,就不会存在这个目录
      /proc这个目录本身是一个虚拟文件系统(virtual filesystem),它放置的数据都是在内存当中,例如系统内核、进程信息(process)、外接设备的状态及网络状态等。因为这个目录下的数据都是在内核当中,所以本身不占任何硬盘空间。比较重要的文件例如:/proc/cpuinfo、/proc/dma、/proc/interrupts、/proc/ioports、/proc/net/*等
      /sys这个目录其实根/proc非常类似,也是一个虚拟的文件系统,主要也是记录内核与系统硬件信息相关的内容。包括目前已加载的内核模块与内核检测到的硬件设备信息等,这个目录同样不占硬盘容量
    • CentOS 7.x开始,就将/sbin、/bin、/lib通通被移动到了/usr下面。
    • 建议/usr目录即使被挂载成只读,系统还是可以正常运行
  • /usr的意义与内容

    • FHS建议所有软件开发者应该将他们的数据合理的分别放置到这个目录下的子目录,而不要自行建立该软件自己独立的目录。
    • /usr子目录的建议
      目录应放置文件内容
      第一部分:FHS要求必须要存在的目录
      /usr/bin/所有一般用户能够使用的命令都放在这里。目前CentOS 7已经将全部的用户命名放置于此,而使用链接文件的方式将/bin链接至此。也就是说,/usr/bin与/bin是一模一样的。另外,FHS要求在此目录下不应该有子目录
      /usr/lib/基本上与/lib功能相同,所以/lib就是链接到此目录中的
      /usr/local/系统管理员在本机安装自己下载的软件(非发行版默认提供者),建议安装到此目录
      /usr/sbin/非系统正常运行所需要的系统命令,
      /usr/share/主要放置只读的数据文件,当然也包括共享文件,在这个目录下放置的数据几乎是不分硬件架构均可读取的数据,因为几乎都是文本文件。在此目录下常见的还有这些子目录:
      • /usr/share/man:在线帮助文件;
      • /usr/share/doc:软件的说明文档;
      • /usr/share/zoneinfo:与时区有关的时区文件
      FHS建议可以存在的目录
      /usr/games/与游戏比较相关的数据放置处
      /usr/include/c/c++等程序语言的头文件(header)与包含文件(include)放置处,当我们以Tarball方式(*.tar.gz的方式安装软件)安装某些程序时,会使用到里面的许多文件
      /usr/libexec/某些不被一般用户常用的执行文件或脚本(script)等,都会放置在此目录中。例如大部分的X窗口下面的操作命令,很多都是放置在此目录下
      /usr/lib<qual>/与/lib<qual>/功能相同,因此目前/lib<qual>就是链接到此目录中
      /usr/src/一般源代码建议放置到这里,src有srouce的意思。至于内核源代码则建议放置到/usr/src/Linux/目录下
  • /var的意义与内容 > 如果说/usr是安装时会占用较大硬盘容量的目录,那么/var就是在系统运行后才会渐渐占用硬盘容量的目录。因为/var目录主要针对经常性变动的文件,包括缓存(cache)、日志文件(log file)以及某些软件运行所产生的文件,包括程序文件(lock file、run file),或例如MySQL数据库的文件等。

    • 常见子目录:
      目录应放置文件内容
      第一部分:FHS要求必须存在的目录
      /var/cache/应用程序本身运行过程中会产生的一些缓存
      /var/lib/程序本身执行的过程中,需要使用到的数据文件放置的目录。在此目录下各自的软件应该要有各自的目录。举例来说,MySQL的数据库文件放置到/var/lib/mysql/而rpm的数据库则放到/var/lib/rpm中
      /var/lock/锁目录,目前此目录已经被移动到/run/lock中
      /var/log/这是日志文件放置的目录,里面比较重要的文件有/var/log/messages、/var/log/wtmp(记录登录信息)等
      /var/mail/放置个人电子邮件的目录,不过这个目录也被放置到/var/spool/mail目录中,通常这两个目录是互为链接文件
      /var/run/这个目录被链接到/run目录
      /var/spool/这个目录通常放置一些队列数据,所谓队列数据就是排队等待其他进程使用的数据。这些数据被使用后通常都会被删除。举例,系统收到新邮件会放置到/var/spool/mail中,但用户收下该邮件后该封信原则上就会被删除,邮件如果暂时寄不出去会被放到/var/spool/mqueue/中,等到被送出后就被删除。如果是计划任务数据(crontab),就会被放置到/var/spool/cron/目录中

目录树

  • 特征
    • 目录树的起始点为根目录(/,root)
    • 每一个目录不止能使用本地分区的文件系统,也可以使用网络上的文件系统。
    • 每一个文件在此目录树中的文件名(包含完整路径名)都是独一无二的。
  • 最好能将/var独立出来,这样对于系统的数据有一些安全性的保护。因为至少/var死掉时,你的根目录还会或者,还能够进入恢复模式。

LSB(Linux Standard Base)

参考资料与扩展阅读


第6章 Linux文件与目录管理

  • 以下所涉及的命令请查看man page查看具体信息。

目录相关操作

  • . : 当前目录
  • .. : 上一层目录
  • - : 前一个工作目录
  • ~ : 当前用户所在的家目录
  • ~homqyy : homqyy用户的家目录

  • cd : 切换目录

  • pwd : 显示当前目录的路径
  • mkdir : 创建目录
    • -m : 设置权限,不使用umask
    • -p : 帮忙创建所需的目录
  • rmdir : 删除一个空目录

    • -p : 连同上层的空目录都一块删除
  • $PATH变量存放着查找命令时的路径

  • 在命令前面加上反斜杠可以忽略掉alias,例如:\rm test_file.txt

文件与目录管理

  • ls : 查看文件与目录
    • -a : 全部文件,连同隐藏文件(常用)
    • -A : 全部文件,连同隐藏文件,但不包括...这两个目录
    • -d : 仅列出目录本身,而不是列出目录内的文件数据(常用)
    • -f : 直接列出结果,而不进行排序(ls默认会以文件名排序)
    • -F : 根据文件、目录等信息,给予附加数据结构,例如:
      • *:代表可执行文件;
      • /:代表目录;
      • =:代表socket文件;
      • |:代表FIFO文件;
      • @:代表符号链接;
    • -h : human
    • -i : 列出inode
    • -l : 详细信息(常用)
    • -n : 列出UID与GID
    • -r : 将排序结果反向输出
    • -R : 递归(连同子目录内容一起列出来)
    • -S : 以文件容量大小排序,而不是用文件名排序
    • -t : 依据时间排序
    • --color=never : 不要依据文件特性给予颜色显示
    • --color=always : 显示颜色
    • --color=auto : 让系统自行依据设置来判断是否给予颜色
    • --full-time : 以完整时间模式输出
    • --time={atime,ctime} : 输出access时间或改变权限属性时间(ctime),而非内容修改时间
  • cp : 复制
    • -a : 相当于-dr --preserve=all的意思(常用)
    • -d : 若源文件为链接文件的属性,则复制链接文件属性而非文件本身
    • -f : 若目标已经存在且无法开启,则删除后再尝试一次
    • -i : 若目标文件已经存在时,在覆盖时会先询问操作的进行(常用)
    • -l : 进行硬链接的链接文件建立,而非复制文件本身
    • -p : 连同文件的属性(权限、用户、时间)一起复制过去,而非使用默认属性(备份常用)
    • -r : 递归复制,用于目录的复制操作(常用)
    • -s : 复制成为符号链接文件
    • -u : 目标比源旧时才更新,或目标不存在的兴矿才复制
    • --preserve=all : 除了-p的权限相关参数外,还加入SELinux的属性,links,xattr等复制。

      备份的时候要注意特殊文件,例如密码文件(/etc/shadow)以及一些配置文件,就不能直接以cp复制,而必须要加上-a或是-p等可以完整复制文件权限的选项才行。

  • rm : 删除
  • mv : 移动
  • basename : 获取文件名
  • dirname : 获取目录名

文件内容查看

  • cat : 从第一行开始显示文件内容
    • -A : 相当于-vET的整合选项,可列出一些特殊字符而不是空白而已
    • -b : 列出行号,仅针对非空白行做行号显示,空白行不标行号
    • -E : 将结尾的换行符$显示出来
    • -n : 打印出行号,连同空白行也会有行号,与-b的选项不同
    • -T : 将[tab]案件以^I显示出来
    • -v : 列出一些看不出来的特殊字符
  • tac : 从最后一行开始显示,可以看出tac是cat的倒着写
  • nl : 显示的时候,同时输出行号
    • -b : 指定行号显示的方式,主要有两种
      • -b a : 表示不论是否为空行,也同样列出行号(类似cat -n)
      • -b t : 如果有空行,空的那一行不要列出行号(默认值)
    • -n : 列出行号表示的方法,主要有三种
      • -n ln : 行号在屏幕的最左方显示
      • -n rn : 行号在自己栏位的最右方显示,且不加0
      • -n rz : 行号在自己栏位的最右方显示,且加0
    • -w : 行号栏位的占用字符数
  • more : 一页一页地显示文件内容
    • 空格键:代表向下翻一页
    • 回车:代表向下翻一行
    • /:向下查找
    • :f:立即显示出文件名以及目前显示的行数
    • q:代表立即离开more,不再显示该文件内容
    • bctrl+b:代表往回翻页,不过这操作只对文件有用,对管道无用
  • less : 与more类似,但是比more更好的是,它可以往前翻页
    • 空格键:向下翻动一页
    • [pagedown]:向下翻动一页
    • [pageup]:向上翻动一页
    • /:向下查找
    • ?:向上查找
    • n:重复前一个查找(与/?有关)
    • N:反向的重复前一个查找(与/?有关)
    • g:前进到这个数据的第一行
    • G:前进到这个数据的最后一行
    • q:离开less
  • head : 只看前面几行
    • -n -100:列出前100行(不包含100)
  • tail : 只看后面几行
    • -n +100:列出100行以后的行(包含100)
  • od : 以二进制的方式读取文件内容
    • 参数
      • -t : 后面可以届各种【类型(TYPE)】的输出,例如:
        • a : 利用默认的字符来输出
        • c : 使用ASCII字符来输出
        • d[size] : 利用十进制来输出数据,每个整数占用size Bytes
        • f[size] : 利用浮点数值来输出数据,每个数占用size Bytes
        • o[size] : 利用八进制来输出数据,每个整数占用size Bytes
        • x[size] : 利用十六进制来输出数据,每个整数占用size Bytes
    • 例子
      • od -t xCc filename来显示十六进制与字符的对比。 od_eg

修改文件时间或创建新文件:touch

  • 修改时间(mtime)
    • 当文件的**内容数据变更**时,就会更新这个时间
  • 状态时间(ctime)
    • 当文件的**状态改变**时,就会更新这个时间,比如:权限与属性
  • 访问时间(atime)

    • 当文件的**内容被读取**时,就会更新这个时间
  • touch

    • 参数
      • -a : 仅自定义access time
      • -c : 仅修改文件的时间,若该文件不存在则不建立新文件
      • -d : 后面可以接预自定义的日期而不用目前的日期,也可以使用--date="日期或时间"
      • -m : 仅修改mtime
      • -t : 后面可以接预自定义的时间而不用目前的时间,格式为[YYYYMMDDhhmm]
  • 注意:即使我们复制一个文件时,复制所有的属性,也没法复制ctime这个属性,因为它记录着文件最近的状态被改变的时间,因此只要状态发生改变,就会更新它,因此它是不可被复制和修改的。

文件目录的默认权限与隐藏权限

  • 在Linux传统的**ext2、ext3、ext4**文件系统下,我们还可以设置其他的系统隐藏属性,这部分可以通过chattr来设置,而以lsattr来查看。

    • chattr
      • 格式:chattr [+-=] [ASacdistu] 文件或目录名称
        • + : 增加某一个特殊参数
        • - : 减少某一个特殊参数
        • = : 设置参数
        • A : 在存取此文件(或目录)时,atime不会被修改。
        • S : 同步写入磁盘中
        • a : 文件只能增加数据、不能删除也不能修改数据。
        • c : 将文件压缩,在读取的时候将会自动解压缩
        • d : 当dump程序被执行的时候,设置d属性将可使该文件(或目录)不会被dump备份。
        • i : 文件将不能被删除、改名、设置链接也无法写入或新增数据
        • s : 如果该文件被删除,它将会被完全的从硬盘删除,所以如果误删,完全无法恢复
        • u : 与s相反,如果文件被删除了,则数据内容还存在磁盘中,可以恢复该文件。
      • 注意 : xfs文件系统仅支持AadiS而已
      • 说明:+i+a对于系统安全来说有很大助益,比如日志文件就可以通过设置+a来保证其只能增加数据。
    • lsattr
      • 格式:lsattr [adR] 文件或目录
        • -a : 将隐藏文件属性也显示出来
        • -d : 如果接的是目录,仅列出目录本身的属性而非目录内的文件名
        • -R : 连同子目录的数据也一并列出来
  • 文件默认权限:umask umask_eg

文件特殊权限:SUID、SGID、SBIT

  • SUID(Set UID)

    • 仅对二进制程序有效
    • 执行者对于该程序需要具有x的可执行权限
    • 本权限即在执行该程序的过程中有效
    • 执行者将具有该程序拥有者的权限
    • 对目录是无效的
  • SGID(Set GID)

    • SGID对二进制程序有效
    • 执行者对于该程序需要具有x的可执行权限
    • 执行者在执行过程中将会获得用户组的权限
    • 针对目录
      • 用户对此目录具有r与x权限,保证其能进入此目录
      • 用户在此目录下的有效用户组将会变成该目录的用户组
      • 用途:若用户在此目录下具有w的权限(可以新建文件),则用户所建立的新文件的用户组与此目录的用户组相同。
  • SBIT(Sticky Bit)

    • 只对目录有效
    • 当用户对此目录具有w、x权限,即具有写入的权限
    • 当用户在该目录下建立文件或目录时,仅有自己与root才有权利删除该文件
  • 权限设置

    • 权限位
      • SUID: 4
      • SGID: 2
      • SBIT: 1
    • 设置方法
      • SUID
        • chmod 4xxx binary_file
        • chmod u+s binary_file
        • chmod u=rwxs suid_eg
      • SGID
        • chmod 2xxx file_or_dir
        • chmod g+s file_or_dir
        • chmod g=rwxs suid_eg
      • SBIT
        • chmod 1xxx dir
        • chmod o+t dir
        • chmod o=rwxt suid_eg
    • 注意:小写的s或t代表着正常,反之大写(S和T)为无效的,因为拥有者没有可执行权限,因此也就没发使其生效了。 smod_eg

观察文件类型 file

  • 如果想知道某个文件的基本信息,例如是ASCII还是数据文件或是二进制文件,且其中有没有使用到动态链接库,或其兼容平台等信息,可以用file命令查看。

命令与文件的查找

  • 命令

    • which

      • 格式:which [-a] command
        • -a : 将所有由PATH目录中可以找到的命令均列出
      • 作用:根据$PATH环境变量所规范的路径去查找执行文件的文件名
    • type

  • 查找文件顺序

    • 一般先用whereis或locate来检查,如果查找不到了再用find去找。因为whereis只找系统某些特定目录下的文件,而locate则是利用数据库来查找
      • whereis
        • -l : 可以列出whereis会去查找的几个主要目录
        • -b : 只找binary(二进制)格式的文件
        • -m : 只找在书评文件manual路径下的文件
        • -s : 只找source源文件
        • -u : 查找不再上述三个项目当中的其他特殊文件
      • locate
        • 参数
          • -i : 忽略大小写的差异
          • -c : 不输出文件名,仅计算我找到的文件数量
          • -l : 仅输出几行的意思,例如输出5行则是:-l 5
          • -S : 输出locate所使用的数据库文件的相关信息,包括该数据库记录的文件/目录数量等
          • -r : 后面可接正则表达式的显示方式
        • 手动更新数据库
          • updatedb:根据/etc/updatedb.conf的设置去查找系统硬盘内的文件,并更新/var/lib/mlocate内的数据库文件
      • find
        • 与时间相关
          • -mtime +n : n天以前被修改过的文件
          • -mtime n : 第n天内被修改过的文件
          • -mtime -n : n天以内被修改过的文件
        • 与使用者或用户组名称相关
          • uid n : n为用户ID,该值记录在/etc/passwd里面
          • gid n : n为用户组ID,该值记录在/etc/group里面
          • -user name : 用户名
          • -group name : 组名
          • -nouser : 查找文件的用户名不在/etc/passwd中
          • nogroup : 查找文件的用户组不在/etc/group中
        • 与文件权限及名称相关
          • -name filename : 查找文件名称为filename的文件
          • -size [+-]SIZE : 查找比SIZE还要打(+)或小(-)的文件。这个SIZE的规格有:
            • c: 代表Bytes,k: 代表1024Bytes。
          • -type TYPE : 查找文件的类型为TYPE,类型主要有:f(文件), b(块设备), c(字符设备), d(目录), l(链接), s(套接字), p(管道)
          • -perm mode : 查找文件权限刚好等于mode的文件
          • -perm -mode : 查找文件权限包括mode的文件
          • -perm /mode : 查找文件权限包含任意mode的文件
        • 额外可执行操作
          • -exec command : command为其他命令,-exec后面可再接额外的命令来处理查到的结果
            • eg: find / -perm /7000 -exec ls -l {} \;
          • -print : 将结果打印到屏幕上,这个操作是默认运行的

参考资料与扩展阅读


第7章 Linux磁盘与文件系统管理

认识Linux

  • 由于LVM和software raid等技术的出现,允许一个分区可以格式化为多个文件系统或则多个分区可以合成一个文件系统,因此现在可以称呼一个可被挂载的数据为一个文件系统而不是一个分区。
  • 文件系统有两部分数据,内容和属性,通常会将这两部分数据分别存放在不同的区块,权限与属性放置到**inode**中,至于实际数据则放置到**数据区块**中。另外,还有一个**超级区块**会记录整个文件系统的整体信息,包括inode与数据区块的总量、使用量、剩余量等。
    • 超级区块
      • 记录文件系统的整体信息,包括inode与数据区块的总量、使用量、剩余量,以及文件系统的格式与相关信息等。
    • inode
      • 记录文件的属性,一个文件占用一个inode,同时记录此文件的数据所在的区块号码。
    • 数据区块
      • 实际记录文件的内容,若文件太大时,会占用多个区块。
  • 索引式文件系统:通过inode上记录的数据区块编号,来一口气找到所有的数据区块并读取。

    • 其他非索引的例如使用FAT格式的U盘,因为不存在inode且每个区块号码都记录在前一个区块中,因此只能一个一个的找,也因此在写入的区块过于离散的话往往不能一次读取完,效率较低。
  • 碎片整理 > 需要整理碎片的原因就是文件写入的区块过于离散,此时文件读取的性能会变得很差所致。这个时候可以通过碎片整理将同一个文件所属的区块集合在一起,这样数据的读取会比较容易。 > > - 因此,FAT的文件系统经常要碎片整理以下 > - ext2因为是索引式的,因此不太需要碎片整理,但是如果使用太久,还是需要整理以下的。

Linux的ext2文件系统(inode)

  • 文件系统一开始就将inode与数据区块规划好了,除非重新格式化(或利用resize2fs等命令修改其大小),否则inode与数据区块固定后就不再变动。
  • 文件系统最前面有一个启动扇区(boot sector),这个启动扇区可以安装启动引导程序。接着是多个区块群组,每个区块群组都有独立的inode、数据区块、超级区块系统等。 ext2_fs

    图 ext2文件系统示意图

    • data block(数据区块) > 在格式化的时候大小就已经固定,在ext2文件系统中所支持的区块大小有:1K、2K及4K三种。且每个区块都有自己的编号。因为区块大小不同,因此大小的限制也不同: >

      > > > > > > > >
      Block大小1KB2KB4KB
      最大单一文件限制16GB256GB2TB
      最大文件系统总容量2TB8TB16TB
      > > 其他基本限制: > > - 原则上,区块大小与数量在格式化完后就不能再修改(除非重新格式化) > - 每个区块内最多只能够放置一个文件的数据 > - 承上,如果文件大于区块的大小,则一个文件会占用多个区块数量 > - 承上,若文件小于区块,则该区块的剩余容量就不能够再被使用了(磁盘空间会浪费)

      • 提示:在进行文件系统的格式化之前,最好预计下文件系统的使用情况,以便于选择一个相匹配大小的数据区块,既能避免浪费空间还能提高性能(小文件配大区块浪费空间,大文件配小区块影响读写性能)。
    • inode table

      • inode
        • 特性
          • 格式化后inode的数量和大小就已经固定。
          • 每个inode大小均为128B(新的ext4与xfs可设置到256B)。
          • 每个文件都仅会占用一个inode,因此文件系统能够建立的文件数量与inode的数量有关。
          • inode记录一个数据区块需要用4B,因此可能无法记录大文件,所以inode将记录区块号码的区域分为**12个直接**、1个间接一个双间接、**一个三间接**的记录区。 inode_struct

            图 inode结构示意图

            • 以一个数据区块为1K来计算一个inode可以指向的大小:
              • 12个直接指向:\(12{\times}1K=12K\)
              • 间接:每个区块号4B,因此1K的数据区块可以记录256个区块号,\(256{\times}1K=256K\)
              • 双间接:\(256{\times}256{\times}1K=256^2K\)
              • 三间接:\(256^3K\)
              • 总和:\((12+256+256^2+256^3){\times}1K=16GB\) - 系统读取文件时先找到inode并分析相关权限,若符合权限则可读取区块的内容。 - 记录的数据 - 文件的读写属性(rwx) - 文件的拥有者与用户组(owner、group) - 文件的大小 - ctime、atime、mtime - 文件特性标示,比如:SUID - 文件真正内容的指向
              • Superblock
                • 超级区块记录是记录整个文件系统相关信息的地方,主要记录的信息有:
                  • 数据区块与inode的总量
                  • 未使用与已使用的inode与数据区块的数量
                  • 数据区块与inode的大小(block为1、2、4K,inode为128B或256B)
                  • 文件系统的挂载时间、最新一次写入数据的时间、最近一次检验磁盘(fsck)的时间等文件系统的相关信息
                  • 一个有效位数值,若此文件系统已被挂载,则有效位为0,若未被挂载,则有效位为1
                • 一般超级区块大小为1024B,相关信息可以用dumpe2fs命令查看。
                • 一般一个文件系统只有首个区块群组的Superblock是真实有效的,其他群组的Superblock都只是其备份,用于恢复使用。
              • Filesystem Description(文件系统描述说明)
                • 描述每个区块群组的开始与结束的区块,以及说明每个区段(超级区块、区块对应表、inode对应表、数据区块)分别介于哪一个区块之间,可通过dumpe2fs查看。
              • Block Bitmap(区块对应表)
                • 记录着使用或未使用的数据区块号
              • inode Bitmap(inode对应表)
                • 记录着使用或未使用的inode号
            • dumpe2fs的使用
              • blkid查看当前系统被格式化的设备
      [root@study pam.d]#
      [root@study pam.d]#
      [root@study pam.d]# blkid
      /dev/sda2: UUID="7703e582-63b3-48a3-b925-4972a24cdf06" TYPE="xfs" PARTUUID="e80b900a-1f7a-4489-8603-138158a8f95c"
      /dev/sda3: UUID="AP04Be-Lx2l-Psbc-0Vco-cXE3-N9Uj-HiddzF" TYPE="LVM2_member" PARTUUID="8ef31eee-8c18-47e2-9ea1-ac9d6a8d29b5"
      /dev/sda4: UUID="8c7e2ba7-0835-45a1-b38c-7bf1540723ba" TYPE="xfs" PARTLABEL="Linux filesystem" PARTUUID="57ee107c-3479-436e-b0ef-f3ca11dcd532"
      /dev/mapper/centos-root: UUID="569fa037-7f25-4061-a78c-3c1a46364e1c" TYPE="xfs"
      /dev/mapper/centos-swap: UUID="8895e1ff-13b8-4e51-b907-b6a4fa5690f8" TYPE="swap"
      /dev/mapper/centos-home: UUID="41ae3675-50f0-4ff8-9067-aaa9727bcdc8" TYPE="xfs"
      /dev/sda5: UUID="9fd0e17b-40cd-402c-8018-58455b3e3b2c" TYPE="ext4" PARTLABEL="test-part" PARTUUID="096ee6af-8de5-4d50-ad6f-c784439c2f4e"
      /dev/sda1: PARTUUID="2676091d-db5c-4d43-9dc1-51ffd1167271"
      
    • 开始dump ext4的文件系统信息

      [root@study pam.d]#
      [root@study pam.d]# dumpe2fs /dev/sda5
      dumpe2fs 1.42.9 (28-Dec-2013)
      Filesystem volume name:   <none> # 文件系统名称
      Last mounted on:          <not available> # 上次挂载的目录位置
      Filesystem UUID:          9fd0e17b-40cd-402c-8018-58455b3e3b2c
      Filesystem magic number:  0xEF53
      Filesystem revision #:    1 (dynamic)
      Filesystem features:      has_journal ext_attr resize_inode dir_index filetype needs_recovery extent 64bit flex_bg sparse_super large_file huge_file uninit_bg dir_nlink extra_isize
      Filesystem flags:         signed_directory_hash
      Default mount options:    user_xattr acl # 默认挂载时会主动加上的挂载参数
      Filesystem state:         clean # 文件系统状态,clean的意思是没问题
      Errors behavior:          Continue
      Filesystem OS type:       Linux
      Inode count:              63104
      Block count:              252160
      Reserved block count:     12608
      Free blocks:              243473
      Free inodes:              63093
      First block:              0
      Block size:               4096
      Fragment size:            4096
      Group descriptor size:    64
      Reserved GDT blocks:      123
      Blocks per group:         32768
      Fragments per group:      32768
      Inodes per group:         7888
      Inode blocks per group:   493
      Flex block group size:    16
      Filesystem created:       Sat Aug 24 16:59:11 2019
      Last mount time:          Sat Aug 24 17:02:23 2019
      Last write time:          Sat Aug 24 17:02:23 2019
      Mount count:              2
      Maximum mount count:      -1
      Last checked:             Sat Aug 24 16:59:11 2019
      Check interval:           0 (<none>)
      Lifetime writes:          32 MB
      Reserved blocks uid:      0 (user root)
      Reserved blocks gid:      0 (group root)
      First inode:              11
      Inode size:              256
      Required extra isize:     28
      Desired extra isize:      28
      Journal inode:            8
      Default directory hash:   half_md4
      Directory Hash Seed:      2ff369ca-d774-4986-aaa3-faf79d27c3c6
      Journal backup:           inode blocks
      Journal features:         journal_64bit
      Journal size:             16M
      Journal length:           4096
      Journal sequence:         0x00000006
      Journal start:            0
      
      
      Group 0: (Blocks 0-32767) [ITABLE_ZEROED]
      Checksum 0xb26a, unused inodes 7877
      Primary superblock at 0, Group descriptors at 1-1
      Reserved GDT blocks at 2-124
      Block bitmap at 125 (+125), Inode bitmap at 141 (+141)
      Inode table at 157-649 (+157)
      28677 free blocks, 7877 free inodes, 2 directories, 7877 unused inodes
      Free blocks: 138-140, 149-156, 4102-32767
      Free inodes: 12-7888
      Group 1: (Blocks 32768-65535) [INODE_UNINIT, ITABLE_ZEROED]
      Checksum 0xfe81, unused inodes 7888
      Backup superblock at 32768, Group descriptors at 32769-32769
      Reserved GDT blocks at 32770-32892
      Block bitmap at 126 (bg #0 + 126), Inode bitmap at 142 (bg #0 + 142)
      Inode table at 650-1142 (bg #0 + 650)
      32643 free blocks, 7888 free inodes, 0 directories, 7888 unused inodes
      Free blocks: 32893-65535
      Free inodes: 7889-15776
      Group 2: (Blocks 65536-98303) [INODE_UNINIT, ITABLE_ZEROED]
      Checksum 0xe470, unused inodes 7888
      Block bitmap at 127 (bg #0 + 127), Inode bitmap at 143 (bg #0 + 143)
      Inode table at 1143-1635 (bg #0 + 1143)
      28672 free blocks, 7888 free inodes, 0 directories, 7888 unused inodes
      Free blocks: 69632-98303
      Free inodes: 15777-23664
      Group 3: (Blocks 98304-131071) [INODE_UNINIT, ITABLE_ZEROED]
      Checksum 0xdbdb, unused inodes 7888
      Backup superblock at 98304, Group descriptors at 98305-98305
      Reserved GDT blocks at 98306-98428
      Block bitmap at 128 (bg #0 + 128), Inode bitmap at 144 (bg #0 + 144)
      Inode table at 1636-2128 (bg #0 + 1636)
      32643 free blocks, 7888 free inodes, 0 directories, 7888 unused inodes
      Free blocks: 98429-131071
      Free inodes: 23665-31552
      Group 4: (Blocks 131072-163839) [INODE_UNINIT, BLOCK_UNINIT, ITABLE_ZEROED]
      Checksum 0xdb35, unused inodes 7888
      Block bitmap at 129 (bg #0 + 129), Inode bitmap at 145 (bg #0 + 145)
      Inode table at 2129-2621 (bg #0 + 2129)
      32768 free blocks, 7888 free inodes, 0 directories, 7888 unused inodes
      Free blocks: 131072-163839
      Free inodes: 31553-39440
      Group 5: (Blocks 163840-196607) [INODE_UNINIT, ITABLE_ZEROED]
      Checksum 0x39cf, unused inodes 7888
      Backup superblock at 163840, Group descriptors at 163841-163841
      Reserved GDT blocks at 163842-163964
      Block bitmap at 130 (bg #0 + 130), Inode bitmap at 146 (bg #0 + 146)
      Inode table at 2622-3114 (bg #0 + 2622)
      32643 free blocks, 7888 free inodes, 0 directories, 7888 unused inodes
      Free blocks: 163965-196607
      Free inodes: 39441-47328
      Group 6: (Blocks 196608-229375) [INODE_UNINIT, BLOCK_UNINIT, ITABLE_ZEROED]
      Checksum 0x901f, unused inodes 7888
      Block bitmap at 131 (bg #0 + 131), Inode bitmap at 147 (bg #0 + 147)
      Inode table at 3115-3607 (bg #0 + 3115)
      32768 free blocks, 7888 free inodes, 0 directories, 7888 unused inodes
      Free blocks: 196608-229375
      Free inodes: 47329-55216
      Group 7: (Blocks 229376-252159) [INODE_UNINIT, ITABLE_ZEROED]
      Checksum 0x2c00, unused inodes 7888
      Backup superblock at 229376, Group descriptors at 229377-229377
      Reserved GDT blocks at 229378-229500
      Block bitmap at 132 (bg #0 + 132), Inode bitmap at 148 (bg #0 + 148)
      Inode table at 3608-4100 (bg #0 + 3608)
      22659 free blocks, 7888 free inodes, 0 directories, 7888 unused inodes
      Free blocks: 229501-252159
      Free inodes: 55217-63104
      

文件系统与目录树的关系

  • 目录
    • 文件系统会分配给目录:
      • 一个inode:记录该目录的相关权限与属性
      • 至少一块数据区块:记录该目录下的文件名与对应的inode号码
        • 假设执行ls -li时有如下结果:

          [root@study ~]# ls -li
          总用量 8
          25165903 -rw-------. 1 root root 2174 6月   8 23:08 initial-setup-ks.cfg
          25288228 -rw-r--r--. 1 root root   38 7月  31 22:49 README.md
          750992   drwxr--r-x. 2 root root    6 8月  10 23:32 tmp
          

          那么目录数据区块的存储图如下所示: dir_block_struct - 目录树的读取 - 因为文件名时记录在目录的区块中的,因此想要新增文件、删除文件、修改文件名时,必须要拥有目录的w权限。 - 文件系统大小与磁盘读取性能 - 当一个文件系统规划得很大时,由于磁盘上面的数据总是来来去去,整个文件系统上面文件的数据通常无法连续的写在一起,那么就出现了**文件数据离散**的问题了,倘若离散的数据分别在文件系统的开头和结尾,那么这时候由于系统较大,因此磁头读取数据时跨度也大,从而导致效率地下。 - 因此,磁盘分区的规划并不是越大越好,而是要针对用途去规划。

ext2/ext3/ext4文件的存取与日志式文件系统

  • 在新增一个文件时,系统的操作有:
    1. 先确定用户对于欲新增文件的目录是否有w与x权限,有的话才能新增。
    2. 根据inode对照表找到没有使用的inode号码,并将新文件的权限/属性写入。
    3. 根据区块对照表找到没有使用中的区块号码,并将实际的数据写入区块中,且更新inode的区块指向数据。
    4. 将刚刚写入的inode与区块数据同步更新inode对照表与区块对照表,并更新超级区块的内容。
    5. 数据存放区:inode表与数据区块
    6. 元数据(metadata):超级区块、区块对照表、indoe对照表。
  • 数据的不一致状态
    • 当出现系统中断等导致数据不一致的异常现象时,早期的ext2会在重启的时候自动检查(需要对比元数据区域与实际数据存放区),或则手动执行e2fsck。但是这样太费时间。
  • 日志式文件系统(Journaling filesystem)

    • 在文件系统中规划一个区块用来记录写入和修改文件时的步骤。
      • 预备:当系统要写入一个文件时,会现在日志记录区块中记录某个文件准备要写入的信息
      • 实际写入:开始写入文件的权限与数据,开始更新meatadata。
      • 结束:完成数据与metadata的更新后,在日志记录区块中完成该文件的记录。
    • 当发现数据不一致的时候,可以通过检查日志来有效的定位到问题点并进行修复,从而有效的减少了检查修复时间。
    # 以下为dumpe2fs输出的结果
    Journal inode:            8
    Journal backup:           inode blocks
    Journal features:         journal_64bit
    Journal size:             16M
    Journal length:           4096
    Journal sequence:         0x00000006
    Journal start:            0
    

Linux文件系统的运行

  • 由于数据必须加载入内存后CPU才能够处理,而磁盘读写速度有很慢,因此频繁地读写磁盘是不低效的,于是Linux使用异步处理(asynchronously)来处理这个问题:
    • 当系统加载一个文件到内存后会将文件标志为**clean**状态,如果内存的文件数据被修改过了,此时内存中的数据会被设置为**dirty**状态,此时所有的操作都还在内存中执行,并没有写入到磁盘中。接着系统会不定时的将内存中设置为**dirty**的数据写会磁盘,以保持内存与磁盘中的数据一致。
  • 为了提高系统性能,会充分利用内存:
    • 系统会将常用的文件数据放置到内存的缓冲区,以加速文件系统的读写操作。
    • 承上,因此Linux的物理内存最后都会被用光,这是正常的情况,可加速系统性能。
    • 你可以手动使用sync来强制内存中设置为Dirty的文件写回到磁盘中。
    • 若正常关机时,关机米ing玲会主动调用sync来将内存的数据写回磁盘。
    • 但若不正常关机(入断电、宕机或其他不明原因),由于数据尚未写回到磁盘内,因此重新启动后可能回花很多时间在进行磁盘检验,甚至可能导致文件系统的损坏(磁盘损坏)。

挂载点的意义(mount point)

  • 挂载:将文件系统与目录树结合的操作
    • 挂载点一定是目录,该目录为进入该文件系统的入口
  • 每个文件系统都有独立的inode、区块、超级区块等信息。

其他Linux支持的文件系统与VFS

  • 常见支持的文件系统
    • 传统文件系统:ext2、minix、FAT(用vfat模块)、iso9660(光盘)等
    • 日志式文件系统:ext3、ext4、ReiserFS、Windows'NTFS、IBM's JFS、SGI's XFS、ZFS
    • 网络文件系统:NFS、SMBFS
  • 想知道Linux系统支持的文件系统有哪些,可以执行ls -l /lib/modules/$( uname -r )/kernel/fs
  • 查看目前系统已经加载到内存中支持的文件系统,可以执行:cat /proc/filesystems

  • Linux VFS(Virtual Filesystem Switch)

    • 所有Linux系统都是通过VFS在管理文件系统。 VFS

      图 VFS文件系统的示意图

XFS文件系统简介

  • CentOS 7开始,默认文件系统类型从ext4改为xfs。 ext文件系统格式化慢
    • ext文件系统是通过预先规划inode、区块、元数据等数据。这在小容量里不算什么,但在大容量中就需要花费大量的时间了。
  • xfs文件系统的配置 xfs文件系统是一个日志式文件系统,它在数据分布上主要规划为三部分:
    • data section(数据区)
      • 类似于ext系列,包括inode、数据区块、超级区块等数据都放置在该区中。该区分为多个**存储区群组(allocation group)**,每个群组都包含了如下部分:
        • 整个文件系统的超级区块
        • 剩余空间的管理机制
        • inode的分配与追踪
      • inode与区块都是系统需要用到时才动态配置产生,所以格式化操作超级快
      • 区块可在512B ~ 64KB间调整,inode大小可在256B ~ 2MB间调整。
        • 由于pagesize的控制,因此最高可使用的区块大小为4K,超过此设置内核不让挂载
    • log section(活动登录区)
      • 记录文件系统的变化,直到该变化完整地写入到数据区后该记录才会被结束。
      • 因为系统所有操作都会在这个区块做记录,因此这个区块活动相当频繁
      • 该区块允许指定外部的磁盘,因此可以通过指定外部的SSD磁盘来加速其工作。
    • realtime section(实时运行区)
      • 当有文件要被建立时,会在这个区中找到1个或多个extent区块,然后将文件放置到这些区块中。等分配完毕后再写入到data section的inode与区块中。
      • extent大小在格式化时指定,范围在4K ~ 1G间选择。该大小最好不要乱动,因为可能会影响到物理磁盘的性能。
  • XFS文件系统的描述与数据观察 使用xfs_info命令区查看相关信息:

    • 先使用df -T当前已挂载文件系统下的文件系统类型。
    • 找到xfs文件系统类型的设备路径,然后通过xfs_info查看,如下例子:
    [wang_hongqi@study ~]$ df -T
    文件系统                类型        1K-块    已用    可用 已用% 挂载点
    /dev/mapper/centos-root xfs      10475520 6548768 3926752   63% /
    devtmpfs                devtmpfs   915516       0  915516    0% /dev
    tmpfs                   tmpfs      932652       0  932652    0% /dev/shm
    tmpfs                   tmpfs      932652   10736  921916    2% /run
    tmpfs                   tmpfs      932652       0  932652    0% /sys/fs/cgroup
    /dev/sda4               xfs       1038336   32944 1005392    4% /srv/myproject
    /dev/sda2               xfs       1038336  173140  865196   17% /boot
    /dev/mapper/centos-home xfs       5232640   65008 5167632    2% /home
    tmpfs                   tmpfs      186532      32  186500    1% /run/user/1000
    /dev/sda5               ext4       976376    2472  907088    1% /mnt/test_part
    tmpfs                   tmpfs      186532       4  186528    1% /run/user/42
    [wang_hongqi@study ~]$ xfs_info /dev/sda2
    meta-data=/dev/sda2              isize=512    agcount=4, agsize=65536 blks
            =                       sectsz=512   attr=2, projid32bit=1
            =                       crc=1        finobt=0 spinodes=0
    data     =                       bsize=4096   blocks=262144, imaxpct=25
            =                       sunit=0      swidth=0 blks
    naming   =version 2              bsize=4096   ascii-ci=0 ftype=1
    log      =internal               bsize=4096   blocks=2560, version=2
            =                       sectsz=512   sunit=0 blks, lazy-count=1
    realtime =none                   extsz=4096   blocks=0, rtextents=0
    
    • xfs_info结果字段解释
      • isize:inode容量
      • agcount:存储区群组个数
      • agsize:每个存储区群组拥有的区块个数
      • sectsz:逻辑扇区的大小
      • bsize:区块大小
      • sunit与swidth:与磁盘阵列的stripe相关性较高
      • log:log section
        • internal:登录区在文件系统内,而不是外部设备
        • bsize:该区的区块大小
        • blocks:该区的区块数
        • sectsz:该区的逻辑扇区大小
      • realtime:realtime section
        • extsz:extent的大小

文件系统的简单操作

磁盘与目录总容量

  • df:列出文件系统的整体磁盘使用量

    Usage: df [OPTION]... [FILE]...
    -a, --all             include dummy file systems
    -B, --block-size=SIZE  scale sizes by SIZE before printing them;
    -h, --human-readable  print sizes in human readable format (e.g., 1K 234M 2G)
    -H, --si              likewise, but use powers of 1000 not 1024
    -i, --inodes          list inode information instead of block usage
    -k                    like --block-size=1K
    -T, --print-type      print file system type
    
    SIZE is an integer and optional unit (example: 10M is 10*1024*1024).  Units are K, M, G, T, P, E, Z, Y (powers of 1024) or KB, MB, ... (powers of 1000)
    
    • df可以接目录或则是文件,此时它会列出该目录或文件所在文件系统的信息

      [wang_hongqi@study ~]$ df -h /etc/
      Filesystem               Size  Used Avail Use% Mounted on
      /dev/mapper/centos-root   10G  6.3G  3.8G  63% /
      
    • df读取的范围主要是超级区块内的信息,因此速度特别块

  • du:查看每个文件的磁盘使用量(对目录是递归的。常用在查看目录所占磁盘空间)

    • du查看的是真实占用磁盘空间的大小,而不是文件系统名义上占用的大小,比如**空洞文件**,这时候du是会跳过空洞的。
    • -s只列出总量
    • -S排除子目录容量
    Usage: du [OPTION]... [FILE]...
    or:  du [OPTION]... --files0-from=F
    
    -0, --null            end each output line with 0 byte rather than newline
    -a, --all             write counts for all files, not just directories
        --apparent-size   print apparent sizes, rather than disk usage; although the apparent size is usually smaller, it may be larger due to holes in ('sparse') files, internal fragmentation, indirect blocks, and the like
    -B, --block-size=SIZE  scale sizes by SIZE before printing them
    -b, --bytes           equivalent to '--apparent-size --block-size=1'
    -h, --human-readable  print sizes in human readable format (e.g., 1K 234M 2G)
        --inodes          list inode usage information instead of block usage
    -k                    like --block-size=1K
    -m                    like --block-size=1M
    -S, --separate-dirs   for directories do not include size of subdirectories
        --si              like -h, but use powers of 1000 not 1024
    -s, --summarize       display only a total for each argument
    -X, --exclude-from=FILE  exclude files that match any pattern in FILE
        --exclude=PATTERN    exclude files that match PATTERN
    -x, --one-file-system    skip directories on different file systems
    
    SIZE is an integer and optional unit (example: 10M is 10*1024*1024).  Units
    are K, M, G, T, P, E, Z, Y (powers of 1024) or KB, MB, ... (powers of 1000).
    

硬链接与符号链接:ln

  • ln

  • 硬链接

    • 本质:新增一个链接到同一个inode号的文件名。
    • 例如:创建一个硬链接/root/crontab/etc/crontab

      [root@study ~]# ln /etc/crontab ./crontab
      [root@study ~]# ls -li /etc/crontab /root/crontab
      17285698 -rw-r--r--. 2 root root 451 6月  10 2014 /etc/crontab
      17285698 -rw-r--r--. 2 root root 451 6月  10 2014 /root/crontab
      

      hardlink

      图 硬链接的文件读取示意图

      • 可以看到它们inode号是一样的,链接数也变成2了(有两个文件名链接到该inode号)
        • 仅当inode的链接数为0时,才会回收inode和对应的区块。
        • 限制
      • 不能跨文件系统
      • 不能链接目录(太复杂,暂不支持)
  • 符号链接

    • 用一个独立的文件(相当于有独立的inode)去存储链接目标的文件名。然后读取者通过该文件名去获取真正的数据。因此当链接目标文件被删除后,会因为找不到目标文件而打不开链接文件。
    • 例如:创建一个符号链接/root/crontab_symlink/etc/crontab

      [root@study ~]# ln -s /etc/crontab /root/crontab_symlink
      [root@study ~]# ls -li /etc/crontab /root/crontab_symlink
      17285698 -rw-r--r--. 2 root root 451 6月  10 2014 /etc/crontab
      26415296 lrwxrwxrwx. 1 root root  12 8月  25 17:22 /root/crontab_symlink -> /etc/crontab
      

      symlink

      图 符号链接的文件读取示意图

      • 可以看到它们的inode是不一样的,且不增加目标文件的链接数(在硬链接的时候增加到2了,这里并没有增加到3)
      • 而且可以看到/root/crontab_symlink的大小是12B,因为/etc/crontab的长度正好为12B。
  • 目录的链接数

    • 创建一个目录链接数如何变化?
      • 新建目录的链接数:本层目录中的.、上层目录链接新目录。
        • 因此新目录至少链接数为2。
      • 上层目录的连接数:因为新的目录中有..链接到上层,因此上层目录的链接数会加1。
        • 因此每增加一个子目录,目录本身链接数就会加1.

磁盘的分区、格式化、检验与挂载

  • 想在系统里新增一块磁盘需要的操作有:
    1. 对磁盘进行划分,以建立可用的硬盘分区。
    2. 对该硬盘分区进行格式化(format),以建立系统可用的文件系统。
    3. 若想要仔细一点,则可对刚刚创建好的文件系统进行检验。
    4. 在Linux系统上,需要建立挂载点(亦即是目录),并将它挂载上来。

观察磁盘分区状态的工具

  • lsblk:列出系统上的所有磁盘列表

    • 实例:
    [root@study ~]# lsblk
    NAME            MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
    sda               8:0    0   40G  0 disk                # 一整个磁盘
    ├─sda1            8:1    0    2M  0 part                # 分区
    ├─sda2            8:2    0    1G  0 part /boot
    ├─sda3            8:3    0   30G  0 part
    │ ├─centos-root 253:0    0   10G  0 lvm  /              # 在lvm中的文件系统
    │ ├─centos-swap 253:1    0    1G  0 lvm  [SWAP]
    │ └─centos-home 253:2    0    5G  0 lvm  /home
    ├─sda4            8:4    0    1G  0 part /srv/myproject
    └─sda5            8:5    0  985M  0 part /mnt/test_part
    sr0              11:0    1 1024M  0 rom
    
    • 解释
      • 事例系统中主要有sr0sda设备,sda下有5个分区,在分区sda3下还有LVM产生的3个文件系统
      • 关键字
        • NAME:设备的文件名,会省略/dev等前导目录名。
        • MAJ:MIN:主次设备号
        • RM:是否为可卸载设备
        • SIZE:容量
        • RO:是否为只读设备
        • TYPE:是磁盘(disk)、分区(partition)还是只读存储器(rom)等
        • MOUNTPOINT:挂载点
  • blkid:列出设备的UUID等参数

    • UUID:是全局唯一标识符(universally unique identifier),Linux会将系统内所有的设备都给予一个独一无二的标识符,这个标识符就可以拿来作为挂载或是使用这个设备或文件系统。
  • parted:列出磁盘的分区表类型与分区信息

    • 可以通过此命令来查看分区类型,比如下面的事例可以看出为**GPT**分区表:

      [root@study ~]# parted /dev/sda print
      Model: ATA VMware Virtual I (scsi)
      Disk /dev/sda: 42.9GB
      Sector size (logical/physical): 512B/512B
      Partition Table: gpt
      Disk Flags: pmbr_boot
      
      Number  Start   End     Size    File system  Name              Flags
      1      1049kB  3146kB  2097kB                                 bios_grub
      2      3146kB  1077MB  1074MB  xfs
      3      1077MB  33.3GB  32.2GB                                 lvm
      4      33.3GB  34.4GB  1074MB  xfs          Linux filesystem
      5      34.4GB  35.4GB  1033MB  ext4         test-part
      
  • gdisk:对GPT分区表进行分区

    • 执行命令

      [root@study ~]# gdisk /dev/sda
      GPT fdisk (gdisk) version 0.8.6
      
      Partition table scan: # 做了分区表扫描
      MBR: protective
      BSD: not present
      APM: not present
      GPT: present
      
      Found valid GPT with protective MBR; using GPT.
      
      Command (? for help):
      
      • 输入?或者help来查看命令
    • 查看命令

      Command (? for help): ? # 查看命令
      b    back up GPT data to a file
      c    change a partition's name
      d    delete a partition
      i    show detailed information on a partition
      l    list known partition types
      n    add a new partition
      o    create a new empty GUID partition table (GPT)
      p    print the partition table
      q    quit without saving changes # 不保存直接退出
      r    recovery and transformation options (experts only)
      s    sort partitions
      t    change a partition's type code
      v    verify disk
      w    write table to disk and exit # 保存操作后退出
      x    extra functionality (experts only)
      ?    print this menu
      
      • q直接退出不保存操作,即所有对磁盘的操作都不会生效。
      • w保存操作后退出。与q相反
    • 查看分区信息

      Command (? for help): p
      Disk /dev/sda: 83886080 sectors, 40.0 GiB
      Logical sector size: 512 bytes
      Disk identifier (GUID): CF7ACF59-2ED1-4092-9353-928E9D843853
      Partition table holds up to 128 entries
      First usable sector is 34, last usable sector is 83886046
      Partitions will be aligned on 2048-sector boundaries
      Total free space is 16764861 sectors (8.0 GiB)
      
      Number  Start (sector)    End (sector)  Size       Code  Name
      1            2048            6143   2.0 MiB     EF02
      2            6144         2103295   1024.0 MiB  0700
      3         2103296        65026047   30.0 GiB    8E00
      4        65026048        67123199   1024.0 MiB  8300  Linux filesystem
      
      Command (? for help):
      
      • 可以看出磁盘大小为40.0G,有83886080个扇区,且每个扇区的大小为512Byte:\(83886080{\times}512(B) = 40(GB)\)
      • Number: 分区编号,1号指的是/dev/sda1/
      • Start(sector):分区的起始扇区号。\((6143-2048 + 1){\times}512(B) = 2(MB):\)
      • End(sector):分区的结束扇区号
      • Size:分区容量
      • Code:分区内**可能**的文件系统类型,只是一个**提示**而已,不代表就是文件系统的真实类型。
      • Name:文件系统名称
        • 新增一个分区
      Command (? for help): n
      Partition number (5-128, default 5): # 新增分区的编号。回车即可,即往后增加一个编号
      First sector (34-83886046, default = 67123200) or {+-}size{KMGTP}: # 新增分区的起始扇区号。回车即可,即:已使用的最后一个编号+1
      Last sector (67123200-83886046, default = 83886046) or {+-}size{KMGTP}: 1G
      Last sector (67123200-83886046, default = 83886046) or {+-}size{KMGTP}: +1G # 新增分区的结束扇区号。可以指定具体扇区号,也可以通过+或-来让其帮忙计算扇区号
      Current type is 'Linux filesystem'
      Hex code or GUID (L to show codes, Enter = 8300): # 当前的系统类型,提示作用,不知道的话可以键入L查看
      Changed type of partition to 'Linux filesystem'
      
      Command (? for help): p
      Disk /dev/sda: 83886080 sectors, 40.0 GiB
      Logical sector size: 512 bytes
      Disk identifier (GUID): CF7ACF59-2ED1-4092-9353-928E9D843853
      Partition table holds up to 128 entries
      First usable sector is 34, last usable sector is 83886046
      Partitions will be aligned on 2048-sector boundaries
      Total free space is 14667709 sectors (7.0 GiB)
      
      Number  Start (sector)    End (sector)  Size       Code  Name
      1            2048            6143   2.0 MiB     EF02
      2            6144         2103295   1024.0 MiB  0700
      3         2103296        65026047   30.0 GiB    8E00
      4        65026048        67123199   1024.0 MiB  8300  Linux filesystem
      5        67123200        69220351   1024.0 MiB  8300  Linux filesystem
      
    • 保存操作并退出:键入w命令并在提示收否保存时键入:y

    • 查看当前分区情况:
      • lsblkcat /proc/partitions
        • 会发现刚才新建的sda5分区
    • 更新分区表
      • 可以通过partprobe命令来更新分区表。
  • fdisk:对MBR分区表进行分区

    • 默认使用柱面(cylinder)作为分区的最小单位,而gdisk则默认使用扇区作为最小单位。
  • 使用方法:通过lsblkblkid先找到磁盘,再用parted /dev/xxx print来找出内部的分区类型,之后再用gdiskfdisk来管理分区。

  • 注意:千万不要删除一个正在使用中的分区,在操作前确保分区已经卸载。

磁盘格式化

  • 工具:mkfs(make filesystem)

  • XFS文件系统 mkfs.xfs

    mkfs.xfs [-b bsize] [-d parms] [-i parms] [-l parms] [-L label] [-f] [-r parms] 设备名称
    选项与参数:
    关于单位:下面只要谈到【数值】时,没有加单位则为Bytes,可以用k、m、g、t、p(小写)等来解释,比较特殊的是s这个单位,他指的是扇区的【个数】
    -b      后面接的是区块容量,可由512到64k,不过最大容量限制为Linux的4k。
    -d      后面接的是重要的data section的相关参数,主要的值有:
            agcount=数值    : 设置需要几个存储群组(AG)
            agsize=数值     : 指定每个AG为多少,通常agcount与agsize只选一个设置
            file           : 指的是【格式化的设备是个文件而不是设备】的意思,(例如虚拟磁盘)
            size=数值       : data section的容量,即你可以不将真个设备容量用完的意思
            su=数值         : 当有RAID时,那个stripe数值的意思,与下面的sw搭配使用
            sw=数值         : 当有RAID时,用于保存数据的磁盘数量(必须扣除备份盘与备用盘)
            sunit=个数      : 与su相当,不过单位使用的是【几个sector(512Bytes大小)】的意思j
            swidth=个数     : 与sw相当
    -f      如果设备内已有文件系统,则需要使用这个-f来强制格式化
    -i      与inode相关的设置,主要的设置值有:
            size=数值       : inode大小,最小为256Bystes,最大为2k,一般保留256Bytes就够用了
    -l      与log section相关的设置,主要设置值有:
            internal=[0|1] : 是否为内置?默认为1内置,如果要用外部设备,使用下面设置
            logdev=device  : device就是外部设备的文件名,需要internal为0
            size=数值       : 日志的大小,通常要有512个区块,大约2M以上才行
    -L      后面接这个文件系统的标头名称Label name的意思
    -r      指定realtime section的相关设置值,主要设置值有:
            extsize=数值    : extent的大小,一般不需要设置,但有RAID时,最好设置与swidth的数值相同
    
    • AG个数可以跟CPU的内核数来做搭配。(逻辑个数,不是物理个数)
  • XFS文件系统 for RAID性能优化(Optional)

    • RAID(磁盘阵列)
      • 多块磁盘组成一块大磁盘,然后利用同步写入到这些磁盘的技术,不但可以加快读写速度还可以让在某一块磁盘坏掉的时候,整个文件系统还是可以持续运行,即容错。
      • 将文件先细分为数个小型的分区区块(stripe),然后将stripes分别放到RAID里的所有磁盘。
        • stripe数值大多介于4K和1M之间。
      • 为了文件安全性,会保留数个校验磁盘(parity disk),以及可能会保留一个以上的备用磁盘(spare disk)
    • 实例
      • 有4个线程的CPU数量,所以agcount为2
      • RAID的stripe为256K,因此su设置为256K
      • 因为磁盘阵列有8块,但有一块是parity disk,因此sw为7
      • 因此,数据单位容量为:\(256(K){\times}7=1792(K)\),因此extsize为1792K。
      • 因此可以如此设置:

        [root@study ~]# mkfs.xfs -f -d agcount=2,su=256k,sw=7 -r extsize=1792k /dev/sda5
        meta-data=/dev/sda5              isize=512    agcount=2, agsize=131072 blks
                 =                       sectsz=512   attr=2, projid32bit=1
                 =                       crc=1        finobt=0, sparse=0
        data     =                       bsize=4096   blocks=262144, imaxpct=25
                 =                       sunit=64     swidth=448 blks
        naming   =version 2              bsize=4096   ascii-ci=0 ftype=1
        log      =internal log           bsize=4096   blocks=2560, version=2
                 =                       sectsz=512   sunit=64 blks, lazy-count=1
        realtime =none                   extsz=1835008 blocks=0, rtextents=0
        
  • ext4文件系统 mkfs.ext4

    • 默认值配置文件:/etc/mke2fs.conf
  • 其他文件系统 mkfs

文件系统检验

  • xfs_repair:处理XFS文件系统

    • 注意:当有xfs文件系统错乱的时候才用这个命令,否则最好是不要用到。
    Usage: xfs_repair [options] device
    
    Options:
    -f           The device is a file
    -L           Force log zeroing. Do this as a last resort.
    -l logdev    Specifies the device where the external log resides.
    -m maxmem    Maximum amount of memory to be used in megabytes.
    -n           No modify mode, just checks the filesystem for damage.
    -P           Disables prefetching.
    -r rtdev     Specifies the device where the realtime section resides.
    -v           Verbose output.
    -c subopts   Change filesystem parameters - use xfs_admin.
    -o subopts   Override default behaviour, refer to man page.
    -t interval  Reporting interval in seconds.
    -d           Repair dangerously. # 通常用在单人维护模式下,针对根目录(/)进行检查与修复的操作,很危险,不要随便使用。
    -V           Reports version and exits.
    
    • 修复时该文件系统不能被挂载。
    • Linux的根目录无法被卸载,因此需要进入单人维护或恢复模式,然后通过-d选项来检验根目录。
  • fsck.ext4:处理ext4文件系统

  • 注意

    • 通常只有root且你的文件系统有问题时才使用这个命令,否则正常状况下使用此命令的话可能会对系统造成伤害。
    • 由于xfs_repair与fsck.ext4在扫描磁盘的时候可能会造成部分系统文件的改变,因此务必确保要检查的磁盘分区处于卸载状态。

文件系统挂载与卸载

  • 挂载前需要确保
    • 单一文件系统不应该被重复挂载在不同的挂载点(目录)中
    • 单一目录不应该重复挂载多个文件系统
    • 要作为挂载点的目录,理论上应该都是空目录才行
      • 目录被挂载上文件系统后,原油目录下的东西就会暂时地消失。
  • 挂载工具:mount

    • 相关配置文件
      • /etc/filesystems:系统指定的测试挂载文件系统类型的优先级。
      • /proc/filesystems:Linux系统已经加载的文件系统类型。
      • /lib/modules/$(uname -r)/kernel/fs/:Linux支持的文件系统驱动程序所在目录
    • 挂载xfs/ext4/vfat等文件系统

      • 示例:

        [root@study ~]# mkdir /data/xfs
        [root@study ~]# blkid
        /dev/sda2: UUID="7703e582-63b3-48a3-b925-4972a24cdf06" TYPE="xfs" PARTUUID="e80b900a-1f7a-4489-8603-138158a8f95c"
        /dev/sda3: UUID="AP04Be-Lx2l-Psbc-0Vco-cXE3-N9Uj-HiddzF" TYPE="LVM2_member" PARTUUID="8ef31eee-8c18-47e2-9ea1-ac9d6a8d29b5"
        /dev/sda4: UUID="8c7e2ba7-0835-45a1-b38c-7bf1540723ba" TYPE="xfs" PARTLABEL="Linux filesystem" PARTUUID="57ee107c-3479-436e-b0ef-f3ca11dcd532"
        /dev/mapper/centos-root: UUID="569fa037-7f25-4061-a78c-3c1a46364e1c" TYPE="xfs"
        /dev/mapper/centos-swap: UUID="8895e1ff-13b8-4e51-b907-b6a4fa5690f8" TYPE="swap"
        /dev/mapper/centos-home: UUID="41ae3675-50f0-4ff8-9067-aaa9727bcdc8" TYPE="xfs"
        /dev/sda5: UUID="e2887930-05c1-4620-9afa-ab809ff8beb8" TYPE="xfs" PARTLABEL="Linux filesystem" PARTUUID="3808c3e4-1d5d-4939-a767-2d05801b2220"
        /dev/sda1: PARTUUID="2676091d-db5c-4d43-9dc1-51ffd1167271"
        [root@study ~]# mount UUID="e2887930-05c1-4620-9afa-ab809ff8beb8" /data/xfs
        
    • 挂载CD或DVD光盘

      • 示例:

        [root@study ~]# mkdir /data/cdrom
        [root@study ~]# blkid
        /dev/sda2: UUID="7703e582-63b3-48a3-b925-4972a24cdf06" TYPE="xfs" PARTUUID="e80b900a-1f7a-4489-8603-138158a8f95c"
        /dev/sda3: UUID="AP04Be-Lx2l-Psbc-0Vco-cXE3-N9Uj-HiddzF" TYPE="LVM2_member" PARTUUID="8ef31eee-8c18-47e2-9ea1-ac9d6a8d29b5"
        /dev/sda4: UUID="8c7e2ba7-0835-45a1-b38c-7bf1540723ba" TYPE="xfs" PARTLABEL="Linux filesystem" PARTUUID="57ee107c-3479-436e-b0ef-f3ca11dcd532"
        /dev/mapper/centos-root: UUID="569fa037-7f25-4061-a78c-3c1a46364e1c" TYPE="xfs"
        /dev/mapper/centos-swap: UUID="8895e1ff-13b8-4e51-b907-b6a4fa5690f8" TYPE="swap"
        /dev/mapper/centos-home: UUID="41ae3675-50f0-4ff8-9067-aaa9727bcdc8" TYPE="xfs"
        /dev/sda5: UUID="e2887930-05c1-4620-9afa-ab809ff8beb8" TYPE="xfs" PARTLABEL="Linux filesystem" PARTUUID="3808c3e4-1d5d-4939-a767-2d05801b2220"
        /dev/sr0: UUID="2018-11-26-14-22-58-00" LABEL="CentOS 7 x86_64" TYPE="iso9660" PTTYPE="dos"
        /dev/sda1: PARTUUID="2676091d-db5c-4d43-9dc1-51ffd1167271"
        [root@study ~]# mount /dev/sr0 /data/cdrom/
        mount: /dev/sr0 写保护,将以只读方式挂载
        [root@study ~]# df /data/cdrom/
        文件系统         1K-块    已用  可用 已用% 挂载点
        /dev/sr0       4364408 4364408     0  100% /data/cdrom
        
        • 光驱以挂载之后就无法退出光盘了,除非你将它卸载才能够退出。
        • 磁盘使用率为100%的原因是因为其是光盘不可写。
        • 如果是图形界面,那么系统会自动帮你挂载到/media目录
    • 挂载vfat中文移动硬盘(USB磁盘)

      • 示例:
      [root@study wang_hongqi]# blkid
      /dev/sda2: UUID="7703e582-63b3-48a3-b925-4972a24cdf06" TYPE="xfs" PARTUUID="e80b900a-1f7a-4489-8603-138158a8f95c"
      /dev/sda3: UUID="AP04Be-Lx2l-Psbc-0Vco-cXE3-N9Uj-HiddzF" TYPE="LVM2_member" PARTUUID="8ef31eee-8c18-47e2-9ea1-ac9d6a8d29b5"
      /dev/sda4: UUID="8c7e2ba7-0835-45a1-b38c-7bf1540723ba" TYPE="xfs" PARTLABEL="Linux filesystem" PARTUUID="57ee107c-3479-436e-b0ef-f3ca11dcd532"
      /dev/mapper/centos-root: UUID="569fa037-7f25-4061-a78c-3c1a46364e1c" TYPE="xfs"
      /dev/mapper/centos-swap: UUID="8895e1ff-13b8-4e51-b907-b6a4fa5690f8" TYPE="swap"
      /dev/mapper/centos-home: UUID="41ae3675-50f0-4ff8-9067-aaa9727bcdc8" TYPE="xfs"
      /dev/sda5: UUID="e2887930-05c1-4620-9afa-ab809ff8beb8" TYPE="xfs" PARTLABEL="Linux filesystem" PARTUUID="3808c3e4-1d5d-4939-a767-2d05801b2220"
      /dev/sr0: UUID="2018-11-26-14-22-58-00" LABEL="CentOS 7 x86_64" TYPE="iso9660" PTTYPE="dos"
      /dev/sdb1: LABEL="homqyy-32GB" UUID="3A17-2540" TYPE="exfat"
      /dev/sda1: PARTUUID="2676091d-db5c-4d43-9dc1-51ffd1167271"
      [root@study wang_hongqi]# mount -o codepage=950,iocharset=utf-8 UUID="3A17-2540" /data/usb
      FUSE exfat 1.2.7
      [root@study wang_hongqi]# df /data/usb/
      文件系统          1K-块    已用     可用 已用% 挂载点
      /dev/sdb1      30718656 8242240 22476416   27% /data/usb
      
      • 如果是中文名可以在挂载时指定所使用的语系:codepage指定语系。iocharset设置字符集
    • 重新挂载根目录与挂载不特定目录

      • 如果挂载的参数或则根目录出现【只读】状态时,可以通过重新挂载来解决:mount -o remount,rw,auto /
        • 单人维护模式的时候根目录会被挂载为只读,此时可以使用此方法
    • 挂载某个目录到另一个目录mount --bind /var /data/var
  • 卸载工具:umount

磁盘/文件系统参数自定义

  • mknode:创建设备文件名

    • 设备文件本质是通过major与minor来代表设备的。

      [root@study wang_hongqi]# ls -l /dev/sda*
      brw-rw----. 1 root disk 8, 0 8月  25 21:57 /dev/sda
      brw-rw----. 1 root disk 8, 1 8月  25 21:57 /dev/sda1
      brw-rw----. 1 root disk 8, 2 8月  25 21:57 /dev/sda2
      brw-rw----. 1 root disk 8, 3 8月  25 21:57 /dev/sda3
      brw-rw----. 1 root disk 8, 4 8月  25 21:57 /dev/sda4
      brw-rw----. 1 root disk 8, 5 8月  25 21:59 /dev/sda5
      
      • 8是主设备号,0 ~ 5是从设备号。
        • 常见的文件名与设备代码:
          磁盘文件名majominor
          /dev/sda80 ~ 15
          /dev/sdb816 ~ 31
          /dev/loop070
          /dev/loop171
  • xfs_admin:修改XFS文件系统的UUID与Label name

  • uuidgen:产生UUID
  • tune2fs:修改ext4的UUID与Label name

设置启动挂载

启动挂载/etc/fstab及/etc/mtab

  • 系统挂载的一些限制
    • 根目录/是必须挂载的,而且一定要先于其他挂载点被挂载
    • 其他挂载点必须为已建立的目录,可任意指定,但一定要遵守必需的系统目录架构原则(FHS)
    • 所有挂载点在同一时间之内,只能挂载一次。
    • 所有硬盘分区在同一时间之内,只能挂载一次。
    • 若进行卸载,必需先将工作目录移动到挂载点之外。
  • 系统会读取/etc/fstab文件的内容并挂载。

    [root@study wang_hongqi]# cat /etc/fstab
    #
    # /etc/fstab
    # Created by anaconda on Sat Jun  8 22:57:49 2019
    #
    # Accessible filesystems, by reference, are maintained under '/dev/disk'
    # See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
    #
    # Device    Mount point     filesystem      parameters      dump    fsck
    /dev/mapper/centos-root /                       xfs     defaults        0 0
    UUID=7703e582-63b3-48a3-b925-4972a24cdf06 /boot                   xfs     defaults        0 0
    /dev/mapper/centos-home /home                   xfs     defaults        0 0
    /dev/mapper/centos-swap swap                    swap    defaults        0 0
    /dev/sda4 /srv/myproject xfs defaults 0 0
    
    • 6个字段的自已[设备/UUID等] [挂载点] [文件系统] [文件系统参数] [dump] [fsck]
      • 第一栏:磁盘设备文件名/UUID/Lable name
      • 第二栏:挂载点,一定得是目录
      • 第三栏:磁盘分区的文件系统
      • 第四栏:文件系统参数,就是mount的-o后面接的参量
        参数内容意义
        async/sync
        异步/同步
        设置磁盘是否以异步方式运行,默认为async(性能较佳)
        auto/noauto
        自动/非自动
        当执行mount -a时,此文件系统是否会被主动测试挂载,默认为auto
        rw/ro
        可擦写/只读
        让该分区以可读写或只读的状态挂载上来
        exec/noexec
        可执行/不可执行
        限制在此文件系统内是否可以进行【执行】的工作,如果是存粹用来存储数据的目录,那么可以设置为noexec会比较安全。不过,这个参数也不能随便使用,因为你不知道该目录是否默认会有执行文件。
        user/nouser
        允许/不允许用户挂载
        是否允许用户使用mount命令来挂载?一般而言,我们当然不希望一般身份的user能够使用mount,因此这里应该要设置为nouser
        suid/nosuid
        具有/不具有suid权限
        该文件系统是否允许SUID的存在
        defaults同时具有rw、suid、dev、exec、auto、nouser、async等参数,基本上,默认情况使用defaults设置即可
      • 第五栏:能否被dump备份命令作用
        • dump是一个用来做为备份的命令,不过现在有太多的备份方案,所以这个项目可以不要理会,直接输入0就好。
      • 第六栏:是否以fsck检验扇区
    • /etc/fstab是启动时的配置文件,不过实际文件系统的挂载是记录到/etc/mtab/proc/mounts这两个文件中。

特殊设备loop挂载(镜像文件不刻录就挂载使用)

  • 可以将大文件的空间映射为loop设备的空间,然后通过操作loop设备来像操作其他设备一样。这样的话就可以在原有分区里再分出一个文件系统

    • 创建大文件

      [root@study srv]# dd if=/dev/zero of=/srv/loopdev bs=1M count=512
      记录了512+0 的读入
      记录了512+0 的写出
      536870912字节(537 MB)已复制,2.46276 秒,218 MB/秒
      
    • 大型文件的格式化

      [root@study srv]# mkfs.xfs -f /srv/loopdev
      meta-data=/srv/loopdev           isize=512    agcount=4, agsize=32768 blks
               =                       sectsz=512   attr=2, projid32bit=1
               =                       crc=1        finobt=0, sparse=0
      data     =                       bsize=4096   blocks=131072, imaxpct=25
               =                       sunit=0      swidth=0 blks
      naming   =version 2              bsize=4096   ascii-ci=0 ftype=1
      log      =internal log           bsize=4096   blocks=855, version=2
               =                       sectsz=512   sunit=0 blks, lazy-count=1
      realtime =none                   extsz=4096   blocks=0, rtextents=0
      [root@study srv]# blkid /srv/loopdev
      /srv/loopdev: UUID="b1aee6cb-9199-41ae-86a2-c72ed395d70a" TYPE="xfs"
      
    • 挂载

      [root@study srv]# mount -o loop UUID="b1aee6cb-9199-41ae-86a2-c72ed395d70a" /mnt
      [root@study srv]# df /mnt/
      文件系统        1K-块  已用   可用 已用% 挂载点
      /dev/loop0     520868 26388 494480    6% /mnt
      
    • 设置系统自动挂载

      [root@study srv]# vim /etc/fstab
      /srv/loopdev /data/file xfs defaults,loop 0 0
      
      • 因为大多数系统都是通过查询block device来找到UUID,而咱们这个是大文件,因此用文件名来设置比较合适。
  • 挂载CD/DVD镜像文件

    • mount -o loop /path/to/xxxx.iso /path/to/mount_point
    • 通过df可以看到loop设备名:df /path/to/mount_point

内存交换分区(swap)之创建

  • swap分区:用磁盘暂存内存数据的一个分区,当内存不足时会用到。
  • 相关工具
    • mkswap
    • swapon
    • swapoff
  • 在建立系统后创建swap分区的步骤:

    • 分区:使用gdisk工具(如果不能分区则需要创建大文件然后通过loop设备来实现)

      [root@study srv]# gdisk /dev/sda
      GPT fdisk (gdisk) version 0.8.6
      
      Partition table scan:
      MBR: protective
      BSD: not present
      APM: not present
      GPT: present
      
      Found valid GPT with protective MBR; using GPT.
      
      Command (? for help): n
      Partition number (6-128, default 6):
      First sector (34-83886046, default = 69220352) or {+-}size{KMGTP}:
      Last sector (69220352-83886046, default = 83886046) or {+-}size{KMGTP}: +512M
      Current type is 'Linux filesystem'
      Hex code or GUID (L to show codes, Enter = 8300): L
      0700 Microsoft basic data  0c01 Microsoft reserved    2700 Windows RE
      4200 Windows LDM data      4201 Windows LDM metadata  7501 IBM GPFS
      7f00 ChromeOS kernel       7f01 ChromeOS root         7f02 ChromeOS reserved
      8200 Linux swap            8300 Linux filesystem      8301 Linux reserved
      8e00 Linux LVM             a500 FreeBSD disklabel     a501 FreeBSD boot
      a502 FreeBSD swap          a503 FreeBSD UFS           a504 FreeBSD ZFS
      a505 FreeBSD Vinum/RAID    a580 Midnight BSD data     a581 Midnight BSD boot
      a582 Midnight BSD swap     a583 Midnight BSD UFS      a584 Midnight BSD ZFS
      a585 Midnight BSD Vinum    a800 Apple UFS             a901 NetBSD swap
      a902 NetBSD FFS            a903 NetBSD LFS            a904 NetBSD concatenated
      a905 NetBSD encrypted      a906 NetBSD RAID           ab00 Apple boot
      af00 Apple HFS/HFS+        af01 Apple RAID            af02 Apple RAID offline
      af03 Apple label           af04 AppleTV recovery      af05 Apple Core Storage
      be00 Solaris boot          bf00 Solaris root          bf01 Solaris /usr & Mac Z
      bf02 Solaris swap          bf03 Solaris backup        bf04 Solaris /var
      bf05 Solaris /home         bf06 Solaris alternate se  bf07 Solaris Reserved 1
      bf08 Solaris Reserved 2    bf09 Solaris Reserved 3    bf0a Solaris Reserved 4
      bf0b Solaris Reserved 5    c001 HP-UX data            c002 HP-UX service
      ed00 Sony system partitio  ef00 EFI System            ef01 MBR partition scheme
      ef02 BIOS boot partition   fb00 VMWare VMFS           fb01 VMWare reserved
      fc00 VMWare kcore crash p  fd00 Linux RAID
      Hex code or GUID (L to show codes, Enter = 8300): 8200
      Changed type of partition to 'Linux swap'
      
      Command (? for help): w
      
      Final checks complete. About to write GPT data. THIS WILL OVERWRITE EXISTING
      PARTITIONS!!
      
      Do you want to proceed? (Y/N): y
      OK; writing new GUID partition table (GPT) to /dev/sda.
      Warning: The kernel is still using the old partition table.
      The new table will be used at the next reboot.
      The operation has completed successfully.
      [root@study srv]# partprobe
      
    • 格式化:使用mkswap工具

      [root@study srv]# mkswap /dev/sda6
      mkswap: /dev/sda6: warning: wiping old swap signature.
      正在设置交换空间版本 1,大小 = 524284 KiB
      无标签,UUID=0644792f-15bf-4009-92cc-6992d6acfaad
      [root@study srv]# blkid /dev/sda6
      /dev/sda6: UUID="0644792f-15bf-4009-92cc-6992d6acfaad" TYPE="swap" PARTLABEL="Linux swap" PARTUUID="278da640-bde2-4752-8286-27cc76f5dce5"
      
    • 使用:

      [root@study srv]# free -h
                  total        used        free      shared  buff/cache   available
      Mem:           1.8G        890M         87M         10M        843M        688M
      Swap:          1.0G        237M        786M
      [root@study srv]# swapon /dev/sda6
      [root@study srv]# free -h
                  total        used        free      shared  buff/cache   available
      Mem:           1.8G        891M         86M         10M        843M        687M
      Swap:          1.5G        236M        1.3G
      
  • 设置为启动挂载:/path/to/swap_dev swap swap defaults 0 0(在/etc/fstab文件中)

  • 问什么需要建立swap? > 因为内存交换分区主要的功能是当物理内存不够时,则某些在内存当中的程序会暂时被移动到内存交换分区中,让物理内存可以被需要的程序来使用。另外,如果你的主机支持电源管理模式,也就是说你的Linux主机系统可以进入【休眠】模式的话,那么运行当中的程序状态会被记录到内存交换分区中,以作为【唤醒】主机的状态依据。另外,某些程序在运行时,本来就会利用内存交换分区的特性来存放一些数据,所以内存交换分区还是需要建立的,只是不需要太大。

参考资料与扩展阅读

  • NULL(自己补充,不使用书本内容)

第8章 文件与文件系统的压缩

  • 常见的压缩文件扩展名

    *.Z         compress程序压缩的文件
    *.zip       zip程序压缩的文件
    *.gz        gzip程序压缩的文件
    *.bz2       bzip2程序压缩的文件
    *.xz        xz程序压缩的文件
    *.tar       tar程序打包的文件,并没压缩
    *.tar.gz    tar程序打包的文件,并且经过gzip压缩
    *.tar.bz2   tar程序打包,bzip2压缩
    *.tar.xz    tar程序打包,xz压缩
    

gzip, zcat/zmore/zless/zgrep

  • gzip:压缩文件或解压缩文件(可以解开compress、zip与gzip等软件所压缩的文件),它是为了替代compress而出现的。

    Usage: gzip [OPTION]... [FILE]...
    -c, --stdout      write on standard output, keep original files unchanged
    -d, --decompress  decompress
    -f, --force       force overwrite of output file and compress links
    -h, --help        give this help
    -l, --list        list compressed file contents
    -L, --license     display software license
    -n, --no-name     do not save or restore the original name and time stamp
    -N, --name        save or restore the original name and time stamp
    -q, --quiet       suppress all warnings
    -r, --recursive   operate recursively on directories
    -S, --suffix=SUF  use suffix SUF on compressed files
    -t, --test        test compressed file integrity
    -v, --verbose     verbose mode
    -V, --version     display version number
    -1, --fast        compress faster
    -9, --best        compress better
        --rsyncable   Make rsync-friendly archive
    
    With no FILE, or when FILE is -, read standard input.
    
    • 压缩后,源文件会消失,仅留下压缩后的文件,并增加后缀.gz
    • 可以使用-c选项,将压缩结果输出到屏幕,然后通过重定向来保存压缩文件:gzip -c /path/to/src_file > /path/to/compress_file.gz
    • zcat/zmore/zless/zgrep类似与cat/more/zless/zgrep,只是它的目标是gzip的压缩文件
  • znew可以将compress压缩的文件转成gzip格式的压缩文件

bzip2, bzcat/bzmore/bzless/bzgrep

  • bzip2:为了替代gzip而出现的,因此命令与gzip几乎一致。

xz, xzcat/xzmore/xzless/xzgrep

  • xz:比bzip2有更高的压缩比,当然压缩时速度自然也较慢。使用方式与gzip/bzip2几乎一样。

打包命令:tar

  • 压缩:tar -jcv -f filename.tar.bz2 要被压缩的文件或目录名称
  • 查询:tar -jtv -f filename.tar.bz2
  • 解压缩:tar -jxv - f filename.tar.bz2 -C 要解压压缩的目录

  • 基本名称:tarfile,tarball

    • tarfile:指的是只是打包,并未压缩的文件
    • tarball:指的是打包后并压缩的文件
  • tar可以将文件备份到某些特别的设备中:
    • 比如备份/home, /root, /etc到磁带中:tar -cv -f /dev/st0 /home /root /etc
  • 边打包边解压:tar -cvf - /etc | tar -xvf -

  • 恢复备份后的SELinux问题:恢复后发现无法登录系统了

    • 原因:由于/etc/shadow文件的SELinux类型被修改了,因此无法登录。
    • 解决方法:
      • 通过各种可行的恢复方式登录系统,然后修改/etc/selinux/config文件,将SELinux改成permissive模式,重启后就正常了。
      • 第一次恢复系统后,不要立刻重启,先使用restorecon -Rv /etc命令自动修复以下SELinux的类型。
      • 通过各种可行的方式登录系统,建立/.autorelabel文件,然后重新系统后就会自动修复SElinux类型了,并且会再次重启,重启后就正常了。

XFS文件系统的备份与还原

备份 xfsdump

  • 备份方式:完整备份、增量备份 xfsdump

    xfsdump备份示意图

  • xfsdump的限制

    • 不支持没有挂载的文件系统备份,所以只能备份已挂载的文件系统
    • 必须使用root的权限才能操作(涉及文件系统的关系)
    • 只能备份xfs文件系统
    • 备份下来的数据(文件或存储媒介)只能让xfsrestore解析
    • 通过文件系统的UUID来识别各备份文件的,因此不能备份两个具有相同UUID的文件系统
  • xfsdump

    xfsdump: usage: xfsdump [ -f <destination> ... ] # 存储备份的位置
                            [ -l <level> ] # 备份级别
                            [ -I (display dump inventory) ] # 显示在/var/lib/xfsdump/inventory目录下备份信息的状态
                            [ -L <session label> ] # 添加会话的标头
                            [ -M <media label> ... ] # 添加媒体数据的标头
    
    • 示例:
      • 完整备份:xfsdump -l 0 -L boot_all -M boot_all -f /srv/boot.dump /boot
      • 基于完整备份的增量备份:xfsdump -l 1 -L boot_1 -M boot_1 -f /srv/boot.dump1

恢复 xfsrestore

  • xfsrestore

    [root@study srv]# xfsrestore -I                 <==用来查看备份文件
    [root@study srv]# xfsrestore [-f 备份文件] [-L S_label] [-s] 待恢复目录 <==单一文件全系统恢复
    [root@study srv]# xfsrestore [-f 备份文件] [-r] 待恢复目录 <==通过增量备份文件来恢复系统
    [root@study srv]# xfsrestore [-f 备份文件] [-i] 待恢复目录 <==进入交互模式
    xfsrestore: usage: xfsrestore [ -f <source> ... ] # 备份的绘制
                                [ -i (interactive) ] # 进入交互模式,高级管理员使用
                                [ -r (cumulative restore) ] # 如果用文件来存储备份数据,则不需要使用,如果是一个磁带内有多个文件,则需要此项来完成累积恢复
                                [ -s <subtree> ... ] # 接某个目录,即恢复某个文件或目录的意思
                                [ -I (display dump inventory) ] # 查询备份数据,与xfsdump输出一样
                                [ -L <session label> ]
                                [ <destination> ] # 待恢复的目录
    
    • 示例:
      • 完整备份恢复:xfsrestore -f /srv/boot.dump -L boot_all /boot
        • 注意,在恢复的时候只会覆盖旧文件,新文件仍旧存在。
      • 仅恢复单一目录:xfsrestore -f /srv/boot.dump -L boot_all -s grub2 /tmp/boot
      • 增量恢复(这里恢复level1):xfsrestore -f /srv/boot.dump1 /tmp/boot
      • 交互式还原:xfsrestore -f /srv/boot.dump -i /tmp/boot
        • 交互式对查看备份里面有哪些目录文件很有帮助

光盘写入工具

  • 相关工具

    • mkisofs:生成iso文件
    • cdrecore:刻录
    • wodim:新版本使用的刻录工具
    • isoinfo:查看iso信息
    • rsync:一个很好用的备份工具
  • 刻录步骤

    1. 利用mkisofs将所需要备份的数据创建成为一个镜像文件(iso)
    2. 利用cdrecord将镜像文件刻录至CD或DVD当中
  • 制作一般数据光盘镜像文件

    [root@study srv]# mkisofs [-o 镜像文件] [-Jrv] [-V vol] [-m file] 待备份文件... -graft-point isodir=systemdir ...
    选项与参数:
    -o              后面接你想要产生的那个镜像文件
    -J              产生兼容Windows的文件名结构,可增加文件名长度到64个unicode字符
    -r              通过Rock Ridge产生支持UNIX/Linux的文件数据,可记录较多信息(如UID/GID等)
    -v              显示创建ISO文件的过程
    -V vol          建立Volume,有点像Windows的CD卷标
    -m file         排除文件(exclude)的意思,后面的文件不备份到镜像文件中
    -graft-point    嫁接点
    
    • 示例:

      [root@study srv]# mkisofs -o /tmp/myiso/myiso.iso -r -v -graft-point /home=/home /etc/=/etc /root=/etc
      [root@study srv]# blkid /tmp/myiso/myiso.iso
      /tmp/myiso/myiso.iso: UUID="2019-08-26-17-23-56-00" LABEL="CDROM" TYPE="iso9660"
      [root@study srv]# mkdir /mnt/iso
      [root@study srv]# mount -o loop /tmp/myiso/myiso.iso /mnt/iso/
      mount: /dev/loop1 写保护,将以只读方式挂载
      [root@study srv]# ls -alh /mnt/iso/
      总用量 78K
      dr-xr-xr-x.   6 root root 2.0K 8月  26 17:23 .
      drwxr-xr-x.   3 root root   17 8月  26 17:26 ..
      dr-xr-xr-x. 137 root root  36K 8月  26 00:48 etc
      dr-xr-xr-x.   4 root root 2.0K 8月  10 23:35 home
      dr-xr-xr-x. 137 root root  36K 8月  26 00:48 root
      dr-xr-xr-x.  10 root root 2.0K 8月  26 17:23 rr_moved
      
  • 制作/修改可启动光盘镜像文件

    1. 查看镜像,是否为需要的镜像文件:isoinfo -d -i /home/CentOS-7-x86_64-Minimal-1511.iso
    2. 挂载镜像文件:mount /home/CentOS-7-x86_64-Minimal-1511.iso /mnt
    3. 创建并修改新的CD目录
      • mkdir /srv/newcd
      • rsync -a /mnt/ /srv/newcd
      • ...(假设放置了用于启动引导的isolinux/目录)
    4. 制作镜像:
      1. cd /srv/newcd
      2. mkisofs -o /custom.iso -b isolinux/isoLinux.bin -c isolinuxboot.cat -no-emul-boot -V 'CentOS 7 x86_64' -boot-load-size 4 -boot-info-table -R -J -v -T ./

刻录

  • wodim

    [root@study srv]# wodim --devices dev=/dev/sr0... <==检查刻录机的bus位置
    [root@study srv]# wodim -v dev=/dev/sr0 blank=[fast|all] <==抹除重复读写盘
    [root@study srv]# wodim -v dev=/dev/sr0 --format <==格式化DVD+RW
    [root@study srv]# wodim -v dev=/dev/sr0 [可用选项功能] file.iso
    选项与参数:
    --devices               用在扫描磁盘总线并找出可用的刻录机,后续的设备为ATA接口
    -v                      在cdrecord运行的过程中显示过程
    dev=/dev/sr0            可以找出此光驱的bus地址,非常重要
    blank=[fast|all]        blank为抹除可重复写入的CD/DVD-RW,使用fast较快,all较完整
    -format                 对光盘进行格式化,但是仅针对DVD+RW这种格式的DVD而已
    [可用选项功能] 主要是写入CD/DVD时候=可使用的选项,常见的选项包括有:
        -data               指定后年的文件以数据格式写入,不是以CD音轨(-audio)方式写入
        speed=X             指定刻录速度,例如CD可用speed=40为40倍数,DVD可用speed=4之类
        -eject              指定刻录完毕后自动推出光盘
        fs=Ym               指定缓冲内存大小,可用在将镜像文件先暂存至缓冲内存,默认为4m一般建议加到8m,不过还是得看刻录机来设定
    针对DVD的选项功能:
        driveropts=burnfree     打开Buffer Underrun Free模式的写入功能
        -sao                    支持DVD-RW的格式
    
  • 检查刻录机的位置:wodim --divices dev=/dev/sr0

  • 抹除光盘:wodim -v dev=/dev/sr0 blank=fast
  • 刻录光盘:wodim -v dev=/dev/sr0 speed=4 -dummy -eject /tmp/myiso/myiso.iso

其他常见的压缩与备份工具

  • dd:dd可以直接读取磁盘设备的内容(几乎是直接读取扇区)
    • 直接备份分区,无需格式化,但是需要先清除日志
      • xfs_repair -L /dev/sda1
      • dd if=/dev/sda1 of=/dev/sda2
  • cpio

    • 该命令什么都能备份,包括设备文件等。
    • 该命令不会主动找文件来备份,因此需要配合其他工具和重定向来实现。
    [root@study srv]# cpio -ovcB > [file|device] <==备份
    [root@study srv]# cpio -ivcdu < [file|device] <==还原
    [root@study srv]# cpio -ivct < [file|device] <==查看
    

参考资料与扩展阅读

  • 压缩技术:RFC1952

第9章 vim程序编辑器

多文件编辑

  • 多文件编辑的方法:vim file1 file2 ...
  • 常用的按键有:
    多文件编辑的按键
    :n编辑下一个文件
    :N编辑上一个文件
    :files列出目前这个vim开启的所有文件

多窗口功能

  • :[v]sp filename
    • **sp**是横屏,**vsp**是竖屏
    • 没有输入**filename**是在两个窗口显示相同的文件内容,加了**filename**则在另一个窗口打开另一个文件
    • 切换屏幕:
      • ctrl+w+w:按顺时针切屏
      • ctrl+w+[hjkl]:左、下、上、右切屏
    • :close关闭屏幕

关键词补全功能

补齐的内容
组合键
ctrl + x -> ctrl + n通过目前正在编辑的这个【文件的内容文字】作为关键词,予以补齐
ctrl + x -> ctrl + f以当前目录内的【文件名】作为关键字,予以补齐
ctrl + x -> ctrl + o以扩展名作为语法补充,以vim内置的关键字,予以补齐

环境设置与记录

  • ~/.vimrc:该文件是vim初始化配置的文件
    • :set all来查看可以配置的设置
  • ~/.viminfo:该文件是记录你操作信息的文件

  • 常用的vim环境设置参数

    vim的环境设置参数
    :set nu
    :set nonu
    设置与取消行号
    :set hlsearch
    :set nohlsearch
    搜索高亮与否
    :set autoindent
    :set noautoindent
    自动缩进与否
    :set backup
    :set nobackup
    是否自动保存备份文件,如果设置了自动备份,则每次改动文件都会生成一个**filename~**的备份文件
    :set ruler
    :set noruler
    是否在状态栏里显示一些标尺数据
    :set showmode
    :set noshowmode
    是否在状态栏里显示模式
    :set backspace=[0|1|2]设置退格的权限:
    • 0/1:仅可删除刚输入的字符
    • 可以删除任意值
    :set all可以显示目前所有环境参数设置值
    :set显示与系统默认值不同的设置参数
    syntax [on|off]是否开启语法解析(比如高亮、排错等)
    :set bg=[dark|light]设置背景颜色

其他

  • 语系编码转换工具:iconv
  • DOS与Linux的换行符:dos2unix、unix2dos

参考资料

  • NULL

第10章 认知与学习BASH

认识Bash这个Shell

hardware_kernel_user

图 硬件、内核与用户的相关性图例

  • Shell:只要能够操作应用程序的软件都能被成为Shell程序。
    • 狭义:命令行方面的软件,包括bash等。
    • 广义:包括用户界面模式的软件,因为图形界面模式也能够操作各种应用程序来调用内核工作。
  • Shell就是系统的灵魂,图形界面本身也等于禁锢,因此想要管理好系统,玩好系统,Shell操作是必备的技能。

  • 可以通过/etc/shells查看当前系统下支持哪些shell

  • 为什么系统合法的shell要写入/etc/shells这个文件? > > - 因为某些服务在运行中会去检查用户能够使用的shell(/etc/shadow里就写明了用户默认会使用的shell)。 > - 比如:如果你不想让某些用户除了使用FTP外的主机资源时,就可以给他们给予一些奇怪的shell,这样他们就无法以其他服务登录主机。(比如系统中的/sbin/nologin文件)

Bash shelll的功能

  • history
    • 历史命令记录记录在~/.bash_history里,记录的是前一次登录以前执行过的命令,本次登录所执行的命令则被缓存在内存中。当成功注销后就会将缓存写入文件中。
  • 命令与文件补全功能:([Tab]按键的好处)
    • 好处:少打字;确保输入数据的正确
  • alias

    [wang_hongqi@study ~]$ alias dls='ls --color=auto -l -d
    [wang_hongqi@study ~]$ dls ~/test_dir/
    drwxrwxrwt. 2 root root 6 6月   9 22:59 /home/wang_hongqi/test_dir/
    
  • 任务管理、前台、后台控制(job control、foreground、background)

    • 相关工具:fg、bg、jobs
  • shell scripts:shell脚本
  • Wildcard:会自动展开文件名后,作为参数传入命令。例如:ls ~/*

  • type

    • 查找内置命令
    • 查找执行文件而不是一般文件名(文件没有x权限的话,也是不会显示的)
    • 当使用-t参数来显示命令类型的时候,其类型字段意思:
      • file:外部命令
      • alias:别名
      • builtin:shell内置命令
  • 转义:命令太长可以通过\[Enter]来将[Enter]这个按键转义,使之不会执行命令允许继续输入命令。

    • 注意:\转义的是下一个字符,因此\[Enter]间是没有其他字符的,比如空格。
  • 快捷键

Shell的变量功能

变量的设置与使用

  • 环境变量:为了区分,以大写字符来表示。
  • 显示变量:echo $var
  • 设置变量:
    • 变量与变量内容以一个等号来连接:var=value
    • 等号两边不能有空格err_var = value ok_var=value
    • 变量名称只能是英文字母、数字与下划线,但是开头不能是数字:2err_var=value ok_var=value
  • 取消变量:unset var

  • 双引号内可以引用变量:

    [wang_hongqi@study ~]$ var="lang is $LANG"
    [wang_hongqi@study ~]$ echo $var
    lang is zh_CN.UTF-8
    
  • 单引号内不可以引用变量

    [wang_hongqi@study ~]$ var='lang is $LANG'
    [wang_hongqi@study ~]$ echo $var
    lang is $LANG
    
  • 执行命令:

    • 反引号:`命令`

      [wang_hongqi@study ~]$ ls /lib/modules/`uname -r`/kernel
      arch  crypto  drivers  fs  kernel  lib  mm  net  sound  virt
      
    • $ (命令)

      [wang_hongqi@study ~]$ ls /lib/modules/$(uname -r)/kernel
      arch  crypto  drivers  fs  kernel  lib  mm  net  sound  virt
      
  • 限定变量名范围:${var}

  • 将变量导出到环境变量:export var
    • 环境变量会传递给子进程

环境变量的功能

  • env:查看当前shell环境下的所有环境变量

    • HOME 用户的根目录
    • SHELL 目前这个环境使用的SHELL程序
    • HISTSIZE history记录的即使命令条数
    • MAIL 当前环境的mailbox未知
    • PATH 中间以:分隔,执行命令时就是依据PATH中设置的路径按顺序查找的。
    • LANG 语系
    • RANDOM 随机数变量,可以通过这个变量去获取随机数。Linux的发行版本中都会有随机数生成器:/dev/random
  • set:观察所有变量(环境变量、bash操作界面相关变量、用户自定义变量)

    • PS1:提示字符
    • $:本shell的PID
    • ?:上个执行命令的返回值
    • OSTYPE,HOSTTYPE,MACHTYPE:主机硬件与内核的等级
  • export:自定义变量转成环境变量

    • 子进程只会继承父进程的环境变量,不会继承自定义变量。

语系变量

  • locale:显示语系的工具

    • LANG:主语言的环境
    • LC_CTYPE:字符(文字)辨识的编码
    • LC_NUMERIC:数字系统的显示信息
    • LC_TIME:时间系统的显示数据
    • LC_COLLATE:字符的比较与排序
    • LC_MONETARY:货币格式的显示
    • LC_MESSAGES:信息显示的内容、如功能表、错误信息等。
    • LC_ALL:整体语系的环境
  • 系统默认支持的语系文件存放处:/etc/lib/locale

  • 设置系统默认的语系配置文件:/etc/locale.conf

变量的有效范围

  • 环境变量=全局变量;自定义变量=局部变量
  • 子进程继承环境变量的原因:
    • 当启动一个shell时,操作系统会分配一个内存去给shell使用,此内存中的变量可以让子进程使用。
    • 若在父进程利用export功能,则可让自定义变量的内容写到上述内存区域中(环境变量)
    • 当加载另一个shell时,子shell可以将父shell的环境变量所在的内存区导入自己的环境变量区中

read、array、declare

  • read:读取来自键盘输入的变量
  • declare、typeset:声明变量类型。

    • bash对于变量的几个基本定义:
      • 变量类型默认为字符串
      • bash环境中的数值运算,默认最多仅能达到整数形态,所以⅓结果是0.
  • array:数组变量类型。var[1], var[2], var[3]

ulimit

  • 限制用户资源
  • 0意味着没有限制

变量内容的删除、取代与替换

  • 变量内容的删除

    • 从前面开始(左往右)删除

      • ${var#pattern}:符合替换文字的**最短的**那一个
      • ${var##pattern}:符合替换文字的**最长的**那一个
      [wang_hongqi@study ~]$ echo $path
      /usr/lib64/qt-3.3/bin:/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:/home/wang_hongqi/.local/bin:/home/wang_hongqi/bin
      [wang_hongqi@study ~]$ echo ${path#/*qt*/bin:}
      /usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:/home/wang_hongqi/.local/bin:/home/wang_hongqi/bin
      
    • 从后年开始(右往左)删除

      • %:符合替换文字的**最短的**那一个
      • %%:符合替换文字的**最长的**那一个
    • 变量内容的替换
    • ${var/pattern/replace}:替换首个匹配成功的字符串(从左往右)

      [wang_hongqi@study ~]$ echo $path
      /usr/lib64/qt-3.3/bin:/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:/home/wang_hongqi/.local/bin:/home/wang_hongqi/bin
      [wang_hongqi@study ~]$ echo ${path/qt/homqyy}
      /usr/lib64/homqyy-3.3/bin:/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:/home/wang_hongqi/.local/bin:/home/wang_hongqi/bin
      
    • ${var//pattern/replace}:替换所有匹配成功的字符串

    • 变量的测试与内容替换
      变量设置方式str没有设置str为空字符串str已设置为非空字符串
      var=\({str-expr}</td><td>var=expr</td><td>var=</td><td>var=\)str
      var=\({str:-expr}</td><td>var=expr</td><td>var=expr</td><td>var=\)str
      var=\({str+expr}</td><td>var=</td><td>var=expr</td><td>var=\)str
      var=\({str:+expr}</td><td>var=</td><td>var=</td><td>var=\)str
      var=\({str=expr}</td><td>str=expr<br>var=expr</td><td>str不变<br>var=</td><td>str不变<br>var=\)str
      var=\({str:=expr}</td><td>str=expr<br>var=expr</td><td>str=expr<br>var=expr</td><td>str不变<br>var=\)str
      var=\({str?expr}</td><td>expr输出到stderr</td><td>var=</td><td>var=\)str
      var=\({str:?expr}</td><td>expr输出到stderr</td><td>expr输出到stderr</td><td>var=\)str

alias、unalias

  • alias:设置别名
  • unalias:删除别名

history

  • 快速运行历史命令:

    • !number:执行第n条命令
    • !command:执行最近执行过的命令
    • !!:执行上一条命令
  • 问题

    • 多重登录无法保证历史命令的顺序,因此很多人会选择用单一的bash登录,然后用job control来切换不同的任务。
    • 无法记录时间
      • 可以利用~/.bash_logout来解决,比如:

        [wang_hongqi@study ~]$ vim ~/.bash_logout
        >>>>>> .bash_logout
        date >> path/to/my_history
        history 50 >> path/to/my_history
        clear
        <<<<<< end
        

bash shell 的操作环境

  • 命令的运行顺序

    1. 以**相对/绝对路径**执行命令:./ls/bin/ls
    2. 由**alias**找到该命令来执行
    3. 由bash的**builtin**命令来执行
    4. 通过$PATH这个变量的顺序来找到第一个命令来执行
  • 登录与欢迎信息

    • /etc/issue 在终端界面登录时的提示信息,可以通过man issueman agetty来查看详细信息。
    • /etc/issue.net 与issue功能一样,但是是专门给telnet使用的。
    • /etc/motd 功能一样,只是这是在登录后显示

bash 的环境配置文件

  • login与non-login shell

    • login shell:取得bash时需要完整的登录流程,就成为login shell。
      • 读取配置
        • /etc/profile,这个属于整体设置,所有用户都会生效
          • 设置一些关键环境变量,调用/etc/profile.d/*.sh
            • /etc/locale.conf 是被 /etc/profile.d/lang.sh 调用的
            • __/usr/share/bash-completion/completions/__ 是被 */etc/profile.d/bash_completion.sh** 加载的
        • ~/.bash_profile~/.bash_login~/.profile,这个属于用户个人设置
          • 上看三个只有一个文件会生效,那么多文件的原因是由不同shell用户习惯导致。
          • 文件内部会调用~/.bashrc
    • non-login shell:不需要重复登录就能获取bash。比如以XWindow登录Linux后,再以X的图形化接口启动终端;或则在shell中以bash命令进入bash,此时也是一个non-login shell。
      • 读取配置
        • ~/.bashrc
          • 调用/etc/bashrc
            • 设置umask、PS1等,并调用/etc/profile.d/*
  • 其他相关配置文件

    • /etc/man_db.conf:man page的配置文件
    • ~/.bash_histroy:存放历史命令的配置文件
    • ~/.bash_logout:注销bash后,会执行该脚本

终端的环境设置:stty、set

  • stty:设置终端的输入环境

    • 查看当前终端的所有特性设置:stty -a

      • ^的意思是:[ctrl]
      [wang_hongqi@study ~]$ stty -a
      speed 38400 baud; rows 42; columns 158; line = 0;
      intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = M-^?; eol2 = M-^?; swtch = M-^?; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W;
      lnext = ^V; flush = ^O; min = 1; time = 0;
      -parenb -parodd -cmspar cs8 hupcl -cstopb cread -clocal -crtscts
      -ignbrk brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff -iuclc ixany imaxbel iutf8
      opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
      isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt echoctl echoke
      
      • intr:发送一个interrupt信号给目前正在运行的程序
      • quit:发送一个quit信号给目前正在运行的程序
      • erase:向后删除字符
      • kill:删除在目前敏玲航商的所有文字
      • eof:End of file
      • start:重新启动它的output
      • stop:停止output
      • susp:发送一个terminal stop信号给正在运行的程序
  • set:设置命令的输出/输入环境

    • 选项
      • -x:在命令执行前,会显示信息的原始内容(可用于追踪脚本运行情况)。
      • -u:当未使用变量时会显示错误信息
      • -v:在读取输入的时候打印出来
      • -h:在查找并执行命令时记住他们的位置(历史命令)
      • -H:允许使用!来调用历史命令
      • -m:监视模式。作业控制被启用。后台进程单独的在进程组中运行,结束时打印它们的退出状态。
      • -B:允许使用{}扩展
      • -C:使用重定向操作符>, >&, 和 <>时,不会覆盖已存在的文件。可以使用重定向操作符>|代替>来创建输出文件,从而绕过这个限制。
      • -替换为`即是关闭。
    • 显示当前的set设置情况:

      [wang_hongqi@study ~]$ echo $-
      himBH
      
  • 其他关于按键设置的文件:

    • readline

      • 配置文件

        • /etc/inputrc
        • ~/.inputrc

          • 详细:man bash
          [wang_hongqi@study etc]$ cat ~/.inputrc
          Control-]: forward-word
          Control-[: backward-word
          
      • 常用的默认快捷键

        Numeric Arguments 数值参数
            digit-argument (M-0, M-1, ..., M--)
                将这个数字加入已有的 (already accumulating) 参数中,或者开始新的参数。 M-- 开始一个否定的参数。
        
        Commands for Moving 移动
            beginning-of-line (C-a)
                移动到当前行的开始。
            end-of-line (C-e)
                移动到当前行的结尾。
            forward-char (C-f)
                向前移动一字。
            backward-char (C-b)
                向后移动一字。
            forward-word (M-f)
                向前移动到下一词尾。词由字符 (字母和数字) 组成。
            backward-word (M-b)
                向后移动到当前或上一词首。
            clear-screen (C-l)
                清除屏幕,保留当前行在屏幕顶端。有参数时,刷新当前行,不清屏。
        
        Commands for Manipulating the History 操纵历史行
            previous-history (C-p)
                从历史列表中取得前一个命令,从列表中向后移动。
            next-history (C-n)
                从历史列表中取得后一个命令,从列表中向前移动。
            beginning-of-history (M-<)
                移动到历史中的第一行。
            end-of-history (M->)
                移动到输入历史行的末尾,也就是当前输入的行的末尾。
            reverse-search-history (C-r)
                从当前行开始向后搜索,按照需要在历史中向“上”移动。这是一个增量的搜索。
            forward-search-history (C-s)
                从当前行开始向前搜索,按照需要在历史中向“下”移动。这是一个增量的搜索。
            edit-and-execute-command (C-xC-e)
                启动一个编辑器,编辑当前命令行,将结果作为 shell 命令运行。 Bash 将依次试着运行 $FCEDIT, $EDITOR, 和 emacs 作为编辑器。
        
        Commands for Changing Text 改变文本
            delete-char (C-d)
                删除 point 处的字符。如果 point 在行首,行中没有字符,最后一次输入的字符 没有被关联到 delete-char,将返回 EOF.
            quoted-insert (C-q, C-v)
                将输入的下一字符保持原样添加到行中。例如,可以用它来插入类似 C-q 的字符。
            tab-insert (C-v TAB)
                插入一个跳格符号。
            transpose-chars (C-t)
                将point之前的字符向前移动,越过point处的字符,同时也改变point的位置。如果point在行尾,将调换point之前的两个字符。负数参数没有作用。
            transpose-words (M-t)
                将 point 之前的词向前移动,越过 point 处的词,同时也改变 point 的位置。 如果 point 在行尾,将调换行中的最后两个词。
            upcase-word (M-u)
                将当前 (或下一个) 词变成全大写。有负值的参数时,将前一个词变为大写, 但是不移动 point。
            downcase-word (M-l)
                将当前 (或下一个) 词变成全小写。有负值的参数时,将前一个词变为小写, 但是不移动 point。
            capitalize-word (M-c)
                将当前 (或下一个) 词变为首字大写。有负值的参数时,将前一个词变为首字大写, 但是不移动 point。
        
        Killing and Yanking 剪切和粘贴
            kill-line (C-k)
                剪切从 point 到行尾的文本。
            unix-line-discard (C-u)
                反向剪切到行首。与 backward-kill-line 没有什么区别。 剪切的文本被保存于 kill-ring 中。
            kill-word (M-d)
                剪切从 point 到当前词尾,或者如果 point 在词之间,那么剪切到下一词尾。
            unix-word-rubout (C-w)
                剪切 point 之后的词,使用空白作为词的边界。剪切的文本被保存于 kill-ring 中。
            yank (C-y)
                将 kill-ring 顶部的内容粘贴到 point 处的缓冲区中
        
        Completing 补全
            complete (TAB)
                试着对 point 之前的文本进行补全。 Bash 依次试着将文本作为一个变量 (如果文本以 $ 开始),一个用户名 (如果文本以 ~ 开始),主机名 (如果文本以@开始),或者命令 (以及别名和函数) 来补全。如果这些都没有匹配,将尝试文件名补全。
            possible-completions (M-?)
                列出 point 之前的文本可能的补全。
            complete-filename (M-/)
                尝试对 point 之前的文本进行文件名补全。
            possible-filename-completions (C-x /)
                列出 point 之前的文本可能的补全,将它视为文件名。
            complete-username (M-~)
                尝试对 point 之前的文本进行补全,将它视为用户名。
            possible-username-completions (C-x ~)
                列出 point 之前的文本可能的补全,将它视为用户名。
            complete-variable (M-$)
                尝试对 point 之前的文本进行补全,将它视为 shell 变量。
            possible-variable-completions (C-x $)
                列出 point 之前的文本可能的补全,将它视为 shell 变量。
            complete-hostname (M-@)
                尝试对 point 之前的文本进行补全,将它视为主机名。
            possible-hostname-completions (C-x @)
                列出 point 之前的文本可能的补全,将它视为主机名。
            complete-command (M-!)
                尝试对point之前的文本进行补全,将它视为命令名。命令补全尝试着将此文本依次与别名,保留字,shell函数,shell内建命令,最后是可执行文件名进行匹配。
            possible-command-completions (C-x !)
                列出 point 之前的文本可能的补全,将它视为命令名。
        
        Keyboard Macros 宏
            start-kbd-macro (C-x ()
                    开始保存输入字符为当前键盘宏。
            end-kbd-macro (C-x ))
                    停止保存输入字符为当前键盘宏,保存宏定义。
            call-last-kbd-macro (C-x e)
                    重新执行上次定义的键盘宏,即显示出宏中的字符,好像它们是从键盘输入的一样。
        
        Miscellaneous
            set-mark (C-@, M-<space>)
                在 point 处设置 mark。如果给出了数值的参数,标记被设置到那个位置。
            exchange-point-and-mark (C-x C-x)
                交换 point 和 mark。当前光标位置被设置为保存的位置,旧光标位置被保存为 mark。
            character-search (C-])
                读入一个字符,point 移动到这个字符下一次出现的地方。负数将搜索上一个出现。
            character-search-backward (M-C-])
                读入一个字符,point 移动到这个字符上一次出现的地方。负数将搜索下面的出现。
            glob-complete-word (M-g)
                point 之前的词被当作路径扩展的一个模式,尾部暗含了一个星号。这个模式被用来 为可能的补全产生匹配的文件名列表。
        
    • 其他关于终端配置环境

      • /etc/DIR_COLORS*
      • /usr/share/terminfo/*

通配符与特殊符号

符号意义
*代表【0个到无穷多个】任意字符
?代表【一定有一个】任意字符
[]代表【一定有一个在括号内】的字符
[-]编码顺序内字符中的一个字符:[0-9]
[^]非列出的一个字符:[^abc]

数据流重定向

  • 重定向

    • 标准输入(stdin):0,<,<<,>&0

      • <:将指定文件的内容作为输入使用
      • <<:确定结束字符,由交互式输入数据

        [wang_hongqi@study etc]$ cat << "eof"
        > haha
        > haha2
        > eof
        haha
        haha2
        [wang_hongqi@study etc]$
        
    • 标准输出(stdout):1,>,>>,1>,1>>,>&1

    • 标准错误(stderr):2,2>,2>>,>&2
    • 示例
      • 标准输出+标准错误 1:ls exist_not_file ./ > /tmp/test_redirect_result 2>&1
      • 标准输出+标准错误 2:ls exist_not_file ./ &> /tmp/test_redirect_result
  • 黑洞设备:/dev/null

命令

  • 命令执行的判断依据

    • ;:命令之间用;来分隔,前面命令执行完后才执行后面的。
    • &&||
      命令执行情况说明
      cmd1 && cmd2
      1. 若cmd1执行完毕且正确执行(\(?=0),则开始执行cmd2</li><li>若cmd1执行完毕且为错误(\)?≠0),则cmd2不执行
      cmd1 || cmd2
      1. 若cmd1执行完毕且正确执行(\(?=0),则cmd2不执行</li><li>若cmd1执行完毕且为错误(\)?≠0),则开始执行cmd2
  • 管道(pipe)

    • 将前一个命令的stdout作为下一个命令的stdin:ls -al /etc | less
  • cut

    [wang_hongqi@study etc]$ cut -d '分隔字符' -f fields
    [wang_hongqi@study etc]$ cut -c 字符区间
    选项与参数:
    -d      与-f配合使用。字段分隔符。
    -f      与`-d`配合使用。要取出哪些字段。eg:"-f 3" or "-f 3,4,5"
    -c      以字符的单位区出固定字符区间。eg:“-c 12-15” or "-c 12-"
    
  • last:显示登录着的信息

  • sort:排序

  • uniq:去重
  • wc:统计
  • tee:双重重定向

    • 将数据流同时送到文件和stdout:last | tee last.list | cut -d " " -f 1
  • 字符转换命令:

    • tr:文字的替换和删除
    • col -x:将tab转换成对等的空格 -A:将特殊按键打印出来
    • join
    • paste
    • expand:将tab转换成空格 -t:后面接一个数字n,表示要将tab键以n个空格替换
    • unexpand:将空格转换成tab
  • split:将大文件划分成小文件
  • xargs:将输入作为指定命令的参数

    [wang_hongqi@study etc]$ xargs [-0epn] command
    选项与参数:
    -0          如果输入的stdin含有特殊字符,可以将它们还原成一般字符。
    -e          EOF的意思,后面可以接一个字符,当xargs分析到这个字符时,就会停止工作
    -p          在执行每个命令时候,都会询问使用者的意思
    -n          后面接次数,每次command命令执行时,要使用几个参数的意思
    
  • -被用来当作stdin与stdout使用

参考资料与扩展阅读

  • NULL

第11章 正则表达式与文件格式化处理

  • 使用正则表达式时,需要特别留意当时的语系是什么,否则可能会发现与别人不同的选取结果。
  • 特殊符号
    特殊符号意义
    [:alnum:]字母数字。09、AZ、a~z
    [:alpha:]字母。AZ、az
    [:blank:]空格与[Tab]
    [:cntrl:]控制按键:CR、LF、Tab、Del等
    [:digit:]数字。0~9
    [:graph:]除了[:blank:]外的其他按键
    [:lower:]小写字母。a~z
    [:upper:]大写字母。A~Z
    [:print:]可打印字符
    [:punct:]标点符号。"'?!;:#$
    [:space:]空白字符:空格键、[Tab]、CR等
    [:xdigit:]十六进制的数字类型。09、AF、a~f
  • 基础正则表达式
    RE字符意义与范例
    ^word
    word$
    .
    \
    *
    [list]
    [n1-n2]
    [^list]
    {n,m}
  • 扩展正则表达式

    RE字符意义
    +
    ?
    |
    ()
    ()+

  • grep

    • 基础正则表达式
    [wang_hongqi@study etc]$ grep [OPTIONS] '查找字符串' filename
    OPTIONS:
    -A              后面加数字,为after的意思。eg: -A10
    -B              后面加数字,为before的意思。eg: -B10
    --color=auto    自动上色(匹配的字符串)
    -n              列出行号
    -v              反转匹配结果
    -E              egrep,扩展正则表达式
    -F              fgrep,字符串匹配
    
  • sed

    [wang_hongqi@study etc]$ sed [-nefr] [操作]
    选项与参数:
    -n              使用silent模式,sed默认会把所有stdin都输出到屏幕上,如果使用silent模式后,只有经过sed特殊处理的行才会显示。
    -e              后接sed的script操作
    -f              后接sed的script文件,即会读取该文件并执行
    -r              使用扩展正则表达式
    -i              直接修改读取文件的内容,而不是输出到屏幕上。
    
    操作:[n1[,n2]] function[\text]
    n1,n2           代表要操作的行数
    
    function
    a               追加新行,后接要增加的字符串(下一行)
    i               插入新航,后接要增加的字符串(上一行)
    c               替换,后接要替换n1~n2的字符串
    d               删除
    p               打印,打印某行,通常跟sed -n配合使用
    s               匹配并替换,正则表达式匹配:1,20s/old/new/g
    
  • printf:数据格式化

  • awk:awk脚本工具
  • diff:以行为单位的对比差异的工具

    [wang_hongqi@study etc]$ diff [-bBi] from-file to-file
    from-file       原始文件,可由-替换,即stdin
    to-file         目标文件,可由-替换,即stdin
    -b              忽略一行中仅有多个空白的差异
    -B              忽略空白行的差异
    -i              忽略大小写不同
    
  • cmp:以字节为单位的对比差异工具

    [wang_hongqi@study etc]$ cmp [-l] file1 file2
    选项与参数
    -l              将所有不同点的字节处都列出来。默认只会输出第一个不同点
    
  • patch

    • 与diff密不可分。

      [wang_hongqi@study etc]$ diff -Naur passwd.old passwd.new > passwd.patch
      
    [wang_hongqi@study etc]$ patch -pN < patch_file <==更新
    [wang_hongqi@study etc]$ patch -R -pN < patch_file <==还原
    选项与参数:
    -p              后接要strip目录的数目(要剥离斜杠的数量):/etc/passwd to etc/passwd with -p1 or to passwd with -p2 or don't change with -p0
    -R              代表还原,将新的文件还原成原来旧的版本
    
  • pr:文件打印

第12章 学习shell脚本

其他

  • CentOS 6.x 以前的版本中,系统服务(services)启动的接口是在/etc/init.d/这个目录下。

shell脚本的优势

  • 自动化管理的重要依据
  • 跟踪与管理系统的重要工作
  • 简单入侵检测功能
  • 连续命令单一化
  • 简易的数据处理
  • 跨平台支持与学习历程较短
    • shell脚本在系统管理上是很好的工具,但是用在处理大量数值运算上就不够好,原因在于shell脚本的速度较慢。且使用CPU资源较多,会造成主机资源的分配不良。

脚本注意事项与基础知识

  • 命令是从上往下、从左往右地分析与运行的
    • 因此,使用函数功能的时候,函数一定要写在调用点的上方
  • 命令执行时,命令、选项与参数间的多个空格都会被忽略掉。
  • 空白行也将被忽略到,且按[Tab]按键所产生的空白同样视为空格。
  • 如果读取到一个Enter符号(CR),就尝试开始执行该行命令
  • 如果一行的内容太多,可以使用【\[Enter]】来扩展至下一行
  • #可作为注释,任何加在#后面的数据都被忽略
  • 编写脚本时候最好用vim而不是vi,因为vim有语法检验功能

  • 执行脚本命令的方式:

    • 相对路径:./tmp.sh
    • 绝对路径:/home/wang_hongqi/bin/tmp.sh
    • 放置在$PATH中,然后执行:export PATH="$PATH:/home/wang_hongqi/bin/tmp.sh" && tmp.sh
    • bash程序调用:bash tmp.sh
  • 良好的变成习惯,在脚本开头写入相关信息:

    • 脚本的功能
    • 脚本的版本信息
    • 脚本的作者与联系方式
    • 脚本的版权声明方式
    • 脚本的历史记录
    • 脚本内较特殊的命令,使用【绝对路径】的方式来执行
    • 脚本运行时需要的环境变量预先声明与设置
  • $(( 计算式 ))

    • 只能计算整数,如果要计算小数可以使用bc工具
    [wang_hongqi@study etc]$ echo $(( 13 % 3 ))
    

脚本的执行差异

  • source:父进程直接执行
  • sh script:子进程,因此变量不会回传给父进程
  • ./script:子进程,因此变量不会回传给父进程

脚本的使用简述

  • 测试

    • 方式
      • test
      • 判断符号:[]
        • 在中括号[]内的每个组件都需要有空格来分隔
        • 在中括号内的变量,最好都以双引号括起来
        • 在中括内的常数,最好都以单或双引号括起来
    • 注意:在bash中使用一个等号和两个等号效果是一样的。
  • shell脚本的默认变量

    • $0:脚本文件名
    • \(1、\)2、...:脚本参数
    • $#:脚本的参数个数
    • $@:代表"$1" "$2" "$3" ...
    • $*:代表"$1c$2c$3c...",c为分隔符,默认为空格
  • shift:将参数移出,并重新编号

    [wang_hongqi@study bin]$ vim test_shift.sh
    >>>>>> test_shift.sh
    #!/bin/bash
    
    echo "Parameter is: $@"
    
    shift
    echo "Parameter is: $@"
    
    shift 3
    echo "Parameter is: $@"
    <<<<<< end
    [wang_hongqi@study bin]$ sh test_shift.sh 1 2 3 4 5 6 7 8
    Parameter is: 1 2 3 4 5 6 7 8
    Parameter is: 2 3 4 5 6 7 8
    Parameter is: 5 6 7 8
    
  • seq:产生序列

    • seq 1 100
  • if...then

    • 逻辑判断
      • 可以在一个中括号间用使用逻辑判断参数:[ "$cond" == "1" -o "$cond" == "2" ]
      • 在两个中括号间使用:&&||[ "$cond" == "1" ] || [ "$cond" == "2" ]
    # 单条件
    if [ condition ]; then
        语句
    fi
    
    # 多重条件
    if [ condition ]; then
        语句1
    elif [ condition ]; then
        语句2
    else
        语句3
    fi
    
  • case...esac

    case $变量名称 in
        "第一个变量内容")
            语句1
            ;;
        "第二个变量内容")
            语句2
            ;;
        *)
            语句3
            ;;
    esac
    
  • 循环

    • while do done

      while [ condition ]
      do
          语句
      done
      
    • until do done

      until [ condition ]
      do
          语句
      done
      
    • for...do...done

      • 固定循环

        for var in con1 con2 con3 ...
        do
            语句
        done
        
      • 数值处理

        for (( 初始值; 限制值; 赋值运算 ))
        do
            语句
        done
        
        # 赋值运算处允许使用 i++
        
  • function

    • 内置变量
      • $0:函数名
      • $1、$2、...:函数参数
    function fname () {
        语句
    }
    
    fname arg1 arg2
    
  • shell脚本的跟踪与调试

    • 通过sh -x来追踪脚本执行的命令

第13章 Linux账号管理与ACL权限设置

用户账号

  • 备份账号需要备份文件:/etc/passwd/etc/shadow。详细信息可以man 5 passwdman 5 shadow
  • /etc/passwd的文件结构

    • 简述:每行都代表一个账号,很多账号都是系统运行所必须的,可以称为系统账号,比如 bin、daemon、adm、nobody 等,这些账号不要随意删除。
    • 字段解释

      [root@study wang_hongqi]# head -n 4 /etc/passwd
      root:x:0:0:root:/root:/bin/bash
      bin:x:1:1:bin:/bin:/sbin/nologin
      daemon:x:2:2:daemon:/sbin:/sbin/nologin
      adm:x:3:4:adm:/var/adm:/sbin/nologin
      
      1. 账号名称
      2. 密码:密码被放置到/etc/shadow文件了,因此这里是x
      3. UID
        ID范围该ID用户特性
        0
        (系统管理员)
        当UID是0时,代表该账号是系统管理员,因此要让其他的账号名称也具有root的权限时,就将该账号的UID改为0。也就是说一台系统中的系统管理员不见得就只有root,不过不建议有多个账号的UID是0,容易让系统管理员混乱
        1 ~ 999
        (系统账号)
        保留给系统使用的ID,其实除了0外,其他UID权限与特性并没有不一样,默认1000以下留给系统作为保留账号只是一个习惯。
        由于系统上面启动的网络服务或后台服务希望使用较小的权限去运行,因此不希望使用root的身份去执行这些服务,所以我们就得提供账号给这些运行中的程序使用。这些系统账号通常是不可登录的,所以才会有/sbin/nologin这个特殊的shell存在
        1000 ~ 60000
        (可登录账号)
        给一般用户使用,事实上目前Linux内核(3.10.x)已经可以支持到4G的ID号了
      4. GID
      5. 用户信息说明栏
      6. 家目录
      7. shell:要使一个账号无法获取shell环境,就在这里指定为/sbin/nologin
      8. /etc/shadow的文件结构
        • 字段解释
      [root@study wang_hongqi]# head -n 4 /etc/shadow
      root:$6$0phgUaxbePBNxPsB$rwiC2MlGdvAhka40rSDarpIw7TNlx26PQJ3kANVgvVdY6Q6hxRYvFa3ex7xRNtZrVEzfVOUlSkBiNiKlpaHWs.::0:99999:7:::
      bin:*:17632:0:99999:7:::
      daemon:*:17632:0:99999:7:::
      adm:*:17632:0:99999:7:::
      
      1. 账号名称
      2. 密码:使用摘要算法计算的,因此修改该字段会导致密码失效。如果改变其长度,就对令其暂时失效。
      3. 最近修改密码的日期:记录的是从1970/01/01起到最近修改密码的天数
      4. 密码不可被修改的天数(与第三字段比较):允许连续修改密码的时间间隔
      5. 密码需要重新修改的天数(与第三字段比较):需要重新修改密码的时间间隔
      6. 密码需要修改期限的警告天数(与第五字段比较):需要修改密码前的警告天数
      7. 密码过期后的账号宽限时间(与第五字段比较):在超过需要修改密码的时间后,最大宽限期限
      8. 账号失效日期:也是使用从1970/01/01起的天数来表示账号失效的日期。,付费账号中可以使用
      9. 保留
      10. 密码忘记的解决办法
        • 一般用户的密码忘记了:请系统管理员用passwd修改即可
        • root密码忘记了
      11. 重启进入linux单人维护模式,接着以passwd修改密码
      12. 以Live CD启动后挂载根目录去修改/etc/shadow,将里面的root密码字段晴空,再重新启动后root不用密码即可登录,登录后再以passwd命令去设置root密码。
      13. 查看shadow用什么加密机制:
    [root@study wang_hongqi]# authconfig --test | grep hashing
    password hashing algorithm is sha512
    

用户组

  • /etc/group文件结构

    • 字段解释

      [root@study wang_hongqi]# head -n 4 /etc/group
      root:x:0:root_1
      bin:x:1:
      daemon:x:2:
      sys:x:3:
      
      1. 组名
      2. 用户组密码:因为密码放置在/etc/shadow文件中,因此该处为x
      3. GID
      4. 此用户组支持的账号名称
        • 以该组作为初始用户组的用户群无需加入到该字段中
      5. 初始用户组
        • 用户以登录就会获取该组的权限。在/etc/shadow的第4字段的GID就是初始用户组
      6. 有效用户组
        • 作用是新建文件
      7. groups:输出的第一个是有效用户组
      8. newgroup:有效用户组的切换
        • 创建一个新的shell环境,以目标作为有效用户组。exit退出
      9. 加入用户组的方式
        • root通过usermod工具帮忙加入
        • 通过组管理员以gpasswd工具帮忙加入
  • /etc/gshadow文件结构

    • 字段解释

      [root@study wang_hongqi]# head -n 4 /etc/gshadow
      root:::root_1
      bin:::
      daemon:::
      sys:::
      
      1. 组名
      2. 密码栏:!或空表示该用户组不具有用户组管理员
      3. 用户组管理员账号
      4. 有加入该用户组支持的所属账号(与/etc/group内容相同)
      5. gpasswd:最大作用是建立用户组管理员

账号管理

管理描述

  • 通过useradd创建账号,通过passwd来设置密码
  • useradd

    • 参考文件
      • /etc/default/useradd

        [root@study wang_hongqi]# cat /etc/default/useradd
        # useradd defaults file
        GROUP=100
        HOME=/home
        INACTIVE=-1
        EXPIRE=
        SHELL=/bin/bash
        SKEL=/etc/skel
        CREATE_MAIL_SPOOL=yes
        
        • GROUP=100:新建账号的初始用户组使用GID为100
          • 私有用户组机制
            • 系统会建立一个与账号一模一样的用户和组给用户作为初始用户组,并创建加目录且权限为700。代表发行版有:RHEL、Fedora、CentOS等。
          • 公共用户组机制
            • 以GROUP=100这个只作为新建账号的初始用户组,每个账号都属于user这个用户组,且默认家目录的权限会是drwxr-xr-x,由于每个账号都属于user用户组,因此大家可以共享加目录内的数据。代表发行版有:SUSE等。
        • HOME=/home:家目录的基准目录(basedir)
        • INACTIVE=-1:密码过期后是否会失效的设置,0代表密码过期立即失效,-1则是永远也不会失效。
        • EXPIRE=:账号失效日期
        • SHELL=/bin/bash:默认使用的shell
        • SKEL=/etc/skel:用户家目录参考基准目录
        • CREATE_MAIL_SPOOL=yes:建立用户的mailbox。建立位置参考/etc/login.defs - /etc/skel
        • 默认的家目录基准目录 - /etc/login.defs
        [root@study wang_hongqi]# sed -e 's/#.*//g' -e 's/^\s+$//g' /etc/login.defs | grep -ve '^$'
        MAIL_DIR                /var/spool/mail     # 使用者默认又想放置目录
        PASS_MAX_DAYS           99999               # 需要修改的最大天数
        PASS_MIN_DAYS           0                   # 连续修改密码的最小间隔天数
        PASS_MIN_LEN            5                   # 密码的最小长度
        PASS_WARN_AGE           7                   # 密码过期前的告警天数
        UID_MIN                 1000                # 用户ID的最小值
        UID_MAX                 60000               # 用户ID的最大值
        SYS_UID_MIN             201                 # 系统用户ID的最小值
        SYS_UID_MAX             999                 # 系统用户ID的最大值
        GID_MIN                 1000                # 组ID的最小值
        GID_MAX                 60000               # 组ID的最大值
        SYS_GID_MIN             201                 # 系统用户组ID的最小值
        SYS_GID_MAX             999                 # 系统用户组ID的最大值
        CREATE_HOME             yes                 # 是否创建家目录
        UMASK                   077                 # 家目录的权限掩码
        USERGROUPS_ENAB         yes                 # 使用userdel删除时,是否删除初始用户组
        ENCRYPT_METHOD          SHA512              # 密码加密机制(摘要算法)
        
        • UID/GID:系统设置一个账号的UID时,是先参考UID_MIN获取最小值,然后再通过/etc/passwd获取最大的UID值,接着以获取到的最大UID值+1来作为新账号的UID
        • USERGROUPS_ENAB yes:如果使用uesrdel删除一个账号,且该账号所属的初始用户组已经没有人隶属于该用户组了,那么就删掉该用户组。
  • 系统账号:由于系统账号主要用来执行系统所需服务的权限设置,因此系统账号默认都不会主动建立家目录。

  • 密码管理
    • 密码管理机制写在/etc/pam.d/passwd中,该文件与密码有关的测试模块就是使用**pam_cracklib.so**,这个模块会检验密码的相关信息,并且替换/etc/login.defs内的 PASS_MIN_LEN的设置
    • 密码设置简单方式:echo "abc12345abc" | passwd --stdin wang_hongqi
      • 缺点:会被保留到命令历史中,未来系统被攻击可能会泄漏密码
    • 让账号在暂时失效的方法:
      • 通过passwd锁定
      • 直接修改/etc/shadow文件中目标账户的密码字段,改变其长度即可。

相关工具汇总

  • chage
    • 用户第一次登录时,强制他们修改密码:chage -d 0 wang_hongqi(将最近修改密码时间设置为0,即shadow的第3字段)
  • useradd
  • usermod:调整useradd的参数
  • userdel:
    • 删除用户一定要小心,因为/etc/passwd和/etc/shadow的用户数据会一并被删除。如果只是想暂时让用户无效,可以修改/etc/shadow的第8字段(账户失效日期),设置为0,即立刻使账户失效。
    • 如果要将某个账户完整删除,最好在执行userdel -r username之前,先find / -user username查出整个系统隶属于username的文件,然后再删除。
  • passwd
  • id
  • finger:查看用户信息
  • chfn:change finger
  • chsh:修改shell
  • groupadd
  • groupmod
  • groupdel
    • 删除用户组前必须要确认在/etc/passwd中没有任何账号使用该用户组作为初始用户组
  • gpasswd:用户组管理员功能
  • authconfig-tui:打开身份认证系统配置界面

ACL

什么是ACL

  • ACL是访问控制列表的意思,主要目的是提供传统的属主、所属群组、其他人的读、写、执行权限之外的详细权限设置。ACL可以针对单一用户、单一文件或目录来进行r、w、x的权限设置,对于需要特殊权限的使用状况非常有帮助。
  • 控制目标
    • 用户(user)
    • 用户组(group)
    • 默认属性(mask):针对在该目录下建立新文件/目录时,规范新数据的默认权限。
  • 查看系统是否支持acl

    [root@study wang_hongqi]# dmesg | grep -i acl
    [    0.923054] systemd[1]: systemd 219 running in system mode. (+PAM +AUDIT +SELINUX +IMA -APPARMOR +SMACK +SYSVINIT +UTMP +LIBCRYPTSETUP +GCRYPT +GNUTLS +ACL +XZ +LZ4 -SECCOMP +BLKID +ELFUTILS +KMOD +IDN)
    [    1.980408] SGI XFS with ACLs, security attributes, no debug enabled
    
    • 可以看出xfs是支持acl的

getfacl、setfact

  • setfacl

    [root@study wang_hongqi]# setfacl --help
    setfacl 2.2.51 -- set file access control lists
    Usage: setfacl [-bkndRLP] { -m|-M|-x|-X ... } file ...
    -m, --modify=acl        modify the current ACL(s) of file(s)
    -M, --modify-file=file  read ACL entries to modify from file
    -x, --remove=acl        remove entries from the ACL(s) of file(s)
    -X, --remove-file=file  read ACL entries to remove from file
    -b, --remove-all        remove all extended ACL entries
    -k, --remove-default    remove the default ACL
        --set=acl           set the ACL of file(s), replacing the current ACL
        --set-file=file     read ACL entries to set from file
        --mask              do recalculate the effective rights mask
    -n, --no-mask           don't recalculate the effective rights mask
    -d, --default           operations apply to the default ACL
    -R, --recursive         recurse into subdirectories
    -L, --logical           logical walk, follow symbolic links
    -P, --physical          physical walk, do not follow symbolic links
        --restore=file      restore ACLs (inverse of `getfacl -R')
        --test              test mode (ACLs are not modified)
    -v, --version           print version and exit
    -h, --help              this help text
    
    • acl entries:

      • 格式
        • [d[efault]:] [u[ser]:]uid [:perms]:Permissions of a named user. Permissions of the file owner if uid is empty.
        • [d[efault]:] g[roup]:gid [:perms]:Permissions of a named group. Permissions of the owning group if gid is empty.
        • [d[efault]:] m[ask][:] [:perms]:Effective rights mask
          • 用户/用户组设置的权限必须要存在于mask的权限设置范围内才会生效。即,mask=r--时,即便user:wang_hongqi:rwx,真实有效的也只是user:wang_hongqi:r--
          • 可以使用该配置来规范最大允许的权限,从而避免不小心开放某些权限给其他用户或用户组
        • [d[efault]:] o[ther][:] [:perms]:Permissions of others.
      • 描述
        • Whitespace between delimiter characters and non-delimiter characters is ignored.
        • Proper ACL entries including permissions are used in modify and set operations. (options -m, -M, --set and --set-file). Entries without the perms field are used for deletion of entries (options -x and -X)
        • For uid and gid you can specify either a name or a number.
        • The perms field is a combination of characters that indicate the read ®, write (w), execute (x) permissions. Dash characters in the perms field (-) are ignored. The character X stands for the execute permission if the file is a directory or already has execute permission for some user. Alternatively, the perms field can define the permissions numerically, as a bit-wise combination of read (4), write (2), and execute (1). Zero perms fields or perms fields that only consist of dashes indicate no permissions.
        • default应用在目录上,可以让该目录下新建的文件或目录继承其acl规则
    • 使用:一个文件设置了ACL参数后,它的权限部分就会多处一个+号,但是此时你看到的权限与实际权限可能会有点误差。

      [root@study test_facl]# touch test_acl
      [root@study test_facl]# ll test_acl
      -rw-r--r--. 1 root root 0 9月   8 15:11 test_acl
      [root@study test_facl]# setfacl -m u:wang_hongqi:rx test_acl
      [root@study test_facl]# ll test_acl
      -rw-r-xr--+ 1 root root 0 9月   8 15:11 test_acl
      
  • getfacl

    getfacl 2.2.51 -- get file access control lists
    Usage: getfacl [-aceEsRLPtpndvh] file ...
    -a,  --access           display the file access control list only
    -d, --default           display the default access control list only
    -c, --omit-header       do not display the comment header
    -e, --all-effective     print all effective rights
    -E, --no-effective      print no effective rights
    -s, --skip-base         skip files that only have the base entries
    -R, --recursive         recurse into subdirectories
    -L, --logical           logical walk, follow symbolic links
    -P, --physical          physical walk, do not follow symbolic links
    -t, --tabular           use tabular output format
    -n, --numeric           print numeric user/group identifiers
    -p, --absolute-names    don't strip leading '/' in pathnames
    -v, --version           print version and exit
    -h, --help              this help text
    
    • 使用

      [root@study test_facl]# getfacl test_acl
      # file: test_acl
      # owner: root
      # group: root
      user::rw-
      user:wang_hongqi:r-x
      group::r--
      mask::r-x
      other::r--
      

用户身份切换

su与sudo

  • su

    • 使用su -来切换为root身份时,需要的是root密码
    • 直接输入su来切换身份时,读取的变量设置方式为non-login shell的方式,这种方式很多原本变量不会被修改。
    Usage:
    su [options] [-] [USER [arg]...]
    
    Change the effective user id and group id to that of USER.
    A mere - implies -l.   If USER not given, assume root.
    
    Options:
    -m, -p, --preserve-environment  do not reset environment variables
    -g, --group <group>             specify the primary group
    -G, --supp-group <group>        specify a supplemental group
    
    -, -l, --login                  make the shell a login shell
    -c, --command <command>         pass a single command to the shell with -c
    --session-command <command>     pass a single command to the shell with -c and do not create a new session
    -f, --fast                      pass -f to the shell (for csh or tcsh)
    -s, --shell <shell>             run shell if /etc/shells allows it
    
  • sudo

    • 仅有被规范到/etc/sudoers内的用户才能够执行sudo这个命令
    • 使用该sudo -s来切换root身份时,需要的是管理员自己的密码
    • sudo的执行流程
      1. 当用户执行sudo时,系统于/etc/sudoers文件中查找该用户是否有执行sudo的权限
      2. 若用户具有可执行sudo的权限后,便让用户输入自己的密码来确认
      3. 若密码输入成功,便开始进行sudo后续接的命令(root执行sudo或则切换身份相同时,无需输入密码)
    • 使用visudo去修改(相当于用vi打开/etc/sudoers文件)
    sudo - execute a command as another user
    
    usage: sudo -h | -K | -k | -V
    usage: sudo -v [-AknS] [-g group] [-h host] [-p prompt] [-u user]
    usage: sudo -l [-AknS] [-g group] [-h host] [-p prompt] [-U user] [-u user] [command]
    usage: sudo [-AbEHknPS] [-r role] [-t type] [-C num] [-g group] [-h host] [-p prompt] [-T timeout] [-u user] [VAR=value] [-i|-s] [<command>]
    usage: sudo -e [-AknS] [-r role] [-t type] [-C num] [-g group] [-h host] [-p prompt] [-T timeout] [-u user] file ...
    
    Options:
    -A, --askpass                 use a helper program for password prompting
    -b, --background              run command in the background
    -C, --close-from=num          close all file descriptors >= num
    -E, --preserve-env            preserve user environment when running command
        --preserve-env=list       preserve specific environment variables
    -e, --edit                    edit files instead of running a command
    -g, --group=group             run command as the specified group name or ID
    -H, --set-home                set HOME variable to target user's home dir
    -h, --host=host               run command on host (if supported by plugin)
    -i, --login                   run login shell as the target user; a command may also be specified
    -K, --remove-timestamp        remove timestamp file completely
    -k, --reset-timestamp         invalidate timestamp file
    -l, --list                    list user's privileges or check a specific command; use twice for longer format
    -n, --non-interactive         non-interactive mode, no prompts are used
    -P, --preserve-groups         preserve group vector instead of setting to target's
    -p, --prompt=prompt           use the specified password prompt
    -r, --role=role               create SELinux security context with specified role
    -S, --stdin                   read password from standard input
    -s, --shell                   run shell as the target user; a command may also be specified
    -t, --type=type               create SELinux security context with specified type
    -T, --command-timeout=timeout terminate command after the specified time limit
    -U, --other-user=user         in list mode, display privileges for user
    -u, --user=user               run command (or edit file) as specified user name or ID
    -v, --validate                update user's timestamp without running a command
    --                            stop processing command line arguments
    
  • /etc/sudoers

    • 几个常见的语法格式
    # 使用者账号    登录者来源主机名称=(可切换的身份)   可执行的命令
    root            ALL=(ALL)                       ALL
    
    # 用户组        登录者来源主机名称=(可切换的身份)   可执行的命令
    %wheel          ALL=(ALL)                       ALL
    
    # 不需要输入密码即可sudo
    wang_hongqi     ALL=(ALL)                       NOPASSWD: ALL
    
    # 按需自定义:密码管理员,限定其可登录主机为192.168.90.145,允许修改除了root用户的密码
    passwd           192.168.90.145=(root)          NOPASSWD: /usr/bin/passwd [A-Za-z]*, !/usr/bin/passwd root, !/usr/bin/passwd
    
    # 别名
    User Alias PASSWD_MANAGES = pwm1, pwm2, pwm3
    Cmnd Alias PASSWD_MANAGES_CMDS = !/usr/bin/passwd, !/usr/bin/passwd root, /usr/bin/passwd [A-Za-z]*
    Host Alias PASSWD_MANAGES_HOSTS = 192.168.90.145, 192.168.90.146, 192.168.90.147
    PASSWD_MANAGES  PASSWD_MANAGES_HOSTS=(root)            NOPASSWD: PASSWD_MANAGES_HOSTS
    

特殊shell

  • 想让无法登录shell的用户知道,可以建立/etc/nologin.txt文件,在该文件中说明不能登录的原因,而不是使用默认的内容。

PAM(Pluggable Authentication Modules)

  • 以passwd为例

    1. 用户执行/usr/bin/passwd程序,并输入密码
    2. passwd调用PAM进行验证
    3. PAM到/etc/pam.d/目录找与程序passwd同名的配置文件
    4. 根据/etc/pam.d/passwd内的设置,引用相关的PAM模块逐步进行验证分析
    5. 将验证结果返回给passwd
    6. passwd依据验证结果决定下一步操作

    7. /etc/pam.d/passwd

      [root@study tmp]# cat /etc/pam.d/passwd
      #%PAM-1.0
      auth       include      system-auth
      account    include      system-auth
      password   substack     system-auth
      -password   optional    pam_gnome_keyring.so use_authtok
      password   substack     postlogin
      
  • pam配置文件格式

    • 第一字段:验证类别
      • auth
      • account
      • session
      • password
    • 第二个字段:验证的控制标识(control flag)
      • required
        • 成功:继续,携带success标志
        • 失败:继续,携带failure标志
      • requisite
        • 成功:继续,携带success标志
        • 失败:终止,返回failure标志
      • sufficient
        • 成功:终止,返回success标志
        • 失败:继续,携带failure标志
      • optional:不做认证,大多用在显示消息而已
      • include:请调用后面的文件来作为这个类别的验证
  • 常用模块简介

    • 相关配置文件:
      • /etc/pam.d/*:每个程序的PAM配置文件
      • /lib64/security/*:PAM模块文件的实际放置目录
      • /etc/security/*:其他PAM环境的配置文件
      • /usr/share/doc/pam-*/:详细的PAM说明文件
    • 模块
      • pam—securetty.so
        • 限制系统管理员(root)只能从安全的终端登录。安全的终端设置就写在/etc/securetty文件中。
      • pam_nologin.so
        • 这个模块可以限制一般用户是否能够登录主机。当/etc/nologin这个文件存在时,则所有一般用户均无法再登录系统了。若存在则在用户登录时将该文件的内容显示出来(注意,该文件与/etc/nologin.txt不同)
      • pam_seLinux.so
      • pam_console.so
      • pam_loginuid.so
        • 规范UID
      • pam_env.so
        • 设置环境变量,可以参考:/etc/security/pam_env.conf
      • pam_unix.so
      • pam_pwquality.so
        • 检验密码强度。兼容pam_cracklib.so
      • pam_limits.so
        • ulimit的实现其实就是通过该模块,详细可以参考/etc/security/limits.conf
    • 阶段顺序
      1. auth(认证)
      2. account(授权)
      3. password(密码)
      4. session(会话)
  • 日志
    • /var/log/secure
    • /var/log/messages

Linux主机上的用户信息传递

  • 查询用户
    • w:显示当前在线用户
    • who:显示当前在线用户
    • last:显示最近登录情况
    • lastlog:会去读取/var/log/lastlog
  • 用户对谈
    • write:给当前登录的某个用户写消息
    • mesg:使能控制消息的接收
    • wall:给当前登录的用户广播消息
    • mail:邮箱
      命令意义
      h列出邮件标头:h 20
      d删除后续接的邮件号码:h 20
      s将邮件存储为文件:s 5 ~/mail.file
      x不执行操作,退出
      q执行操作并退出

大量创建账号的方法

  • 相关工具
    • pwck:检查/etc/passwd里面的内容是否有误
    • pwconv:将/etc/passwd里面的账号密码移动到/etc/shadow中
    • pwunconv:pwconv的反过程
    • chpasswd:改变密码

第14章 磁盘配额(Quota)与高级文件系统管理

磁盘配额

  • ext系列:针对文件系统进行磁盘配额
  • xfs:可以使用project模式,针对个别目录来进行磁盘配额

  • 不要在根目录使用磁盘配额设置,这样会使文件系统变得复杂。

  • 相关工具

    • xfs_quota:xfs的磁盘配额工具
  • 磁盘配额限制

    • ext文件系统仅能针对整个文件系统
    • 内核必须支持磁盘配额
    • 只对一般身份用户有效
    • 若启用SELinux,非所有目录均可设置磁盘配额
  • xfs磁盘配额的规范设置选项

    • 配额目标:user、group、project
    • 限制方式:block、inode
    • 限制类型:hard、soft
      • 当超过soft值时,会有一段"grace time"的时间让用户缩减使用值,当超过grace time仍未将使用值低于soft时,会把soft转为hard,禁止目标继续增加使用值。
      • 目标无法超过hard,达到hard时,直接锁定,禁止目标继续增加使用值。

user、group磁盘配额设置

  1. 查看/home的文件类型(xfs)

    [root@study ~]# df -Th /home/
    Filesystem              Type  Size  Used Avail Use% Mounted on
    /dev/mapper/centos-home xfs   5.0G   66M  5.0G   2% /home
    
  2. 打开/home的user、group磁盘配额设置

    • 磁盘配额选项:
      • uquota/usrquota/quota:用户
      • gquota/grpquota:用户组
      • pquota/prjquota:目录,不可与用户组同时存在
    # 卸载
    [root@study ~]# umount /home/
    
    # 修改挂载设置
    [root@study ~]# vim /etc/fstab
    >>>>>> /etc/fstab
    < - /dev/mapper/centos-home /home                   xfs     defaults                          0 0
    > + /dev/mapper/centos-home /home                   xfs     defaults,usrquota,grpquota        0 0
    <<<<<< end
    
    # 重新挂载
    [root@study ~]# mount -a
    
    # 查看挂载信息
    [root@study ~]# mount | grep home
    /dev/mapper/centos-home on /home type xfs (rw,relatime,seclabel,attr2,inode64,usrquota,grpquota)
    
  3. 查看当前文件系统的磁盘配额参数

    [root@study ~]# xfs_quota -x -c "print"
    Filesystem          Pathname
    /                   /dev/mapper/centos-root
    /srv/myproject      /dev/sda4
    /boot               /dev/sda2
    /data/file          /dev/loop0
    /home               /dev/mapper/centos-home (uquota, gquota)
    
  4. 查看/home目录下所有用户的配额限制值

    [root@study ~]# xfs_quota -x -c "report -ubih" /home/
    User quota on /home (/dev/mapper/centos-home)
                            Blocks                            Inodes
    User ID      Used   Soft   Hard Warn/Grace     Used   Soft   Hard Warn/Grace
    ---------- --------------------------------- ---------------------------------
    root          32K      0      0  00 [------]      7      0      0  00 [------]
    wang_hongqi  32.7M      0      0  00 [------]    499      0      0  00 [------]
    root_1        24K      0      0  00 [------]     14      0      0  00 [------]
    myuser1       20K      0      0  00 [------]     13      0      0  00 [------]
    myuser2       20K      0      0  00 [------]     13      0      0  00 [------]
    myuser3       16K      0      0  00 [------]     12      0      0  00 [------]
    
  5. 查看目前支持磁盘配额的文件系统状态

    [root@study ~]# xfs_quota -x -c "state"
    User quota state on /home (/dev/mapper/centos-home)
        Accounting: ON
        Enforcement: ON
        Inode: #1004 (2 blocks, 2 extents)
    Group quota state on /home (/dev/mapper/centos-home)
        Accounting: ON
        Enforcement: ON
        Inode: #1025 (2 blocks, 2 extents)
    Project quota state on /home (/dev/mapper/centos-home)
        Accounting: OFF
        Enforcement: OFF
        Inode: #1025 (2 blocks, 2 extents)
    Blocks grace time: [7 days]
    Inodes grace time: [7 days]
    Realtime Blocks grace time: [7 days]
    
  6. 限制

    [root@study ~]# xfs_quota -x -c "limit [-ug] b[soft|hard]=N i[soft|hard]=N name"
    [root@study ~]# xfs_quota -x -c "timer [-ug] [-bir] Ndays"
    

project磁盘配额设置

  1. 打开磁盘配额设置

    # 卸载
    [root@study ~]# umount /home/
    
    # 修改挂载设置
    [root@study ~]# vim /etc/fstab
    >>>>>> /etc/fstab
    < - /dev/mapper/centos-home /home                   xfs     defaults,usrquota,grpquota        0 0
    > + /dev/mapper/centos-home /home                   xfs     defaults,usrquota,prjquota        0 0
    <<<<<< end
    
    # 重新挂载
    [root@study ~]# mount -a
    
    # 查看挂载信息
    [root@study ~]# mount | grep home
    /dev/mapper/centos-home on /home type xfs (rw,relatime,seclabel,attr2,inode64,usrquota,prjquota)
    
  2. 查看目前支持磁盘配额的文件系统状态

    [root@study ~]# xfs_quota -x -c "state"
    User quota state on /home (/dev/mapper/centos-home)
        Accounting: ON
        Enforcement: ON
        Inode: #1004 (2 blocks, 2 extents)
    Group quota state on /home (/dev/mapper/centos-home)
        Accounting: OFF
        Enforcement: OFF
        Inode: #1025 (2 blocks, 2 extents)
    Project quota state on /home (/dev/mapper/centos-home)
        Accounting: ON
        Enforcement: ON
        Inode: #1025 (2 blocks, 2 extents)
    Blocks grace time: [7 days]
    Inodes grace time: [7 days]
    Realtime Blocks grace time: [7 days]
    
  3. 限制

    # 设置配置文件:
    [root@study ~]# echo "11:/home/project" >> /etc/projects # id:directory
    [root@study ~]# echo "myquotaproject:11" >> /etc/projid  # name:id
    
    # 初始化
    [root@study ~]# xfs_quota -x -c "project -s myquotaproject"
    Setting up project myquotaproject (path /home/project)...
    Processed 1 (/etc/projects and cmdline) paths for project myquotaproject with recursion depth infinite (-1).
    Setting up project myquotaproject (path /home/project)...
    Processed 1 (/etc/projects and cmdline) paths for project myquotaproject with recursion depth infinite (-1).
    Setting up project myquotaproject (path /home/project)...
    Processed 1 (/etc/projects and cmdline) paths for project myquotaproject with recursion depth infinite (-1).
    Setting up project myquotaproject (path /home/project)...
    Processed 1 (/etc/projects and cmdline) paths for project myquotaproject with recursion depth infinite (-1).
    Setting up project myquotaproject (path /home/project)...
    Processed 1 (/etc/projects and cmdline) paths for project myquotaproject with recursion depth infinite (-1).
    
    # 查看磁盘配额参数
    [root@study ~]# xfs_quota -x -c "print" /home/
    Filesystem          Pathname
    /home               /dev/mapper/centos-home (uquota, pquota)
    /home/project       /dev/mapper/centos-home (project 11, myquotaproject)
    
    # 查看磁盘配额设置
    [root@study ~]# xfs_quota -x -c "report -pbih" /home/
    Project quota on /home (/dev/mapper/centos-home)
                            Blocks                            Inodes
    Project ID   Used   Soft   Hard Warn/Grace     Used   Soft   Hard Warn/Grace
    ---------- --------------------------------- ---------------------------------
    #0          32.9M      0      0  00 [------]    569      0      0  00 [------]
    myquotaproject      0      0      0  00 [------]      1      0      0  00 [------]
    
    # 限制
    [root@study ~]# xfs_quota -x -c "limit -p bsoft=450M bhard=500M myquotaproject" /home/
    
    # 查看配额配置设置
    [root@study ~]# xfs_quota -x -c "report -pibh" /home/
    Project quota on /home (/dev/mapper/centos-home)
                            Blocks                            Inodes
    Project ID   Used   Soft   Hard Warn/Grace     Used   Soft   Hard Warn/Grace
    ---------- --------------------------------- ---------------------------------
    #0          32.9M      0      0  00 [------]    569      0      0  00 [------]
    myquotaproject      0   450M   500M  00 [------]      1      0      0  00 [------]
    

磁盘配额管理

  • disable
    • xfs_quota -x -c "disable -up" /home
    • xfs_quota -x -c "disable -ug" /home
  • enable
    • xfs_quota -x -c "enable -up" /home
    • xfs_quota -x -c "enable -ug" /home
  • off:完全被关闭,关闭后要恢复只能重新挂载
    • xfs_quota -x -c "off -up" /home
    • xfs_quota -x -c "off -ug" /home
  • remove:当文件系统处于off状态时,可以remove完全移除磁盘配额配置
    • xfs_quota -x -c "remove -up" /home
    • xfs_quota -x -c "remove -ug" /home

软件磁盘阵列(Software RAID)

  • 磁盘阵列(Redundant Arrays of Inexpensive Disks, RAID) > RAID可以通过技术(软件或硬件)将多个较小的磁盘整合为一个较大的磁盘设备,而这个较大的磁盘功能可不止是存储而已,它还具有数据保护的功能。
    • RAID依据级别又不同的功能,常见级别:
      • RAID 0(等量模式,stripe):性能最佳
      • RAID 1(镜像模式,miroor):完整备份
        • RAID 1最大的优点在于数据的备份。不过由于磁盘容量有一半用在备份,因此总容量会是全部磁盘容量的一半而已。虽然RAID 1的写入性能不佳,不过读取的性能则还可以。这是因为数据有两份在不同磁盘上面,如果多个进程在读取同一条数据时,RAID会自动获取最佳的读写速度平衡。
      • RAID 1+0, RAID 0+1
        • RAID 1+0:先设置两组RAID 1,再将两组RAID 1组成RAID 0。(目前存储设备厂商最推荐的方法)
      • RAID 5:性能与数据备份的均衡考虑
        • 每次triping都会加入一个奇偶校验值
        • 总总量 = (磁盘数-1) * 单磁盘容量
        • 任意一个磁盘损坏都能由其他磁盘恢复
      • 热备份磁盘
        • 当发现有磁盘损坏时,RAID会自动重建,将坏的磁盘数据在热备盘中恢复,然后将坏的磁盘踢出阵列用热备盘替代。
  • RAID优点
    1. 数据安全与可靠性:指的并非网络信息安全,而是当硬件(指磁盘)损坏时,数据是否还能够安全地恢复或使用之意。
    2. 读写性能:例如RAID 0可以加强读写性能,让你的系统I/O部分得以改善。
    3. 容量:可以让多块磁盘组合起来,故单一文件系统可以有相当大的容量。
  • RAID对比
    项目RAID 0RAID 1RAID 10RAID 5RAID 6
    最少磁盘数22434
    最大容错磁盘数(1)n-1n/212
    数据安全性(1)完全没有最佳最佳比RAID5好
    理论写入性能(2)n1n/2<n-1<n-2
    理论读取性能(2)nnn<n-1<n-2
    可用容量(3)n1n/2n-1n-2
    一般应用强调性能但数据不重要的环境数据与备份服务器、云系统常用数据与备份数据与备份

硬件RAID,软件RAID

  • 硬件RAID:通过磁盘阵列卡来完成磁盘阵列功能。
    • 优点
      1. 有一块专门的芯片处理RAID的任务,因此性能方面不会消耗原有的I/O总线
      2. 一般的中高级磁盘阵列卡都支持热插拔
    • 缺点
      • 价格昂贵
    • 在Linux下就是一块实际的大磁盘,因此硬件RAID的设备文件名为/dev/sd[a-p],因为使用到SCSI的模块缘故。
  • 软件RAID:利用软件来模拟磁盘阵列的功能

    • 工具
      • mdadm:通过分区或磁盘为单位来设计磁盘阵列
    • 因为是系统模拟的,因此使用的设备文件名是系统的设备文件,文件名为/dev/md0/dev/md1
  • mdadm

    [root@homqyy-centos ~]# mdadm --detail /dev/md0
    [root@homqyy-centos ~]# mdadm --manage /dev/md[0-9] [--add 设备] [--remove 设备] [--fail 设备]
    [root@homqyy-centos ~]# mdadm --create /dev/md[0-9] --auto=yes --level=[015] --chunk=NK \
    > --raid-devices=N --spare-devices=N /dev/sdx /dev/hdx...
    选项与参数:
        -C, --create            : Create a new array
    For create, build, or grow:
        -n, --raid-devices=     : specify the number of active devices in the array.
        -x, --spare-devices=    : specify the number of spare (eXtra) devices in the initial array.
        -c, --chunk=            : specify chunk size of kilobytes. The default when creating an array is 512KB. To ensure compatibility with earlier versions, the default when building an array with no persistent metadata is 64KB. This is only meaningful for RAID0, RAID4, RAID5, RAID6 and RAID10.
                                  RAID4, RAID5, RAID6 and RAID10 require the chunk size to be a power of 2. In any case it must be a multiple of 4KB.
                                  A suffix of 'K', 'M' or 'G' can be given to indicate Kilobytes, Megabytes or Gigabytes respectively.
        -l, --level=            : Set RAID level. When used with --create, options are: linear, raid0, 0, stripe, raid1, 1, mirror, raid4, 4, raid5, 5, raid6, 6, raid10, 10, mutipath, mp, faulty, container. Obviously some of these are synonymous.
        --auto=yes              : 创建使用标准格式命名的md设备
    For Misc mode:
        --detail                : Print detail  of one or more md devices.
    For Manage mode:
        -a, --add               : 热添加设备
        -r, --remove            : 从列表中移除设备
        -f, --fail              : 标记列表中指定的设备为异常
    
  • 开机自动启动RAID并自动挂载

    1. get uuid of raid:
      • mdadm --detail /dev/md0 | grep -i uuid
        • assume uuid is d0fff96d:a261:9630:63d5:b45ebcda66a7
      • or you can get from UUID of the device one of array by blkid
    2. write following content to /etc/mdadm.conf: > ARRAY /dev/md0 UUID=d0fff96d:a261:9630:63d5:b45ebcda66a7
    3. get uuid of md0: blkid /dev/md0:
      • assume uuid is 4a5c62f5-cd8e-46d5-8712-8b0795659ad4
    4. write following content to /etc/fstab: > UUID=4a5c62f5-cd8e-46d5-8712-8b0795659ad4 /srv/raid xfs defaults 0 0
    5. unmunt /dev/md0; mount -a
  • 关闭软件RAID(重要

    1. 卸载且删除配置文件内与md0相关的设置
      1. umount /srv/raid
      2. delete mount set from /etc/fstab
    2. 覆盖RAID的metadata以及XFS的superblock
      1. dd if=/dev/zero of=/dev/md0 bs=1M count=50
      2. mdadm --stop /dev/md0
      3. dd if=/dev/zero of=/dev/sdb1 bs=1M count=10
      4. dd if=/dev/zero of=/dev/sdb2 bs=1M count=10
      5. dd if=/dev/zero of=/dev/sdb3 bs=1M count=10
      6. dd if=/dev/zero of=/dev/sdb4 bs=1M count=10
      7. dd if=/dev/zero of=/dev/sdb5 bs=1M count=10

逻辑卷管理器(Logical Volume Manager)

  • LVM的重点:可以弹性地调整文件系统的容量

LVM: PV、VG、LV、PE

  • PV(Physical Volume)
    • 实际分区经过调整System ID成为LVM的标识符,然后通过pvcrete将其转成LVM最底层的PV后才可以使用。
  • VG(Volume Group)
    • 将多个PV整合起来。PV将被切分为以PE为容量单位存在。
  • LV(Logical Volume)
    • VG会被切分为LV。在32位机器上,每个LV最多只能有65534个PE
    • 将数据写入LV的方式
      • 线性模式(linear):加入将/dev/vda1、/dev/vdb1这两个分区加入VG中,且整个VG中只有一个LV时,那么只有在/dev/vda1的容量用完后/dev/vdb1才会被用到
      • 交错模式(triped):同上假设,但写入时是将一份数据在两分区中写入,因此读写性能会比较好。
        • 由于LVM主要目的是弹性调整容量,而不是性能,因此默认方式为线性模式,如果使用triped模式的话,要注意当任何一个分区损坏时,所有数据都会损坏。
  • PE(Physical Extent)
    • LVM中的最小容量单位

lvm

LVM各组件的实现流程图示

  • 实践流程
    • 4个磁盘分区,每个分区的容量均为1G,且system ID为Linux LVM
    • 全部的分区整合为一个VG,VG名称为vg1,且PE的大小为16MB
    • 在vg1中建立一个名为lv1的LV,且容量为2G左右
    • vg1_lv1格式化为xfs文件系统,且挂载在/srv/lvm/1
    • 磁盘阶段(实际的磁盘)
      • gdisk分出4个分区:sdb6、sdb7、sdb8、sdb9
    • PV阶段
      • pvcreate:将物理分区建立成为PV
        • 生成4个PV:pvcreate /dev/sdb{6,7,8,9}
      • pvscan:查找目前系统里面任何具有PV的磁盘
      • pvdisplay:显示出目前系统上面的PV状态
      • pvremove:将PV属性删除,让该分区不具有PV属性
    • VG阶段
      • vgcreate
        • 生成vg1:vgcreate -s 16M vg1 /dev/sdb{6,7,8,9}
      • vgscan
      • vgdisplay
      • vgextend:在VG内增加额外的PV
      • vgreduce:在VG内删除PV
      • vgchange:设置VG是否启动(active)
      • vgremove:删除一个VG
    • LV阶段
      • lvcreate
        • 创建2G的lv1:lvcreate -L 2G -n lv1 vg1
      • lvscan
      • lvdisplay
      • lvextend:增加容量
      • lvreduce:减少容量
      • lvremomve:删除LV
      • lvresize:调整LV容量
      • 注意:LV需要使用全名
    • 文件系统阶段
      1. 格式化LV:mkfs.xfs /dev/vg1/lv1
      2. 挂载:mkdir /srv/lvm/1; mount /dev/vg1/lv1 /srv/lvm/1

放大LV容量

  • ext4,可以缩小和放大。
  • xfs只能放大:xfs_growfs命令实现

LVM thin Volume

  • 概念:创建一个thin池,然后通过thin创建LV,且最多只能使用thin池的最大容量。
  • 实践流程:
    • 从vg1的剩余容量取出1GB来创建一个名为tpool1的thin pool LV设备。
    • 由vg1/tpool1产生一个名为lv2_from_tpool1的LV设备。
    • 将vg1/lv2_from_tpool格式化为xfs文件系统,且挂载到/srv/lvm/2
    • 创建thin pool:lvcreate -L 1G -T vg1/tpool1
    • 通过tpool创建lv设备:lvcreate -V 10G -T vg1/tpool1 -n lv2_from_tpool1
    • 格式化lv2_from_tpool1,并挂载:mkfs.xfs /dev/vg1/lv2_from_tpool1; mount /dev/vg1/lv2_from_tpool1 /srv/lvm/2

LVM的LV磁盘快照

  • 磁盘快照:将当时的系统信息记录下来,就好想照相记录一般。未来若有任何数据修改,则原始数据会被搬移到快照区,没有修改的区域则由快照区与文件系统共享。
    • 由于快照区与原本的LV共享很多PE数据块,因此快照区与被快照的LV必须要在同一个VG上面。
  • 传统快照区的建立
    1. 查看VG还有多少容量:vgdisplay vg1
    2. 创建快照区:lvcreate -s -l 54 -n snap1_of_lv1 /dev/vg1/lv1
    3. 挂载快照区:mkdir /srv/lvm/snap1; mount -o nouuid /dev/vg1/snap1_of_lv1 /srv/lvm/snap1
      • 因为xfs不允许相同的uuid文件系统的挂载,因此加上nouuid参数来忽略相同UUID造成的问题。
  • 利用快照区恢复系统
    • 注意:要恢复的数据量不能大于快照区所能负载的实际容量。
    • 备份快照区:xfsdump -l 0 -L lvm1 -M lvm1 -f /home/lvm_vg1_lv1.dump /srv/lvm/snap1
    • 卸载并删除快照区:umount /srv/lvm/snap1; lvremove /dev/vg1/snap1_of_lv1
    • 格式化lv1:umount /srv/lvm/1; mkfs.xfs -f /dev/vg1/lv1; mount /dev/vg1/lv1 /srv/lvm/1
    • 恢复lv1数据:xfsrestore -f /home/lvm_vg1_lv1.dump -L lvm1 /srv/lvm/1
  • 利用快照区进行连续与测试任务,再以原系统还原快照 > 将原本的数据当作备份数据,然后创建快照作为使用,当使用完毕时候只需要将快照删除即可。

LVM相关命令几何与LVM关闭

  • 相关命令
    任务PV阶段VG阶段LV阶段文件系统(XFS/ext4)
    查找(scan)pvscanvgscanlvscanlsblk、blkid
    建立(create)pvcreatevgcreatelvcreatemkfs.xfsmkfs.ext4
    列出(display)pvdisplayvgdisplaylvdisplaydf、mount
    增加(extend)vgextendlvextend(lvresize)xfs_growfsresize2fs
    减少(reduce)vgreducelvreduce(lvresize)不支持resize2fs
    删除(remove)pvremovevgremovelvremoveumount、重新格式化
    修改容量(resize)lvresizexfs_growfsresize2fs
    修改属性(attribute)pvchangevgchangelvchange/etc/fstab、remount
  • LVM关闭
    1. 先卸载系统上年的LVM文件系统
    2. 使用lvremove删除LV
    3. 使用vgchange -a n VGname 让VGname这个VG不具有Active的标志
    4. 使用vgremove删除VG
    5. 使用pvremove删除PV
    6. 最后,使用fdisk/gdisk修改ID

RAID + LVM

  1. 创建/dev/md0
  2. 给md0转为PV:pvcreate /dev/md0
  3. 创建VG:vgcreate vg2_raid /dev/md0
  4. 创建LV:lvcreate -L 1.5G -n lv1 vg2_raid
  5. 格式化并挂载:mkdir /srv/lvm_raid/1; mkfs.xfs /dev/vg2_raid/lv1; mount /dev/vg2_raid /srv/lvm_raid/1

第15章 计划任务

  • 计划任务种类

    • 例行性
      • crontab
        • 服务:crond
    • 突发性
      • at
        • 服务:atd
  • CentOS 常见的例行性工作

    • 执行日志文件的轮询(logrotate)
    • 日志文件分析logwatch的任务
    • 建立locate的数据库
    • manpage查询数据库的建立:mandb构建manpagedb数据库
    • RPM软件日志文件的建立
    • 删除缓存(tmpwatch)

atd与at

  • at的运行方式 > 通过at命令将要运行的任务以文本文件的方式写入/var/spool/at目录内,该任务便能等待atd这个服务的使用与执行了。
  • at的管理
    • 利用/etc/at.allow/etc/at.deny管理
    • 先寻找/etc/at.allow这个文件,以白名单形式管理
    • 如果/etc/at.allow这个文件不存在,就查找/etc/at.deny文件,以黑名单的形式管理
    • 如果两个文件都不存在,则只有root可以使用at命令
  • at

    • 执行命令时最好使用绝对路径,避免出现问题
    • 脱机执行:由于at计划任务时脱离工作bash的,会直接将任务交给系统的atd程序接管,因此加入任务后就可以脱机了。
    [root@homqyy-centos ~]# at [-mldv] TIME
    [root@homqyy-centos ~]# at -c 任务号码
    选项与参数:
    -m          : Send mail to the user when the job has completed even if there was no output.
    -l          : Is an alias for atq.
    -d          : Is an alias for atrm.
    -v          : Shows the time the job will be executed before reading the job.
    -c          : cats the jobs listed on the command line to standard output.
    TIME:时间格式, /usr/share/doc/at-x.x.xx/timespec
        HH:MM                           : to run a job at a specific time of day.(If that time is already past, the next day is assumed.)
        midnight, noon, teatime(4pm)    :
        HH:MM [CC]YY-MM-DD
        HH:MM[am|pm] [Month] [Date]
        HH:MM[am|pm] + number [minutes|hours|days|weeks]
    
  • atq > lists the user's pending jobs, unless the user is the superuser; in that case, everybody's jobs are listed. The format of the output lines (one for each job) is: Job number, date, hour, queue, and username.

  • atrm > delete jobs, identified by their job number
  • batch > executes commands when system load levels permit; in other words, when the load average drops below below 0.8, or the value specified in the invocation of atd.

crond与crontab

  • crontab的运行方式
    • 通过crontab命令将要运行的任务以文本方式写入到/var/spool/cron中,而且是以账号来作为判断依据的。
      • 加入有账户wang_hongqi执行了crontab添加任务,则任务将被写入到/var/spool/cron/wang_hongqi中。
    • cron执行的每一项任务都会被记录到/var/log/cron中。
  • crontab管理
    • 利用/etc/cron.allow/etc/cron.deny管理
  • crontab

    [root@homqyy-centos ~]# crontab [-u username] [-l|-e|-r]
    选项与参数:
    -u          : Appends the name of the user whose crontab is to be modified. If this option is not used, crontab examines "your" crontab, i.e., the crontab of the person executing the command. Note that su may confuse crontab, thus, when executing commands under su you should always use the -u option.
    -e          : Edits the current crontab using the editor specified by the VISUAL or EDITOR environment variables. After you exit from the editor, the modified crontab will be installed automatically.
    -l          : Displays the current crontab on standard output.
    -r          : Removes the current crontab.
    
    • 格式
      字段分钟小时日期月份用户名(在/var/spool/cron/中不需要该字段)命令
      0 - 590 - 231 - 310 - (7周日=0 or 7) 或则 sun,mon,tue,wed,thu,fri,sat执行命令的用户需要执行的命令
      • 特殊字符
        特殊字符代表意义
        (星号)代表任何时刻
        ,(逗号)代表分隔时段的意思:0 3,6 * * * root command
        -(减号)代表一段时间范围内:20 8-12 * * * root command
        /N(斜线)每间隔N:/5 * * * * root command
    • crond
    • 配置文件
      • /etc/crontab
      • /etc/cron.d/*
      • /var/spool/cron/*

anacron

  • 作用:可唤醒停机期间的工作任务
  • 原理:anacron会分析现在的时间与时间记录文件所记载的上次执行anacron的时间,两者比较后若发现有差异,那就是在某些时刻没有执行crontab,此时anacron就会开始执行未执行的crontab任务了。
  • 配置文件
    • /etc/anacrontab:记录着要监控的任务
      • 格式
        字段天数延迟时间工作名称定义实际要执行的命令串
        若时间差超过该值则准备执行任务若准备执行任务,则先延迟该时间后再执行记录在/var/log/cron里的任务名称任务内容
    • /var/spool/anacron/*:记录着任务最近执行的时间戳
  • anacron是一个程序,并非一个服务,在/etc/cron.hourly/0anacron中运行。

  • anacron

    [root@homqyy-centos ~]# anacron [-sfn] [job]...
    [root@homqyy-centos ~]# anacron -u [job]...
    选项与参数:
    -s          : Serializes execution of jobs. Anacron does not start a new job before the previous one finished.
    -f          : Forces execution of all jobs, ignoring any timestamps.
    -n          : Runs jobs immediately and ignores the specified delays in the /etc/anacrontab file. This options implies -s.
    -u          : Updates the timestamps of all jobs to the current date, but does not run any.
    job         : 由/etc/anacrontab定义的各项任务名称。
    
    • 为了保证anacron不会误判时间,因此/etc/cron.hourly/0anacron文件名有个0作为前缀,以确保其第一个执行,以更新时间戳。

第16章 进程管理与SELinux初探

任务管理

  • bash任务管理的限制
    • 这些任务所出发的进程必须来自于你shell的子进程
    • 前台:可以控制于执行命令的这个环境称为前台的任务(foreground)
    • 后台:可以自动执行的任务,你无法使用[ctrl]+c终止它,可使用bg、fg调用该任务。
    • 后台中执行的进程不能等待terminal或shell的输入(input)
  • job control
    • 将命令丢到后台:在命令末尾增加&
    • 将当前任务丢到后台(暂停):[ctrl]+z
    • 查看后台任务:jobs
      • +:代表最近被放到后台的任务号码
      • -:代表最近第二个被放置到后台中的任务号码
    • bg
      • %N:代表任务号
    • fg
      • %N:代表任务号
    • kill
      • %N:代表任务号 => kill -15 %1

脱机管理

  • nohup
  • at

进程管理

  • ps
    • 只查看自己的bash进程:ps -l

      [root@homqyy-centos wang_hongqi]# ps -l
      F S   UID   PID  PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
      4 S     0 13418 13365  0  80   0 -  4332 poll_s pts/1    00:00:00 sudo
      4 S     0 13420 13418  0  80   0 -  1819 do_wai pts/1    00:00:00 bash
      0 R     0 13431 13420  0  80   0 -  2436 -      pts/1    00:00:00 ps
      
      • F:代表这个进程的标识,说明这个进程的权限,常见号码有:
        • 4:此进程的权限为root
        • 1:此子进程仅fork而没有实际exec
      • S:进程状态
        • R:Running
        • S:Sleep,睡眠状态(idle),可被唤醒(signal)
        • D:不可被唤醒的睡眠状态,通常这个进程可能在等待I/O的情况
        • T:停止状态(stop),可能是在任务控制(后台展厅)或跟踪(traced)状态
        • Z:Zombie,僵尸状态,进程已经终止但却无法被删除至内存外
      • UID/PID/PPID
      • C:CPU使用率,单位为百分比
      • PRI/NI:Priority/Nice
      • ADDR/SZ/WCHAN:与内存相关
        • ADDR:是kernel function,指出该进程在内存的哪个部分,如果是个running的进程,一般就会显示【-】
        • SZ:代表此进程用掉多少内存
        • WCHAN:表示目前进程是否运行,同样的,若为【-】表示正在运行
      • TTY:登录着的终端位置
      • TIME:使用的CPU时间,注意,是此进程实际花费CPU运行的时间,而不是系统时间
      • CMD:command
        • 查看所有系统运行的进程:ps aux
      USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
      root         1  0.0  0.2  26236  6064 ?        Ss   10月06   0:02 /usr/lib/systemd/systemd --switched-root --system --deserialize 22
      root         2  0.0  0.0      0     0 ?        S    10月06   0:00 [kthreadd]
      root         4  0.0  0.0      0     0 ?        S<   10月06   0:00 [kworker/0:0H]
      root         6  0.0  0.0      0     0 ?        S    10月06   0:00 [ksoftirqd/0]
      
      • USER
      • PID
      • %CPU:该进程使用掉的CPU资源百分比
      • %MEM:该进程所占用的物理内存百分比
      • VSZ:该进程使用掉的虚拟内存量(KB)
      • RSS:该进程占用的固定的内存量(KB)
      • TTY:若为 ? 则表示与终端无关
      • STAT:进程目前的状态
      • START:进程被触发启动的时间
      • TIME:该进程实际使用CPU运行的时间
      • COMMAND
      • top:动态查看进程变化
        • 查看完整信息可以将结果存储到文件中来实现:top -b -n 2 > /tmp/top.txt
      • pstree

Priority 与 Nice

  • 值越低代表越优先
  • 优先级计算公式: > PRI(new) = PRI(old) + nice
  • nice调整范围:-20 ~ 19
    • 一般用户可调节范围:0 ~ 19
    • 一般用户仅可以调高值
  • nice值会从父进程传递到子进程
  • 调整nice值的方法
    • nice
    • renice
    • top

查看系统资源

  • free:查看内存使用情况
  • uname:查看系统与内核相关信息
  • uptime:查看系统启动时间与任务负载
  • netstat:追踪网络或socket文件
  • dmesg:分析内核产生的信息
  • vmstat:检测系统资源变化

/proc/*代表的意义

  • /proc/N:N为进程号,里面的文件是与该进程相关的信息
    • cmdline:这个进程被启动的命令串
    • environ:这个进程的环境变量内容
  • 针对整个Linux
    文件名文件内容
    /proc/cmdline加载内核时所执行的相关命令与参数,查看此文件,可了解命令是如何启动的
    /proc/cpuinfo本季的CPU的相关信息
    /proc/devices这个文件记录了系统各个主要设备的主要设备代号,与mknod有关
    /proc/filesystems目前系统已经加载的文件系统
    /proc/interrupts目前系统上面的IRQ分配状态
    /proc/ioports目前系统上面各个设备所配置的I/O地址
    /proc/kcore这个就是内存的大小。很大,不要读它
    /proc/loadavg任务负载均值
    /proc/meminfo使用free列出的内存信息,在这里也能够查看到
    /proc/modules目前我们的Linux已经加载的模块列表,也可以想成是驱动程序
    /proc/swaps到底系统挂载的swap内存就在此
    /proc/partitions所有的分区记录
    /proc/uptime就是用uptime时出现的信息
    /proc/version内核版本,等效于uname -a
    /proc/bus/*一些总线设备,还有usb设备也记录在此

查看已使用文件或已执行进程使用的文件

  • fuser:借由文件(或文件系统)找出正在使用该文件的进程
  • lsof:列出被进程所使用的文件名称
  • pidof:找出讴歌正在执行的进程的PID

SELinux

什么是SELinux

  • SELinux:Security Enhanced Linux
    • 最初设计目的:避免资源误用
    • SELinux是在进行进程、文件等详细权限配置时依据的一个内核模块。由于启动网络服务的也是进程,因此刚好也是能够控制网络服务能否读写系统资源的一道关卡。
    • 更多信息查看:
  • 访问控制类型
    • 自主访问控制(DAC, Discretionary Access Control):
      • 传统的文件权限与账号的关系:依据进程的拥有者与文件资源的rwx权限来决定有误读写的权限
        • 缺点
          • 对root用户无效
          • 可以通过进程来修改文件资源的访问权限
    • 强制访问控制(MAC, Mandatory Access Control):
      • 以策略规则制定特定进程读取特定文件 dac-mac

        使用DAC/MAC产生的不同结果

SELinux的运行模式

  • 基本概念
    • 主体(Subject):进程
    • 目标(Object):文件资源(等效于文件系统)
    • 策略(Policy):读写安全性策略
      • targeted:针对网络服务限制较多,针对本机限制较少,是否认的策略(建议使用)
      • minimun:由target自定义而来,仅针对选择的进程来保护
      • mls:完整的SELinux限制,限制方面较为严格
    • 安全上下文(Security context):主体与目标的安全上下文必须一致才能够顺利读写。 SELinux

      SELinux运行的各组件之相关性

  • 安全上下文

    • 存储位置:存储于主体进程(内存)目标文件资源(inode)
    • 查看

      • 主体进程:ps -eZ

        [root@homqyy-centos ~]#
        LABEL                             PID TTY          TIME CMD
        system_u:system_r:init_t:s0         1 ?        00:00:02 systemd
        system_u:system_r:kernel_t:s0       2 ?        00:00:00 kthreadd
        system_u:system_r:kernel_t:s0       4 ?        00:00:00 kworker/0:0H
        # Identify:role:domain
        # 身份识别:角色:类型
        
      • 文件资源:ls -Z

        [root@homqyy-centos ~]# ls -Z
        -rw-------. root root system_u:object_r:admin_home_t:s0 anaconda-ks.cfg
        # Identify:role:type
        # 身份识别:角色:类型
        
    • 身份识别(Identify):相当于账号方面的身份识别

      • unconfined_u:不受限的用户(来之非受限进程,即来自于不受SELinu控制的进程)
      • system_u:系统用户(大部分就是系统自己产生的文件)
    • 角色(Role):通过此来了解该数据是属于进程、文件资源还是用户
      • object_r:代表的是文件或目录等资源
      • system_r:代表的是进程,不过,一般用户也会被指定为该角色
    • 类型(Type)(最重要):在target中,只关心Type。
      • 类型在主体进程与目标文件资源中的定义:
        • domain:在主体进程(Subject)中称为Domain
        • type:在文件资源(Object)上面称为Type
      • 只有当domain与type匹配时,进程才能够顺利读取文件资源
    • domain与type的关系 SELinux_domain_type

      domain与type间的关系

    • 运行程序,进程得到domain

    • 进程读取文件时,会通过domain去比对策略中的规则(对比上下文)
    • 通过策略检测后,对比rwx权限
    • 权限通过后便可读取文件资源

SELinux的模式及相关配置文件及命令

  • 模式类型
    • Enforcing:强制模式
    • permissive:宽容模式,只会有警告不会真正的进行限制,可以作为debug使用
    • Disabled:关闭模式
  • 查看模式:getenforce
  • 查看策略状态:sestatus
  • 配置文件:/etc/selinux/config
  • 启动与关闭
    • 需要重启的操作
      • 修改策略
      • 模式
        • Enforcing/Permissive => Disabled
        • Disabled => Enforcing/Permissive
    • 修改模式:
      • setenforce [0|1]
        • 0:Permissive
        • 1:Enforcing
      • 修改配置文件
  • 还原所有SELinux的类型:restorecon -Rv

SELinux策略内的规则管理

  • 查看各个规则的布尔值:getsebool
  • 查看策略组成信息:seinfo
  • 搜索策略中的规则信息
  • 策略配置工具:semanage
  • 设置规则bool值:setsebool

SELinux安全上下文的修改

  • 修改文件的安全上下文:chcon
  • 让文件恢复正确的SELinux类型:restorecon
    • 设置默认文件上下文的默认值
      • semanage fcontext -{a|d|m} [-frst] file_spec
        • eg: semanage fcontext -a -t system crond_spool_t "/srv/mycron(/.*)?"

日志文件

  • 记录SELinux产生的错误的服务

    • auditd
    • setroubleshootd
      • 日志
        • 错误信息写入:/var/log/messages
        • 解决方法写入:/var/log/setroubleshoot/*
      • 软件:setroubleshoot、setroubleshoot-server

        在CentOS 6.x(含7.x)以后,将两者结合在auditd中了,因此setroubleshootd已经不存在了 CentOS 7.x对setroubleshootd的运行方式:

        1. auditd服务 调用 audispd服务
        2. audispd服务 启动 sedispatch程序
        3. sedipatch进程将原本的auditd信息转成setroubleshootd的信息,并进一步存储下来
  • 查看告警信息:sealert

参考资料与扩展阅读

第17章 认识系统服务(daemon)

  • 从CentOS 7.x开始,传统的init已经被systemd取代。
  • service:提供某些功能
  • daemon:实现service的进程

早期System V的init管理

  • 服务的启动、关闭与查看等方式
    • 所有的服务启动脚本放置于/etc/init.d/目录,基本上都是使用bash shell缩写的脚本程序,操作如下:/etc/init.d/daemon {start|stop|restart|status}
  • 服务启动的分类
    • 独立启动模式(stand alone):服务独立启动,该服务直接常驻于内存中,提供本机或用户的服务操作,反应速度快。
    • 超级守护进程(super daemon):由特殊的xinetd或inetd这两个总管程序提供socket管理。当用户要求时,xintd才会去唤醒相应的服务程序。当该要求结束时,此服务也会被结束,因为通过xinetd管理因此xinetd被称为super daemon。
      • 好处:可以通过super daemon来执行服务的时程、连接需求等控制
      • 缺点:唤醒服务有延迟。
  • 服务的依赖性问题
    • init在管理员自己手动处理这些服务时,是没有办法协助唤醒以来服务的。
  • 运行级别的分类
    • Linux提供7个运行级别:
      • 0:单人维护模式
      • 1
      • 2
      • 3:纯命令行模式
      • 4
      • 5:图形界面
      • 6
      • 7
    • 各个运行级别的启动脚本通过将/etc/rc.d/rc[0-6]/SXXdaemon链接到/etc/init.d/daemon来实现服务的启动。
      • S为启动该服务,XX是启动的顺序。
  • 制定运行级别默认要启动的服务
    • 默认要启动:chkconfig daemon on
    • 默认不启动:chkconfig daemon off
    • 查看默认为启动与否:chkconfig --list daemon
    • 如果chkconfig --add daemon报错,请man chkconfig,查看RUNLEVEL FILES章节
  • 运行级别的切换操作
    • init
  • 更多可参考:http://linux.vbird.org/linux_basic/0560daemons/0560damons-centos5.php

systemd使用的unit分类

  • systemd的好处
    • 并行处理所有服务,加速开机流程
    • 一经要求就响应的on-demand启动方式:通过systemd服务来支持
    • 服务依赖性的自我检查
    • 依daemon功能分类:service、socket、target、path、snapshot、timer等
    • 将多个daemons集合成为一个群组:target
    • 向下兼容旧的init服务脚本:
      • 但是仍旧有无法替换的地方:
        • 在1、3、5级别中有对应到target中,但是其他没有
        • 使用systemctl统一控制,无法像init.d为脚本灵活
        • 如果服务是自己手动启动的,那么systemd将无法再管理该进程。
        • 无法与管理员通过标准输入传入信息
  • systemd的配置文件
    • /usr/lib/systemd/system/:每个服务最主要的启动脚本设置,类似/etc/init.d
    • /run/systemd/system/:系统执行过程中所产生的服务脚本,这些脚本的优先级要比/usr/lib/systemd/system/高
    • /etc/systemd/system/:管理员根据主机系统的需求所建立的执行脚本,类似于/etc/rc.d/rc5.d/Sxx,执行优先级比/run/systed/system/高
  • 常见的systemd服务类型
    扩展名主要服务功能
    .service一般服务类型(service unit):主要是系统服务,包括服务器本身所需要的本地服务以及网络服务等。经常被使用到的服务大多是这种类型。所以,这也是最常见的类型
    .socket据交换的socket服务(socket unit):主要是IPC的传输信息socket文件功能。这种类型的服务通常在监控信息传递的socket文件中,当通过此socket文件传递信息要链接服务时,就根据当时的状态将该用户的要求传送到对应的daemon,若daemon尚未启动,则启动该daemon后再传送用户要求。
    .target执行环境类型(target unit):其实是一群unit的集合
    .mount文件系统挂载相关的服务(automount unit/mount unit):例如来自网络的自动挂载、NFS文件系统挂载等与文件系统相关性较高的进程管理
    .automount
    .path检查特定文件或目录类型(path unit):某些服务需要检测某些特定的目录来提供队列服务,例如最常见的打印服务。
    .timer循环执行的服务(timer unit):类似于anacrontab

systemctl管理服务

  • 当前状态
    • active(running)
    • inactive(dead):已被注销
    • active(exited):正常结束
    • active(waiting):正在运行当中,不过还需要等待其他的时间发生才能继续
  • 默认状态
    • enabled:开机被运行
    • disabled
    • static:不可以手动启动,不过可能会被其他enabled的服务唤醒
    • mask:无法被启动,因为已经被强制注销,可通过systemctl unmask来取消。

管理不同的操作环境(target unit)

  • 查看环境:systemctl list-units --type=target --all
  • 根操作界面相关性较高的target
    • graphical.target:multi-user.target + 图形界面
    • multi-user.target:纯命令模式
    • rescue.target:在无法使用root登录的情况下,systemd在启动时会多家一个额外的临时系统,与你原本的系统无关,这时你可以取得root的权限来维护你的系统。但是需要chroot到原有的系统中。
    • emergency.target:紧急处理系统的错误,在无法使用secue.target时,可以尝试该模式
    • shutdown.target:关机模式
    • getty.target:可以设置tty
  • 获取默认target:systemctl get-default
  • 设置默认target:systemctl set-default <unit.target>
  • 切换模式:systemctl isolate <unit.target>
  • 其他操作
    • 关机:systemctl poweroff
    • 重启:systemctl reboot
    • 挂起:systemctl suspend
    • 休眠:systemctl hibernate
    • 恢复:systemctl rescue
    • 紧急恢复:systemctl emergency
  • 分析依赖性:systemctl list-dependencies [unit] [--reverse]
  • 与systemd的daemon运行相关目录
    • /usr/lib/systemd/system/
    • /run/systemd/system/
    • /etc/systemd/system/
    • /etc/sysconfig/*:服务会将初始化的一些选项设置写入到这个目录中。
    • /var/lib/:一些会产生数据的服务都会将它的数据写入到该目录中。
    • /run/:放置了好多daemon的缓存,包括lock文件以及PID文件
  • 查看daemon用到的socket文件:systemctl list-sockets

针对service类型的配置文件

  • 配置文件文件
    • 规则
      • 设置项目通常是可以重复的,不过后面的值会替换前面的
      • 如果设置参数需要有bool值,可以使用:
        • 启动:1、yes、true、on
        • 关闭:0、no、false、off
      • 空白行、开头为#或;的哪一行都代表注释
    • section
      • [Unit]:unit本身的说明,以及与其他以来daemon的设置,包括在神恶魔服务之后才启动此unit之类的设置值
      • [Service]、[Socket]、[Timer]、[Mount]、[Path]:不同的unit类型就得要使用相对应的设置项目。服务的话就用[Service]
      • [Install]:安装此unit到哪个target
  • [Unit]:man systemd.unit
    [Unit] 部分
    设置参数参数意义说明
    Descriptionsystemctl list-units输出的说明信息
    Documentation提供管理员能够进一步的文件查询功能,例如:
    • Documentation=http://www...
    • Documentation=man:sshd(8)
    • Documentation=file:/etc/ssh/sshd_config
    After说明此unit是在哪个daemon启动之后才启动。只是说明启动顺序,并非强制
    Before与After反义
    Requires说明此unit是在哪个daemon启动之后才启动。强制约束
    Wants期望在之后能启动哪个daemon的意思
    Conflicts冲突检测。如果后面接的服务已经启动,则不启动unit本身。如果我们已经启动,则后面的项目就不能启动
  • [Service]:man systemd.service
    [Service] 部分
    设置参数参数意义说明
    Typedaemon的启动方式:
    • simple: 默认值,这个daemon主要由ExecStart接的命令来启动,启动后常驻于内存。
    • forking: 由ExecStart启动的程序通过spawns扩展出其他子进程来作为此daemon的主要服务,原生的父进程在启动结束后就会终止运行。传统的unit服务大多属于这种项目,例如httpd这个WWW服务,当httpd的进程因为运行过久因此即将关闭,则systemd会重新生成一个子进程继续运行后,再将父进程删除。据说这样性能更好
    • oneshot: 与simple类似,不过这个进程在工作完毕后就关闭,不会常驻于内存
    • dbus: 与simple类似,但这个daemon必须要在获取一个D-Bus的名称后,才会继续运行,因此设置这个项目时,通常也要设置BusName= 才行
    • idle: 与simple类似,意思是要执行这个daemon必须要所有的工作都顺利执行完毕后才会执行,这类的daemon通常是开机到最后才执行的服务
    EnvironmentFile可以指定启动脚本的环境配置文件。也可以使用Environment= 后面接多个不同的Shell变量来给予设置
    ExecStart启动时执行的命令。也可以使用ExecStartPre以及ExecStartPost来设置前后需要额外执行的动作。
    ExecStop停止时执行的命令。
    ExecReload重载时执行的命令。
    Restart如果Restart=1,则服务终止后,会再次启动此服务。
    RemainAfterExit当RemainAfterExit=1时,当daemon所属的所有进程都终止之后,此服务会再次尝试尝试启动,这对于Type=oneshot的服务很有帮助
    TimeoutSec若这个服务在启动或关闭时,因为某些缘故导致无法顺利【正常启动或正常结束】时,我们将等待此项目指定的时间后才进入【强制结束】的状态
    KillMode可以是process、control-group、none其中一种:
    • process:daemon终止时,只会终止主要的进程
    • control-group:daemon所产生的其他control-group进程也都会被关闭
    • none:没有进程会被关闭
    RestartSec如果服务被关闭,然后需要重启时,需要sleep多久才重启。默认是100ms
  • [Install]
    [Install] 部分
    设置参数参数意义说明
    WantedBy后面正常接的是*.target unit,意思是本unit依附于哪个target unit
    Also当unit被enable时,Also后面接的unit也enable
    Alias运行一个链接的别名的意思

多重的重复设置方法

  • 配置文件
    • 原始文件:服务名称@.service
    • 执行文件:服务名称@范例名称.service
      1. 先查看/usr/lib/systemd/system/、/etc/systemd/system/中有没有服务名称@范例名称.service
      2. 如果没有则查找服务名称@.service 并且将范例名称%I的形式传入
  • 将tty的数量由6降低到4
    1. 修改/etc/systemd/logind.conf,将NAutoVTs的值设置为4
    2. 关闭多余的tty服务:systemctl stop getty@tty{5,6}.service
    3. 重启服务:systemctl restart systemd-logind.service

systemctl针对timer的配置文件

  • 通过timer unit去定时驱动其他unit,默认是去驱动同名service unit。可以通过Uint=去驱动特定uint。 默认存在如下依赖关系:

    • Conflicts=shutdown.target
    • Before=shutdown.target
    • After=timer-sync.target
  • 优势

    • 所有的systemd的服务产生的信息都会被记录(log),因此比crond在debug傻姑娘面要更清楚方便
    • 各项timer的任务可以跟systemd的服务结合
    • 各项timer的任务可以跟control group(cgroup,用来替换/etc/secure/limit.conf的功能)结合,来限制该任务的资源利用
    • 精确到毫秒
  • 添加定时任务需要的条件

    • timer.target一定要启动
    • 需要有个sname.service服务(sname为自定义的名字)
    • 需要有个sname.timer的时间启动服务存在
  • [Timer]:man systemd.timer

    [Timer] 部分
    设置参数参数意义说明
    OnActiveSec当timers.target启动多久之后才执行这个unit
    OnBootSec当启动完成后多久之后才执行
    OnStartupSec当systemd第一次启动之后多久才执行
    OnUnitActiveSec这个timer配置文件所管理的那个unit服务在最后一次启动后,隔多久后再执行一次的意思
    OnUnitInactiveSec这个timer配置文件所管理的那个unit服务在最后一次停止后,隔多久再执行一次的意思
    OnCalendar使用实际时间(非循环时间)的方式来启动服务的意思,与UNIX标准时间的时间间隔
    Unit可以指定要驱动的unit,如果没有指定subffix的话,则默认为service unit(即.service)

Centos 7.x 默认服务概要

  • 系统默认启动的服务
    Centos 7.x 默认启动的服务内容
    服务名称功能简介
    abrtd(系统)abrtd服务可以提供用户一些方式,让用户可以针对不同的应用软件去设计错误登录的机制,当软件产生问题时,用户就可以根据abrtd的日志文件来进行错误解决的操作。还有其他的abrt-xxx.service均是使用这个服务来加强应用程序的debug任务
    accounts-daemon
    (可关闭)
    (系统)使用accounts service计划所提供的一系列D-Bus界面来进行用户账户信息的查询。基本上是与useradd、usermod、userdel等软件有关
    alsa-X
    (可关闭)
    (系统)开头为alsa的服务有不少,这些服务大部分都与音效有关。一般来说,服务器如果不开图形界面的话,这些服务可以关闭
    atd(系统)单一的计划任务,详细说明请参考第15章。
    Auditd(系统)可以让系统需SELinux审核的信息写入/var/log/audit/audit.log中
    avahi-daemon(系统)也是一个客户端的服务,可以通过Zeroconf自动地分析与管理网络。Zeroconf较常用在笔记本电脑与移动设备上,所以我们可以先关闭它
    brandbot
    rhel-
    (系统)这些服务大多用于启动过程中所需要的各种检测环境的脚本,同时也提供网络界面的启动与关闭。基本上,不要关闭这些服务比较妥当
    chronyd
    ntpd
    ntpdate
    (系统)都是网络校正时间的服务。一般来说,你可能需要的仅有chronyd而已
    cpupower(系统)提供cpu的运行规范,可以参考/etc/sysconfig/cpupower得到更多的信息。
    crond(系统)系统配置文件为/etc/crontab
    cups
    可关闭
    (系统/网络)用来管理打印机的服务,可以提供网络连接的功能,优点类似打印服务器的共呢个。你可以在Linux本机上面以浏览器的http://localhost:631来管理打印机。没有打印机可以关闭
    dbus(系统)使用D-Bus的方式在不同的应用程序之间传送信息,使用的方向例如应用程序间的信息传递、每个用户登录时提供的信息数据等
    dm-event
    multipathd
    (系统)监控设备映射(device mapper)的抓哟服务,当然不能关闭。否则就无法让Linux使用我们的外围存储设备了。
    dmraid-activation
    mdmonitor
    (系统)用来启动Software RAID的重要服务。最好不要关闭,虽然你可能没有RAID
    dracut-shutdown(系统)用来处理initramfs的相关操作,这雨启动流程相关性较高
    ebtables(系统/网络)通过类似iptables这种防火墙规则的设置方式,设计网卡作为桥接时的封包分析策略。其实就是防火墙,不过与下面谈到的防火墙应用不太一样。如果没有使用虚拟化,或启用了firewalld,这个服务可以不启动
    emergency
    rescue
    (系统)进入紧急模式或是恢复模式的服务
    firewalld(系统/网络)就是防火墙。以前有iptables与ip6tables等防火墙机制,新的firewalld搭配firewall-cmd命令,可以快速地创建好你的防火墙系统。因此,从CentOS 7.1以后,iptables服务的启动脚本已经被忽略了。请使用firewalld来替换iptables服务
    gdm(系统)GNOME的登录管理员,就是图形界面上一个很重要的登录管理服务
    getty@(系统)就是要在本机系统产生几个命令行界面(tty)登录的服务
    hyper
    ksm*
    libvirt*
    vmtoolsd
    (系统)跟建立虚拟机有关的许多服务。如果你不玩虚拟机,那么这些服务可以先关闭。此外如果你的Linux本来就在虚拟机下面,那这些服务对你就没有用,因为这些服务是让物理机来建立虚拟机的
    irqbalance(系统)如果你的系统是多内核的硬件,那么这个服务要启动,因为它可以自动地分配系统终端(IRQ)之类的硬件资源
    iscsi*(系统)可以挂载来自网络驱动器的服务。这个服务可以在系统中模拟很贵的SAN网络驱动器。如果你确定系统上面没有挂载这种网络驱动器,也可以将它关闭。
    kdump(可关闭)(系统)如果内核出错,用来记录
    lvm2-跟LVM相关性较高的许多服务,当然也不能关
    microcodeIntel的CPU会提供一个外挂在微命令集提供系统运行,不过,如果你没有下载Intel相关的命令集文件,那么这个服务不需要启动的,也不会影响系统运行
    ModemManager
    network
    NetworkManager
    (系统/网络)主要就是调制解调器、网络设置等服务。进入CentOS 7之后,操作系统似乎不太希望我们使用network服务,比较建议的是使用NetworkManager搭配nmcli命令来处理网络设置,所以,反而是NetworkManager要开,而network不用开
    quotaon(系统)启动磁盘配额要用到的服务
    rc-local(系统)兼容于/etc/rc.d/rc.local的调用方式。只是,你必须要让/etc/rc.d/rc.local具有x的权限后,这个服务才讷讷个真的运行。否则你写入/etc/rc.d/rc.local的脚本还是不会运行的。
    rsyslog(系统)这个服务可以记录系统所产生的各项信息,包括/var/log/messages内的几个重要的日志文件
    smartd(系统)这个服务可以自动检测硬盘状态,如果硬盘发生问题的话,还能够自动报告给系统管理员,是个非常有帮助的服务,不可关闭它
    sysstat(系统)事实上,我们的系统有个名为sar的命令会记载某些时间点下操作系统的资源使用情况,包括CPU/流量/输入输出量等,当sysstat服务启动后,这些记录的数据才能够被写入到记录文件(log)里面去
    systemd-(系统)大概都是属于系统运行过程所需要的服务,没必要都不要修改它的默认状态
    plymount
    upower
    (系统)与图形界面的使用相关性较高的一些服务。没有启动图形界面时,这些服务可以暂时不管它
  • 其他服务
    其他服务的简要说明
    服务名称功能简介
    dovecot(网络)可以设置POP3/IMAP等首发邮件的服务,如果你的Linux主机是邮件服务器才需要这个服务,否则不需要启动它
    httpd(网络)网站服务器
    named(网络)域名服务器
    nfs
    nfs-server
    (网络)Network Filesystem,是UNIX-like之间相互作为网络驱动器的一个功能
    smb
    nmb
    (网络)可以让Linux模拟成为Windows上面的网络邻居。
    vsftpd(网络)ftp服务器
    sshd(网络)ssh服务器
    rpcbind(网络)完成RPC协议的重要服务,包括NFS、NIS等都需要这东西的协助
    postfix(网络)邮件发送主机,因为系统还是会产生很多email信息,例如crond、atd就会发送email给本机用户,所以这个服务千万不能关,即使你不是邮件服务器也是要启动这个服务才行

参考资料与扩展阅读

第18章 认识与分析日志文件

日志文件简易说明

  • 为什么日志文件? > 记录系统活动信息的文件。例如:何时、何地(来源IP)、何人(什么服务名称)、做了什么操作(信息登录)
  • Linux常见的日志文件名称
    • /var/log/boot.log > 启动时内核会检测并启动硬件,并启动内核支持的功能。该过程会记录在该日志,不过只记录本次开机的启动信息
    • /var/log/cron
    • /var/log/dmesg > 记录系统在开机的时候内核检测过程所产生的各项信息
    • /var/log/lastlog > 记录系统上面所有的账号最近一次登录系统时的相关信息。
    • /var/log/maillog或/mvr/log/mail/* > 记录邮件的往来信息,其实主要是记录postfix(SMTP协议提供者)与devecot(POP3协议提供者)所产生的信息。
    • /var/log/messages > 记录系统发生的错误信息
    • /var/log/secure > 牵扯到【需要输入账号密码】的软件,无论登录结果如何都会被记录到此文件中
    • /var/log/wtmp、/var/log/faillog > 记录正确登录系统者的账户信息(wtmp)与错误登录时所使用的账户信息(failog)
  • 日志文件需要的daemon:分为“服务本身记录”和“rsyslog.service“统一管理
    • systemd-journald.service:最主要的信息记录者,由systemd提供。
      • 日志信息被放置到内存中,可以通过journalctl以及systemctl status unit.service来查看不同服务的日志文件。
      • 记录日志信息后会发送给rsyslog.service做进一步记录。
    • rsyslog.service:主要收集登录系统与网络等服务的信息。
    • logrotate:主要在进行日志文件的轮询功能。

日志文件内容的一般格式

  • 事件发生的日期与时间
  • 发生此事件的主机名
  • 启动此事件的服务名称(如systemd、crond等)或命令与函数名称(如su、login..)
  • 该信息的实际内容

rsyslog.service

配置文件:/etc/rsyslog.conf

  • 目的:为了让不同的信息放置到不同的文件当中,好让我们分门别类的进行日志文件的管理。
  • 该文件规定了:什么服务什么等级信息需要被记录在哪里(设备或文件)
  • 格式:服务名称[.=!\信息等级 信息记录的文件名或设备或主机

    # mail服务产生的大于等于info等级的信息都记录到/var/log/maillog_info文件中
    mail.info       /var/log/maillog_info
    
  • 服务名称(man 3 syslog或syslog.h)

    相对序号服务类别说明
    0kern(kernel)就是内核(kernel)产生的信息,大部分都是硬件检测以及内核功能的启用
    1user在用户阶层所产生的信息
    2mail只要与邮件收发有关的信息记录都属于这个
    3daemon主要是系统的服务所产生的信息
    4auth主要与认证/授权有关的机制,例如login、ssh、su等需要账号密码的东西
    5syslog就是由syslog相关协议产生的信息,其实就是rsyslogd这个程序本身产生的信息
    6lpr打印
    7news新闻组服务器相关
    8uucpUNIX to UNIX Copy Protocol,早期用于UNIX系统间的程序数据交换
    9cron计划任务cron、at等
    10authpriv与auth类似,但记录较多账号的私人信息,包括pam模块的运行等。
    11ftp与FTP相关
    16~23local0 ~ local7保留给本机用户使用的一些日志文件信息,较常与终端互动

  • 信息等级

    等级数值等级名称说明
    7debug用来debug(除错)时产生的数据
    6info仅是一些基本的信息说明而已
    5notice虽然是正常信息,但比info还需要被注意到的一些信息内容
    4warning(warn)警示的信息,可能有问题,但是还不至于影响到某个daemon运行的信息。基本上,info、notice、warn这三个信息等级都是在告知一些基本信息而已,应该还不至于造成一些系统运行困扰
    3err(error)一些重大的错误信息,例如配置文件的某些设置值造成该服务无法启动的信息说明,通常借由err的错误告知,应该可以了解到该服务无法启动的问题
    2crit比error还要严重的错误信息,这个crit是临界点(critical)的缩写,这个错误已经很严重了
    1alert警告,已经很有问题的等级
    0emerg(panic)以指系统几乎要宕机的状态,很严重的错误等级。通常大概只有硬件出问题,导致整个内核无法顺利运行,就会出现这样的等级的信息

    • 除此之外还有none级别(不需要记录级别)
    • 信息级别连接符号的意思
      • .:严重等级高于或等于
      • .=:相匹配的级别
      • .!:除此级别之外
    • 信息记录的文件名或设备或主机
    • 文件的绝对路径:例如/var/log/example.log
    • 打印机或其他:例如/dev/lp0
    • 用户名称:显示给用户
    • 远程主机:例如@study.homqyy
    • *:代表目前在线的所有人,类似wall这个命令
    • 服务、daemon与函数名称
    • syslog:函数
    • rsyslogd:daemon
    • rsyslog.service:将rsyslogd加入到systemd中控制
  • 示例

    # mail的信息级别记录到/var/log/maillog中
    mail.info /var/log/maillog
    
    # news和cron的日志信息记录到/var/log/cronnews
    # news和cron的warn级别日志记录到/var/log/cronnews.warn
    news.*;cron.* /var/log/cronnews
    news.=warn;cron.=warn /var/log/cronnews.warn
    
    # 所有日志信息都记录到/var/log/message,除了cron、mail外
    # 逗号只需在最后接级别即可
    # 分号需要单独写
    *.*;news,cron,mail.none /var/log/messages
    *.*;news.none;cron.none;mail.none /var/log/message
    
  • CentOS 7.x默认rsyslog.conf内容

    #kern.*                                                 /dev/console
    *.info;mail.none;authpriv.none;cron.none                /var/log/messages
    authpriv.*                                              /var/log/secure
    mail.*                                                  -/var/log/maillog
    cron.*                                                  /var/log/cron
    *.emerg                                                 :omusrmsg:*
    uucp,news.crit                                          /var/log/spooler
    local7.*                                                /var/log/boot.log
    
    1. #kern.*:只要是内核产生的信息都送到console去
    2. mail.*:日志文件前面的-表示的意思是,将mail的所有日志信息都存储到/var/log/maillog,但是先存储在较快的内存缓冲区(buffer)中,等到数据量够大了再一次性写入磁盘。这里需要注意,如果异常断电可能会丢失信息
    3. *emerg:将所有emerg级别的日志以wall的方式广播给所有系统登录的账号。
    4. local7.*:将本机启动时应该显示到屏幕的信息写入到/var/log/boot.log中。
  • 修改配置文件使之生效的方法:systemctl restart rsyslog.service

日志文件的安全性设置

  • rsyslogd的日志文件只要【被编辑过】就无法继续记录,只能重启rsyslog.service
  • 可以通过chattr +a来确保日志只能增。

日志服务器的设置

  • 服务器
    • 监听端口:TCP/UDP 514
  • 客户端

    [root@study ~]# vim /etc/rsyslog.conf
    >>>>>> /etc/rsyslog.conf
    *.*     @@192.168.1.100 # TCP
    # *.*     @192.168.1.100 # UDP
    <<<<<< end
    [root@study ~]# systemctl restart rsyslog.service
    

logrotate

  • 配置文件

    • / etc/logrotate.conf
    • /etc/logrotate.d/

      logrotate.conf才是主要的参数文件,至于logrotate.d则是一个目录,该目录里面的所有文件都会被主动的读入logrotate.conf当中使用。

    logrotate_4times

    日志文件进行logrotate的结果(4次)

  • 内容

    # see "man logrotate" for details
    # rotate log files weekly
    weekly
    
    # keep 4 weeks worth of backlogs
    rotate 4
    
    # create new (empty) log files after rotating old ones
    create
    
    # use date as a suffix of the rotated file
    dateext # 增加了此后缀后,备份数量不再受rotate配置控制
    
    # uncomment this if you want your log files compressed
    #compress
    
    # RPM packages drop log rotation information into this directory
    include /etc/logrotate.d
    
    # no packages own wtmp and btmp -- we'll rotate them here
    /var/log/wtmp {
        monthly
        create 0664 root utmp # 指定新建文件的"权限"、"所有者"、"组"
        minsize 1M # 至少1M才进行轮询
        rotate 1 # 仅保留1份备份
    }
    
  • 语法

    日志文件的绝对路径与文件名 ... {
        参数设置
    }
    
    # /etc/logrotate.d/syslog
    /var/log/cron
    /var/log/maillog
    /var/log/messages
    /var/log/secure
    /var/log/spooler
    {
        missingok
        sharedscripts
        postrotate
        /bin/kill -HUP `cat /var/run/syslogd.pid 2> /dev/null` 2> /dev/null || true
        endscript
    }
    
    • 文件名:绝对路径文件名写在前面,可以用空格符分隔多个日志文件。
    • 参数:通过{}包裹
    • 执行脚本:该设置需放置在sharedscripts......endscript之间
      • prerotate:启动logrotate之前
      • postrotate:启动logrotate之后

systemd-journald.service

过去只有rsyslogd的年代,由于rsyslogd必须要启动完成并且执行rsyslogd这个daemon之后,日志文件才会开始记录。所以,内核还得要自己产生一个klogd的服务,才能将系统在启动过程、启动服务的过程中的信息记录下来,然后等rsyslogd启动后才传送给它来处理。 现在有了systemd之后,由于它是内核唤醒且第一个运行的,因此它可以主动调用systemd-journald来协助记录日志文件,因此在开机启动过程中的所有信息。 不过systemd-journald由于是使用内存记录,因此重新启动后,上次的记录将丢失,因此还是建议启动rsyslogd来协助分类记录,即:systemd-journald用来管理与查询此次启动后的登录信息,而rsyslogd可以用来记录以前及现在的所有数据到磁盘文件中,方便未来进行查询。 systemd-journalds所记录的数据在/run/log/下面

  • journalctl:查询登录信息

    [wang_hongqi@homqyy-centos log]$ journalctl --help
    journalctl [OPTIONS...] [MATCHES...]
    
    Query the journal.
    
    Flags:
        --system              Show the system journal
        --user                Show the user journal for the current user
    -M --machine=CONTAINER   Operate on local container
    -S --since=DATE          Show entries not older than the specified date
    -U --until=DATE          Show entries not newer than the specified date
    -c --cursor=CURSOR       Show entries starting at the specified cursor
        --after-cursor=CURSOR Show entries after the specified cursor
        --show-cursor         Print the cursor after all the entries
    -b --boot[=ID]           Show current boot or the specified boot
        --list-boots          Show terse information about recorded boots
    -k --dmesg               Show kernel message log from the current boot
    -u --unit=UNIT           Show logs from the specified unit
    -t --identifier=STRING   Show entries with the specified syslog identifier
    -p --priority=RANGE      Show entries with the specified priority
    -e --pager-end           Immediately jump to the end in the pager
    -f --follow              Follow the journal
    -n --lines[=INTEGER]     Number of journal entries to show
    --no-tail             Show all lines, even in follow mode
    -r --reverse             Show the newest entries first
    -o --output=STRING       Change journal output mode (short, short-iso,
                                    short-precise, short-monotonic, verbose,
                                    export, json, json-pretty, json-sse, cat)
        --utc                 Express time in Coordinated Universal Time (UTC)
    -x --catalog             Add message explanations where available
        --no-full             Ellipsize fields
    -a --all                 Show all fields, including long and unprintable
    -q --quiet               Do not show privilege warning
        --no-pager            Do not pipe output into a pager
    -m --merge               Show entries from all available journals
    -D --directory=PATH      Show journal files from directory
        --file=PATH           Show journal file
        --root=ROOT           Operate on catalog files underneath the root ROOT
        --interval=TIME       Time interval for changing the FSS sealing key
        --verify-key=KEY      Specify FSS verification key
        --force               Override of the FSS key pair with --setup-keys
    
    Commands:
    -h --help                Show this help text
        --version             Show package version
    -F --field=FIELD         List all values that a specified field takes
        --new-id128           Generate a new 128-bit ID
        --disk-usage          Show total disk usage of all journal files
        --vacuum-size=BYTES   Reduce disk usage below specified size
        --vacuum-time=TIME    Remove journal files older than specified date
        --flush               Flush all journal data from /run into /var
        --header              Show journal header information
        --list-catalog        Show all message IDs in the catalog
        --dump-catalog        Show entries in the message catalog
        --update-catalog      Update the message catalog database
        --setup-keys          Generate a new FSS key pair
        --verify              Verify journal file consistency
    
  • logger:记录信息到日志文件中

    Usage:
    logger [options] [message]
    
    Options:
    -T, --tcp             use TCP only
    -d, --udp             use UDP only
    -i, --id              log the process ID too
    -f, --file <file>     log the contents of this file
    -h, --help            display this help text and exit
    -S, --size <num>      maximum size for a single message (default 1024)
    -n, --server <name>   write to this remote syslog server
    -P, --port <port>     use this port for UDP or TCP connection
    -p, --priority <prio> mark given message with this priority
    -s, --stderr          output message to standard error as well
    -t, --tag <tag>       mark every line with this tag
    -u, --socket <socket> write to this Unix socket
    -V, --version         output version information and exit
    
  • 配置文件:/etc/systemd/journald.conf

    • 详情:man 5 journald.conf
  • 将journald记录的日志信息记录到日志文件中

    1. 创建日志目录:mkdir /var/log/journal
    2. 改变属性:
      1. chown root:systemd-journal /var/log/journal
      2. chmod 2775 /var/log/journal
    3. 重新启动服务:systemctl restart systemd-journald.service

    注意:因为整个日志文件的荣来给你会持续增长,因此最好查看一下系统能用的总容量,避免不小心文件系统的容量被填满。因为已经有rsyslog.service以及logrotate存在,因此建议就让其在/run/log即可。

分析日志

  • logwatch:CentOS默认提供的软件,每天分析一次日志文件,并将数据以email的格式寄送给root。(TODO: 测试失败,没有发邮件)

  • 鸟哥自己的日志分析程序:http://linux.vbird.org/linux_basic/0570syslog/logfile_centos7.tar.gz

    1. 解压到根目录:tar -zxvf /path/to/logfile_centos7.tar.gz -C /
    2. 查看定时任务:cat /etc/cron.d/vbirdlogfile
    3. 执行脚本测试:sh /root/bin/logfile/logfile.sh

第19章 启动流程、模块管理与Loader

启动流程

  1. 加载BIOS的硬件信息与自检,并根据设置取得第一个可启动的设备。
  2. 读取并执行第一个启动设备内MBR的启动引导程序(grub2、spfdisk等程序)。
  3. 根据启动引导程序的设置加载Kernel,Kernel会开始检测硬件与加载驱动程序。
  4. 驱动启动成功后,Kernel会主动调用systemd程序,并以default.target流程启动:
    1. systemd 执行 sysinit.target初始化系统及basic.target准备操作系统。
    2. systemd 启动 multi-user.target下的本机与服务器服务。
    3. systemd 执行 multi-user.target下的/etc/rc.d/rc.local文件。
    4. systemd 执行 multi-user.target下的getty.target及登录服务。
    5. systemd 执行 graphical需要的服务。

BIOS、boot loader与kernel加载

BIOS:不论传统BIOS还是UEFI BIOS都会被简称为BIOS MBR:虽然分区表有传统MBR以及新式GPT,不过GPT也有保留一块兼容MBR的区块,因此,下面的说明在安装boot loader的部分,还是简称为MBR。总之mBR就代表该磁盘的最前面可安装boot loader的那个区块。

  • BIOS:

    1. 系统会加载BIOS,并让BIOS去加载CMOS信息,然后通过CMOS内的设置值取得主机的各项硬件配置。
    2. 接着会进行自检与初始化,并定义出可启动的设备顺序。
    3. 指定好启动设备后,利用INT 13终端功能来读取启动设备的boot loader,并交由其去引导操作系统的启动。
  • boot loader的功能

    • 主要功能:
      • 提供选项:用户可以选择不同的启动选项,这也是多重引导的重要功能。
      • 加载内核文件:直接指向可启动的程序区域来启动操作系统。
      • 转交其他loader:将启动管理功能转交给其他loader负责。
        • Windows的loader默认不具有控制权转交的功能。
    • 每个文件系统都会保留一块boot sector提供操作系统安装boot loader Loader

      图 loader

    • 安装Linux的时候可以选择将boot loader安装到MBR或则不安装。

    • 安装Windows的时候会默认的将MBR与boot sector都装上一份boot loader。
  • 加载内核检测硬件与initramfs

    • 当boot loader读取内核文件后,Linux会利用内核的功能开始开始测试与驱动各个周边设备,包括存储设备、CPU、网卡、声卡等。此时Linux内核会以自己的功能重新检测一次硬件,而不一定会使用BIOS检测到的硬件信息。也就是说,内核此时才开始接管BIOS后的工作。
    • 内核文件放置位置:/boot/vmlinuz

      [root@whq-server ~]# ls --format=single-column -F /boot
      config-3.10.0-514.26.2.el7.x86_64 # 此版本内核被编译时,选择功能与模块的配置文件
      config-3.10.0-514.el7.x86_64
      grub/ # 旧版本grub1,不需要理会这目录
      grub2/ # 启动引导程序grub2相关数据目录
      initramfs-0-rescue-963c2c41b08343f7b063dddac6b2e486.img # 下面几个为虚拟文件系统文件,这个是用来恢复的
      initramfs-3.10.0-514.26.2.el7.x86_64.img # 正常启动会用到的虚拟文件系统
      initramfs-3.10.0-514.26.2.el7.x86_64kdump.img # 内核出问题时会用到的虚拟文件系统
      initramfs-3.10.0-514.el7.x86_64.img
      initramfs-3.10.0-514.el7.x86_64kdump.img
      initrd-plymouth.img
      symvers-3.10.0-514.26.2.el7.x86_64.gz
      symvers-3.10.0-514.el7.x86_64.gz
      System.map-3.10.0-514.26.2.el7.x86_64 # 内核功能放置到内存地址的对应表
      System.map-3.10.0-514.el7.x86_64
      vmlinuz-0-rescue-963c2c41b08343f7b063dddac6b2e486* # 恢复用的内核文件
      vmlinuz-3.10.0-514.26.2.el7.x86_64* # 内核文件,最重要
      vmlinuz-3.10.0-514.el7.x86_64*
      
    • Linux内核支持动态加载内核模块,放置在/lib/modules/目录内。 > 由于模块放置到磁盘根目录内(/lib不能与/分别放置在不同的磁盘分区),因此在启动的过程中,内核必须要挂载根目录,这样才能够加载驱动程序。因为担心影响磁盘内的文件系统,因此以只读方式挂载根目录。

    • 虚拟文件系统(Initial RAM Disk 或 Initial RAM Filesystem) > > - 一般使用的文件名为/boot/initrd或/boot/initramfs,这个文件的特色是它也能够通过boot loader加载到内存中,然后这个文件会被解压缩并且在内存当中模拟成一个根目录,且能够提供一个可以加载启动过程中所最需要的内核模块的可执行程序,通常这些模块是USB、RAID、LVM、SCSI等文件系统与磁盘接口的驱动程序。等加载完成后,会帮助内核重新调用systemd来开始后续的正常启动流程。 > - 更详细的initramfs可以man initrd查看

      loading_flow_of-BIOS-boot_loader-kernel - 用lsinitrd查看/boot/initramfs-xxxx.img的内容

      # 首先会调用initramfs最前面为看透的许多内容介绍,这部分会占用一些容量
      Image: /boot/initramfs-3.10.0-514.26.2.el7.x86_64.img: 19M
      ========================================================================
      Early CPIO image
      ========================================================================
      drwxr-xr-x   3 root     root            0 Sep 12  2017 .
      -rw-r--r--   1 root     root            2 Sep 12  2017 early_cpio
      drwxr-xr-x   3 root     root            0 Sep 12  2017 kernel
      drwxr-xr-x   3 root     root            0 Sep 12  2017 kernel/x86
      drwxr-xr-x   2 root     root            0 Sep 12  2017 kernel/x86/microcode
      -rw-r--r--   1 root     root        25600 Sep 12  2017 kernel/x86/microcode/GenuineIntel.bin
      ========================================================================
      Version: dracut-033-463.el7_3.2
      
      Arguments: -f --add-drivers ' xen-blkfront xen-blkfront virtio_blk virtio_blk virtio_pci virtio_pci virtio_console virtio_console'
      
      dracut modules: # 加载模块
      bash
      nss-softokn
      ...(省略)...
      ========================================================================
      drwxr-xr-x  12 root     root            0 Sep 12  2017 .
      crw-r--r--   1 root     root       5,   1 Sep 12  2017 dev/console
      crw-r--r--   1 root     root       1,  11 Sep 12  2017 dev/kmsg
      crw-r--r--   1 root     root       1,   3 Sep 12  2017 dev/null
      ...(省略)...
      lrwxrwxrwx   1 root     root           23 Sep 12  2017 init -> usr/lib/systemd/systemd
      ...(省略)...
      drwxr-xr-x   2 root     root            0 Sep 12  2017 var
      lrwxrwxrwx   1 root     root           11 Sep 12  2017 var/lock -> ../run/lock
      lrwxrwxrwx   1 root     root            6 Sep 12  2017 var/run -> ../run
      ========================================================================
      # 最后会列出这个initramfs里面的所有文件。也就是说,这个initramfs文件大概存着两部分内容:
      # 1. 文件头声明的许多文件部分
      # 2. 真正会被内核使用的全部附加的数据
      
      • initramfs里面有两大区块,"事先声明的一些数据"包括kernel/x86/microcode/Genuinelntel.bin这些东西。和"内核会去读取的重要文件"
      • 解开文件内容:需要去除前面的声明数据才能解开

        [root@whq-server ~]# mkdir /tmp/initramfs
        [root@whq-server ~]# cd /tmp/initramfs/
        # TODO:前面的数据多长?需要研究
        

systemd及default.target

  • systemd
    • 内核加载完毕、硬件检测和驱动加载完毕后,主机硬件进入ready状态,此时内核会调用第一个程序systemd,因此其PID为1号。
    • 最主要功能:准备软件执行的环境,包括系统的主机名、网络设置、语言设置、文件系统格式及其他服务的启动等。所有的操作都通过/etc/systemd/system/default.target来规划,已经放弃了多年的System V的runlevel。
  • 常见的操作环境target与兼容runlevel

    • multi-user.target
    • graphical.target
    • rescue.target
    • emergency.target
    • shutdown.target
    • initrd.target:在initramfs中
    • runlevel*.target:为了兼容,因此也设立了runlevel的操作环境集合

      [root@whq-server ~]# ls -ld  /lib/systemd/system/runlevel*.target
      lrwxrwxrwx 1 root root 15 8月  18 2017 /lib/systemd/system/runlevel0.target -> poweroff.target
      lrwxrwxrwx 1 root root 13 8月  18 2017 /lib/systemd/system/runlevel1.target -> rescue.target
      lrwxrwxrwx 1 root root 17 8月  18 2017 /lib/systemd/system/runlevel2.target -> multi-user.target
      lrwxrwxrwx 1 root root 17 8月  18 2017 /lib/systemd/system/runlevel3.target -> multi-user.target
      lrwxrwxrwx 1 root root 17 8月  18 2017 /lib/systemd/system/runlevel4.target -> multi-user.target
      lrwxrwxrwx 1 root root 16 8月  18 2017 /lib/systemd/system/runlevel5.target -> graphical.target
      lrwxrwxrwx 1 root root 13 8月  18 2017 /lib/systemd/system/runlevel6.target -> reboot.target
      
      • 总结其关系
        System Vsystemd
        init 0systemctl poweroff
        init 1systemctl rescue
        init [234]systemctl isolate multi-user.target
        init 5systemctl isolate graphical.target
        init 6systemctl reboot
  • systemd的处理流程

第20章 基础系统设置与备份策略

第21章 软件安装:源代码与Tarball

第22章 软件安装RPM、SRPM与YUM

第23章 X Window 设置介绍

第24章 Linux内核编译与管理

评论