第1章 linux介绍与安装
学习目标:
了解linux是什么
安装rhel8操作系统
1.1 Linux的介绍与发展
1.1.1 什么是linux
Linux是一个诞生于网络、成长于网络且成熟于网络的奇特的操作系统。要了解什么是Linux,首先我们要了从她如何创作者说起,林纳斯•本纳第克特•托瓦兹(Linus Benedict Torvalds, 1969年出生 ),当今世界最著名的电脑程序员、黑客。Linux内核的发明人及该计划的合作者。托瓦兹利用个人时间及器材创造出了这套当今全球最流行的操作系统(作业系统)内核之一。
Linux的诞生充满了很多偶然。在李纳斯上大学期间,经常要用他的终端仿真器(Terminal Emulator)去访问大学主机上的新闻组和邮件,为了方便读写和下载文件,他自己编写了磁盘驱动程序和文件系统,这些程序与代码在后来逐步发展成为了Linux第一个内核的雏形。当时是1991年。
在自由软件之父理查德斯托曼( Richard Stallman) 某些精神的感召下,李纳斯以Linux的名字把这款类Unix的操作系统加入到了自由软件基金会(FSF)的GNU计划中,并通过GPL的通用版权许可协议对他自己开发的代码进行发布,允许任何用户销售、拷贝并且自由改动软件源代码,但是当用户修改了自由共享的原代码之后必须将同样的自由把自己的知识成果继续传递下去,而且必须免费公开你修改后的代码。GPL的版权宣告定义了Linux并不是被刻意创造的,她是全球无数的自由软件开发者与爱好者是日积月累的知识结晶,是经验、创意和一小段一小段代码的集合体。
也正是李纳斯的这一举措带给了Linux和他自己带来了巨大的成功和极高的声誉。短短几年间,在Linux身边已经聚集了成千上万的狂热分子,大家不计得失的为Linux增加、修改,并随之将开源运动的自由主义精神传扬下去,通过GPL,Linux成为GNU阵营中的主要成员之一,也正是此原因让Linux操作系统的推广与普及变成可能。
现在,Linux凭借优秀的设计,不凡的性能,加上IBM、INTEL、CA、CORE、ORACLE等国际知名企业的大力支持,市场份额逐步扩大,逐渐成为主流操作系统之一。
上述的一小段文字,我们简单地介绍了Linux操作系统起源,但是要真正地了解Linux操作系统,我们还得从Uinx开始讲解,一般我们称Linux操作系统是一个类Unix的操作系统,这个要从Unix的发展历史开始了解。
Unix操作系统最早于1969年在AT&T的贝尔实验室开发。经过众多科学家的长期发展和完善,使得Unix系统具有技术成熟、结构简练、可靠性高、可移植性好、可操作性强、网络和数据库功能强、伸缩性突出和开放性好等特色,她可以满足各个行业的需要,特别是满足企业重要业务的需要,在二十世纪初期,它主要服务在巨型计算机、大型机上作为网络操作系统使用,也可用于个人计算机和嵌入式系统。是服务器操作系统的首选,但其价格非常昂贵,不适合一般的中小型企业和个人用户使用,这也是Linux状大,Unix衰落的原因。

Unix的发展大致可以分为以下几个阶段:
1)诞生期
Unix的诞生和Multics(Multiplexed Information and Computing System)是有一定渊源的。Multics是由麻省理工学院,AT&T贝尔实验室和通用电气合作进行的操作系统项目,被设计运行在GE-645大型主机上,但是由于整个目标过于庞大,糅合了太多的特性,Multics虽然发布了一些产品,但是性能都很低,最终以失败而告终。
AT&T最终撤出了投入Multics项目的资源,其中一个开发者,Ken Thompson则继续为GE-645开发软件,并最终编写了一个太空旅行游戏。经过实际运行后,效果不是很好。
在Dennis Ritchie的帮助下,Thompson用PDP-7的汇编语言重写了这个游戏,并使其在正常上运作起来。这次开发经历加上Multics项目的经验,让Thompson萌发了一个在DEC PDP-7上的设计一个新操作系统计划。Thompson和Ritchie领导一组开发者,开发了一个新的多任务操作系统。这个系统包括命令解释器和一些实用程序,这个项目被称为UNICS(Uniplexed Information and Computing System),因为它支持多用户操作。后来被命名为UNIX。
2)成长期
由于最初的Unix操作系统是用汇编语言编写的,一些应用程序是用B语言的解释型语言和汇编语言混合编写的。存在很多瓶颈,因此Thompson和Ritchie决定对Unix进行改造,并于1971年共同发明了C语言。1973 年Thompson和Ritchie用C语言重写了Unix。为了实现最高效率, 用C语言重新编写了Unix,重新编写过后的Unix代码简洁紧凑、易移植、易读、易修改,为此后Unix的发展奠定了坚实基础。
1974年,Thompson和Ritchie合作在ACM通信上发表了一篇关于UNIX的文章,这是UNIX第一次出现在贝尔实验室以外。此后UNIX被政府机关,研究机构,企业和大学注意到,并逐渐流行开来。
1982年,AT&T基于Unix版本7为蓝本,开发了UNIX第三版的第一个子版本,这是第一个商业版Unix。为了解决UNIX版权问题,AT&T综合了其他大学和公司开发的各种UNIX,审请并注册了Unix商标,并发布了商业的Unix第五版。
新版Unix商业发布版本不再包含源代码,加州大学Berkeley分校为教学与研究需要,继续开发BSD Unix,将其作为Unix第三版和第五版替代选择。BSD对UNIX最重要的贡献之一是TCP/IP。并发布了很多的相关协议版本,这些发布版中的TCP/IP代码几乎是现在所有系统中TCP/IP实现的前辈,包括AT&T System V UNIX 和Microsoft Windows。
其他一些公司也开始为其自己的小型机或工作站提供商业版本的UNIX系统,根据版本的不同出现了不同的分支,如在BSD基础上开发的SunOS。
AT&T后期为UNIX System V增加了文件锁定,系统管理,作业控制,流和远程文件系统。不断的完善Unix操作系统的功能。
3) Unix现状
UNIX第四版发布后,AT&T就将其所有UNIX权利出售给了Novell。Novell期望以此来对抗微软的Windows NT,但收效甚微,最终Novell将SVR4的权利出售给了定义Unix标准的产业团体。而且大部分的Unix市场被后起的Linux和微软的服务器版操作系统所占据。
以上是关于Unix的一些小知识点的补充,Unix的诞生、发展对Linux有着深远的影响。

1.1.2 linux的起源
1) Linux的起源
理查德•马修•斯托曼(Richard Matthew Stallman, RMS,生于1953年),自由软件运动的精神领袖、GNU计划以及自由软件基金会(Free Software Foundation)的创立者、著名黑客。在软件商业化环境下,他于1985年发表了著名的GNU宣言(GNU Manifesto),正式宣布要开始进行一项宏伟的计划:创造一套完全自由免费,兼容于Unix的操作系统GNU(GNU's Not Unix!),目的是打破大型网络供应商的垄断并最终取代昂贵的商业软件。
为了保护GNU计划所开发软件的版权,他于1989年与一群律师起草了广为使用的GNU通用公共许可协议(GNU General Public License, GNU GPL),创造性地提出了“反版权”的概念。同时,GNU计划开发并完成了绝大多数软件,但是最关键的操作系统内核没有完成。
1990年,芬兰大学生Linus Torvalds决定编写一个自己的Minix内核,让其能运行在X86的机器上,初名为Linus'Minix,意为Linus的Minix内核,受斯托曼的自由软精神影响, 1991年李纳斯(Linus Torvalds)用GPL许可协议发布他自己的Linux操作系统内核,并加入了GNU计划,当GNU软件与Linux内核结合后,一个真正的自由的Linux操作系统诞生了,也标识着GNU计划正式完成。
今天GNU/Linux已经成为发展最为活跃的自由/开放源码的类Unix操作系统。至此,操作系统被命名为GNU/Linux(或简称Linux)。Linux操作系统的诞生,发展与状大,离不开GNU计划、GPL版权言和FSF(自由软件基金会),下面我们将对这几个概念做一个概述:
GNU计划:GNU(GNU is “ not UNIX”的缩写)计划创建于一九八四年,其创建的目的在于创建一个对Unix向上兼容的完整的自由软件系统(free software system)。由Richard Stallman主持创建,上述单词“ free”指的是自由(freedom) ,而不是价格。你可能需要或者不需要为获取GNU软件而支付费用。不论是否免费,一旦你得到了软件,你在使用中就拥有以下三种特定的自由:
1)复制程序并且把它送给你的朋友或者同事的自由;
2)通过获取完整的源代码,按照你的意愿修改程序的自由;
3)重新发布软件的改进版并且有助于创建自由软件社团的自由。
(如果你重新发布 GNU软件,你可能对分发拷贝这项体力劳动收费,也可能不收费。)
1983年Richard Stallman构思GNU计划是为了提供一种找回在计算机界早期的盛行的共享彼此的智力成果与合作精神的方式,并希望通过此计划使合作成为可能,进而排除因私有软件盛行给所有合作开发者的合作障碍。
1971年,Richard Stallman开始了在他MIT的职业生涯,MIT是一个专门使用自由软件的工作组。那时候大部分计算机公司也经常发布自由软件。互联网上各地的程序员通过网络可以自由地共享他们彼此的开发成果。
但是到了80年代,几乎所有的软件都是私有的,私有软件的存在旨在保护版权,禁止共享合作,GNU计划就在此种环境下诞生。
每个拥有计算机的用户都需要一个操作系统帮用户完成工作需求;如果没有可以自由使用的操作系统存在,而且你也不求助于私有软件,那么这台计算机根本就没有办法使用,所以GNU计划的目的就是创建自由的操作系统。
创作一个完整的操作系统是一项十分庞大的工程,它不仅仅是一个内核;它还包括编译器、编辑器、文本排版程序,电子邮件软件,以及许多其他东西。GNU计划成立之初,Unix的设计理念已经得到广泛流传与广大程序员及开发者的认可,为减少开发复杂度,GNU计划决定他们创建的操作系统能与Unix相兼容。同时也可以使Unix的用户非常容易把他们的软件移植到GNU上来,经过GNU计划的不断努力,到了90年代,已经开发完成了除了内核之外的所有主要成分直到1991年,由Linux Torvalds开发并共享了Linux内核,并把Linux和GNU系统结合起来,就构成了一个完整的操作系统:即一个基于Linux内核的GNU系统Linux操作系统。目前有非常庞大的个人与企业用户群体都在使用基于GNU的Linux系统,包括Slackware、Debian、Red Hat以及其它。
当然,GNU计划的创建不限于操作系统,其目标是提供所有类型的软件,无论有多少用户需要它,GNU计划最终希望在未来不但拥有对普通用户桌面操作系统,还为计算机专家的提供软件,还提供游戏和其它娱乐。
GNU计划为了保证他们所开发的自由软件的最终自由度,Richard Stallman和一群律师共同起草了GPL自由软件宣言,来保护自由软件。
GPL版权宣言:GNU通用公共许可证(简称为GPL),是由自由软件基金会发行的用于计算机软件的许可证。最初由Richard Stallman为GNU计划而撰写。目前大多数的GNU程序和超过半数的自由软件都使用此许可证。此许可证最新版 本为“ V2” ,1991年发布。 GNU宽通用公共许可证(简称LGPL)是由GPL衍生出的许可证,被用于一些GNU程序库。GPL和LGPL是GNU的两种协议。越来越多的自由软件(Free Software)使用GPL作为其授权声明,如果对GPL一点都不了解,有可能在使用自由软件时违反了GPL的授权。如果是个人或不正规的公司倒也无所谓,但如果是有规模的公司,恐怕会有被起诉的风险。
当一个自由软件使用GPL声明时,该软件的使用者有权重新发布、修改该软件,并得到该软件的源代码;但只要使用者在其程序中使用了该自由软件,或者是使用修改后的软件,那么使用者的程序也必须公布其源代码,同时允许别人发布、修改。也就是说,使用GPL声明下的的自由软件开发出来的新软件也一定是自由软件。
LGPL是GPL的变种,也是GNU为了得到更多的甚至是商用软件开发商的支持而提出的。与GPL的最大不同是,可以私有使用LGPL授权的自由软件,开发出来的新软件可以是私有的而不需要是自由软件。所以任何公司在使用自由软件之前应该保证在LGPL或其它GPL变种的授权下。
类似的自由软件非常多,比如生活中常见的Bt下载软件电驴、射手播放器、火狐浏览器等都是GPL下的产物,自由软件带给我们的不仅是应用,更重要的一人们之间彼此共享的人类文明的物质与精神的智力成果。
自由软件可以走多远?这没有限制,除非诸如版权法之类的法律完全地禁止自由软件。但是这种情况是不可能会发生的。
自由软件基金会:(Free Software Foundation,FSF)是一个推广自由软件的美国民间非盈利性组织,致力于消除对计算机程序在复制、分发、理解和修改方面的限制。
许多组织都在分发所有可以获得的自由软件。与之不同的是,自由软件基金会致力于开发新的自由软件,以及将这些软件构造成为一个协调一致的系统,这样的系统将彻底消除使用私有软件的必要。
它于1985年10月由理查德•斯托曼建立。其主要工作是执行GNU计划,开发更多的免费、自由以及可自由流通软件。从其建立到1990年代中自由软件基金会的基金主要被用来雇用编程师来发展自由软件。从1990年代中开始写自由软件的公司和个人太多了,因此自由软件基金会的雇员和自愿者主要在自由软件运动的法律和结构问题上工作。
自由软件基金会最早的目的在于促进自由软件的开发,同样,自由软件基金会也有开发GNU操作系统的任务。而且自由软件基金会同样具有施行GNU通用公共许可证和其它GNU许可证的能力和资源,自由软件基金会只对它拥有版权的软件负责。其它软件必须由它们自己的拥有人来负责,原因是从法律规定上自由软件基金会无法为这些其它软件负责。自由软件基金会每年约接触到50个违反GNU通用公共许可证的事件,自由软件基金会试图不通过法院使对方遵守GNU通用公共许可证。
监督版权: 自由软件基金会拥有大多数GNU软件和一些非GNU自由软件的版权。每个GNU软件包的贡献者必须签署版权文件,这样自由软件基金会可以在诉讼案中在法庭上维护这些软件。此外这样假如许可证有所变化的话不必征求软件所有的贡献者的同意。
自由软件目录: 自由软件目录是所有自由软件包的一个列表。其中列出的每个软件包含47条信息,比如工程的主页、程序师、编程语言等。目的是提供一个自由软件的搜索引擎和为用户提供一个检查一个软件包是否自由的工具。自由软件基金会为此从联合国教科文组织获得少数基金。计划是将来这个目录可以翻译成不同的语言。
维持自由软件的定义: 自由软件基金会维持多个定义自由软件运动的文献。
法律教育: 自由软件基金会举办关于GNU通用公共许可证的法律问题的研究会,向律师提供咨询服务。
工程管理: 自由软件基金会通过它的GNU草原(GNU Savannah)页面提供工程管理的服务。
颁发奖励: 自由软件基金会每年颁发两部奖励:自由软件进步大奖和社会福利自由软件奖励(Free Software Award forProjects of Social Benefit)。社会福利自由软件奖励。

1.2 linux发行版本与RHEL7的安装
1.2.1 什么是linux发行版
Linux发行版本可以大体分为两类,一类是商业公司维护的发行版本,一类是社区组织维护的发行版本,商业版Linux著名的Redhat(RHEL)为代表,社区版Linux以Debian为代表;Redhat红帽发行版,包括企业版Redhat Enterprise Linux, (也叫RHEL;分为红帽企业版、红帽高级企业版、红帽工作站版等等,目前最新企业版为红帽发行的第五个版本)、RedHat是在国内使用人群最多的通用Linux版本,甚至有人将Redhat等同于Linux,有些专业用户和企业更是只用这一个版本的Linux。因此针对红帽公司的发版本的特点就是使用人群数量大,资料非常多,网络上所提供的解决方案也非常丰富,非常适合Linux爱好者或初学者,而且网上的一般Linux教程都是以RedHat公司的发行版为例来讲解的。RedHat系列的软件包管理方式采用的是基于RPM包的YUM软件管理方式,包分发方式是编译好的二进制文件。稳定性方面RHEL非常好,适合于服务器使用,是属于收费版的Linux操作系统,其中基于红帽企业版Linux的演生版也非常多,如CentOS,Oracle的Linux发行版等。
Fedora Core(由原来的Redhat桌面版本发展而来,自由版本,目前是由红帽提供技术开发与维护的一个社区桌面版,但红帽官方不针对此版本提供任何的技术支持)、Fedora Core为用户提供,最新、最前沿的Linux技术与解决方案,有非常丰富的应用软件与桌面环境,适合于个人或桌面用户使用。
Debian,也称Debian为系列,典型代表是Debian和Ubuntu等。Debian是社区类Linux的典范,是迄今为止最遵循GNU规范的Linux系统。Debian最早由Ian Murdock于1993年创建,分为三个版本分支(branch):stable、testing和unstable。其中,unstable为最新的测试版本,其中包括最新的软件包,但是也有相对较多的bug,适合桌面用户。testing的版本都经过unstable中的测试,相对较为稳定,也支持了不少新技术(比如SMP等)。而stable一般只用于服务器,上面的软件包大部分都比较过时,但是稳定和安全性都非常的高。Debian最具特色的是apt-get /dpkg包管理方式,跟RedHat的YUM管理方式略有区别。
各大发型版之间软件的功能大同小异,读者可以跟据自己的喜好选择适合自己的版本,不过编者建议读者选择通用的Linux做为学习工具会让你的学习事半功倍的。

1.2.2 安装rhel8操作系统
1.插入rhel8安装光盘,启动主机,设置以光盘启动,随后将出现以下介面:

(1)Install Red Hat Enterprise Linux 7.2:表示安装rhel7.2
(2)Test this media & install Red Hat Enterprise Linux 7.2:表示先对光盘进行检测,再进行安装
(3)Troubleshooting:表示进入排错模式
注:默认选项为第二项,可用键盘的上下键进行切换选项

2.直接回车,等待进入欢迎介面:

欢迎介面,这里可以选择安装过程中所使用的语言,默认为英语

3.使用鼠标点击continue,进入安装选项介面:

(1)LOCALIZATION:时间和时区、键盘、系统语言选项
(2)SECURITY:安全选项
(3)SOFTWARE:软件安装选项
(4)SYSTEM:系统选项

4.点击DATE & TIME选项,更改时间和时区:

(1)Region:区域
(2)city:城市
(2)Network Time:网络时间,也就是设置NTP同步
设置完成,点击左上角Done,返回上一级介面

5.点击SOFTWARE SELECTION,选择需要安装的软件

这里选择Server with GUI,安装图形化界面。否则,默认情况下,是最小化安装,也就是说没有图形化。

6.点击INSTALLATION DESTINATION,对硬盘进行分区格式化:

这里,直接点击Done,自动进行分区,关于分区后面会有具体介绍。

7.点击NETWORK & HOSTNAME选项,配置网络和主机名称:

(1)点击右上角的滑块,开启网络功能
(2)在左下角host name:后面,设置该主机的主机名
完成,点击左上角的Done,返回选项介面

8.点击右下角的Begin Installation,进行安装:

(1)ROOT PASSWORD:点击设置系统管理员(root)的密码
注意:这里对密码复杂性有要求,可双击Done,忽略复杂性要求
(2)USER CREATION:点击创建一个普通系统用户

9.等待安装完成,至出现如下画面:

(1)点击Reboot,重新启动,系统完装完毕

1.3 练习:安装RHE7系统
要求:
1)设置时区为:Asia/Shanghai
2)设置安装图形化
3)设置自动分区
4)设置开启网络
5)设置主机名为:server.example.com
6)设置root密码为:redhat

第2章 命令行介绍
2.1访问命令行
要输入命令,首先要得到一个能提供命令行交互界面的shell,那shell又是什么呢?
2.1.1 shell
所谓shell,是指“为用户提供用户界面”的软件,通常分为两类:命令行和图形界面,但一般指的是命令行界面的解析器。
一般来说,shell是指操作系统中,为访问内核提供服务的程序,比如输入一条命令,是需要通过shell将命令翻译给内核去执行相应的动作。shell也用于泛指所有为用户提供操作界面的程序,也就是程序和用户交互的层面
在红帽操作系统中,已经包含了多种shell,不同的shell,命令会有所差异,而红帽操作系统,默认采用的是bash这个shell,也是目前使用最广泛的linux shell,所以本教材主要针对bash shell进行讲解。

可通过以下命令查看系统自带了哪些shell:
[root@server ~]# cat /etc/shells
/bin/sh
/bin/bash
/sbin/nologin
/usr/bin/sh
/usr/bin/bash
/usr/sbin/nologin

那怎么打开一个shell呢?其实很简单,我们得到的命令行界面,就是一个shell,或通过SSH远程连接也是打开了一个shell。当我们触发了一个shell,会得到一个提示符:
[root@server ~]#
·中括号内分别表示:登陆用户名@主机名 当前路径
·#:表示当前是root用户
·$:表示当前是一个普通用户
2.1.2虚拟控制台(tty)
一个键盘、一个鼠标、一个显示器就是一个控制台。每打开一个终端,就虚拟出一个控制台,也就是说一个终端就是一个虚拟控制台,同时触发一个shell进程。
如果有安装图形化,默认系统自带有6个控制台。第一个控制台运行图形界面;第二至第六个运行文本界面。
如果没有安装图形脂,则只有5个虚拟控制台,全是文本界面。
那么怎么在虚拟控制台之间互相切换呢?使用ctrl+alt+f键进行切换,f1对应第一个控制台,f2对应第二个控制台,以至类推。

例1
[root@server ~]# echo hello world > /dev/tty2

向第二个控制台发送一句话:hello world、

此时,切换到第二个控制台,就可看见这句话

2.1.3终端(pts)
所谓终端,就是动态生成的虚拟的控制台,比如一个SSH远程连接,就会产生一个虚拟控制台。在图形环境下,可以支持多个虚拟终端控制台,而每个虚拟控制台可以作为一个独立的终端。

例2
前提:打开两个终端
[root@server ~]# who
root tty1 2017-03-01 14:37
root pts/0 2017-03-01 15:10 (192.168.1.1)
root pts/1 2017-03-01 16:10 (192.168.1.1)

who命令用于查看有哪些用户登陆到当前系统,以及所使用终端

[root@server ~]# echo hello > /dev/pts/1

从0号终端,向1号终端发送hello

这时,在1号终端显示该字符

2.1.4命令行基本语法
命令、选项(以-或--开头)、参数

所谓命令就是一个可执行文件,文件本身包含了可执行的程序代码,那命令的可执行文件在哪儿呢?

例3
[root@server ~]# which ls
alias ls='ls --color=auto'
/usr/bin/ls

可以看到ls命令就是/usr/bin/ls这个文件

which命令是用来查找所有可执行的命令文件所在具体位置

那为什么无论在什么位置直接执行命令就可以了,而不用指定命令的完整路径呢?那是因为系统有个PATH环境变量,执行某个命令的时候,系统会到PATH环境指定的路径里面去寻找这些命令的可执行文件,如果找到,就执行,如果没找到,会提示找不到这个命令。

例4
[root@server ~]# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin

打印PATH这个变量的值,所有命令所在路径,以冒号(:)隔开

如果一个新命令所在目录不在PATH环境变量中,怎么办呢?只需将新命令所在路径加入到PATH环境变量值中即可

例5
[root@server ~]# PATH=$PATH:/dir

增加/dir路径到PATH变量中

2.1.5 TAB补全
输入命令、选项、参数时,可以通过tab键补全功能来减轻输入压力。键入的内容如果足够使其唯一,按一次tab键即可补全,如果键入的内容不够使其唯一,按两次tab键,即可以显示以键入的字符为开头的所有命令。
在RHEL7/CentOS7以前的版本中,bash自动补全功能仅限于命令和文件名,然而网络设备往往可以自动补全命令的参数,常常让搞网络出身的工程师唏嘘不已。
在新出的RHEL7/CentOS7中的Bash已经可以自动补全命令参数了,需要注意的是RHEL7/CentOS7的默认安装类型是最小安装,它是没有这个功能的。要启用这个功能,你需要安装一个bash-completion包,然后退出bash,重新登录即可(未重启bash的情况下继续使用可能出现补全功能异常,出现一堆代码)。

例6
[root@server ~]# rpm -qa |grep bash-completion

查看bash-complition这个包有没有装

关于rpm,后面会有具体讲解

2.1.6命令历史记录
在每个用户的家目录,都有一个隐藏的历史记录文件:.bash_history。当一个用户登陆成功后,这个用户所有的历史记录会先记录到内存中,当正常退出这个用户时,才会将内存中的历史记录写到.bash_history文件中

例7
[root@server ~]# cat /root/.bash_history

查看root用户的历史记录文件

上面的例子,查看的只是当次root用户登陆之前的历史记录,那当前的历史记录怎么查呢?主要使用history命令

历史记录命令:
[root@server ~]# histroy

查看历史命令记录

[root@server ~]# !1

执行历史记录中编号为1的命令

[root@server ~]# !ca

执行历史记录中最近的一个以ca开头的命令。

[root@server ~]#!$

表示上一个命令的最后一段字符

历史记录快捷键:
上、下箭头

可以上下查阅历史记录

左、右箭头

在当前命令行中左右移动光标

esc+.

将上一命令的最后一个参数复制到当前命令行光标处,重复使用,将继续到更早的命令。

alt+.

将上一个命令的最后一段字符复制到当前,重复使用。

ctrl+r

在历史记录列表中搜索某一模式的命令

history -c

清除历史

2.1.7命令行快捷键
ctrl+a

光标定位到命令行首

ctrl+e

光标定位到命令行尾

ctrl+u

将光标处前面的内容清除

ctrl+k

将光标处后面的内容清除

ctrl+左箭头

跳到命令行中前一字的开头

ctrl+右箭头

跳到命令行中下一字的末尾

ctrl+c

截断进程

ctrl+l

清空屏幕

第3章 用户与组的管理
3.1 用户与组的概念
Linux是个多用户多任务的分时操作系统,所有一个要使用系统资源的用户都必须先向系统管理员申请一个账号,然后以这个账号的身份进入系统。用户的账号一方面能帮助系统管理员对使用系统的用户进行跟踪,并控制他们对系统资源的访问;另一方面也能帮助用户组织文件,并为用户提供安全性保护。每个用户账号都拥有一个惟一的用户名和用户口令。用户在登录时键入正确的用户名和口令后,才能进入系统和自己的主目录。
用户组(group)就是具有相同特征的用户(user)的集合体;比如有时我们要让多个用户具有相同的权限,比如查看、修改某一文件或执行某个命令,这时我们需要用户组,我们把用户都定义到同一用户组,我们通过修改文件或目录的权限,让用户组具有一定的操作权限,这样用户组下的用户对该文件或目录都具有相同的权限。

3.2 用户的管理
在linux下,共有3种用户类型:
1)超级管理员账号(root),该用户装完系统后,默认就存在
2)系统账号,系统服务和内核进程所需要的用户
3)普通账号,也就是给用户使用的账号

3.2.1 创建用户
创建一个用户,使用useradd命令,关于此命令有一些选项是需要掌握的:
1)-c 添加描述信息
3)-g 指定主要组
4)-G 指定附属组
2)-s 指定shell
3)-u 指定UID,注意,只能使用1000以上,并且不能和其它UID冲突

例1
[root@server ~]# useradd user1

创建一个用户,叫user1

[root@server ~]# useradd -c "this is a test user" -s /usr/bin/bash -u 1002 user2

创建一个用户叫user2

给这个用户添加一个描述信息:this is a test user

指定该用户使用的shell是:/usr/bin/bash

指定该用户的UID为1002

当我们创建了一个用户之后,这些用户信息被存放到哪里去了呢?在/etc/passwd文件中,我们可以使用文件查看命令查看一下这个文件:
[root@server ~]# tail -n 2 /etc/passwd
user1:x:1000:1000::/home/user1:/bin/bash
user2:x:1002:1002:this is a test user:/home/user2:/usr/bin/bash

通过上面可以发现,用户信息在/etc/passwd文件中,都是以一行一个用户的形式进行保存,并且使用冒号(:)将该用户的信息分隔成7段,那这7段分别代表什么意思呢?下面按从左到右的顺序进行解释:
1)用户名
2)本来这是用户密码所在位置,但考虑到安全因素,将密码保存到其它位置了,这里就用x填充
3)用户的UID
4)GID,用户的主要组ID,一个用户只能属于一个主组,但可以属于多个附加组
5)此用户的描述信息
6)此用户的家目录
7)此用户的shell类型

3.2.2 更改用户
更改用户信息使用usermod命令,该命令也有一些选项需要掌握:
1)-g 更改主要组
2)-G 更改附属组,如果之前已经指定过附属组,会把该用户从之前附属组中删除
6)-s 更改用户的shell

例2
[root@server ~]# usermod -s /user/sbin/nologin user1

更改user1用户的shell类型为:/usr/sbin/nologin

3.2.3 删除用户
删除一个用户,使用userdel命令,这里,需要注意一个选项:-r,同时删除用户和家目录,如果不加这个选项,只删除用户,而家目录还在

例3
[root@server ~]# userdel -r user1

删除用户user1,并且将该用户的家目录一起删除

3.2.4 修改用户密码
修改用户密码,使用passwd命令。

例4
[root@server ~]# passwd user2

修改user2用户的密码

当我们为一个用户设置了密码,那它的密码又保存到哪里了呢?在/etc/shadow文件中,我们可以查看下该文件:
[root@server ~]# tail -n 1 /etc/shadow
user2:$6$WPZQOC0.$o62QaPlDaZYTOaQzam96qRkC/13xcZpt2Tbe.urwqipl930klSsti7sGN3fa/mmWIDiapx.IFBCUzfhzRHDbV/:17229:0:99999:7:::

通过上面可以发现,用户密码也是按一行一个用户的方式保存在/etc/shadow文件中,并且也是以冒号(:)为分隔符,将相关信息分隔成9段,下面我们还是从左到右的方式来解析各段所代表的意思:
1)用户名
2)密码,我们会发现,这里所显示的并不是我们输入的密码,这是因为考虑到安全因素,保存到文件中的密码都是经过hash加密过的。如果此处是两个叹号(!!),表示这个用户没有设置密码
3)上次更改密码的日期,这个时间是从1970年1月1日算起,到修改密码时,中间的总天数
4)最短密码期限,从最近一次更改密码的日期算起,再过多少天之后才能再次更改密码,0表示无最短期限,随时可以改
5)最长密码期限,必须在这个期限内更改密码,否则过了这个期限,密码将过期
6)密码警告期限,密码过期前多少天开始提醒用户更改密码,0表示不提醒
7)密码过期之后的宽限天数,也就是说,密码过期之后,在这个期限内,密码还是可以用的,但如果过了这个期限,还不更改密码,密码也就真的失效了,只能找管理员改密码了。
8)账号到期时间,也是从1970年1月1日算起,至到期时间,中间的总天数
9)保留

3.3 组的管理
3.3.1 创建组
创建组使用groupadd命令

例1
[root@server ~]# groupadd group1

创建一个组,叫group1

当我们创建了一个组,该组的信息会保存到/etc/group文件中,可以查看一下:
[root@server ~]# tail -n 1 /etc/group
group1:x:1003:

3.3.2 添加用户到组
添加用户到组,我们有两个命令可实现:gpasswd和usermod

例2
[root@server ~]# gpasswd -a user2 group1

添加用户user2到组group1

[root@server ~]# usermod -G group1 user1

修改用户user1的信息,将自己加入到group1组中

3.3.2 删除组
删除组,使用groupdel命令

例2
[root@server ~]# groupdel group1

删除组gropu1

3.4 练习
要求:
1)创建一个用户user1,并指定该用户的shell为/usr/sbin/nologin
2)创建一个组group1,并将用户user1加入到该组

第4章 文件和目录的管理
在linux下,一切皆文件,文件就要有一定的组织方式,linux是以树形结构组织文件,FHS标准规定了每个目录下面应该放哪些内容,这样做的好处是便于系统管理,因为linux系统有很多发布版本,比如:redhat、ubuntu、fedora、suse等等,如果每个发行版本都自己设计一套文件组织方式,这将造成用户切换发行版本带来不便。
4.1 目录结构
既然linux是以树形结构组织文件,树就有一个根,在linux系统中所有其它目录都属于根下的一个分支

[root@server ~]# ls /
bin dev home lib64 mnt proc run srv tmp var
boot etc lib media opt root sbin sys usr

1)/

根目录,所有的文件和目录,皆是由根目录延伸。

2)/boot

开机启动过程所需的文件,比如:内核文件,引导文件,驱动文件,boot目录一般在200M左右

3)/usr

编辑安装的第三方软件、共享的库,包括文件和静态只读程序数据,重要的子目录:/usr/bin,用户命令;/usr/sbin,系统管理命令;/usr/local,本地自定义软件。

4)/etc

主要是服务的配置文件

5)/var

动态变化的文件,如:数据库、缓存目录、日志文件、打印机后台处理文档和网站内容

6)/run

自本次系统启动以来启动的进程的运行时数据。包括进程ID文件和锁定文件等。此目录中的内容在重启时会重新创建。

7)/root

root用户的家目录

8)/home

普通用户的个人数据和配置文件的主目录,每切换用户时,首先就是切换到用户的家目录,每个用户的家目录里面有这个用户特有的环境变量,可以用ls -a查看有四个.bash开头的文件,就是这个用户的环境变量。比如:在root家目录下.bash_profile定义一个环境变量,export dd=test,在其它用户echo $dd,是不能输出的。工作中有可能需要为某些用户设置独有的环境变量。

9)/proc

放置的是内存数据,不会占用磁盘空间,内存里有什么:1.系统开机时的硬件信息,比如;CPU的信息:/proc/cpuinfo,内存信息:/pro/meminfo。2进程信息,数字命名的文件都是进程的信息,数字代表这个进程的PID。

10)/sys

对proc的归纳、结合、整理,。这是历史原因,为了兼容以前的版本。

11)/tmp

临时文件使用的全局可写目录。10天内未访问、未修改的文件将自动删除。还有一个临时目录,/var/tmp,该目录下的文件如果30天内未访问、修改,将自动删除

12)/dev

设备文件目录,供系统用于访问硬件

13)/mnt

一般会把外设设备挂载目录

14)/bin、/sbin

存放二进制可执行文件。比如系统命令

15)/lib、/lib64

系统或服务运行中,所需的库文件

4.2 目录的管理
对于目录而言,它所管理的仅仅是该目录下的文件或子目录的名字而已

4.2.1 查看目录
查看一个目录或该目录下的子目录和文件,我们使用ls命令

Ls命令选项
-l 查看目录下子目录和文件的权限、拥有者、拥有组、大小等详细信息
-d 查看指定目录本身的属性
-h 以人类可读的方式显示大小,按大小排序:-Sh
-a 包含隐藏文件在内的所有文件,以点(.)开头的都是隐藏文件。
-R 递归,包含子目录的内容
-t 按时间排序,时间越近的越靠前,如果想反过,时间越久的越靠前,-tr

例1
[root@server ~]# ls /root
anaconda-ks.cfg

查看/root目录下所有子目录和文件的名字

[root@server ~]# ls -l /root
total 4
-rw-------. 1 root root 1200 Mar 1 14:15 anaconda-ks.cfg

查看/root目录下所有子目录和文件的属性

[root@server ~]# ls -d /root
/root

查看/root目录本身的名字

[root@server ~]# ls -ld /root
dr-xr-x---. 2 root root 4096 Mar 1 17:12 /root

查看/root目录下的所有子目录和文件的属性

4.2.2 创建目录
创建目录,使用mkdir命令

mkdir命令选项
-p 同时创建多级目录
-m 创建目录同时,给予权限,比如:mkdir -m 777 /tmp/tt

例2
[root@server ~]# mkdir /root/doc1

在/root目录下创建一个子目录,叫doc1

[root@server ~]# mkdir -p /root/doc2/test

在/root目录下创建一个子目录,叫doc2,并且在doc2目录下再创建一个子目录,叫test

4.2.3 目录的复制
目录的复制,使用cp命令

例3
[root@server ~]# cp -r /root/doc2 /tmp/

复制/root/doc2目录到/tmp/目录下

-r,表示递归,将目录及目录下的文件和子目录一同复制,cp的本意是复制一个文件。

[root@server ~]# cp -r /root/doc1 /tmp/d1

复制/root/doc1目录到/tmp目录下,并且改个名字,叫d1

4.2.4 目录的移动
目录的移动,使用mv命令

例4
[root@server ~]# mv /root/doc1 /mnt/

将/root/doc1目录移动到/mnt目录下.

[root@server ~]# mv /root/doc2/ /mnt/d2

将/root/doc2目录,及子目录移动到/mnt/目录下,并且改名叫d2

4.2.5 删除目录
删除目录操作,使用rmdir和rm命令,不过要注意,执行删除操作之前,一定要先确认好想要删除的东西,否则没有后悔的机会

rmdir命令,只能删除空目录,如果要删除的目录下还存在子目录或文件,必须先把子目录和文件删除,才能删除该目录

rm命令,本意是删除一个文件,如果要删除一个目录,需要加上选项-r,表示递归删除,先删除该目录下的子文件和子目录,再删除指定目录。

例3
[root@server ~]# rm -r /root/doc1
rm: remove directory ‘/root/doc1’? y

删除/root/doc1目录,要求输入y确认

[root@server ~]# rm -rf /root/doc2

强制递归删除目录/root/doc2,并且不需要确认

4.3 文件的管理
4.3.1 创建文件
创建文件,使用touch命令

例1
[root@server ~]# touch /root/file1

在/root目录下创建一个空文件,叫file1

注意:如果文件已经存在,不会改变文件内容,只会改变文件的修改时间

4.3.2 复制文件
文件的复制使用cp命令

例2
[root@server ~]# cp /root/file1 /tmp/

复制文件/root/file1到/tmp目录下

4.3.3 移动文件
文件的移动使用mv命令

例3
[root@server ~]# mv /root/file1 /mnt/

移动/root/file1文件到/mnt目录

4.3.4 删除文件
文件的删除使用rm命令

例4
[root@server ~]# rm -f /mnt/file1

删除文件/mnt/file1

4.3.2 查看文件
在linux中,查看文件的命令有很多,如cat、more、less、head、tail等

例5
[root@server ~]# cat /etc/passwd

将/etc/passwd文件的内容全部输出到当前shell

[root@server ~]# more /etc/passwd

同样将/etc/passwd文件内容输出到当前shell,但是,它是分页显示

使用空格键往下翻页

使用enter键往下翻一行

使用q键退出

[root@server ~]# less /etc/passwd

同样以分页的形式将/etc/passwd文件内容输出到当前shell,但是

使用空格键往下翻页

使用enter键往下翻一行

使用PgUp键往上翻页

使用q键退出

注意:more命令和less命令的区别,more命令只能往下翻页,并且所有内容完成就结束了,而less命令是可以循环查看的

[root@server ~]# head /etc/passwd

只查看/etc/passwd文件的头10行内容

[root@server ~]# head -n 20 /etc/passwd

查看/etc/passwd文件的头20行

-n,指定想查看的行数

[root@server ~]# tail /etc/passwd

查看/etc/passwd文件的最后10行

[root@server ~]# tail -n 20 /etc/passwd

查看/etc/passwd文件的最后20行

-n,指定想查看的行数

4.4 VIM的使用
vim是linux系统下标准的文本编辑器,相当于windows系统中的记事本一样,但vim的功能却要强大的多。vim是我们使用linux系统不能缺少的工具。

例1
[root@server ~]# cp /etc/passwd /tmp/

拷贝/etc/passwd文件到到/tmp/目录下

[root@server ~]# vim /tmp/passwd

使用vim,打开/tmp/passwd文件

当我们使用vim打开一个文件后,默认处于命令行模式,此时,只能使用命令对文件内容进行简单的修改。也可以输入相应命令进入其它模式,对文件进行操作,下面我们就来讲讲vim的几种模式。
注意:在不同模式之间切换,必须先回到命令行模式,再输入相应的命令进入另一个模式。返回到命令行模式,使用esc键。

4.4.1命令行模式
yy 复制一行,复制10行:10yy
p 粘贴到光标所在的下一行,10p就是把复制的内容粘贴10次
P 粘贴到光标所在的上一行
dd 剪切光标所在行,100dd,剪切光标以下100行
d1G 从光标所在行,删除到第一行
dG 从光标所在行,删除到最后一行
D 从光标处剪切到行尾,这时,p,会在光标后面粘贴
gg 光标回到第一行行首
G 光标到最后一行行首
$ 移动光标到当前行尾
0 数字零,移动光标到当前行首
x 删除光标所在字符,2x,从光标往后删除2个字符
X 往前删
r 替换光标处单个字符,r2,把光标处字符替换成2
R 进入替换模式,一直替换,除非按esc,回到命令行模式
u 撤消上一次操作
ctrl+r 恢复上一次的撤消操作
. 重复上一次操作
h 向左移动
j 向下移动
k 向上移动
l 向右移动
ctrl+f 向下一页
ctrl+b 向上一页

4.4.2编辑模式
从命令行模式进入编辑模式的方式:
i 在光标当前位置的前面插入字符
I 光标移动当前行的行首
a 光标往后退一个字符
A 光标移动到行尾
o 光标所在行的下一行新起一行
O 光标所在行的上一行新起一行

4.4.3末行模式
:wq 保存并退出,或:x
:wq! 强制保存退出,对一个只读文件。不过到底能不能写入,还是跟权限有关
:w f1 另存到f1这个文件
:q 退出
:q! 强制不保存退出
:set nu 显示行号
:set nonu 取消行号
:9 光标移动到第9行行首
:1,$s/root/togogo/g 从第一行到最后一行,把root替换成togogo
:! ls /boot 叹号,表示会暂时离开vim,然后去执行叹号后面的命令
:r /etc/passwd 把r后面的文件,读取到当前vim编辑器
:r ! ls /boot 把ls /boot命令的输出,读取到当前vim编辑器
/ 往光标所在行之下搜索关键字
? 往光标所在行之上搜索关键字
n 下一个关键字
N 上一个关键字

第5章 权限管理

5.1 权限的概念
Linux操作系统最强大的功能之一就是多用户多任务,在这种复杂的工作环境中,如何实现文件、用户、组的权限管理就显示非常关键。根据其安全设计原则,可以定义三种安全形式,即用户、组、其他人(不属于用户、组的第三方用户统称为其他人)。用户是这个安全模型的最小基本单位,不论是文件还是正在运行中的进程,系统都会根据用户帐号的属性,来规定用户能做什么事情,不能做什么事情。因此,权限是我们在本节中重点讨论的知识点。

5.2 权限的管理
5.2.1 查看权限
查看文件或目录的权限,使用ls -l命令

例1

ls -l命令的返回结果,如上图所示,在这个文件的详细列表中,所有信息一共分成七列,每一列所代表的意义如下:
第一列:表示这个文件的类型与权限
在第一列中显示的信息一共有10个字符,这些字符代表分别代表文件与目录的类型与权限,第一个字符代表文件的类型,如上例中“d”代表目录,“-”代表常规文件;第二个字符到第十个字符代表用户、组、其他人的权限,如下图所示:

在上图中,数字第0列代表文件的属性,数字第1-3列代表用户(user)的权限,数字第4-6列代表组(group)的权限,数字第7-9列代表其他人(other)的权限。
系统中的基本权限有四种,即读(read),写(write),执行(eXecute),无权限(nopermission),这四种权限分别用字符“r”,“w”,“x”,“-”表示;分别代表的意义见下表所示:
权限类型 功能
r (read) 拥有读取文件内容或目录清单的权限(在目录内可以执行ls命令);
w (write) 具有更改删除文件或目录清单的权限(在目录内可能新建、删除、改名与移动目录);
x (excute) 文件具有x位代表其有执行权限;针对目录设置x位,代表用户可以进入这个目录,在目录内可以执行ls -l命令查看目录详细内容,也可以执行目录内的命令等;

  • (none) 没有任何权限;

系统为用户、组、其他定义了权限之后,是如何控制他们的具体权限的呢?请看如下权限匹配流程图所示:

从上图可以分析出系统针对权限的应用流程细分为:用户在访问相应的文件时,首先检查该用户的UID是否为0,如果用户的UID为0就应用管理员的权限;如果文件的UID与访问该文件用户的UID相同,那么应用用户权限;如果用户的UID与文件的UID不相同,安全机制继续检查文件的GID是否与用户的GID相同,如果相同,就应用文件组的权限;如果前面三个条件都不符合,那么系统将最后应用其他人的权限了。

第二列:代表文件的链接个数
每一个文件存储在系统中上都由两个部份组成,即文件头也叫文件的属性;另一部份就是文件的数据内容,也叫文件体;文件头部包含文件的名称、权限等信息。每个文件都会将它的权限与属性存储在文件系统的i节点中,Linux文件系统结构就是使用文件名来组织这个目录中的所有文件。因此,为了方便管理与维护每一个文件,系统都为文件分配有一个i节点,所有的i节点的组合就叫i节点表,i节点表管理着有各个文件所使用的数据块。

第三列与第四列: 文件或目录的拥有人与组属性
记录着文件拥有人与文件拥有组的信息。在系统中,一个用户帐号可能会属于多个组,加入共享组的目的就是为了访问共享文件之用。

第五列: 文件的容量与目录的目录项属性
代表文件的容量大小,默认以字节为单位,如果是目录的话则代表的是目录项的数据。 

第六列: 文件或目录的最后修改时间,如果用户想要查看每一个文件的详细信息可以使用stat命令或ls命令中的“--full-time”参数。

第七列: 文件或目录的具体名称,包含文件名带“.”的隐藏文件。

5.2.2 设置权限
通过对文件权限与成员关分析,我们了解到在Linux系统中文件的权限对于系统的安全性是多么的重要。如何通过有效的手段设置与管理文件的权限来提高数据的安全性就显得非常重要了。文件权限的更改可以分为用户、组和权限设置三种,其对应命令为chown,chgrp,chmod。

1.改变文件拥有人与组命令:chown
要更改文件的拥有人息就包含两个部份,一个是文件的拥有人;一个是文件的拥有组。 在Linux系统中,只有管理员才有权限更改文件拥有人与拥有组,chown命令的用法如下所示:

例1:更改/tmp/file1.txt文件的拥有人为"user2",组为"user2"
[root@server ~]# chown user2:user2 /tmp/file1.txt
[root@server ~]# ll /root/file1.txt
-rw-r--r--. 1 user2 user2 0 Mar 15 00:43 /root/file1.txt

例2:将/etc目录复制到/tmp目录内,调整/tmp/etc目录的拥有人为user2,组为user2
[root@server ~]# cp -R /etc/ /tmp/
[root@server ~]# ls -l /tmp
total 8
drwxr-xr-x. 77 root root 4096 Mar 15 01:06 etc
-rw-r--r--. 1 root root 0 Mar 5 05:33 file1
[root@server ~]# chown user2:user2 /tmp/etc/
[root@server ~]# ls -l /tmp/etc
total 1108
-rw-r--r--. 1 root root 16 Mar 15 01:06 adjtime
-rw-r--r--. 1 root root 1518 Mar 15 01:06 aliases
-rw-r--r--. 1 root root 12288 Mar 15 01:06 aliases.db
drwxr-xr-x. 2 root root 4096 Mar 15 01:06 alternatives
-rw-------. 1 root root 541 Mar 15 01:06 anacrontab
-rw-r--r--. 1 root root 55 Mar 15 01:06 asound.conf
drwxr-x---. 3 root root 41 Mar 15 01:06 audisp
drwxr-x---. 3 root root 79 Mar 15 01:06 audit
drwxr-xr-x. 2 root root 33 Mar 15 01:06 avahi
drwxr-xr-x. 2 root root 4096 Mar 15 01:06 bash_completion.d
-rw-r--r--. 1 root root 2835 Mar 15 01:06 bashrc
drwxr-xr-x. 2 root root 6 Mar 15 01:06 binfmt.d
......省略

例3:使用-R参数,将/tmp/ect目录下的所有文件拥有人与组属性更改为“user2”
[root@server ~]# chown -R user2:user2 /tmp/etc/
[root@server ~]# ls -l /tmp/etc/passwd
-rw-r--r--. 1 user2 user2 1104 Mar 15 01:06 /tmp/etc/passwd

2、仅更改文件或目录组成员属性命令:chgrp
chown命令可以设置文件拥有人或同时更改文件拥有人与拥有组。如果系统中的某个文件或目录仅需要调整组成员关系,使用这个工具就不是那么有效了。虽然可以使用chown命令重复设置,不过总是会带来些许不便。chgrp命令可以帮助用户非常简单的更改组成员属性.

例1:使用chgrp命令一次性更改/tmp/etc目录及目录内所有文件的组成员为root
[root@server ~]# chgrp -R root /tmp/etc/
[root@server ~]# ls -l /tmp/etc/passwd
-rw-r--r--. 1 user2 root 1104 Mar 15 01:06 /tmp/etc/passwd

3、调整文件或目录权限命令:chmod
chmod文件权限更改命令可以使用两种方式设置文件或目录的权限,即字符方式与数字方式;字符方式分为以下几种类型:
1) owner(文件拥有人):用字母“u”代表;
2) group(文件拥有组):用字母“g”代表;
3) other(文件其他人):用字母“o”代表;
4) all(所有人):用字母“a”代表;

数字权限更改方式是使用4,2,1,0代表“r”,“ w”,“x”,“-”(即“4”代表只读权限“r”,“2”代表写权限“w”,“1”代表执行权限“x”,“0” 代表没有权限),每种身份“owner,group,other”的“r,w,x”用数字设置的时候,只需要将每种身份的权限值累加即可,如“owner”的权限是“rwx”那么用数字表示即为“4+2+1=7”,其他权限依此类推即可;针对权限的操作同样也有以下几种表示方式,如下所示:
加号“+”: 在现有的权限上增加权限;
减号“-”: 在现有的权限上去掉某个权限;
等号“=”: 忽略现有的权限, 重设文件的权限; 

权限更改命令使用方式如下所示:
command who operater permission files/Direcotry
symbolic digit
chmod u
g
o
a +

= r
w
x

  • 4
    2
    1
    0 文件或目录

例1:用字符表示方式将file1.txt文件添加执行权限
[root@server ~]# chmod u+x /root/file1.txt
[root@server ~]# ls -l /root/file1.txt
-rwxr--r--. 1 user2 user2 0 Mar 15 00:43 /root/file1.txt

例2:用字符表示方式将file1.txt文件去掉组与其他人的可读权限
[root@server ~]# chmod g-r,o-r /root/file1.txt
[root@server ~]# ls -l /root/file1.txt
-rwx------. 1 user2 user2 0 Mar 15 00:43 /root/file1.txt

例3:用字符表示方式将file1.txt文件权限重新设置为所有成员具有完控制权限
[root@server ~]# chmod a=rwx /root/file1.txt
[root@server ~]# ls -l /root/file1.txt
-rwxrwxrwx. 1 user2 user2 0 Mar 15 00:43 /root/file1.txt

例4:用数字表示方式将file1.txt文件的写权限取消
[root@server ~]# chmod 555 /root/file1.txt
[root@server ~]# ls -l /root/file1.txt
-r-xr-xr-x. 1 user2 user2 0 Mar 15 00:43 /root/file1.txt

例5:将/tmp/etc目录内所有的文件和目录的权限设置为所有用户只读
[root@server ~]# chmod -R 444 /tmp/etc/
[root@server ~]# ls -l /tmp/etc/passwd
-r--r--r--. 1 user2 root 1104 Mar 15 01:06 /tmp/etc/passwd

4.系统默认权限:umask
在了解了Linux系统的安全模型与文件的权限管理知识以后,读者是否存在这样一个疑问?为什么我使用管理员用户帐号在系统中创建的目录权限是755,创建的文件权限都是644;而使用普通用户帐号创建的目录权限却又是775,文件的权限是664呢?
普通用户与管理员用户在系统中创建的文件与目录之所以会存在不同的权限,是由操作系统的默认权限控制的。在 Linux操作系统中,目录权限在设计之初就为每个新建的目录暂定的权限为777,这就意味着在系统中的任何用户对新建的目录都有完全控制权限。如,可以在这些新创建的目录中创建文件、修改、移动、甚至删除文件;同时,针对新建的文件,系统所定义的初始权限是666,这种初始权限非可怕。从前面的知识点中我们了解到,如果某个用户对一个文件具有写权限,表示该用户对这个文件具有修改文件名、修改文件内容、删除文件内容、甚至删除文件的权限(系统中所有新建的文件,默认是强制取消执行权限的,并且可执行文件的属性不是由文件的附件名称规定,而是由文件的可执行权限控制。如果一个纯文本文件中包含一些危害系统安全的命令存在,当用户运行这类文件时,就可能就会产生破坏系统的可能性。如果一个应用程序不具备执行的能力,就算是一个已经封装好的应用程序,在Linux系统中同样是不能被执行的)。为了规避目录与文件在创建之初的初始权限太大而造成的安全问题,Linux系统采用了umask默认权限覆盖机制来消除目录与文件的初始权限在组成员和其他人权限上的不安全设置,用来保护文件系统的安全性。
用户可以使用umask命令查看系统定义的umask值。在红帽的Linux发行版中,管理员的umask值是022;普通用户的umask值是002。如果用户需要调整,可以使用"umask [-p] [-S][mode]"命令重新设置。
同时,每个新创建的文件默认是禁止分配执行权限的,不论当前的umask值是多少。文件的执行权限需要用户使用chmod命令设置,而对于新建的目录,系统会结合用户身份为目录分配一个可执行权限,目的为了用户能够正常使用该目录。下面我们用几个实例来检验系统umask的默认权限覆盖机制。

例1:使用umask命令查看管理员的umask值,并分析目录与文件经过权限覆盖机制处理之后的权限
[root@server ~]# umask
0022
[root@server ~]# mkdir root-dir
[root@server ~]# touch root.txt
[root@server ~]# ll
total 0
drwxr-xr-x. 2 root root 6 Mar 15 02:06 root-dir
-rw-r--r--. 1 root root 0 Mar 15 02:06 root.txt
在上例中的root-dir目录初始目录权限是777,系统结合管理员的umask值022对目录权限进行处理,将root-dir目录的组和其他人权限去掉w的权限位,最终root-dir目录的权限为755;root.txt文件的初始权限是666,系统结合管理员的umask值,去掉文件的组和其他人的w权限,因此,最终得到root.txt文件的权限就是644。

例2:分析普通用户user2的umask值,理解普通用户创建的文件与目录最终权限
[root@server ~]# su - user2
[user2@server ~]$ umask
0002
[user2@server ~]$ mkdir user2-dir
[user2@server ~]$ touch user2.txt
[user2@server ~]$ ll
total 0
drwxrwxr-x. 2 user2 user2 6 Mar 15 02:09 user2-dir
-rw-rw-r--. 1 user2 user2 0 Mar 15 02:10 user2.txt
在上例中的user3-dir目录初始目录权限是777,系统结合普通用户的umask值002对目录权限进行处理,将user3-dir目录的组和其他人权限去掉w的权限位,最终user3-dir目录的权限为775;user3.txt文件的初始权限是666,系统结合普通用户的umask值,去掉文件的组和其他人的w权限,最终user3.txt文件的权限就是664。
为什么系统针对管理员和普通用户的分别使用不同的umask值呢?这种设计的目的为了方便普通用户的权限管理。
那么umask到底是如何工作的呢,针对管理员与普通用户,编者分别用不同的工作原理图为读者进行讲解,如下示例与图解所示:

例3:管理员的目录最终权限计算原理如下图所示,下图中用反斜线标的部份代表权限被去掉的过程

例4:管理员的文件最终权限计算原理如下图所示,下图中用反斜线标注的部分代表权限被去掉的过程

例5:普通用户的目录最终权限计算原理如下图所示,下图中用反斜线标注的部分代表权限被去掉的过程

例6:普通用户的文件最终权限计算原理如下图所示,下图中用反斜线标注的部分代表权限被去掉的过程

读者在计算umask值的方法中,切记不要使用很多辅导材料上说的方法,用文件与目录的初始权限减去umask值所得出的结果。虽然大部份情况是可行的,但是当umask值为033的时候,这种计算机制就会出错。所以,读者需要了解umask的工作原理,而不是错误的指导原则(如果umask值是033,用户可以参考上述实例自行计算结果,编者在此不再复述)。

5.3 特殊权限
在标准的Linux文件系统安全模型中,权限分为“读”、“写” 、“执行”及没有任何权限这四种,分别用“r”、“w”、“x”、“-”表示。这四种权限控制着整个Linux文件系统的安全性。
基于这些权限我们不难理解,如果一个用户对某个文件具有“读”的权限,她就可以查看这个文件的内容;如果对一个二进制可执行文件(程序或命令等)具有“执行”权限也就代表这个用户执行这个文件或文件内的可执行元素等。在这种权限设计上我们很容易管理与规划用户与文件系统的安全性,但是在Linux操作系统很多程序或文件是禁止普通用户查看的。举例来说,一个用户如果需要修改用户自己的密码,只需执行passwd命令重设密码之后,操作系统理所当然地就会把该用户设置的新密码信息写入/etc /shadow文件。细心的读者可能会留意到/etc/shadow文件的特殊性,因为它的权限是“-r--------”,这种权限意味着只有管理员才能读取该文件件的内容,普通用户是没有权限查看该文件的,更不用说修改这个文件的内容了!为什么普通用户可以修改密并更新密码呢?其实这是“/usr/bin/passwd”这个命令“作怪”,因为这个命令上设置有特殊权限。
什么是特殊权限呢?特殊权限也叫附加权限是附加在用户、组、其他人基本权限之上的权限,这种权限必须以基本权限为基础进行设置,因此叫特殊权限(附加权限)。
特殊权限有三种,分别是基于用户SUID权限,基于组的SGID权限以及基于其他人的STICKY权限。这三种附加权限分别体现在这三种身份的可执行权限位“x”上,执行权限为依据进行扩展,因“x”位而生,也因“x”位的消失而显示出不同的信息。
针对Linux操作系统中的特殊权限(附加权限)的特殊功能,编者将其如下表,以帮助读者加深理解,如下表所示;
特殊权限 表现方式 功能
SUID -rwsr-xr-x

-rwSr-xr-x SUID权限对文件有效,其权限应用在用户权限的"x"位上,表现为"s"或"S"(文件对用户没有开放执行权限);
SUID仅针对二进制可执行程序有效,用户拥有该程序的可执行权限;SUID功能仅在程序运行时发生特殊作用,不论哪个用户运行设置有SUID权限的应用程序时(该用户必须允许执行这个程序),执行该程序的用户身份会更换成文件的拥有人(owner)身份;
SGID -rwxr-sr-x

-rwxr-Sr-x SGID对文件与目录有效,其权限应用在组权限的"x"位上,表现为"s"或"S"(目录对组用户没有执行权限);
SGID对二进制可执行程序有用,程序的执行者必须具有执行权限,当用户在运行具有SGID权限的程序时,会以该程序的组成员身份执行;
如果该目录对组开放有写权限,那么用户在这个目录下创建文件的有效组将与目录的有效组相同;
STICKY -rwxr-xr-t

-rwxr-xr-T STICKY仅对目录有效,其权限应用在该目录的其他人权限的"x"位上,表现为"t"或"T"(目录对其他人没有执行权限);
如果一个目录设置有STICKY权限,这个目录内的所有文件仅有管理员和文件拥有者才有权限删除,包括文件的移动、改名等操作

特殊权限的设置方式分成两种,一种是字符方式另一种是数字方式,具体设置方式如下表所示:
command who operater permission files/directory
symbolic digit
chmod u
g
o +

  • s
    s
    t 4
    2
    1 文件或目录

在使用数字的方式设置特殊权限的时候读者需要注意,由于用户、组与其他人分别使用一个数字位表示,已经占用了三组字数位,那么数字特殊权限设置位在哪里呢?相信读者应该还记得设置系统默认权限(umask)的命令吧!在使用umask命令查看用户的默认权限时一共显示有四个数字位,第一个数字位就是系统用来设置特殊权限的,后面的三位数据分别代表用户、组及其他人数字权限设置位,如下所示:
[root@server ~]# umask
0022
特殊权限的数字设置方式与用户、组、其他人的设置方式相同。SUID权限用数字4表示;SGID权限用数字2表示;STICKY权限用数字1表示,读者只需将特殊权限值进行累加就可以了。
例如为一个目录分配所有权限包括特殊权限位的数字设置方式为:用户的全部权限4+2+1=7;组的所有权限4+2+1=7;其他人的所有权4+2+1=7;特殊权限为(SUID+SGID+STICKY)4+2+1=7;所有权限值划分好之后,用户只需要执行“chmod 7777目录”就可以设置完成了。

例1:检验/usr/bin/passwd文件的特殊权限,并验证特殊权限的应用过程:
[root@server ~]# ls -l /usr/bin/passwd
-rwsr-xr-x. 1 root root 27832 Jan 30 2014 /usr/bin/passwd
[root@server ~]# useradd user1
[root@server ~]# passwd user1
Changing password for user user1.
New password:
BAD PASSWORD: The password is shorter than 8 characters
Retype new password:
passwd: all authentication tokens updated successfully.
为用户user1设置密码之后,使用"su - user1"命令切换用户为user1,以检验SUID命令的工作过程:
[root@server ~]# su - user1
[user1@server ~]$ passwd
Changing password for user user1.
Changing password for user1.
(current) UNIX password:
用户user1执行密码重设passwd之后,无需设置密码,目的是为了验证设置有SUID权限的passwd命令真正的用户身份,接下来读者需要打开另一个终端,运行"ps aux |grep -i passwd"命令检查使用passwd命令的真正用户身份,如下所示:
[root@server ~]# ps aux |grep -i passwd
root 2788 0.0 0.1 168820 2004 pts/0 S+ 02:03 0:00 passwd
root 2813 0.0 0.0 112644 972 pts/1 S+ 02:06 0:00 grep --color=auto -i passwd
通过上面的命令过滤出来的结果显示真正执行passwd命令的用户是"root",而非"user1"

例2:取消"/usr/bin/passwd"命令的SUID权限,验证用户user1是否可以重设密码
[root@server ~]# chmod u-s /usr/bin/passwd
[root@server ~]# ls -l /usr/bin/passwd
-rwxr-xr-x. 1 root root 27832 Jan 30 2014 /usr/bin/passwd
[root@server ~]# su - user1
-rwxr-xr-x. 1 root root 27832 Jan 30 2014 /usr/bin/passwd
[user1@server ~]$ passwd
Changing password for user user1.
Changing password for user1.
(current) UNIX password:
New password:
Retype new password:
passwd: Authentication token manipulation error
如上所示,虽然用户user1可以执行passwd命令,由于user1没有权限修改/etc/shadow文件的内容,因此系统提示授权维护操作失败。
[root@server ~]# ps aux |grep -i passwd
user1 2883 0.0 0.1 168820 1960 pts/1 S+ 02:18 0:00 passwd
root 2888 0.0 0.0 112644 976 pts/0 R+ 02:18 0:00 grep --color=auto -i passwd
最后再来检验真正执行命令的用户身份,如上所示。此时在执行passwd命令的用户就是user1,读者记得验证完成之后将/usr/bin/passwd命令的SUID权限还原回去,以免系统中所有的普通用户都无法修改密码了^_^!

例4:在当前主机的目录树结构中创建一个目录为/dir,添加一个组,组名为sgid。设置/dir目录有效组为sgid,之后添加两个用户帐号分别为user2、user3,并授权user2、user3可以在/dir目录新建文件以便测试/dir目录上的SGID权限是否生效,如下所示:
[root@server ~]# mkdir /dir
[root@server ~]# chmod 777 /dir
[root@server ~]# ls -ld /dir
drwxrwxrwx. 2 root root 6 Mar 16 02:21 /dir
[root@server ~]# groupadd sgid
[root@server ~]# chgrp sgid /dir
[root@server ~]# chmod g+s /dir
[root@server ~]# useradd user2
[root@server ~]# useradd user3
[root@server ~]# useradd user4

[root@server ~]# su - user2
Last login: Wed Mar 15 02:09:30 CST 2017 on pts/0
[user2@server ~]$ touch /dir/user2
[user2@server ~]$ ll /dir/user2
-rw-rw-r--. 1 user2 sgid 0 Mar 16 02:25 /dir/user2

[root@server ~]# su - user3
[user3@server ~]$ touch /dir/user3
[user3@server ~]$ ll /dir/user3
-rw-rw-r--. 1 user3 sgid 0 Mar 16 02:27 /dir/user3

例5:为/dir目录设置STICKY权限,控制目录内的文件仅允许root和文件拥有者才能删除或修改相应的文件
[root@server ~]# chmod o+t /dir
[root@server ~]# ls -ld /dir
drwxrwsrwt. 2 root sgid 30 Mar 16 02:27 /dir
[root@server ~]# su - user2
Last login: Thu Mar 16 02:36:57 CST 2017 on pts/0
[user2@server ~]$ rm -f /dir/user2
[user2@server ~]$ rm -f /dir/user3
rm: cannot remove ‘/dir/user3’: Operation not permitted

5.4 练习
1)新建目录:/dir
2)新建用户:user2、user3
3)新建组:group1
4)更改/dir目录的组为group1,并且以后在此目录创建的文件或目录都自动继承组身份
5)用户user2和user3分别在/dir目录下创建文件,但各自只能删除自己创建的文件

第6章 包管理
本章将为读者详细介绍在红帽的Linux发行版中常用的软件包管理工具YUM与RPM的使用技巧,撑握定制操作系统的流程及配置的私有软件仓库等知识点。
6.1 包的类型
软件包主要分两大类:源码包和二进程包。源码包也就是还没有经过编译的源代码,需要自己编译安装;而二进程包,就是已经被编译过的软件包,比如windows下的.exe文件。
在linux中,二进程软件包主要又分为RPM软件包和DEB软件包两类,其中redhat、centos等系统使用RPM软件包;ubuntu等系统使用DEB软件包。本文主要介绍redhat的包管理方法。

6.1.1 源码包
在linux下的很多软件都是通过源码包方式发布的,这样做对于最终用户而言,虽然相对于二进制软件包,配置和编译起来繁琐点,但是它的可移植性却好得多,针对不同的体系结构,软件开发者往往仅需发布同一份源码包,不同的最终用户经过编译就可以正确运行,这也是非常符合c语言的设计哲学的,一次编写,到处编译。

6.1.2 rpm包
RPM是“Red Hat Package Manager”的简称,也叫“RPM Package Manager”。是由Red Hat公司开发出来的一套软件包管理机制,主要以数据库记录的方式管理所有RPM类型的软件包。它需要将软件的源代码编译并打包成RPM包,通过编译时在软件包中设置好的数据库来记录这个软件在安装时必须具备的条件即软件包的依赖性(依赖性指的是在安装某个软件包的时候需要先安装好其他的软件包才能完成该软件包的安装过程),当用户在安装软件包的时候,首先查询系统是否满足软件包的安装需求,如果满足就安装该软件,并将软件包的信息写入RPM数据库,以便将来查询、验证、升级或反安装需要。反之系统会提示用户如果需要安装这个软件包必须要先解决哪些条件。
使用RPM包最大的好处就是安装、升级、查询、验证与反安装都非常方便,也非常适合网络传输。不足的地方就是在安装之前用户需要先准备好系统环境、确认RPM包可用的系统平台以及适用的软件包版本。RPM包一般分成两种,即已经编译并封装好的可以用于直接安装的rpm类型的应用程序,以.rpm方式命名;另一种是SRPM,也叫原代码软件包,这种软件包提供的是没有经过编译的原程序,通常以.src.rpm方式命名。SRPM与RPM不同之处就是它封装的是原程序,在这些原程序中包含有参数配置文件用来记录软件包的依赖性,用户在下载这种类型的软件包需要用RPM管理工具进行编译封装成RPM包才能安装。 SRPM包是Linux的发行商为用户提供的源码包,为方便用户定制软件而提供的。
每一个RPM类型的软件包都有固定的命名规则,用于区分软件包的版本与适用的平台。其命令方式通常为:“软件包名称-软件包版本-软件包修订次数.适用的硬件平台.扩展名”。 如zsh-html-4.2.6-3.el5.i386.rpm文件名称解释如下:
软件包名称:即zsh-html-4.2.6-3.el5.i386.rpm的软件包名称为zsh-html;
软件的版本信息:即zsh-html-4.2.6-3.el5.i386.rpm的软件包的版本为4.2.6;用于区分软件包的新旧,其中版又分区主版本号与次版本号, 以zsh-html-4.2.6-3.el5.i386.rpm文件为例, 主版本号为4,次版本号为2;次版本即为在主版本的基础上扩展而来的新版本。
注意:主版本号与次版本号在定义内核的时候具有特别的意义,当内核次版本号为奇数时,代表该内核为开发版或测试版本,适用于内核开发与测试人员;当内核次版本号为偶数时,代表该内核为稳定版本,适用于生产环境;如2.6.18代表稳定版本,而2.33.164代表测试版。
修订次数:即zsh-html-4.2.6-3.el5.i386.rpm的软件包的修订次数为3.el5;也叫软件的编译次数,通常指软件小幅度更新或修复之后发布的RPM软件包。
适用的硬件平台:即zsh-html-4.2.6-3.el5.i386.rpm的软件包硬件平台为i386;硬件平台以CPU的等级进行区分,在Linux系统中RPM包适用的平台有很多种,主要是为不同的软件适用不同的CPU做了些特定的优化, 因此用户在选择软件包的时候需注意硬件平台的不同,关于硬件平台说明见下表所示;

硬件平台 功能说明
i386 适用于所有x86平台(或所有的CPU),i指的是intel的CPU,386代表CPU的级别;
i586 适用于CPU级别为586的计算机平台,如intel的奔腾I以下,386以上级别的CPU以及AMD的k5,k6系列的CPU等;
i686 适用于Intel奔腾II或AMD K7以上级别CPU的硬件平台,并进行优化过的应用程序;
x86-64 适用于64位的CPU硬件平台,如当前主流的CPU都属于这一类型;
noarch 此种软件没有硬件平台限制,通常这类型的软件属于shell脚本方面的软件包;

6.2 源码包安装
要进行源码包的安装,首先要知道linx系统上真正认识的可执行程序是二进制程序,而源码,只是程序员编写的纯文本而已。所以我们需要将源代码编译成系统看的懂的二进制程序,而要编译就需要用到编译器。在linux下最常用的一个编译器就是gcc。
事实上,使用类似gcc的编译器来进行编译的过程非常复杂。这个时候,我们需要使用make命令的相关功能来简化编译过程。
make命令会在当前路径下搜索makefile文件,makefile文件里记录了源码该如何编译的详细信息,从而根据这些信息对源码进行编译。但是makefile文件该怎么产生呢?通常软件开发商都会写一个检测程序,用来检测使用者的系统环境,以及该系统环境中是否有该软件所需要的其他功能。检测程序检测完毕后,就会自动的建立这个makefile文件。通常这个检测程序的名称叫configure或config。
一般来说,检测程序会检测如下内容:
1)系统环境中是否有适合的编译器可以编译本软件的源代码;
2)系统环境中是否已经存在本软件所需要的函数库,或其他需要的依赖软件;
3)系统平台是否适合本软件,包括linux的内核版本。
最后,使用make install命令安装本程序。

例1:源码安装inotify-tools工具
[root@server ~]# wget http://github.com/downloads/rvoicilas/inotify-tools/inotify-tools-3.13.tar.gz

下载inotify-tools工具源码包

[root@server ~]# tar -zxvf inotify-tools-3.13.tar.gz

解压压缩包

[root@server ~]# cd inotify-tools-3.13

切换工作目录到解压之后的目录中

[root@server ~]# .configure --prefix=/program

执行环境检测程序

并指定程序将安装到/program目录下

[root@server ~]# make

执行编译

[root@server ~]# make install

执行安装

[root@server ~]# ln -s /program/bin/* /usr/bin

将安装的二进制程序,也就是inotify的命令,软链接到/usr/bin下

这样,以后就可以直接输入inotify工具的命令,而不用指定路径了

6.3 RPM包的安装
关于rpm包的安装,共有两种方式:rpm和yum

6.3.1 rpm安装
rpm(redhat packages manager),为rpm包的原生安装工具,但它有个致命弱点,即不能自动解决软件包之间的依赖关系。

例1:使用rpm工具安装samba软件包
[root@server ~]# echo "/dev/sr0 /mnt/dvd iso9660 defaults 0 0" >> /etc/fstab

配置光盘开机自动挂载到/mnt/dvd目录

[root@server ~]# mkdir /mnt/dvd

创建挂载点

[root@server ~]# mount -a

立即挂载

[root@server ~]# rpm -ivh /mnt/dvd/Packages/samba-4.2.3-10.el7.x86_64.rpm
warning: /mnt/dvd/Packages/samba-4.2.3-10.el7.x86_64.rpm: Header V3 RSA/SHA256 Signature, key ID fd431d51: NOKEY
error: Failed dependencies:
samba-common = 4.2.3-10.el7 is needed by samba-0:4.2.3-10.el7.x86_64
samba-common-libs = 4.2.3-10.el7 is needed by samba-0:4.2.3-10.el7.x86_64
samba-common-tools = 4.2.3-10.el7 is needed by samba-0:4.2.3-10.el7.x86_64
samba-client-libs = 4.2.3-10.el7 is needed by samba-0:4.2.3-10.el7.x86_64
samba-libs = 4.2.3-10.el7 is needed by samba-0:4.2.3-10.el7.x86_64
。。。以下省略

通过上面的例子,我们发现,包与包之间是有依赖关系的,在安装想要的软件包之前,必须先将它所依赖的包装好,才能再安装,此过程太过繁琐,所以在实际工作中,我们一般不直接使用rpm工具来安装软件包,而是使用yum。
但是rpm工具,除了用来安装软件包,还有其它功能,比如:查询系统已安装的软件包、查询软件包的安装文件等,这些功能才是我们使用最广的。

例2:使用rpm工具查询软件包
[root@server ~]# rpm -qa
jansson-2.4-6.el7.x86_64
redhat-release-server-7.2-9.el7.x86_64
dmidecode-2.12-9.el7.x86_64
filesystem-3.2-20.el7.x86_64
libestr-0.1.9-2.el7.x86_64
.....以下省略

查询系统当前已经安装的所有软件包

[root@server ~]# rpm -ql openssh-server-6.6.1p1-22.el7.x86_64
/etc/pam.d/sshd
/etc/ssh/sshd_config
/etc/sysconfig/sshd
/usr/lib/systemd/system/sshd-keygen.service
/usr/lib/systemd/system/sshd.service
/usr/lib/systemd/system/sshd.socket
/usr/lib/systemd/system/sshd@.service
/usr/lib64/fipscheck/sshd.hmac
/usr/libexec/openssh/sftp-server
/usr/sbin/sshd
/usr/sbin/sshd-keygen
/usr/share/man/man5/moduli.5.gz
/usr/share/man/man5/sshd_config.5.gz
/usr/share/man/man8/sftp-server.8.gz
/usr/share/man/man8/sshd.8.gz
/var/empty/sshd

查询openssh-server-6.6.1p1-22.el7.x86_64这个软件所包含的文件,安装的时候,分别保存到了系统的哪些位置。

[root@server ~]# rpm -qc openssh-server-6.6.1p1-22.el7.x86_64
/etc/pam.d/sshd
/etc/ssh/sshd_config
/etc/sysconfig/sshd

仅查询ssh这个服务的配置文件在哪儿

[root@server ~]# rpm -qf /etc/ssh/ssh_config
openssh-clients-6.6.1p1-22.el7.x86_64

查询/etc/ssh/ssh_config这个文件是由哪个软件包提供的。

6.3.2 yum安装
yum(全称为 Yellow dog Updater, Modified)是一个在Fedora和RedHat以及SUSE发行版专门针对RPM包进行管理与维护的前端软件包管理器,它能够通过分析RPM包中的标题数据为软件包的安装提供一种合适的解决方案, 并自动下载与安装所需要的软件,帮助用户解决在安装、删除与更新rpm包的时候存在的各种问题。
yum实现的软件包管理机制就是将RPM类型的软件包存放到一个yum可以管理的容器内(也叫软件仓库),yum通过分析软件存在的依赖性问题,并将其汇总成清单列表,这些列表与软件包都存储在软件仓库内(repository),当客户端有安装软件的需求时,客户端会从可用的yum服务器上下载软件信息清单列表,并与本机中的RPM数据库中记录的软件数据进行比较就会得出软件的安装结果,系统在完成软件包的安装之后会将这些软件包的清单列表信息缓存在/var/cache/yum目录,以便下次使用。使用yum仓库的目的在于区分rpm包的内容与版本之间的区别。
Yum支持的软件仓库可以是本地主机特定目录内的软件包文件,也可以是通过网络文件共享协议发布出来的资源如ftp或http等。

例1:配置yum仓库
[root@server ~]# vi /etc/yum.repos.d/dvd.repo
[dvd]
name=dvd
baseurl=file:///mnt/dvd/
enabled=1
gpgcheck=0

生成一个以.repo结尾的文件,这就是yum的仓库配置文件

[],指定仓库的id

name,指定仓库的名称

baseurl,指定仓库地址,注意:仓库地址路径必须为repodata目录的上一级目录

enabled,是否开启这个仓库

gpgcheck,指定要不要对软件包进行完整性、安全检查

例2:查询yum仓库中的所有软件包名称
[root@server ~]# yum list

列出仓库中的所有软件包名称

例3:在yum仓库中查询包含ssh关键字的软件包
[root@server ~]# yum search ssh
Loaded plugins: product-id, search-disabled-repos, subscription-manager
This system is not registered to Red Hat Subscription Management. You can use subscription-manager to register.
====================================== N/S matched: ssh =======================================
fence-agents-ilo-ssh.x86_64 : Fence agent for HP iLO devices via SSH
ksshaskpass.x86_64 : A KDE version of ssh-askpass with KWallet support
libssh2.i686 : A library implementing the SSH2 protocol
libssh2.x86_64 : A library implementing the SSH2 protocol
openssh.x86_64 : An open source implementation of SSH protocol versions 1 and 2
openssh-askpass.x86_64 : A passphrase dialog for OpenSSH and X
openssh-clients.x86_64 : An open source SSH client applications
openssh-keycat.x86_64 : A mls keycat backend for openssh
openssh-server.x86_64 : An open source SSH server daemon

Name and summary matches only, use "search all" for everything.

例4:查询ping命令是由哪个软件包提供的
[root@server ~]# yum provides ping
Loaded plugins: product-id, search-disabled-repos, subscription-manager
This system is not registered to Red Hat Subscription Management. You can use subscription-manager to register.
dvd/filelists_db | 3.2 MB 00:00:00
iputils-20121221-7.el7.x86_64 : Network monitoring tools including ping
Repo : dvd
Matched from:
Filename : /usr/bin/ping

iputils-20121221-7.el7.x86_64 : Network monitoring tools including ping
Repo : @anaconda/7.2
Matched from:
Filename : /usr/bin/ping

例5:使用yum安装httpd软件包
[root@server ~]# yum install -y httpd
Loaded plugins: product-id, search-disabled-repos, subscription-manager
This system is not registered to Red Hat Subscription Management. You can use subscription-manager to register.
Resolving Dependencies
--> Running transaction check
---> Package httpd.x86_64 0:2.4.6-40.el7 will be installed
--> Processing Dependency: httpd-tools = 2.4.6-40.el7 for package: httpd-2.4.6-40.el7.x86_64
--> Processing Dependency: /etc/mime.types for package: httpd-2.4.6-40.el7.x86_64
--> Processing Dependency: libapr-1.so.0()(64bit) for package: httpd-2.4.6-40.el7.x86_64
--> Processing Dependency: libaprutil-1.so.0()(64bit) for package: httpd-2.4.6-40.el7.x86_64
--> Running transaction check
---> Package apr.x86_64 0:1.4.8-3.el7 will be installed
---> Package apr-util.x86_64 0:1.5.2-6.el7 will be installed
---> Package httpd-tools.x86_64 0:2.4.6-40.el7 will be installed
---> Package mailcap.noarch 0:2.1.41-2.el7 will be installed
--> Finished Dependency Resolution
.....以下省略

6.4 练习
1)挂载系统光盘到本地/mnt/dvd/目录
2)配置yum仓库,指定仓库地址为光盘
3)安装httpd软件包
第7章 配置网络
要使得RHEL7对外提供服务,首先必须要在RHEL7中设置好IP的相关信息,主要有IP地址、子网掩码、网关以及DNS服务器。与RHEL6相比,RHEL7新增加了nmcli配置命令、Team网卡绑定等技术,在网卡的命名上,也与RHEL6有一些变化,本章主要讲解在RHEL7中如何设置IPv4、IPv6以及网卡的绑定。
学习目标:
熟练在RHEL7中配置IPv4的相关信息
熟练在RHEL7中配置IPv6的相关信息
掌握在RHEL7中配置网卡的绑定
7.1 IPv4网络设置
7.1.1 IPv4网络概述
目前的网络都是基于IPv4,IPv4的地址是点分十进制的,由32位二进制数组成。在IPv4的网络里,需要管理员配置的信息主要有IP地址、子网掩码、网关以及DNS。在RHEL7中,主要通过图形工具、修改配置文件以及nmcli命令等方法来对网络进行配置,本节讲解的是这三种方法的具体配置步骤。
在RHEL7中,网卡名不一定就是eth0或eth1了,它的命名发生了变化,主要根据固件、设备类型、拓扑结构等,具体的规则如下:
首先是看接口的网络类型,如果是以太网则为en开头,无线局域网则为wl开头,广域网则为ww开头。其次是看网卡适配器的类型,如果为o代表板载网卡,s代表热插拔网卡,p代表PCI插槽网卡。接下来数字是融入了MAC地址。最后,使用数字代表索引或端口ID。在无法确定的情况下,则使用以前的名称eth0。
比如常见的网卡名有enp5s0,eno1等。
7.1.2 图形工具配置网络
需要配置的IPv4信息如表7.1所示。
表7.1 IP地址相关信息
IP地址 192.168.100.1
掩码 255.255.255.0
网关 192.168.100.254
DNS1 61.144.56.101
具体配置步骤如下:
1、在终端上输入如下命令,打开网络连接配置界面如图7.1所示。
[root@server ~]#nm-connection-editor

图7.1 网络连接配置
在图7.1所示的对话框中,选择网卡“ens33”,单击“Edit...”按钮,弹出如图7.2所示的对话框。在图7.2所示的对话框中,选择“IPv4 Settings”选项卡,进行配置IPv4相关的信息。在“Method”右边的下拉菜单中选择“Manual”,然后单击“Add”按钮,根据表7.1中的数据,设置好网络信息,包括“Address”、“Netmask”、“Gateway”以及“DNS servers”。最后单击“Save”按钮保存配置。

图7.2 网卡ens33配置
2、重启网络,让网络配置生效。
[root@server ~]# systemctl restart network
3、查看网络相关的信息,检查配置是否生效。
(1)查看IP地址与掩码。
[root@server ~]# ip addr show ens33
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:0c:29:d4:82:23 brd ff:ff:ff:ff:ff:ff
inet 192.168.100.1/24 brd 192.168.100.255 scope global ens33
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:fed4:8223/64 scope link
valid_lft forever preferred_lft forever
(2)查看网关。
[root@server ~]# ip route
default via 192.168.100.254 dev ens33 proto static metric 1024
192.168.100.0/24 dev ens33 proto kernel scope link src 192.168.100.1
(3)查看DNS服务器的信息。
[root@server ~]# cat /etc/resolv.conf

Generated by NetworkManager

search wyl.com
nameserver 61.144.56.101
7.1.3 修改配置文件方法
图形配置方法比较简单,适合于初学者,管理员一般是通过修改配置文件的方法来配置网络。在RHEL7中,可以新增连接名,适应不同场合的网络配置,本节新增加一个连接work,并设置网络信息如表7.2所示。
表7.2 work连接的IP地址相关信息
IP地址 192.168.200.1
掩码 255.255.255.0
网关 192.168.200.254
DNS1 61.144.56.101
具体配置步骤如下:
1、进入网卡的配置文件目录,通过复制生成ifcfg-work的网卡配置文件。
[root@server ~]# cd /etc/sysconfig/network-scripts/
[root@server network-scripts]# ls
ifcfg-ens33 ifdown-ppp ifup-eth ifup-sit
ifcfg-lo ifdown-routes ifup-ippp ifup-Team
ifdown ifdown-sit ifup-ipv6 ifup-TeamPort
ifdown-bnep ifdown-Team ifup-isdn ifup-tunnel
ifdown-eth ifdown-TeamPort ifup-plip ifup-wireless
ifdown-ippp ifdown-tunnel ifup-plusb init.ipv6-global
ifdown-ipv6 ifup ifup-post network-functions
ifdown-isdn ifup-aliases ifup-ppp network-functions-ipv6
ifdown-post ifup-bnep ifup-routes
[root@server network-scripts]# cp ifcfg-ens33 ifcfg-work
2、设置网卡的配置文件,把网卡的配置文件ifcfg-work通过vim编辑器修改如下所示。
[root@server network-scripts]# vim ifcfg-work
[root@server network-scripts]# cat ifcfg-work
BOOTPROTO="none"
IPADDR0=192.168.200.1
PREFIX0=24
NAME="work"
ONBOOT="yes"
GATEWAY0=192.168.200.254
DNS1=61.144.56.101
DEVICE=ens33
网卡配置文件中关键词的主要意义如表7.3所示。
表7.3 网卡配置文件中关键词的主要意义
BOOTPROTO 设置网卡的配置方式,值为“none”或“static”则为手工配置网卡,如值为“dhcp”则自动获取IP地址。
IPADDR0 设置IP地址,0代表的是第一个IP地址,1当表第二个IP地址,以此类推,主要用于在一个网卡上可以配置多个IP地址。
PREFIX0 掩码
NAME 连接名
ONBOOT 系统引导时是否启动此网卡
GATEWAY0 网关
DNS1 DNS服务器
DEVICE 设备名
3、重启网络。只有通过重启网络之后,新的连接名work才会生效。
[root@server network-scripts]# nmcli connection show
NAME UUID TYPE DEVICE
ens33 2fce29ed-5c0b-42ba-aa55-b118a69b1d2d 802-3-ethernet ens33
[root@server network-scripts]# systemctl restart network
[root@server network-scripts]# nmcli connection show
NAME UUID TYPE DEVICE
work 04ad2aea-4b93-258e-2f3b-0329e01eb035 802-3-ethernet --
ens33 2fce29ed-5c0b-42ba-aa55-b118a69b1d2d 802-3-ethernet ens33
4、激活work连接名。
[root@server network-scripts]# nmcli connection show --active
NAME UUID TYPE DEVICE
ens33 2fce29ed-5c0b-42ba-aa55-b118a69b1d2d 802-3-ethernet ens33
[root@server network-scripts]# nmcli connection up work
[root@server ~]# nmcli connection show --active
NAME UUID TYPE DEVICE
work 04ad2aea-4b93-258e-2f3b-0329e01eb035 802-3-ethernet ens33

5、查看连接名为work的网络信息。
(1)查看IP地址与掩码。
[root@server ~]# ip addr show ens33
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:0c:29:d4:82:23 brd ff:ff:ff:ff:ff:ff
inet 192.168.200.1/24 brd 192.168.200.255 scope global ens33
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:fed4:8223/64 scope link
valid_lft forever preferred_lft forever
(2)查看网关。
[root@server ~]# ip route
default via 192.168.200.254 dev ens33 proto static metric 1024
192.168.200.0/24 dev ens33 proto kernel scope link src 192.168.200.1
(3)查看DNS服务器信息。
[root@server ~]# cat /etc/resolv.conf

Generated by NetworkManager

search wyl.com
nameserver 61.144.56.101
7.1.4 nmcli命令方法
直接通过nmcli命令来修改配置文件,让网络配置生效,这是RHEL7中新增的命令,此命令灵活,是配置IP信息的另外一种方法,本节再增加一个连接home,并设置相关的网络信息,网络信息如表7.4所示。
表7.4 work连接的IP地址相关信息
IP地址 192.168.255.1
掩码 255.255.255.0
网关 192.168.255.254
DNS1 61.144.56.100
DNS2 8.8.8.8
具体配置步骤如下:
1、添加一个连接名为home的连接,并且设置IP地址、掩码与网关。
[root@server ~]# nmcli connection add con-name "home" type ethernet ifname ens33 autoconnect no ip4 192.168.255.1/24 gw4 192.168.255.254
Connection 'home' (926511fd-4cd4-4194-adc0-635d20f2be29) successfully added.
2、设置DNS。
[root@server ~]# nmcli connection modify "home" ipv4.dns 61.144.56.100
3、添加第二DNS。
[root@server ~]# nmcli connection modify "home" +ipv4.dns 8.8.8.8
4、连接名为home的连接已生效。
[root@server ~]# nmcli connection show
NAME UUID TYPE DEVICE
home 926511fd-4cd4-4194-adc0-635d20f2be29 802-3-ethernet --
work 04ad2aea-4b93-258e-2f3b-0329e01eb035 802-3-ethernet ens33
ens33 2fce29ed-5c0b-42ba-aa55-b118a69b1d2d 802-3-ethernet --
5、激活home的连接。
[root@server ~]# nmcli connection show --active
NAME UUID TYPE DEVICE
work 04ad2aea-4b93-258e-2f3b-0329e01eb035 802-3-ethernet ens33
[root@server ~]# nmcli connection up home
[root@server ~]# nmcli connection show --active
NAME UUID TYPE DEVICE
home 926511fd-4cd4-4194-adc0-635d20f2be29 802-3-ethernet ens33
6、查看配置信息。
(1)查看IP地址与掩码。
[root@server ~]# ip addr show ens33
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:0c:29:d4:82:23 brd ff:ff:ff:ff:ff:ff
inet 192.168.255.1/24 brd 192.168.255.255 scope global ens33
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:fed4:8223/64 scope link
valid_lft forever preferred_lft forever
(2)查看网关。
[root@server ~]# ip route
default via 192.168.255.254 dev ens33 proto static metric 1024
192.168.255.0/24 dev ens33 proto kernel scope link src 192.168.255.1
(3)查看DNS。
[root@server ~]# cat /etc/resolv.conf

Generated by NetworkManager

search wyl.com
nameserver 61.144.56.100
nameserver 8.8.8.8
7.2 IPv6网络设置
7.2.1 IPv6概述
IPv6是未来的发展趋势,尤其是我们发展中国家,急需IPv6地址来解决面临枯竭的IPv4地址问题,目前的部分骨干网络就已经是IPv6的网络。IPv6的地址是冒分十六进制,由128位二进制数组成,分成八组。本节通过两种方法讲解在RHEL7中设置IPv6网络。
7.2.2 IPv6图形配置方法
需要配置的IPv6信息如表7.5所示。
表7.5 IP地址相关信息
IP地址 2001:db9:0:3::451
前缀 64
网关 2001:db9:0:3::1
DNS1 2001::1
具体配置步骤如下:
1、输入如下命令,打开网络配置的图形界面,如图7.3所示。
[root@server ~]# nm-connection-editor

图7.3 配置网络连接
在图7.3所示的对话框中,选择网卡“ens33”,单击“Edit...”按钮,弹出如图7.4所示的对话框。在图7.4所示的对话框中,选择“IPv6 Settings”选项卡,进行配置IPv6相关的信息,先在“Method”的下拉菜单中选择“Manual”,然后单击“Add”按钮,根据表7.5相关的数据填写相关的IPv6信息,包括“Address”、“Prefix”、“Gateway”以及“DNS servers”,最后单击“Save”按钮保存网络配置。

图7.4 设置IPv6
2、重启网络,使配置生效。
[root@server ~]# systemctl restart network
3、查看IPv6相关信息。
(1)查看IPv6的地址与前缀。
[root@server ~]# ip addr show ens33
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:0c:29:d4:82:23 brd ff:ff:ff:ff:ff:ff
inet 192.168.100.1/24 brd 192.168.100.255 scope global ens33
valid_lft forever preferred_lft forever
inet6 2001:db9:0:3::451/64 scope global
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:fed4:8223/64 scope link
valid_lft forever preferred_lft forever
(2)查看网关。
[root@server ~]# ip -6 route show
unreachable ::/96 dev lo metric 1024 error -101
unreachable ::ffff:0.0.0.0/96 dev lo metric 1024 error -101
2001:db9:0:3::/64 dev ens33 proto kernel metric 256
unreachable 2002:a00::/24 dev lo metric 1024 error -101
unreachable 2002:7f00::/24 dev lo metric 1024 error -101
unreachable 2002:a9fe::/32 dev lo metric 1024 error -101
unreachable 2002:ac10::/28 dev lo metric 1024 error -101
unreachable 2002:c0a8::/32 dev lo metric 1024 error -101
unreachable 2002:e000::/19 dev lo metric 1024 error -101
unreachable 3ffe:ffff::/32 dev lo metric 1024 error -101
fe80::/64 dev ens33 proto kernel metric 256
default via 2001:db9:0:3::1 dev ens33 proto static metric 1024
(3)查看DNS。
[root@server ~]# cat /etc/resolv.conf

Generated by NetworkManager

search wyl.com
nameserver 61.144.56.101
nameserver 2001::1
7.2.3 修改配置文件方法
需要配置的IPv6信息如表7.6所示。
表7.6 IP地址相关信息
IP地址 2001:db9:0:3::200
前缀 64
网关 2001:db9:0:3::2
具体配置步骤如下:
1、进入网卡配置文件的目录。
[root@server ~]# cd /etc/sysconfig/network-scripts/
[root@server network-scripts]# ls
ifcfg-ens33 ifdown-post ifup-eth ifup-Team
ifcfg-home ifdown-ppp ifup-ippp ifup-TeamPort
ifcfg-lo ifdown-routes ifup-ipv6 ifup-tunnel
ifcfg-work ifdown-sit ifup-isdn ifup-wireless
ifdown ifdown-Team ifup-plip init.ipv6-global
ifdown-bnep ifdown-TeamPort ifup-plusb network-functions
ifdown-eth ifdown-tunnel ifup-post network-functions-ipv6
ifdown-ippp ifup ifup-ppp
ifdown-ipv6 ifup-aliases ifup-routes
ifdown-isdn ifup-bnep ifup-sit
2、修改之前配置的work连接的配置文件ifcfg-work,通过vim编辑器设置IPv6的IP地址、前缀与网关。
[root@server network-scripts]# vim ifcfg-work
[root@server network-scripts]# cat ifcfg-work
BOOTPROTO="none"
IPADDR0=192.168.200.1
PREFIX0=24
NAME="work"
ONBOOT="yes"
GATEWAY0=192.168.200.254
DNS1=61.144.56.101
DEVICE=ens33
IPv6INIT=yes
IPv6_AUTOCONF=no
IPv6ADDR=2001:db3:0:1::200/64
IPv6_DEFAULTGW=2001::2
3、重启网络,并激活work连接。
[root@server ~]# systemctl restart network
[root@server ~]# nmcli connection up work
4、检查配置是否生效。
(1)查看IPv6地址与前缀。
[root@server ~]# ip addr show ens33
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:0c:29:d4:82:23 brd ff:ff:ff:ff:ff:ff
inet 192.168.200.1/24 brd 192.168.200.255 scope global ens33
valid_lft forever preferred_lft forever
inet6 2001:db3:0:1::200/64 scope global
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:fed4:8223/64 scope link
valid_lft forever preferred_lft forever
(2)查看IPv6网关。
[root@server ~]# ip -6 route
unreachable ::/96 dev lo metric 1024 error -101
unreachable ::ffff:0.0.0.0/96 dev lo metric 1024 error -101
2001::1 via 2001::2 dev ens33 metric 0
cache
2001::2 dev ens33 proto static metric 1024
2001:db3:0:1::/64 dev ens33 proto kernel metric 256
unreachable 2002:a00::/24 dev lo metric 1024 error -101
unreachable 2002:7f00::/24 dev lo metric 1024 error -101
unreachable 2002:a9fe::/32 dev lo metric 1024 error -101
unreachable 2002:ac10::/28 dev lo metric 1024 error -101
unreachable 2002:c0a8::/32 dev lo metric 1024 error -101
unreachable 2002:e000::/19 dev lo metric 1024 error -101
unreachable 3ffe:ffff::/32 dev lo metric 1024 error -101
fe80::/64 dev ens33 proto kernel metric 256
default via 2001::2 dev ens33 proto static metric 1024
7.3 多网卡绑定
7.3.1 网卡绑定概述
Network Teaming是将多个物理网卡绑定在一起,在逻辑上来讲就相当于一个网卡,它可以提高网络的容错与吞吐量。在RHEL6使用的是Bonding技术,而在RHEL7中使用的是Teaming技术。Teaming是一个新的实现技术,不影响老的Bonding技术的应用。配置Teaming主要有两种方式,第一种是使用nmcli命令的配置方法,第二种是直接修改配置文件。
Teaming模式有broadcast、roundrobin、activebackup、loadbalance、lacp几种,下面介绍最常用的两种模式轮循与主备。
7.3.2 nmcli命令的配置方法
roundrobin模式也称之为轮循模式,它是基于每一个数据包的。如图7.5所示,当某一台服务器的两个网卡设置Teaming模式设置为roundrobin,此时服务器发送出去的数据包是在两个物理网卡上进行轮循,即第一个数据包走第一个网卡,第二个数据包走第二个网卡,第三个数据包走第一个网卡,第四个数据包走第二个网卡,依此轮循。这种模式需要交换机的以太通道的支持,也就意味着必须要在交换机上做以太通道。

图7.5 roundrobin模式拓扑图
具体配置步骤如下:
1、查看服务器上的配置。
(1)查看网卡。
[root@server ~]# ip addr
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:0c:29:d4:82:23 brd ff:ff:ff:ff:ff:ff
inet 192.168.100.1/24 brd 192.168.100.255 scope global ens33
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:fed4:8223/64 scope link
valid_lft forever preferred_lft forever
2: ens37: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:0c:29:d4:82:23 brd ff:ff:ff:ff:ff:ff
inet 192.168.100.2/24 brd 192.168.100.255 scope global ens33
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:fed4:8223/64 scope link
valid_lft forever preferred_lft forever
……其他显示省略
通过上面的命令,发现有两个网卡,ens33与ens37。
(2)创建team接口team0,同时设置teaming模式为roundrobin。
[root@server ~]# nmcli connection add type team con-name team0 ifname team0 config '{"runner":{"name":"roundrobin"}}'
Connection 'team0' (ae1b4b98-9718-498f-9536-a8438ab6343b) successfully added.
(3)给接口team0设置IP地址。
[root@server ~]# nmcli connection modify team0 ipv4.addresses 192.168.1.1/24
[root@server ~]# nmcli connection modify team0 ipv4.method manual
(4)把物理接口加入到team0。
[root@server ~]# nmcli connection add type team-slave con-name team0-port1 ifname ens33 master team0
Connection 'team0-port1' (9be9cb58-f906-4d35-b7c3-fe88ef2e74a5) successfully added.
[root@server ~]# nmcli connection add type team-slave con-name team0-port2 ifname ens37 master team0
Connection 'team0-port2' (652778e0-3354-495c-b2f1-093b17bd6b65) successfully added.
(5)查看team0状态。
可以看出,teaming的模式为roundrobin,同时有两个物理接口,分别是ens33与ens37,都是up的状态。
[root@server ~]# teamdctl team0 state
setup:
runner: roundrobin
ports:
ens33
link watches:
link summary: up
instance[link_watch_0]:
name: ethtool
link: up
ens37
link watches:
link summary: up
instance[link_watch_0]:
name: ethtool
link: up
2、交换机上的配置。
交换机需要以太通道的支持,在交换机上配置如下。
Switch(config)#interface range fastEthernet 0/1 -2
Switch(config-if-range)#channel-group 1 mode on
Switch(config-if-range)# interface port-channel 1
Switch(config-if)#switchport mode access
Switch(config-if)#switchport access vlan 1
3、测试。
可以通过两个方面来进行测试。
一是测试两条物理链路是否有冗余,禁用其中某一块网卡,另一块网卡是否照常工作。使用一台windows主机作为测试机,去ping服务器,ping命令加上-t参数,也就是一直ping下去,然后在服务器上禁用某一个网卡,执行命令:
[root@server network-scripts]# nmcli device disconnect ens33,
结果可以看出在windows主机上还是能ping通服务器的.
另一方面要测试两条物理链路之间有没有轮循,可以采用抓包的方式,比如ping四个包,看一下,第一块网卡上面有两个请求包,第二块网卡上有两个请求包,就说明它们之间有轮循。
7.3.3 直接修改配置文件方法
Activebackup是主备模式,不需要交换机的支持,当网卡绑定成这种模式之后,此时一个物理网卡的状态是主要的,另一个物理网卡的状态是备用的,平时是利用主要的物理网卡传输数据包,当主要的网卡失效之后,备用的网卡就会接管主网卡的工作。
具体配置步骤如下:
1、创建team0的配置文件。
[root@server ~]#cd /etc/sysconfig/network-scripts
[root@server network-scripts]# cat ifcfg-team0
DEVICE=team0
TEAM_CONFIG="{\"runner\":{\"name\":\"activebackup\"}}"
DEVICETYPE=Team
BOOTPROTO=none
NAME=team0
ONBOOT=yes
IPADDR0=192.168.1.1
PREFIX0=24
2、创建两个物理网卡的配置文件team0-port1与team0-port2。
[root@server network-scripts]# cat ifcfg-team0-port1
BOOTPROTO=dhcp
NAME=team0-port1
DEVICE=ens33
ONBOOT=yes
TEAM_MASTER=team0
DEVICETYPE=TeamPort
[root@server network-scripts]#
[root@server network-scripts]# cat ifcfg-team0-port2
BOOTPROTO=dhcp
NAME=team0-port2
DEVICE=ens37
ONBOOT=yes
TEAM_MASTER=team0
DEVICETYPE=TeamPort
3、重启网络,让team0生效。
[root@server network-scripts]#systemctl restart network
4、查看Teaming的状态。
[root@server network-scripts]# teamdctl team0 state
setup:
runner: activebackup
ports:
ens33
link watches:
link summary: up
instance[link_watch_0]:
name: ethtool
link: up
ens37
link watches:
link summary: up
instance[link_watch_0]:
name: ethtool
link: up
runner:
active port: ens33
5、测试。
(1)可以使用另外一台主机来ping此台服务器,当禁用主网卡ens33的时候,另一个备用网卡ens37就会接管工作。
[root@server network-scripts]# nmcli device disconnect ens33
[root@server network-scripts]# teamdctl team0 state
setup:
runner: activebackup
ports:
ens37
link watches:
link summary: up
instance[link_watch_0]:
name: ethtool
link: up
runner:
active port: ens37
(2)启用网卡ens33,为了高可用性,ens37还处于active状态。
[root@server network-scripts]# nmcli connection up team0-port1
Connection successfully activated (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/13)
[root@server network-scripts]#
[root@server network-scripts]# teamdctl team0 state
setup:
runner: activebackup
ports:
ens37
link watches:
link summary: up
instance[link_watch_0]:
name: ethtool
link: up
ens33
link watches:
link summary: up
instance[link_watch_0]:
name: ethtool
link: up
runner:
active port: ens37
第8章 磁盘管理
磁盘作为存储数据的重要载体,在如今日渐庞大的软件资源面前显得格外重要。在计算机领域,广义的说硬盘、光盘、软盘、U盘等用来保存数据信息的磁性存储介质都可以称为磁盘。
如何规划和管理磁盘特别是硬盘是网络管理员的重要工作内容之一。硬盘购买后,必须经过物理安装、分区、格式化(即创建文件系统)和挂载等环节后才能存储程序和数据,熟练掌握磁盘的每一个环节的技术是对网络管理员的基本要求。
同时,作为网络管理员,还必须掌握磁盘配额、逻辑卷管理(LVM)等技术,以便更加灵活、有效、安全的管理好磁盘。本章将对磁盘管理的基本过程和技术进行介绍。
学习目标:
理解磁盘的基本概念
会使用fdisk命令对磁盘进行分区
能对各类分区进行格式化操作
会挂载和卸载分区
会对磁盘进行配额管理
使用LVM实现动态磁盘管理

8.1 磁盘的基本概念

8.1.1硬盘的接口类型
ATA,全称AdvancedTechnology Attachment
是用传统的 40-pin 并口数据线连接主板与硬盘的,接口速度最大为133MB/s,因为并口线的抗干扰性太差,且排线占用空间较大,不利电脑内部散热,已逐渐被SATA 所取代。
SATA,全称Serial ATA
也就是使用串口的ATA接口,因抗干扰性强,且对数据线的长度要求比ATA低很多,支持热插拔等功能,SATA-II的接口速度為375MB/s,而新的SATA-III标准可达到750MB/s的传输速度。SATA的数据线也比ATA的细得多,有利于机箱內的空气流通,整理线材也比较方便。
SCSI,全称是SmallComputer System Interface(小型机系统接口)
经历多代的发展,从早期的 SCSI-II,到目前的 Ultra320 SCSI 以及 Fiber-Channel (光纤通道),接口型式也多种多样。SCSI 硬盘广为工作站级個人电脑以及服务器所使用,因此会使用较为先进的技術,如碟片转速15000rpm的高转速,且资料传输时CPU占用率较低,但是单价也比相同容量的 ATA 及 SATA 硬盘更加昂贵。
SAS,全称是SerialAttached SCSI
新一代的SCSI技术,和SATA硬盘相同,都是采取序列式技术以获得更高的传输速度,可达到6Gb/s。此外也透过缩小连接线改善系统内部空间等。
此外,由于SAS硬盘可以与SATA硬盘共享同样的背板,因此在同一个SAS存储系统中,可以用SATA硬盘来取代部分昂贵的SAS硬盘,节省整体的存储成本。但SATA存储系統并不能连接SAS硬盘。
FC,全称是FibreChannel(光纤通道接口)
拥有此接口的硬盘在使用光纤联接时具有热插拔性、高速带宽(4Gb/s或10Gb/s)、远程连接等特点;内部传输速率也比普通硬盘更高。限制于其高昂的售价, 通常用于高端服务器领域。
SSD:是由控制单元和固态存储单元(DRAM或FLASH芯片)组成的硬盘。
固态硬盘的接口规范和定义、功能及使用方法上与普通硬盘的相同,在产品外形和尺寸上也与普通硬盘一致,SSD分类两类,一种是闪存(FLASH芯片)作为存储介质,另外一种是采用DRAM作为存储介质。SSD的特点是性能好,价格高
8.1.2磁盘在Linux系统中的表示
Linux中,磁盘的表示方法不像Windows中表示的一样,如表8.1
表8.1.1 Linxu磁盘设备文件名对照表
设备 设备文件名
软盘驱动器 /dev/fd[0-1]
当前CD ROM/DVD ROM /dev/cdrom
IDE硬盘 /dev/hd[a-z]
虚拟磁盘/半虚拟化 /dev/vd[a-z]
SCSI/SATA/SAS/USB硬盘/U盘 /dev/sd[a-z]

第1个磁盘阵列设备 /dev/md0
第1个SCSI磁带设备 /dev/st0
在将一个磁盘合理的分区后,分区的表示方式 设备名称+分区号,如图8.1.2 sda1(第一块硬盘的第一个分区),sda2
图8.1.2 Linux磁盘分区显示
主流的分区机制分为MBR和GPT,分区不是硬盘的功能,而是一个软件的概念,下一章将会讲解MBR和GPT

8.2 MBR/GPT

8.2.1 什么是MBR和GPT?
MBR的全称是Master Boot Record(主引导记录)
MBR早在1983年IBM PC DOS 2.0中就已经提出。之所以叫“主引导记录”,是因为它是存在于驱动器开始部分的一个特殊的启动扇区。这个扇区包含了已安装的操作系统的启动加载器和驱动器的逻辑分区信息。
主引导扇区是硬盘的第一扇区。它由三个部分组成,主引导记录MBR、硬盘分区表DPT和硬盘有效标志。在总共512字节的主引导扇区里MBR占446个字节,偏移地址0000H--0088H),它负责从活动分区中装载,并运行系统引导程序;第二部分是Partition table区(DPT分区表),占64个字节;第三部分是Magic number,占2个字节。
MBR分区表系统
所谓启动加载器,是一小段代码,用于加载驱动器上其他分区上更大的加载器。如果你安装了Windows,Windows启动加载器的初始信息就放在这个区域里——如果MBR的信息被覆盖导致Windows不能启动,你就需要使用Windows的MBR修复功能来使其恢复正常。如果你安装了Linux,则位于MBR里的通常会是GRUB加载器。
MBR最大支持2.2TB磁盘,它无法处理大于2.2TB容量的磁盘。MBR还只支持最多4个主分区——如果你想要更多分区,你需要创建所谓“扩展分区”,并在其中创建逻辑分区。

GPT的全称是Globally Unique Identifier Partition Table
意即GUID分区表,鉴于MBR的磁盘容量和分区数量已经不能满足硬件发展的需求,GPT首要的任务就是突破了2.2T分区的限制,最大支持18EB的分区。
GPT分区表系统
而在分区数量上,GPT会为每一个分区分配一个全局唯一的标识符,理论上GPT支持无限个磁盘分区,不过在Windows系统上由于系统的限制,最多只能支持128个磁盘分区,基本可以满足所有用户的存储需求。在每一个分区上,这个标识符是一个随机生成的字符串,可以保证为地球上的每一个GPT分区都分配完全唯一的标识符。
在安全性方面,GPT分区表也进行了全方位改进。在早期的MBR磁盘上,分区和启动信息是保存在一起的。如果这部分数据被覆盖或破坏,事情就麻烦了。相对的,GPT在整个磁盘上保存多个这部分信息的副本,因此它更为健壮,并可以恢复被破坏的这部分信息。GPT还为这些信息保存了循环冗余校验码(CRC)以保证其完整和正确——如果数据被破坏,GPT会发觉这些破坏,并从磁盘上的其他地方进行恢复。

MBR和GPT的优缺点
MBR的优点:
支持32bit和64bit系统
兼容旧电脑
MBR的缺点:
最多4个主分区
扩展分区:一个扩展分区会占用一个主分区的一个名额
逻辑分区:在逻辑分区中,继续划分扩展分区,最多支持63个IDE分区和15个SCSI分区
最大支持2.2TB磁盘

GPT的优点:
支持超过2T的硬盘
向后兼容MBR
GPT的缺点:
必须在支持UEFI的硬件上才能使用
必须使用64bit系统

说完了磁盘的分区类型,就该轮到磁盘工具的使用了,如何分区格式化等,将在下一节讲解。

8.3 磁盘工具
8.3.1 磁盘工具类型
由于目前磁盘分区主要有MBR以及GPT两种,而这两种格式的分区工具都不太一样,我们会使用fdisk处理MBR分区或gdisk来处理GPT分区。当然还有一个parted 这个都能使用的工具。
8.3.2 fdisk的使用
fdsik 能划分磁盘成为若干个区,同时也能为每个分区指定分区的文件系统,比如linux 、fat32、 linux 、linux swap 、fat16 以及其实类Unix类操作系统的文件系统等;当然我们用fdisk 对磁盘操作分区时,并不是一个终点,我们还要对分区进行格式化所需要的文件系统;这样一个分区才能使用。
我们可以通过fdisk -l 详细的查看机器的磁盘和分区情况
[root@server ~]# fdisk -l

Disk /dev/sda: 21.5 GB, 21474836480 bytes, 41943040 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk label type: dos
Disk identifier: 0x000c55ae

Device Boot Start End Blocks Id System
/dev/sda1 * 2048 1026047 512000 83 Linux
/dev/sda2 1026048 41943039 20458496 8e Linux LVM

Disk /dev/mapper/centos-root: 18.8 GB, 18756927488 bytes, 36634624 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes

Disk /dev/mapper/centos-swap: 2147 MB, 2147483648 bytes, 4194304 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes

通过上面的信息,我们知道此机器中挂载一个磁盘,Disk /dev/sda

如果我们想查看单个硬盘情况,可以通过fdisk -l /dev/sda1 来操作
以fdisk -l 输出的硬盘标识为准
其中 sda有两个主分区,分别是主分区 sda1和sda2  
硬盘总容量=主分区(包括扩展分区)总容量
扩展分区容量=逻辑分区总容量

为了直观的体验fdisk 拿了一块新的磁盘/dev/sdb
[root@server ~]# fdisk /dev/sdb
Welcome to fdisk (util-linux 2.23.2).

Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.

Device does not contain a recognized partition table
Building a new DOS disklabel with disk identifier 0xabc7f208.

Command (m for help):
按下m 可以查看帮助
Command action
a toggle a bootable flag
b edit bsd disklabel
c toggle the dos compatibility flag
d delete a partition
g create a new empty GPT partition table
G create an IRIX (SGI) partition table
l list known partition types
m print this menu
n add a new partition
o create a new empty DOS partition table
p print the partition table
q quit without saving changes
s create a new empty Sun disklabel
t change a partition's system id
u change display/entry units
v verify the partition table
w write table to disk and exit
x extra functionality (experts only)
Command (m for help):
增加一个新的分区,n
p 表示主分区 默认是p
e 表示扩展分区
CCommand (m for help): n
Partition type:
p primary (0 primary, 0 extended, 4 free)
e extended
Select (default p): <默认是p 主分区>
Using default response p
Partition number (1-4, default 1): <4个主分区>
First sector (2048-41943039, default 2048): <从2048开始>
Using default value 2048
Last sector, +sectors or +size{K,M,G} (2048-41943039, default 41943039): +1G
Partition 1 of type Linux and of size 1 GiB is set
<这里选择+1G ,完成后p查看一下>
Command (m for help): p

Disk /dev/sdb: 21.5 GB, 21474836480 bytes, 41943040 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk label type: dos
Disk identifier: 0xabc7f208
<这就是刚刚创建好的>
Device Boot Start End Blocks Id System
/dev/sdb1 2048 2099199 1048576 83 Linux

Command (m for help):
我们尝试添加一个扩展分区
Command (m for help): n
Partition type:
p primary (1 primary, 0 extended, 3 free)
e extended
Select (default p): e <选择扩展分区>
Partition number (2-4, default 2):
First sector (2099200-41943039, default 2099200): <默认就好>
Using default value 2099200
Last sector, +sectors or +size{K,M,G} (2099200-41943039, default 41943039): +10G
Partition 2 of type Extended and of size 10 GiB is set <添加了10G>

Command (m for help): p

Disk /dev/sdb: 21.5 GB, 21474836480 bytes, 41943040 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk label type: dos
Disk identifier: 0xabc7f208

Device Boot Start End Blocks Id System
/dev/sdb1 2048 2099199 1048576 83 Linux
/dev/sdb2 2099200 23070719 10485760 5 Extended

Command (m for help):

但是 扩展创建好了并不能使用,扩展分区的作用就是 划分逻辑分区
Command (m for help): n
Partition type:
p primary (1 primary, 1 extended, 2 free)
l logical (numbered from 5) <扩展分区创建后,只能创建逻辑分区了>
Select (default p): l <选择创建逻辑分区>
Adding logical partition 5 <会自动顺序从5开始选择>
First sector (2101248-23070719, default 2101248):
Using default value 2101248
Last sector, +sectors or +size{K,M,G} (2101248-23070719, default 23070719): +5G
Partition 5 of type Linux and of size 5 GiB is set <选择加5G >
<创建第二个逻辑分区>
Command (m for help): n
Partition type:
p primary (1 primary, 1 extended, 2 free)
l logical (numbered from 5)
Select (default p): l
Adding logical partition 6<这里就变成了6>
First sector (12589056-23070719, default 12589056):
Using default value 12589056
Last sector, +sectors or +size{K,M,G} (12589056-23070719, default 23070719):
Using default value 23070719
Partition 6 of type Linux and of size 5 GiB is set

Command (m for help): p

Disk /dev/sdb: 21.5 GB, 21474836480 bytes, 41943040 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk label type: dos
Disk identifier: 0xabc7f208

Device Boot Start End Blocks Id System
/dev/sdb1 2048 2099199 1048576 83 Linux
/dev/sdb2 2099200 23070719 10485760 5 Extended
/dev/sdb5 2101248 12587007 5242880 83 Linux
/dev/sdb6 12589056 23070719 5240832 83 Linux

Command (m for help):

从上面的步骤,创建了两个主分区(包含扩展分区) 和两个逻辑分区 ,逻辑分区的空间是扩展分区的空间。
当规划完3个主分区后,剩余的空间最好全部分配给扩展分区,以免浪费。

创建完你需要的分区 用w保存
保存后 用lsblk查看当前磁盘情况
Command (m for help): w
The partition table has been altered!

Calling ioctl() to re-read partition table.
Syncing disks.
[root@server ~]# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 20G 0 disk
├─sda1 8:1 0 500M 0 part /boot
└─sda2 8:2 0 19.5G 0 part
├─centos-root 253:0 0 17.5G 0 lvm /
└─centos-swap 253:1 0 2G 0 lvm [SWAP]
sdb 8:16 0 20G 0 disk
├─sdb1 8:17 0 1G 0 part <1G 的主分区>
├─sdb2 8:18 0 1K 0 part
├─sdb5 8:21 0 5G 0 part
└─sdb6 8:22 0 5G 0 part

用lsblk 查看磁盘信息 可以看的出来,逻辑分区的序号从5开始

如果发现自己规划的不是很完美可以用d 来删除
[root@server ~]# fdisk /dev/sdb
Welcome to fdisk (util-linux 2.23.2).

Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.

Command (m for help): d
Partition number (1,2,5,6, default 6): 6
<1是主分区,2是扩展分区,5,6是逻辑分区>
Partition 6 is deleted

Command (m for help): d
Partition number (1,2,5, default 5): 5
Partition 5 is deleted

Command (m for help): d
Partition number (1,2, default 2):
Partition 2 is deleted

Command (m for help): p

Disk /dev/sdb: 21.5 GB, 21474836480 bytes, 41943040 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk label type: dos
Disk identifier: 0xabc7f208

Device Boot Start End Blocks Id System
/dev/sdb1 2048 2099199 1048576 83 Linux

Command (m for help):

重新规划后创建了三个主分区一个扩展分区,三个逻辑分区
[root@server ~]# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 20G 0 disk
├─sda1 8:1 0 500M 0 part /boot
└─sda2 8:2 0 19.5G 0 part
├─centos-root 253:0 0 17.5G 0 lvm /
└─centos-swap 253:1 0 2G 0 lvm [SWAP]
sdb 8:16 0 20G 0 disk
├─sdb1 8:17 0 1G 0 part
├─sdb2 8:18 0 2G 0 part
├─sdb3 8:19 0 2G 0 part
├─sdb4 8:20 0 1K 0 part
├─sdb5 8:21 0 5G 0 part
├─sdb6 8:22 0 5G 0 part
└─sdb7 8:23 0 5G 0 part

8.3.3 gdisk的使用
gdisk磁盘管理工具,是针对GPT而开发的,也只能对GPT格式分区才能使用,对于MBR是没什么用的。
gdisk的使用方法跟fdisk很相似,进入到交互界面用使用“?”查看帮助
[root@server ~]# gdisk /dev/sdb
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): ?
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

Command (? for help):
创建一个分区
Command (? for help): n
Partition number (1-128, default 1): <上限128>
First sector (34-41943006, default = 2048) or {+-}size{KMGTP}:
Last sector (2048-41943006, default = 41943006) or {+-}size{KMGTP}: +1G
Current type is 'Linux filesystem' <默认的格式是 linux filesystem>
Hex code or GUID (L to show codes, Enter = 8300):
Changed type of partition to 'Linux filesystem'

Command (? for help): p
Disk /dev/sdb: 41943040 sectors, 20.0 GiB
Logical sector size: 512 bytes
Disk identifier (GUID): 47381B75-C564-4531-9C82-CFC72A1B7A65
Partition table holds up to 128 entries
First usable sector is 34, last usable sector is 41943006
Partitions will be aligned on 2048-sector boundaries
Total free space is 39845821 sectors (19.0 GiB)

Number Start (sector) End (sector) Size Code Name
1 2048 2099199 1024.0 MiB 8300 Linux filesystem

Command (? for help): w <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/sdb.
The operation has completed successfully.
创建一个分区,用lsblk查看是否创建成功
[root@server ~]# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 20G 0 disk
├─sda1 8:1 0 500M 0 part /boot
└─sda2 8:2 0 19.5G 0 part
├─centos-root 253:0 0 17.5G 0 lvm /
└─centos-swap 253:1 0 2G 0 lvm [SWAP]
sdb 8:16 0 20G 0 disk
└─sdb1 8:17 0 1G 0 part
GPT分区的上限是128已经能满足普通使用了,分区的默认标识是8300 Linux filesystem。
gdisk其他的操作与fdisk很类似,在上一小节详细的讲过了,gdisk就由你们自己慢慢体验了。
8.3.4 parted的使用
在工作中常用的磁盘工具,支持超大的磁盘(2TB以上)分区,可以用与MBR/GPT,下面来学习parted的使用。
[root@server ~]# parted /dev/sdb
GNU Parted 3.1
Using /dev/sdb
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted)
这就是parted 的交互界面
使用 help来查看帮助
(parted) help
align-check TYPE N check partition N for TYPE(min|opt)
alignment
help [COMMAND] print general help, or help on COMMAND
mklabel,mktable LABEL-TYPE create a new disklabel (partition table)
mkpart PART-TYPE [FS-TYPE] START END make a partition
name NUMBER NAME name partition NUMBER as NAME
print [devices|free|list,all|NUMBER] display the partition table, available
devices, free space, all found partitions, or a particular partition
quit exit program
rescue START END rescue a lost partition near START and END
rm NUMBER delete partition NUMBER
select DEVICE choose the device to edit
disk_set FLAG STATE change the FLAG on selected device
disk_toggle [FLAG] toggle the state of FLAG on selected device
set NUMBER FLAG STATE change the FLAG on partition NUMBER
toggle [NUMBER [FLAG]] toggle the state of FLAG on partition
NUMBER
unit UNIT set the default unit to UNIT
version display the version number and copyright
information of GNU Parted
(parted)
在交互界面 使用p可以查看单个磁盘的信息
(parted) p
Model: VMware, VMware Virtual S (scsi)
Disk /dev/sdb: 21.5GB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags:

Number Start End Size File system Name Flags
1 1049kB 1075MB 1074MB Linux filesystem
使用parted -l可以查看所有磁盘信息
[root@server ~]# parted -l
Model: VMware, VMware Virtual S (scsi)
Disk /dev/sda: 21.5GB
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Disk Flags:

Number Start End Size Type File system Flags
1 1049kB 525MB 524MB primary xfs boot
2 525MB 21.5GB 20.9GB primary lvm

Model: VMware, VMware Virtual S (scsi)
Disk /dev/sdb: 21.5GB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags:

Number Start End Size File system Name Flags
1 1049kB 1075MB 1074MB Linux filesystem

Model: Linux device-mapper (linear) (dm)
Disk /dev/mapper/centos-swap: 2147MB
Sector size (logical/physical): 512B/512B
Partition Table: loop
Disk Flags:

Number Start End Size File system Flags
1 0.00B 2147MB 2147MB linux-swap(v1)

Model: Linux device-mapper (linear) (dm)
Disk /dev/mapper/centos-root: 18.8GB
Sector size (logical/physical): 512B/512B
Partition Table: loop
Disk Flags:

Number Start End Size File system Flags
1 0.00B 18.8GB 18.8GB xfs

Warning: Unable to open /dev/sr0 read-write (Read-only file system). /dev/sr0
has been opened read-only.
Model: NECVMWar VMware IDE CDR10 (scsi)
Disk /dev/sr0: 4330MB
Sector size (logical/physical): 2048B/2048B
Partition Table: msdos
Disk Flags:

Number Start End Size Type File system Flags
2 4563kB 30.2MB 25.7MB primary
简单的使用parted工具
[root@server ~]# parted /dev/sdb
GNU Parted 3.1 <parted的软件版本号>
Using /dev/sdb <将对这个磁盘进行操作>
Welcome to GNU Parted! Type 'help' to view a list of commands.<欢迎信息>
(parted) p <p 查看分区信息>
Model: VMware, VMware Virtual S (scsi)
Disk /dev/sdb: 21.5GB
Sector size (logical/physical): 512B/512B
Partition Table: pc98
Disk Flags:

Number Start End Size File system Name Flags

(parted) mklabel <修改分区标签>
New disk label type? gpt
Warning: The existing disk label on /dev/sdb will be destroyed and all data on this
disk will be lost. Do you want to continue?
Yes/No? yes
(parted) p
Model: VMware, VMware Virtual S (scsi)
Disk /dev/sdb: 21.5GB
Sector size (logical/physical): 512B/512B
Partition Table: gpt <修改成功>
Disk Flags:

Number Start End Size File system Name Flags

(parted) mkpart
Partition name? []? gpt2t <指定分区名字>
File system type? [ext2]? ext3 <指定分区文件系统>
Start? 1 <指定分区开始位置>
End? 2GB <指定分区结束位置>
(parted) p
Model: VMware, VMware Virtual S (scsi)
Disk /dev/sdb: 21.5GB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags:

Number Start End Size File system Name Flags
1 1049kB 2000MB 1999MB gpt2t

(parted) q <退出>
Information: You may need to update /etc/fstab.

深入使用parted工具
[root@server ~]# parted /dev/sdb
GNU Parted 3.1
Using /dev/sdb
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted) p
Model: VMware, VMware Virtual S (scsi) <显示磁盘类型为scsi磁盘>
Disk /dev/sdb: 21.5GB <磁盘大小为21.5GB>
Sector size (logical/physical): 512B/512B <扇区大小为512B>
Partition Table: gpt
Disk Flags:

Number Start End Size File system Name Flags

(parted) mkpart
Partition name? []? part1 <创建分区>
File system type? [ext2]? ext2 <设定分区名称>
Start? 1 <指定起始位置>
End? 1G <指定终止位置>
(parted) mkpart
Partition name? []? part2
File system type? [ext2]? ext3
Start? 1.1G
End? 2G
(parted) mkpart
Partition name? []? part3
File system type? [ext2]? ext4
Start? 2.1G
End? -1
(parted) p
Model: VMware, VMware Virtual S (scsi)
Disk /dev/sdb: 21.5GB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags:

Number Start End Size File system Name Flags
1 1049kB 1000MB 999MB part1
2 1000MB 2000MB 999MB part2
3 2000MB 21.5GB 19.5GB part3

(parted) rm 3 <删除分区3>
(parted) p <再次查看分区状态>
Model: VMware, VMware Virtual S (scsi)
Disk /dev/sdb: 21.5GB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags:
<显示分区删除成功,剩下两个>
Number Start End Size File system Name Flags
1 1049kB 1000MB 999MB part1
2 1000MB 2000MB 999MB part2

(parted) q
Information: You may need to update /etc/fstab.

parted磁盘工具使用也比较简单,忘记了一些命令用help查看帮助,既然分区好了 那就要使用了,使用之前我们还需要做一件事,那就是格式化。

8.4 分区格式化
8.4.1文件系统
文件系统是操作系统用于明确存储设备或分区上的文件的方法和数据结构;即在存储设备上组织文件的方法。操作系统中负责管理和存储文件信息的软件机构称为文件管理系统,简称文件系统。
文件系统由三部分组成:文件系统的接口,对对象操纵和管理的软件集合,对象及属性。从系统角度来看,文件系统是对文件存储设备的空间进行组织和分配,负责文件存储并对存入的文件进行保护和检索的系统。
简单的来说文件系统是在磁盘或分区组织存储文件或数据的方法和格式。
文件系统有很多类型:
表8.4.1 Linux文件系统类型介绍
名称 文件系统详细描述
Vfat 是Linux对Dos、windows系统下的FAT(包括FAT16和FAT32)文件系统的一个统称。
ext 第一个专门为Linux设计的文件系统类型,称为扩展文件系统。
由于在稳定性、速度和兼容性方面存在许多缺陷,现已很少使用。
ext2 称为二级扩展文件系统。1993年发布,专门为Linux设计的
在速度和CPU利用率上具有较突出的优势,是GNU/Linux系统中标准的文件系统,支持256字节的长文件名,文件存取性能极好。
ext2既可用于块设备(如硬盘),也被用在软盘等移动存储设备上
Ext3 第3代扩展(Extended)文件系统,是Red Hat Linux 7.2版本以后ext2的升级版本,兼容ext2
增加了文件系统日志记录功能,称为日志式文件系统
是目前Linux默认采用的文件系统。最大支持8TB的分区。
RHEL5经过优化,最大支持16T的分区
ext4 是下一代文件系统,理论支持1024PB大小(1PB=1024TB)的存贮设备,支持文件的连续写入,减少文件碎片,提高磁盘的读写性能
swap 使用交换分区来提供虚拟内存,大小一般是系统物理内存的2倍。
在安装Linux操作系统时创建
由操作系统自行管理。
ReiserFS 是基于平衡树的文件系统结构,尤其对于大量文件的巨型文件系统,如服务器上的文件系统,搜索速度要比ext2快;ext2使用局部的二分查找法,综合性能比不上ReiserFS。
XFS 64 位日志文件系统。最初是由 Silicon Graphics,Inc. 于 90 年代初开发的。
JFS IBM 企业服务器使用的企业级日志文件系统
nfs 即网络文件系统,用于在Unix系统间通过网络进行文件共享,用户可将网络中NFS服务器提供的共享目录,挂载到本地的文件目录中,从而实现操作和访问NFS文件系统中的内容。
iso9660 是光盘所使用的标准文件系统,Linux对该文件系统也有很好的支持,不仅能读取光盘和光盘ISO映像文件,而且还支持刻录光盘。
ntfs WinNT/2000/2003使用的文件系统
我们常用的就两种,xfs和ext4类型。
8.4.2 xfs与ext4文件系统
xfs一种高性能的日志文件系统,最早于1993年,由Silicon Graphics为他们的IRIX操作系统而开发,是IRIX 5.3版的默认文件系统。2000年5月,Silicon Graphics以GNU通用公共许可证发布这套系统的源代码,之后被移植到Linux 内核上。xfs 特别擅长处理大文件,同时提供平滑的数据传输。
为什么xfs开发了那么久还那么受欢迎呢? 因为xfs为 Linux提供了一种健壮的、优秀的以及功能丰富的文件系统,并且这种文件系统所具有的可伸缩性能够满足最苛刻的存储需求。
使用mkfs命令将分区转换为xfs文件系统
[root@server ~]# mkfs -t xfs /dev/sdb2
meta-data=/dev/sdb2 isize=256 agcount=4, agsize=60992 blks
= sectsz=512 attr=2, projid32bit=1
= crc=0 finobt=0
data = bsize=4096 blocks=243968, imaxpct=25
= sunit=0 swidth=0 blks
naming =version 2 bsize=4096 ascii-ci=0 ftype=0
log =internal log bsize=4096 blocks=853, version=2
= sectsz=512 sunit=0 blks, lazy-count=1
realtime =none extsz=4096 blocks=0, rtextents=0
[root@server ~]#
ext4是继承了ext3的文件系统,第四代扩展文件系统,并嵌入在Linux内核中,所以不需要安装包就可以使用。
和xfs文件系统一样,使用mkfs工具就可以将分区转换成ext4
[root@server ~]# mkfs -t ext4 /dev/sdb3
mke2fs 1.42.9 (28-Dec-2013)
Filesystem label=
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
Stride=0 blocks, Stripe width=0 blocks
65536 inodes, 262144 blocks
13107 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=268435456
8 block groups
32768 blocks per group, 32768 fragments per group
8192 inodes per group
Superblock backups stored on blocks:
32768, 98304, 163840, 229376

Allocating group tables: done
Writing inode tables: done
Creating journal (8192 blocks): done
Writing superblocks and filesystem accounting information: done

[root@server ~]#

8.5 分区挂载
8.5.1 手动挂载
磁盘进行分区,格式化,我们想使用这个分区要怎么做呢?不像windows一样,可以直接使用,linux 中需要挂载才能使用。
首先要创建一个挂载点。
[root@server ~]# mkdir xfs
[root@server ~]# ls
anaconda-ks.cfg Documents Music Public Videos
Desktop Downloads Pictures Templates xfs
然后利用mount工具挂载到挂载点上
[root@server ~]# mount /dev/sdb3 xfs
挂载成功
[root@server ~]# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 20G 0 disk
├─sda1 8:1 0 500M 0 part
└─sda2 8:2 0 19.5G 0 part
├─centos-root 253:0 0 17.5G 0 lvm /
└─centos-swap 253:1 0 2G 0 lvm [SWAP]
sdb 8:16 0 20G 0 disk
├─sdb1 8:17 0 953M 0 part
├─sdb2 8:18 0 953M 0 part
└─sdb3 8:19 0 1G 0 part /root/xfs
 <挂载点上出现了挂载目录,表示挂载成功>
在这个目录上写入数据的时候,就会将数据写入到sdb3这个分区

8.5.2 自动挂载
手动挂载有个缺点,那就是重启后就会断开挂载,那么为了下次开机能正常使用,就只能用别的办法了。
那就是写入文件了,开机挂载的文件 /etc/fstab

/etc/fstab

Created by anaconda on Mon Dec 5 20:24:55 2016

#

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

#
/dev/mapper/centos-root / xfs defaults 0 0
/dev/mapper/centos-swap swap swap defaults 0 0
其实这个 /etc/fstab 就是将我们使用 mount 来挂载一个装置到系统的某个挂载点, 所需要下达的指令内容,将这些内容通通写到 /etc/fstab 里面去,而让系统一开机就主动挂载。
那么 mount 下达指令时,需要哪些参数?
/dev/sdb3 /root/ext4 ext4 defaults 0 0
分区 挂载点 文件系统类型 参数 dump备份 fsck扫描磁盘
前面的4个已经很熟悉了,每个档案系统还有很多参数可以加入的,例如中文编码的 iocharset=big5,codepage=950 之类的,当然还有很多常见的参数,具体可以看mount中的详细介绍。
具体说一下后2个:dump和fsck。
是否dump备份指令作用:
在 Linux当中,可以利用dump这个指令来进行系统的备份。
而 dump 指令则会针对 /etc/fstab 的设定值,去选择是否要将该 partition 进行备份的动作,0代表不要做dump备份,1代表要进行dump的动作。2 也代表要做dump备份动作,不过该 partition 重要度比1小。
是否以fsck检验扇区:
开机的过程中,系统预设会以 fsck 检验我们的 partition 内的 filesystem 是否完整 (clean)。不过,某些 filesystem 是不需要检验的,例如虚拟内存 swap ,或者是特殊档案系统,例如 /proc 与 /sys 等等。
所以在这个字段中,我们可以设定是否要以fsck检验该 filesystem。0 是不要检验, 1 是要检验, 2 也是要检验,不过 1 会比较早被检验 一般来说,都不需要检验。

一般来说, 当我们编辑 /etc/fstab 后,为了避免可能的错误,通常就会以 mount -a (模拟开机自动挂载操作)这个指令来测试是否能正常挂载。这是很重要的一个测试动作。
如果有错误,会这样提示。
[root@server ~]# mount -a
mount: wrong fs type, bad option, bad superblock on /dev/sdb3,
missing codepage or helper program, or other error

   In some cases useful info is found in syslog - try
   dmesg | tail or so.

8.6 逻辑卷管理
8.6.1 LVM是什么?
LVM(Logical Volume Manager)逻辑卷管理,是Linux对磁盘分区管理的一种机制。
Linux用户安装Linux时容易错误的评估分区大小,容易导致空间不够,或者空间剩太多,导致资源浪费,普通的磁盘分区管理方式在逻辑分区划分好之后就无法改变其大小,当一个逻辑分区存放不下某个文件时,这个文件因为受上层文件系统的限制,也不能跨越多个分区来存放,所以也不能同时放到别的磁盘上。
如果要扩充的话,只能换一个更大块的磁盘,然后分区,格式化,数据备份,再copy过去。一不小心又太大了,再把上面的步骤再来一次。多麻烦啊!
LVM的重点在于 可以弹性的调整filesystem的容量。而且,还可以整合多个磁盘,让多块大小不同的磁盘整合成一块,如此看来LVM是非常方便好用的。
下面就来学习LVM。
8.6.2 PV/VG/LV的使用
在学习LVM之前,需要了解PV,PE,VG.LV是什么。
图8.6.2 LVM框架
PV(physical volume):物理卷
物理卷在逻辑卷管理系统最底层,可为整个物理硬盘或实际物理硬盘上的分区。
VG(volume group):卷群组
卷组建立在物理卷上,一卷组中至少要包括一物理卷,卷组建立后可动态的添加卷到卷组中,一个逻辑卷管理系统工程中可有多个卷组。
LV(logical volume):逻辑卷
逻辑卷建立在卷组基础上,卷组中未分配空间可用于建立新的逻辑卷,逻辑卷建立后可以动态扩展和缩小空间。
PE(physical extent):物理卷单元块
物理区域是物理卷中可用于分配的最小存储单元,物理区域大小在建立卷组时指定,一旦确定不能更改,同一卷组所有物理卷的物理区域大小需一致,新的pv加入到vg后,pe的大小自动更改为vg中定义的pe大小。

基本的原理讲解完了,那么就开始学习如何使用LVM。
1.准备物理分区(Physical Partions)
首先,我们需要选择用于 LVM 的物理存储器。这些通常是标准分区,但也可以是已创建的 Linux Software RAID 卷。这里我利用fdisk命令,将sdb、sdc两块磁盘分了两个区sdb1、sdc1, 通过fdisk的t指令指定分区为8e类型(Linux LVM) 。

2.创建物理卷PV(Physical Volumes)
物理卷(Physical Volumes)简称PV,是在磁盘的物理分区或与磁盘分区具有同样功能的设备(如RAID)上创建而来。它只是在物理分区中划出了一个特殊的区域,用于记载与LVM相关的管理参数。
创建物理卷的命令是 pvcreate :
[root@server ~]# pvcreate /dev/sdb1
Physical volume "/dev/sdb1" successfully created
[root@server ~]# pvcreate /dev/sdc1
Physical volume "/dev/sdc1" successfully created
以上命令分别将/dev/sdc1、/dev/sdd1初始化成物理卷,使用物理卷显示命令pvdisplay查看物理卷情况如下:
[root@server ~]# pvdisplay
--- NEW Physical volume ---
PV Name /dev/sdb1
VG Name
PV Size 36.00 GB
Allocatable NO
PE Size (KByte) 0
Total PE 0
Free PE 0
Allocated PE 0
PV UUID QDmnUd-tuvH-U4Hn-n5Ry-zGRT-O1yK-67Dxbb
--- NEW Physical volume ---
PV Name /dev/sdc1
VG Name
PV Size 36.00 GB
Allocatable NO
PE Size (KByte) 0
Total PE 0
Free PE 0
Allocated PE 0
PV UUID NDBf68-6qrD-9hE6-Rotv-RdxL-Azvv-7NlC0S

3.创建卷组VG(Volume Groups)
卷组(Volume Group)简称VG,它是一个或者多个物理卷的组合。卷组将多个物理卷组合在一起,形成一个可管理的单元,它类似于非LVM系统中的物理硬盘。
创建卷组的命令为vgcreate,下面利用它创建了一个名为“lvmdisk”的卷组,该卷组包含/dev/sdb1、/dev/sdc1两个物理卷。
[root@server ~]# vgcreate lvmdisk /dev/sdb1 /dev/sdc1
Volume group "lvmdisk" successfully created
使用卷组查看命令vgdisplay显示卷组情况:
[root@server ~]# vgdisplay
--- Volume group ---
VG Name lvmdisk
System ID
Format lvm2
Metadata Areas 2
Metadata Sequence No 1
VG Access read/write
VG Status resizable
MAX LV 0
Cur LV 0
Open LV 0
Max PV 0
Cur PV 2
Act PV 2
VG Size 71.98 GB
PE Size 4.00 MB
Total PE 18428
Alloc PE / Size 0 / 0
Free PE / Size 18428 / 71.98 GB
VG UUID SARfuj-wAUI-od81-VWAc-A1nt-aaFN-JWaPVf
当多个物理卷组合成一个卷组后时,LVM会在所有的物理卷上做类似格式化的工作,将每个物理卷切成一块一块的空间,这一块一块的空间就称为PE(Physical Extent ),它的默认大小是4MB。
由于受内核限制的原因,一个逻辑卷(Logic Volume)最多只能包含65536个PE(Physical Extent),所以一个PE的大小就决定了逻辑卷的最大容量,4 MB 的PE决定了单个逻辑卷最大容量为 256 GB,若希望使用大于256G的逻辑卷,则创建卷组时需要指定更大的PE。在Red Hat Enterprise Linux AS 4中PE大小范围为8 KB 到 16GB,并且必须总是 2 的倍数。
例如,如果希望使用 64 MB 的PE创建卷组,这样逻辑卷最大容量就可以为4 TB,命令如下:

vgcreate - 64MB lvmdisk /dev/sdb1 /dev/sdc1

4.创建逻辑卷LV(Logical Volumes)
逻辑卷(Logical Volumes)简称LV,是在卷组中划分的一个逻辑区域,类似于非LVM系统中的硬盘分区。
创建逻辑卷的命令为lvcreate,通过下面的命令,我们在卷组lvmdisk上创建了一个名字为pldy1的逻辑卷,大小为15GB,其设备入口为/dev/lvmdisk/pldy1。
[root@server dev]# lvcreate -L 15G -n pldy1 lvmdisk
Logical volume "pldy1" created
也可以使用-l参数,通过指定PE数来设定逻辑分区大小。
例如,希望创建一个使用全部空间的逻辑卷,需要先查清卷组中的PE总数,通过上面的vgdisplay命令查得当前卷组PE总数为18428,命令如下:

lvcreate -l 18428 -n pldy1 lvmdisk

当逻辑卷创建成功后,可以使用lvdisplay命令查看逻辑卷情况:
[root@server ~]# lvdisplay
--- Logical volume ---
LV Name /dev/lvmdisk/pldy1
VG Name lvmdisk
LV UUID FQcnm3-BMyq-NkJz-hykw-9xg1-Qy8d-8UeGCN
LV Write Access read/write
LV Status available

open 0

LV Size 15.00 GB
Current LE 3840
Segments 1
Allocation inherit
Read ahead sectors 0
Block device 253:0
同卷组一样,逻辑卷在创建的过程中也被分成了一块一块的空间,这些空间称为LE(Logical Extents),在同一个卷组中,LE的大小和PE是相同的,并且一一对应。

5.创建文件系统
在逻辑卷上创建ext3文件系统:
[root@server ~]# mkfs -t ext3 /dev/lvmdisk/pldy1
创建了文件系统以后,就可以加载并使用了:
[root@server ~]# mkdir /opt/Oracle
[root@server ~]# mount /dev/lvmdisk/pldy1 /opt/Oracle
为了在系统启动时自动加载文件系统,则还需要在/etc/fstab中添加内容:
/dev/lvmdisk/pldy1 /opt/Oracle ext3 defaults 1 2
管理LVM
LVM的最大好处就是可以动态地调整分区大小,而无须重新启动机器,下面让我们来体验一下吧!继续上面的实例,现假设逻辑卷/dev/lvmdisk/pldy1空间不足,需要增加其大小,我们分两种情况讨论:

1.卷组中有剩余的空间
通过vgdisplay命令可以检查当前卷组空间使用情况:
[root@server ~]# vgdisplay
--- Volume group ---
VG Name lvmdisk
System ID
Format lvm2
Metadata Areas 2
Metadata Sequence No 2
VG Access read/write
VG Status resizable
MAX LV 0
Cur LV 1
Open LV 0
Max PV 0
Cur PV 2
Act PV 2
VG Size 71.98 GB
PE Size 4.00 MB
Total PE 18428
Alloc PE / Size 3840 / 15.00 GB
Free PE / Size 14588 / 56.98 GB
VG UUID SARfuj-wAUI-od81-VWAc-A1nt-aaFN-JWaPVf
确定当前卷组剩余空间56.98GB,剩余PE数量为14588个。在这里将所有的剩余空间全部增加给逻辑卷 /dev/lvmdisk/pldy1。
[root@server Oracle]# lvextend -l+14588 /dev/lvmdisk/pldy1
Extending logical volume pldy1 to 56.98 GB
Logical volume pldy1 successfully resized
上面的命令使用了-l+14588参数,它的意思是给指定的逻辑卷增加14588个PE。如果不是将全部空间都使用,还可使用其他形式的lvextend命令。
例如将逻辑卷/dev/lvmdisk/pldy1增加5GB的空间,使其空间达到20GB,可写成:

lvextend -L+5G /dev/lvmdisk/pldy1

lvextend -L 20G /dev/lvmdisk/pldy1

增加了逻辑卷容量后,就要通过ext2online命令刷新文件系统的大小了。
[root@server ~]# ext2online /opt/Oracle/
转换好后,让我们查看一下文件系统的当前状态:
[root@server ~]# df -lh
Filesystem 1k-blocks Used Available Use% Mounted on
/dev/sda1 7.4G 1.8G 5.3G 25% /
none 135M 0 135M 0% /dev/shm
/dev/mapper/lvmdisk-pldy1 71G 81M 68G 1% /opt/Oracle

2.卷组中空间不足
当卷组中没有足够的空间用于扩展逻辑卷的大小时,就需要增加卷组的容量,而增加卷组容量的惟一办法就是向卷组中添加新的物理卷。
首先是增加一块新硬盘(36GB SCSI 硬盘),并对其完成分区、创建物理卷等工作。接下来是利用vgextend命令将新的物理卷(/dev/sdd1)加入到卷组中。
扩展卷组的命令如下:
[root@server ~]# vgextend lvmdisk /dev/sdd1
Volume group "lvmdisk" successfully extended
利用vgdisplay命令查看卷组lvmdisk的情况:
[root@server ~]# vgdisplay
--- Volume group ---
VG Name lvmdisk
System ID
Format lvm2
Metadata Areas 3
Metadata Sequence No 3
VG Access read/write
VG Status resizable
MAX LV 0
Cur LV 1
Open LV 0
Max PV 0
Cur PV 3
Act PV 3
VG Size 107.97 GB
PE Size 4.00 MB
Total PE 27640
Alloc PE / Size 3840 / 15.00 GB
Free PE / Size 23800 / 92.97 GB
VG UUID l8YPvz-uD7h-oj1A-0qS5-TFcT-mbC7-QbjzCu
完成卷组的扩容后,就可以按照第一种情况的方法完成逻辑卷的扩容,最终实现分区的动态调整。

第九章进程管理
学习目标:
理解进程的概念
理解子进程、父进程
熟练掌握ps、pstree、top命令查看进程
熟练掌握free、uname、uptime、netstat监控进程活动
9.1.、进程的概述
9.1.1进程,究竟什么是进程呢?
在 Linux 系统当中:触发任何一个事件时,系统都会将他定义成为一个程序,并且给予这个程序一个 ID ,称为 PID,同时依据启发这个程序的使用者与相关属性关系,给予这个 PID 一组有效的权限设定。从此以后,这个 PID 能够在系统上面进行的动作,就与这个 PID 的权限有关了。
一个应用程序被触发(执行),就会对这个程序产生相对应的进程。也就是已启动可执行程序的运行中实例。一个进程被触发,那么该进程的拥有者就是触发该进程的用户,进程的权限也就是触发进程用户的权限。
9.1.2程序与执行文件
我们如何产生一个 Process ID (PID) 呢?其实很简单啦,就是执行一个程序或指令就可以触发一个事件了而取得一个PID。系统仅认识 binary file (二进制文件),系统工作的时候启动的binaryfile,就是一个程序。

9.2、父进程和子进程
在我们登入系统后,会取得一个 bash 的 shell ,然后,我们用这个 bash 提供的接口去执行另一个指令,例如 /usr/bin/passwd 或者是 touch 等等,那些另外执行的指令也会被触发成为PID,这个PID 就是子程序,而在我们的 bash 环境下,就称为父程序了。
在系统上面的各个程序可能是有相关性,也就是有所谓的父程序与子程序的关系,至于程序的相关性,我们可以使用 pstree 程序去查验,就能知道彼此之间的关系了。如何pstree使用查验进程间的关系,在本章后面将会在详细的说明。

9.3、在linux系统中进程的四种状态
名称 标志 描述
运行中 R TASK_RUNNING:进程正在CPU上执行,或者正在等待运行

睡眠 S TASK_INTERRUPTIBLE:进程等待某一条件:硬件请求、系统资源访问或信号。
D TASK_UNINTERRUPTITBLE:此进程处于不会响应传递信号的睡眠状态。
K TASK_KILLABLE:允许等待中的任务通过响应信号而被中断(彻底退出)。

已停止 T TASK_STOPPED:进程已被停止或暂停
T TASK_TRACED:正在被调试的进程也会临时停止,并且共享同一个T状态标志。

僵停 Z EXIT_ZOMBIE:子进程在退出时向父进程发出信号。除PID外的所有资源都已释放。
X EXIT_DEAD:当父进程清理剩余的子进程的结构时,进程现在已彻底释放。
注意:
在linux系统的四种进程状态中,有以下几个算是比较危险的。分别是Z、K、D、X;当出现这四种情况的时候你就需要特别注意了。

9.4、在linux系统中使用ps、pstree、top去查看进程
9.4.1、ps命令:
当需要查看系统中执行的的程序时,ps虽然不是唯一的命令,但是绝对是使用最频繁的命令。
下面表格是与ps结合使用的一些参数:
参数 含义
a 显示在终端机下的所有程序
-A 显示所有程序
c 列出程序时,显示每个程序的真正指令名称
-e 与-A相同
e 列出程序时,显示每个程序所使用的环境变量
f 用ASCII字符显示树状结构
u 以用户为主的格式来显示程序状况
s 采用程序信号的格式来显示程序状况
-l 长格式
-m 显示所有的线程
案列1:
利用ps –l来查看进程

F 代表这个程序的旗标(flag);4代表的是超级用户
S 代表这个程序的状态
PID 程序的ID
C CPU使用的资源百分比
PRI Priority的缩写,优先级;数值越小越早被执行
NI Nice值
ADDR Kernelfunction,指出该程序在内存的那个部分;如果程序running,一般是“-“
SZ 使用掉的内存大小
WCHAH 程序是否正在运行,“-” 表示正在运行
TTY 登入者的终端机位置
TIME 使用掉的CPU时间

案列2:
多个参数与ps结合使用

案例3:
管道“|”和more与ps的结合使用

[root@server ~]# ps -elf | more
F S UID PID PPID C PRI NI ADDR SZ WCHAN STIME TTY TIME CMD
4 S root 1 0 0 80 0 - 31484 ep_pol 06:42 ? 00:00:07 /usr/lib/system
d/systemd --system --deserialize 25
1 S root 2 0 0 80 0 - 0 kthrea 06:42 ? 00:00:00 [kthreadd]
1 S root 3 2 0 80 0 - 0 smpboo 06:42 ? 00:00:03 [ksoftirqd/0]
1 S root 7 2 0 -40 - - 0 smpboo 06:42 ? 00:00:00 [migration/0]
1 S root 8 2 0 80 0 - 0 rcu_gp 06:42 ? 00:00:00 [rcu_bh]
1 S root 9 2 0 80 0 - 0 rcu_no 06:42 ? 00:00:00 [rcuob/0]
1 S root 10 2 0 80 0 - 0 rcu_no 06:42 ? 00:00:00 [rcuob/1]
1 S root 11 2 0 80 0 - 0 rcu_no 06:42 ? 00:00:00 [rcuob/2]
1 S root 12 2 0 80 0 - 0 rcu_no 06:42 ? 00:00:00 [rcuob/3]
1 S root 13 2 0 80 0 - 0 rcu_no 06:42 ? 00:00:00 [rcuob/4]
--More--

9.4.2、pstree命令
功能:以树状图的形式来显示进程之间的关系
语法:pstree [-acGhlnpuUV][-H <程序识别码>][<程序识别码>/<用户名称>]
注意:
pstree指令用ASCII字符显示树状结构,清楚地表达程序间的相互关系。如果不指定程序识别码或用户名称,则会把系统启动时的第一个程序视为基层,并显示之后的所有程序。若指定用户名称,便会以隶属该用户的第一个程序当作基层,然后显示该用户的所有程序。
参数:
-a 显示每个程序的完整指令,包含路径,参数或是常驻服务的标示
-c 不使用精简标示法
-G 使用VT100终端机的列绘图字符。
-h 列出树状图时,特别标明现在执行的程序
-H <程序识别码> 此参数的效果和指定”-h”参数类似,但特别标明指定的程序。
-l 采用长列格式显示树状图。
-n 用程序识别码排序。预设是以程序名称来排序。
-p 显示程序识别码。
-u 显示用户名称。
-U 使用UTF-8列绘图字符。
-V 显示版本信息。
-A 各程序树之间的连接以ASCII字符来连接

案例1:
在本章的开头有提到子进程与父进程,那么如何清楚地查验子进程和父进程的关系呢?没错,我们可以使用pstree这个程序来查验,让其以树状图的形式更直观地告诉我们子进程和父进程的关系。
[root@server ~]# pstree -A |grep ping
|-sshd---sshd-+-bash---ping
我们用一个简单的ping进程来描述,ping这个子进程的父进程就是前方的bash进程。

案例2:
多个参数与pstree同时使用,通过pstree程序的树状图,我们能够更加清楚地看到进程与进程之间的关系;通过多个参数的结合使用,不仅看到了进程间的关系,同时也看到了PID,如括号内的845、906等等。
[root@server ~]# pstree -Aup
systemd(1)-+-NetworkManager(845)-+-{NetworkManager}(906)
| |-{NetworkManager}(917)
| -{NetworkManager}(920) |-abrt-watch-log(848) |-abrt-watch-log(851) |-abrtd(847) |-accounts-daemon(890)-+-{accounts-daemon}(899) |-{accounts-daemon}(919)
|-at-spi-bus-laun(1451,kiosk)-+-dbus-daemon(1455)---{dbus-daemon}(1457)
| |-{at-spi-bus-laun}(1452)
| |-{at-spi-bus-laun}(1454)
| -{at-spi-bus-laun}(1456) |-at-spi2-registr(1460,kiosk)---{at-spi2-registr}(1461) |-atd(1145) |-auditd(821)-+-audispd(829)-+-sedispatch(832) | |-{audispd}(833)
| -{auditd}(828) |-avahi-daemon(869,avahi)---avahi-daemon(883) |-bluetoothd(1633) |-chronyd(868,chrony) |-colord(1586,colord)-+-{colord}(1591) |-{colord}(1592)
9.4.3、top命令
简介:
top命令是Linux下常用的性能分析工具,能够实时显示系统中各个进程的资源占用状况,类似于Windows的任务管理器
top显示系统当前的进程和其他状况,是一个动态显示过程,即可以通过用户按键来不断刷新当前状态.如果在前台执行该命令,它将独占前台,直到用户终止该程序为止. 比较准确的说,top命令提供了实时的对系统处理器的状态监视.它将显示系统中CPU最“敏感”的任务列表.该命令可以按CPU使用.内存使用和执行时间对任务进行排序;而且该命令的很多特性都可以通过交互式命令或者在个人定制文件中进行设定。
1、top命令的格式
top [-] [d] [p] [q] [c] [C] [S] [n]
2、参数说明
d 指定每两次屏幕信息刷新之间的时间间隔。当然用户可以使用s交互命令来改变之
p 通过指定监控进程ID来仅仅监控某个进程的状态。
q 该选项将使top没有任何延迟的进行刷新。如果调用程序有超级用户权限,那么top将以尽可能高的优先级运行。
S 指定累计模式
s 使top命令在安全模式中运行。这将去除交互命令所带来的潜在危险。
i 使top不显示任何闲置或者僵死进程。
c 显示整个命令行而不只是显示命令名
3、在top命令的显示窗口,我们还可以输入以下字母,进行一些交互
M 根据驻留内存大小进行排序。
P 根据CPU使用百分比大小进行排序
T 根据时间/累计时间进行排序。
W 将当前设置写入~/.toprc文件中。这是写top配置文件的推荐方法。
I 切换显示平均负载和启动时间信息。即显示影藏第一行
q 退出程序。
i 忽略闲置和僵死进程。这是一个开关式命令。
k 终止一个进程。系统将提示用户输入需要终止的进程PID,以及需要发送给该进程什么样的信号。
t 切换显示进程和CPU状态信息。即显示影藏CPU行
一般来说,如果你想找出那个最损耗 CPU 资源的那个程序时,,大多使用的就是 top 这个程序。然后强制以 CPU 使用资源来排序 (在 top 当中按下 P 即可)。你能够清楚的看到进程最损耗CPU的为%1.3;如下所示:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
36647 root 20 0 146408 2340 1424 R 1.3 0.1 0:00.25 top
532 root 20 0 0 0 0 S 0.3 0.0 0:09.00 xfsaild/sda3
3554 loveq 20 0 378020 18836 14564 S 0.3 0.5 0:54.86 vmtoolsd

案例1:
单纯用top命令动态监测进程的状况
[root@server ~]# top
top - 08:04:55 up 13:34, 6 users, load average: 0.07, 0.07, 0.06
Tasks: 521 total, 2 running, 512 sleeping, 7 stopped, 0 zombie
%Cpu(s): 2.7 us, 2.7 sy, 0.0 ni, 94.7 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem : 8162368 total, 260496 free, 3809580 used, 4092292 buff/cache
KiB Swap: 8257532 total, 8253348 free, 4184 used. 4021496 avail Mem
TOP前五行统计信息:统计信息区前五行是系统整体的统计信息
4、第一行是任务队列信息:同 uptime 命令的执行结果
[root@server ~]# uptime
07:58:04up 13:27, 6 users, load average: 0.01, 0.02, 0.05
其内容如下:
07:58:04 当前时间
up 13:27 系统运行时间,格式为时:分
6 users 当前登录用户数
load average: 0.01, 0.02, 0.05 系统负载,即任务队列的平均长度。三个数值分别为 1分钟、5分钟、15分钟前到现在的平均值
5、第二、三行为进程和CPU的信息
当有多个CPU时,这些内容可能会超过两行。内容如下:
Tasks: 521 total 进程总数
2 running 正在运行的进程数
512 sleeping 睡眠的进程数
7 stopped 停止的进程数
0 zombie 僵尸进程数
%Cpu(s): 2.7 us 用户空间占用CPU百分比
2.7 sy 内核空间占用CPU百分比
0.0 ni 用户进程空间内改变过优先级的进程占用CPU百分比
94.7 id 空闲CPU百分比
0.0 wa 等待输入输出的CPU时间百分比
6、第四五行为内存信息。
Mem : 8162368 total 物理内存总量
260496 free 空闲内存总量
3809580 used, 空闲内存总量
4092292 buff/cache 用作内核缓存的内存量
Swap: 8257532 total 交换区总量
8253348 free 使用的交换区总量
4184 used 空闲交换区总量
4021496 avail Mem 缓冲的交换区总量。内存中的内容被换出到交换区,而后又被换入到内存,但使用过的交换区尚未被覆盖,该数值即为这些内容已存在于内存中的交换区的大小。相应的内存再次被换出时可不必再对交换区写入。

PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
36251 root 20 0 146408 2332 1424 R 1.3 0.1 0:01.98 top
1428 root 20 0 553036 16404 5732 S 0.3 0.4 0:06.49 tuned
17554 root 20 0 288596 9796 4024 S 0.3 0.3 0:01.46 docker-containe
1 root 20 0 125936 6516 3856 S 0.0 0.2 0:07.81 systemd
进程信息区统计信息区域的下方显示了各个进程的详细信息,具体如下表所示:
列名 含义
PID 进程id
PPID 父进程id
RUSER Real user name
UID 进程所有者的用户id
USER 进程所有者的用户名
GROUP 进程所有者的组名
TTY 启动进程的终端名.不是从终端启动的进程则显示为 ?
PR 优先级
NI nice值.负值表示高优先级,正值表示低优先级
P 最后使用的CPU,仅在多CPU环境下有意义
%CPU 上次更新到现在的CPU时间占用百分比
TIME 进程使用的CPU时间总计,单位秒
TIME+ 进程使用的CPU时间总计,单位1/100秒
%MEM 进程使用的物理内存百分比
VIRT 进程使用的虚拟内存总量,单位kb,VIRT=SWAP+RES
SWAP 进程使用的虚拟内存中,被换出的大小,单位kb.
RES 进程使用的、未被换出的物理内存大小,单位kb,RES=CODE+DATA
COMMAND 命令名/命令行
WCHAN 若该进程在睡眠,则显示睡眠中的系统函数名
Flags 任务标志
SHR 共享内存大小,单位kb

7、top –d n<n表示多少刷新一次>
案例:这里的案例刷新的时间的单位是秒(s),所以表示每个3s刷新一次
[root@server0 ~]# top -d 3
8、top -n n<n表示总共刷新几次>
案例:此案例表示总共刷新3次,而且刷新三次后就不然刷新了。
root@server0 ~]# top -n 3

9.5、bash环境下的工作管理
这个工作管理 (job control) 是用在 bash 环境下的,也就是说:当我们登入系统取得 bash shell 之后,在单一终端机接口下同时进行多个工作的行为管理。
终端(前景):您可以控制的这个工作称为终端的工作
后台(后景):在内存内可以自行运作的工作,您无法直接控制他,除非以 bg/fg 等指令将该工作调到终端上来。
如果想要同时进行多个工作,那么可以将某些工作丢到后台环境当中,让我们可以继续操作终端的工作。那么如何将工作丢到背景中?最简单的方法就是利用[ &]。
案例1:
[root@server ~]# cp /tmp/test /root/ &
[3] 38158
上面的例子就是把复制一个test文件的操作放到后台,从而我们不必等待指令结束才能在终端上操作。
9.5.1、观察目前的后台工作状态: jobs
jobs [-lrs]
参数:
-l :除了列出 job number 之外,同时列出 PID
-r :仅列出正在后台 run 的工作;
-s :仅列出正在后台当中暂停 (stop) 的工作。
案例2:
[root@server ~]# jobs -l
[1]+ 24988 Stopped
[2]- 25006 Stopped
9.5.2、将后台工作拿到终端来处理:fg
语法: fg %jobnumber
案例3:
[root@server ~]# fg %2
让一个工作在背景底下运行,我们可以在底下这个案例当中来测试。不过在底下的测试要进行的快一点。
案例4:
[root@server ~]# jobs ; bg %1 ; jobs
[1]+ Stopped find / -perm +7000
[1]+ find / -perm +7000 &
[1]+ Running find / -perm +7000 &
9.6、控制作业
刚刚我们可以让一个已经在背景当中的工作继续工作,也可以让该工作以 fg 拿到前景来,那么,如果想要将该工作直接移除呢?或者是将该工作重新启动呢?这个时候就得需要给予该工作一个讯号 (signal) ,此时,就要用到kill/killall了。
9.6.1、kill/killall
语法:kill -signal %jobnumber
-l :这个是 L 的小写,列出目前 kill 能够使用的讯号 (signal) 有哪些?
参数 含义
-1 重新读取一次参数的设定档 (类似 reload);
-2 代表与由键盘输入 [ctrl]-c 同样的动作;
-9 立刻强制删除一个工作
-15 以正常的结束程序来终止该程序。由于是正常的终止,所以后续的动作会将他完成。不过,如果该程序已经发生问题,就是无法使用正常的方法终止时,输入这个 signal 也是没有用的。
案例1:
[root@server ~]# jobs
[1]+ Stopped vim bashrc
[root@linux ~]# kill -9 %1
[1]+ 已砍掉 vim bashrc
案例2:
root@server ~]# killall -9 httpd
[root@server ~]# ps -ef |grep httpd
root 21306 19015 0 04:12 pts/0 00:00:00 grep --color=auto httpd
[root@server ~]# kill -9 21520
Killall后面跟的是关键字,kill后面跟的是PID.
注意:
kill与killall的比较,用killall终止httpd进程,是一次性就所有含有httpd的进程都中断了;而用kill中断进程的时候,因为后面跟的是PID(进程ID),所以只能后一次一个进程的中断

9.7、监控进程活动
系统的程序之外,我们还必须就系统的一些资源进行检查。举例来说,我们使用 top 可以看到很多系统的资源。那么,还有没有其它的工具可以查阅的?底下这些工具指令也可以
9.7.1、free命令
语法:free [-b|-k|-m|-g] [-t]
参数:
-b :直接输入 free 时,显示的单位是 Kbytes,我们可以使用 b(bytes), m(Mbytes)、k(Kbytes), 及 g(Gbytes) 来显示单位。
-t :在输出的最终结果,显示物理内存与 swap 的总量。

案例:
[root@server ~]# free -m
total used free shared buffers cached
Mem: 376 366 10 0 129 94
-/+ buffers/cache: 141 235
Swap: 996 0 995
我的 swap 有 1GB 左右,那我使用 free -m 以 MBytes 来显示时,就会出现上面的信息。Mem 那一行显示的是物理内存的量, Swap 则是虚拟内存的量。 total 是总量, used 是已被使用的量, free 则是剩余可用的量。后面的 shared/buffers/cached 则是在已被使用的量当中,用来作为缓冲及快取的量。
一般来说, swap 最好不要被使用,尤其 swap 最好不要被使用超过 20% 以上,如果您发现 swap 的用量超过 20% ,那么,最好还是买物理内存来插吧。因为, Swap 的效能跟物理内存实在差很多,而系统会使用到 swap ,绝对是因为物理内存不足了才会这样做的。
9.7.2、uname命令
语法:uname [-asrmpi]

参数 含义
-a 所有系统相关的信息
-s 系统核心名称
-r 核心的版本
-m 本系统的硬件名称
-p CPU 的类型
-i 硬件的平台 (ix86)

案例:输出系统的基本信息
[root@server~]# uname -a
Linux linux.site 2.6.12-1.1398_FC4 #1 Fri Jul 15 00:52:32 EDT 2005
i686 i686 i386 GNU/Linux
9.7.3、uptime命令
这个指令很单纯,就是显示出目前系统已经开机多久的时间,以及 1, 5, 15 分钟的平均负载就是了。
案例:
[root@server ~]# uptime
18:06:30 up 52 days, 6:40, 1 user, load average: 0.00, 0.00, 0.00

上面表示,目前是 18:06 ,本系统已经开机 52 天又 6:40 ,有 1 个使用者在在线,

平均负载很低,所以都是 0 。

9.7.4、netstat命令
其实,这个指令比较常被用在网络的监控方面,不过,在程序管理方面也是需要了解的。这个指令的执行如下所示:基本上, netstat 的输出分为两大部分,上面是网络接口相关的联机,下方则是与 unix 程序有关的项目。

语法:netstat -[atunlp]
参数:
参数 含义
-a 将目前系统上所有的联机、监听、Socket 数据都列出来
-t 列出 tcp 网络封包的数据
-u 列出 udp 网络封包的数据
-n 不已程序的服务名称,以埠号 (port number) 来显示
-l 列出目前正在网络监听 (listen) 的服务
-p 列出该网络服务的程序 PID

案例:列出目前系统已经建立的网络联机与 unix socket 状态
[root@server~]# netstat
Active Internet connections (w/o servers)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 256 59-125-83-224.ad:ssh linux.test.s:52679 ESTABLISHED
Active UNIX domain sockets (w/o servers)
Proto RefCnt Flags Type State I-Node Path
unix 16 [ ] DGRAM 4870 /dev/log
unix 2 [ ] DGRAM 3561 @udevd
unix 3 [ ] STREAM CONNECTED 509237
在上面的结果当中,显示了两个部分,分别是网络的联机以及 linux 上面的 socket
联机状态。在网络联机的部分主要内容为:
Proto :网络的封包协议,主要分为 TCP 与 UDP 封包,相关数据请参考服务器篇;
Recv-Q:非由使用者程序连结到此 socket 的复制的总 bytes 数;
Send-Q:非由远程主机传送过来的 acknowledged 总 bytes 数;
Local Address :本地端的 IP
Foreign Address:远程主机的 IP;
State :联机状态,主要有建立(ESTABLISED)及监听(LISTEN);
至于 unix 传统的 socket 连接状态则是:
Proto :一般就是 unix 啦;
RefCnt:连接到此 socket 的程序数量;
Flags :联机的旗标;
Type :socket 存取的类型。主要有确认联机的 STREM 与不需确认的 DGRAM 两种;
State :CONNECTED 表示已经联机建立。
Path :连接到此 socket 的相关程序的路径!或者是相关数据输出的路径

案例2:找出目前系统上已在监听的网络联机及其 PID
[root@linux ~]# netstat -tulnp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:21 0.0.0.0: LISTEN 1598/vsftpd
tcp 0 0 127.0.0.1:25 0.0.0.0:
LISTEN 1666/master
tcp 0 0 :::22 ::: LISTEN 5281/sshd
udp 0 0 0.0.0.0:68 0.0.0.0:
21339/dhclient

第10章 服务管理
在RHEL7以后,系统的守护进程从以前的init换成了现在的systemd。本章中我们通过systemctl工具来管理服务。
学习目标:
熟练在RHEL7中掌握systemd
熟练在RHEL7中管理服务
掌握在RHEL7中配置服务
10.1 systemd的概述
10.1.1 什么是daemon和服务
在RHEL7,守护进程已经从RHEL6的init换成了systemd。而systemd和service是什么呢?提供某种网络功能,完成这个服务的功能,那就是服务。英文叫做service。我们经常会在网上看一些资料,应该常常看到“启动某某daemon来提供某种功能”,那么daemon是什么呢?
简单的说,系统为了提供某些功能必须要要提供一些服务(不论是系统本身还是网络方面),这个服务就称为service。但是service的提供总是需要程序来运作吧,否则如何运行呢?所以达成service运作的程序我们叫做daemon。而事实上,我们不必去吧daemon和service分得很清楚,只要知道每个service的背后都有一个daemon菜能运行就好了。
10.1.2 systemd
systemd 是 Linux 下一个与 SysV 和 LSB 初始化脚本兼容的系统和服务管理器。systemd 使用 socket 和 D-Bus 来开启服务,提供基于守护进程的按需启动策略,保留了 Linux cgroups 的进程追踪功能,支持快照和系统状态恢复,维护挂载和自挂载点,实现了各服务间基于从属关系的一个更为精细的逻辑控制,拥有前卫的并行性能。在RHEL7后已经不用init来管理服务了,但是来绿到某些脚本没办法直接塞入systemd中,因此,有一些被保留。
10.1.3 服务的分类
基本上,systemd将过去的所谓的daemon执行脚本统统成为一个服务单元(unit),而每种服务单元依据功能来区分为不同的类型。基本的类型包括系统服务、资料的监听与交换的插槽档服务(socket)、存储系统状态的快照类型、提供不同类型执行等级分类的操作环境(target)等等。而这么多的类型放置在以下的目录中。
/usr/lib/systemd/system/:每个服务最主要的启动脚本设定,类似于以前/etc/init.d/目录。
/run/systemd/system/:系统执行过程中所产生的服务脚本,这些脚本要比/usr/lib/systemd/system/高。
/etc/system/system/:管理员依据主系统需求所建立的执行脚本,类似于以前/etc/init.d/$xx之类的功能,优先级高于/run/systemd/system/。
也就是说,到底系统开机会不会执行某些服务其实是看/etc/system/system/底下的设定,所以该目录底下是一大堆连接文件。而实际执行的systemd启动脚本文件,其实都是放在/usr/lib/systemd/system/。因此你想要修改某个服务启动设定,得去/usr/lib/system/system/修改,/etc/system/system/只是连接/usr/lib/systemd/system/的正确的执行脚本而已。所以,我们要看服务的脚本,只需到/usr/lib/systemd/system/看。
[root@server system]# ll /usr/lib/systemd/system/
total 1180
-rw-r--r--. 1 root root 275 Jan 10 2015 abrt-ccpp.service
-rw-r--r--. 1 root root 380 Jan 10 2015 abrtd.service
-rw-r--r--. 1 root root 361 Jan 10 2015 abrt-oops.service
-rw-r--r--. 1 root root 266 Jan 10 2015 abrt-pstoreoops.service
-rw-r--r--. 1 root root 262 Jan 10 2015 abrt-vmcore.service
-rw-r--r--. 1 root root 311 Jan 10 2015 abrt-xorg.service
-rw-r--r--. 1 root root 421 Jan 30 2014 accounts-daemon.service
-rw-r--r--. 1 root root 645 Feb 17 2015 anaconda-direct.service
-rw-r--r--. 1 root root 185 Feb 17 2015 anaconda-nm-config.service
-rw-r--r--. 1 root root 660 Feb 17 2015 anaconda-noshell.service
-rw-r--r--. 1 root root 387 Feb 17 2015 anaconda.service
-rw-r--r--. 1 root root 684 Feb 17 2015 anaconda-shell@.service
-rw-r--r--. 1 root root 322 Feb 17 2015 anaconda-sshd.service
-rw-r--r--. 1 root root 312 Feb 17 2015 anaconda.target
drwxr-xr-x. 2 root root 4096 Feb 21 14:56 anaconda.target.wants

10.1.4 服务的类别说明
那 /usr/lib/systemd/system/ 以下的资料如何区分上述所谓的不同的类型 (type) 呢?
[root@server system]# ll /usr/lib/systemd/system/ | grep -E '(vsftpd|multi|cron)'
-rw-r--r--. 1 root root 284 Jul 8 2014 crond.service
-rw-r--r--. 1 root root 567 Jan 10 2015 multipathd.service
-rw-r--r--. 1 root root 524 Dec 22 2014 multi-user.target
drwxr-xr-x. 2 root root 4096 Feb 21 09:42 multi-user.target.wants
lrwxrwxrwx. 1 root root 17 Feb 21 09:41 runlevel2.target -> multi-user.target
lrwxrwxrwx. 1 root root 17 Feb 21 09:41 runlevel3.target -> multi-user.target
lrwxrwxrwx. 1 root root 17 Feb 21 09:41 runlevel4.target -> multi-user.target…
我们可以知道crond其实算是系统服务,而multi-user要算是执行环境相关的类型,根据文件的后缀名,我们可以找到比较常见的systemd的服务类型。
后缀名 主要服务功能
.service 一般服务类型:主要是系统服务,包括服务器本身所需要的的本机服务以及网络服务。经常使用的服务大多都是这种类型。
.socket 内部程序资料交换的插槽服务:主要是IPC的传输讯息插槽功能。这种服务类型一般比较不会被用到。
.target 执行环境类型:其实是一群unit的集合。
.mount
.automount 档案系统挂载相关的服务。
.path 侦测特定档案或目标类型。
.timer 循环执行的服务。

10.2 服务的管理
10.2.1 服务的启动/重启、关闭与开机自动启动
(以httpd服务为例)
服务的启动/关闭/重启:systemctl start/stop/restart service_name
[root@server ~]# systemctl start httpd
[root@server ~]# systemctl stop httpd
[root@server ~]# systemctl restart httpd
服务的开机自启与取消:systemctl enadble/disable service_name
[root@server ~]# systemctl enable httpd.service
ln -s '/usr/lib/systemd/system/httpd.service' '/etc/systemd/system/multi-user.target.wants/httpd.service'
[root@server ~]# systemctl disable httpd.service
rm '/etc/systemd/system/multi-user.target.wants/httpd.service'
[root@server ~]#
10.2.2 服务状态的查询、隔离、服务列表与依赖关系
服务状态的查询:systemctl status service_name
[root@server ~]# systemctl status httpd.service
httpd.service - The Apache HTTP Server
Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled)
Active: active (running) since Mon 2017-02-27 18:01:57 CST; 18min ago
Main PID: 13435 (httpd)
Status: "Total requests: 0; Current requests/sec: 0; Current traffic: 0 B/sec"
CGroup: /system.slice/httpd.service
├─13435 /usr/sbin/httpd -DFOREGROUND
├─13436 /usr/sbin/httpd -DFOREGROUND
├─13437 /usr/sbin/httpd -DFOREGROUND
├─13438 /usr/sbin/httpd -DFOREGROUND
├─13439 /usr/sbin/httpd -DFOREGROUND
└─13440 /usr/sbin/httpd -DFOREGROUND

Feb 27 18:01:47 server httpd[13435]: AH00557: httpd: apr_sockaddr_info_get() failed for server
Feb 27 18:01:47 server httpd[13435]: AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 127.0.0.1. Set the 'Serv...is message
Feb 27 18:01:57 server systemd[1]: Started The Apache HTTP Server.
Hint: Some lines were ellipsized, use -l to show in full.
服务的隔离与取消:systemctl mask/unmask service_name
[root@server ~]# systemctl mask httpd.service
ln -s '/dev/null' '/etc/systemd/system/httpd.service'
[root@server ~]# systemctl unmask httpd.service
rm '/etc/systemd/system/httpd.service'
服务的服务列表:systemctl list-unit-files --type=service --all
[root@server ~]# systemctl list-unit-files --type=service --all
UNIT FILE STATE
abrt-ccpp.service enabled
abrt-oops.service enabled
abrt-pstoreoops.service disabled
abrt-vmcore.service enabled
abrt-xorg.service enabled
abrtd.service enabled
accounts-daemon.service enabled
anaconda-direct.service static
anaconda-nm-config.service static
anaconda-noshell.service static

服务的依赖关系:systemctl list-dependencies
[root@server ~]# systemctl list-dependencies
default.target
├─accounts-daemon.service
├─gdm.service
├─rhnsd.service
├─rtkit-daemon.service
├─systemd-readahead-collect.service
├─systemd-readahead-replay.service
├─systemd-update-utmp-runlevel.service
└─multi-user.target
├─abrt-ccpp.service
├─abrt-oops.service
├─abrt-vmcore.service
├─abrt-xorg.service
├─abrtd.service
├─atd.service
├─auditd.service

10.2.3 系统已图形化或者命令行的方式启动
系统当前已什么方式启动:systemctl get-default
[root@server ~]# systemctl get-default
graphical.target #图形化
重启之后进入命令行:systemctl set-default multi-user.target
[root@server ~]# systemctl set-default multi-user.target
rm '/etc/systemd/system/default.target'
ln -s '/usr/lib/systemd/system/multi-user.target' '/etc/systemd/system/default.target'
进入命令行立刻生效:systemctl isolate multi-user.target
[root@server ~]# systemctl isolate multi-user.target
进入图形化立刻生效:systemctl isolate graphical.target
[root@server ~]# systemctl isolate graphical.target
10.2.4 用systemd对系统的管理
[root@study ~]# systemctl poweroff 系統开机
[root@study ~]# systemctl reboot 重新开机
[root@study ~]# systemctl suspend 进入暂停模式
[root@study ~]# systemctl hibernate 进入休眠模式
[root@study ~]# systemctl rescue 强制进入救援模式
[root@study ~]# systemctl emergency 强制进入紧急救援模式
10.3 服务启动脚本的参数
10.3.1 服务启动脚本的内容
(以sshd.service为例)
我们知道了怎么使用服务脚本,现在来了解一下它的内容吧
[root@server ~]# cat /usr/lib/systemd/system/sshd.service
[Unit] #这个项目与此 unit 的解释、执行服务的依赖性有关
Description=OpenSSH server daemon
After=network.target sshd-keygen.service
Wants=sshd-keygen.service

[Service] #这个项目与实际执行的指令参数有关
EnvironmentFile=/etc/sysconfig/sshd
ExecStart=/usr/sbin/sshd -D $OPTIONS
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=on-failure
RestartSec=42s

[Install] #这个项目说明此unit要挂载那个 target底下
WantedBy=multi-user.target
10.3.2 脚本的结构
从上一节的例子,我们可以大概把整个脚本文件分为三个部分。
[Unit]:unit的本身说明,以及其他相依daemon的设定,包括在什么服务之后才启动此unit之类的设定值。
[service]、[socket]、[timer]、[mount]、[path]:不同的unit类型就得要使用相对应的设定项目。我们拿的是sshd.service来当范本,所以这边就使用[service]来设定。这个项目内主要在规范服务的启动脚本、环境设定文件名、重新启动的方式等等。
[install]:这个项目就是将此unit安装到哪个target里面的意思。
还有一些规范需要说明的:
设定项目通常是可以重复的,例如我可以重复设定两个after在设定文件中,不过,后面的设定会代替前面的。
如果设定参数需要有“是/否”的项目(布灵值,boolean)你可以使用 1, yes, true, on 代表启动,用 0, no, false, off 代表关闭
空白行、开头为 # 或 ; 的那一行,都代表注解!
10.3.3 服务启动脚本的参数
每个部份里面还有很多的设定细项,我们使用一个简单的表格来说明每个项目好了。
[Unit] 部份
设定参数 参数说明
Description 就是当我们使用 systemctl list-units 时,会输出給管理员多看的简易说明!当然,使用 systemctl status 输出的此服务的说明,也是这个项目!
Documentation 这个项目在提供管理员能够进行下一步的文件查询的功能!提供的文件可以是如下的资料:
Documentation=http://www....
Documentation=man:sshd(8)
Documentation=file:/etc/ssh/sshd_config
After 输入简体字,点下面繁体说明此 unit 是在哪个 daemon 启动之后才启动的意思!基本上仅是说明服务启动的顺序而已,并没有强制要求里头的服务一定要启动后此 unit 才能启动。 以 sshd.service 的内容为例,该文件提到 After 后面有 network.target 以及 sshd-keygen.service,但是若这两个 unit 没有启动而强制启动 sshd.service 的话, 那么 sshd.service 应该还是能够启动的!这与 Requires 的设定是有差异的喔!字按钮进行在线转换
Before 与 After 的意义相反,是在什么服务启动前最好启动这个服务的意思。不过这仅是规范服务启动的顺序,并非强制要求的意思。
Requires 明确的定义此 unit 需要在哪个 daemon 启动后才能够启动!就是设定相依服务!如果在此项设定的前导服务没有启动,那么此 unit 就不会被启动!
Wants 与 Requires 刚好相反,规范的是这个 unit 之后最好还要启动什么服务比较好的意思!不过,并没有明确的规范就是了!主要的目的是希望建立让使用者比较好操作的环境。 因此,这个 Wants 后面接的服务如果没有启动,其实不会影响到这个 unit 本身!
Conflicts 代表冲突的服务!亦即这个项目后面接的服务如果有启动,那么我们这个 unit 本身就不能启动!我们 unit 有启动,则此项目后的服务就不能启动! 就是冲突性的检查。
接下来了解一下在 [Service] 当中有哪些项目可以使用!
[Service] 部份
设定参数 参数说明
Type 说明这个 daemon 启动的方式,会影响到 ExecStart!一般来说,有底下几种类型:
simple:预设值,这个 daemon 主要由 ExecStart 接的指令串来启动,启动后常驻于记录中。
forking:由 ExecStart 启动的程序透过 spawns 延伸出其他子程序来作为此 daemon 的主要服务。原生的父程序在启动结束后就会终止运作。 传统的 unit 服务大多属于这种项目,例如 httpd 这个 WWW 服务,当 httpd 的程序因为运作过久因此即将终结了,则 systemd 会再重新生出另一个子程序持续运作后, 再将父程序删除。
oneshot:与 simple 类似,不过这个程序在工作完毕后就结束了,不会常驻在记录中。
dbus:与 simple 类似,但这个 daemon 必须要在取得一个 D-Bus 的名称后,才会继续运作!因此设定这个项目时,通常也要设定 BusName= 才行!
idle:与 simple 类似,意思是,要执行这个 daemon 必须要所有的工作都顺利执行完毕后才会执行。这类的 daemon 通常是开机到最后才执行即可的服务!
比较重要的项目大概是 simple, forking 与 oneshot 了!毕竟很多服务需要子程序 (forking),而有更多的动作只需要在开机的时候执行一次(oneshot),例如档案系统的检查与挂载啊等等的。
EnvironmentFile 可以指定启动脚本的环境设定文件!例如 sshd.service 的设定文件写入到 /etc/sysconfig/sshd 当中!你也可以使用 Environment= 后面接多个不同的 Shell 变数来给予设定!
ExecStart 就是实际执行此 daemon 的指令或脚本程式。你也可以使用 ExecStartPre (之前) 以及 ExecStartPost (之后) 两个设定项目来在实际启动服务前,进行额外的指令行为。 但是你得要特别注意的是,指令串仅接受『指令 参数 参数...』的格式,不能接受 <, >, >>, |, & 等特殊字符,很多的 bash 语法也不支援喔! 所以,要使用这些特殊的字符时,最好直接写入到指令脚本里面去!不过,上述的语法也不是完全不能用,亦即,若要支援比较完整的 bash 语法,那你得要使用 Type=oneshot 才行 其他的 Type 才不能支援这些字符。
ExecStop 与 systemctl stop 的执行有关,关闭此服务时所进行的指令。
ExecReload 与 systemctl reload 有关的指令行为
Restart 当设定 Restart=1 时,则当此 daemon 服务终止后,会再次的启动此服务。举例来说,如果你在 tty2 使用文字界面登入,操作完毕后登出,基本上,这个时候 tty2 就已经结束服务了。 但是你会看到萤幕又立刻产生一个新的 tty2 的登入画面等待你的登入!那就是 Restart 的功能!除非使用 systemctl 强制将此服务关闭,否则这个服务会源源不绝的一直重复产生!
RemainAfterExit 当设定为 RemainAfterExit=1 时,则当这个 daemon 所属的所有程序都终止之后,此服务会再尝试启动。这对于 Type=oneshot 的服务很有帮助!
TimeoutSec 若这个服务在启动或者是关闭时,因为某些缘故导致无法顺利『正常启动或正常结束』的情况下,则我们要等多久才进入『强制结束』的状态!
KillMode 可以是 process, control-group, none 的其中一种,如果是 process 则 daemon 终止时,只会终止主要的程序 (ExecStart 接的后面那串指令),如果是 control-group 时, 则由此 daemon 所产生的其他 control-group 的程序,也都会被关闭。如果是 none 的话,则没有程序会被关闭喔!
RestartSec 与 Restart 有点相关性,如果这个服务被关闭,然后需要重新启动时,大概要 sleep 多少时间再重新启动的意思。预设是 100ms (毫秒)。
最后,再来看看那麽 Install 内还有哪些项目可用?
[Install] 部份
设定参数 参数说明
WantedBy 这个设定后面接的大部分是 *.target unit !意思是,这个 unit 本身是附挂在哪一个 target unit 底下的!一般来说,大多的服务性质的 unit 都是附挂在 multi-user.target 底下!
Also 当目前这个 unit 本身被 enable 时,Also 后面接的 unit 也请 enable 的意思!也就是具有相依性的服务可以写在这裡呢!
Alias 进行一个连结的别名的意思!当 systemctl enable 相关的服务时,则此服务会进行连结档的建立!以 multi-user.target 为例,这个家伙是用来作为预设操作环境 default.target 的规划, 因此当你设定用成 default.target 时,这个 /etc/systemd/system/default.target 就会连结到 /usr/lib/systemd/system/multi-user.target

10.4 做自己的服务
10.4.1 编写一个脚本
我们先编写一个脚本/backups/backup.sh,位置在/backups/下
[root@server ~]# vim /backups/backup.sh

!/bin/bash

source="/etc /home /root /var/lib /var/spool/{cron,at,mail}"
target="/backups/backup-system-$(date +%Y-%m-%d).tar.gz"
[ ! -d /backups ] && mkdir /backups
tar -zcvf ${target} ${source} &> /backups/backup.log

[root@server ~]# chmod a+x /backups/backup.sh
[root@server ~]# ll /backups/backup.sh
-rwxr-xr-x. 1 root root 221 Feb 27 19:13 /backups/backup.sh
10.4.2 编写一个启动脚本
接着,我们编写一个backup.service的启动脚本,位置在/etc/systemd/system/
[root@server ~]# vim /etc/systemd/system/backup.service

[Unit]
Description=backup my server
Requires=atd.service
[Service]
Type=simple
ExecStart=/bin/bash -c " echo /backups/backup.sh | at now"
[Install]
WantedBy=multi-user.target

因为 ExecStart 里面有用到 at 这个指令,因此, atd.service 就是一定要的服务!

[root@server ~]# systemctl daemon-reload
[root@server ~]# systemctl start backup.service
[root@server ~]# systemctl status backup.service
backup.service - backup my server
Loaded: loaded (/etc/systemd/system/backup.service; disabled)
Active: inactive (dead)

Feb 27 19:16:37 server systemd[1]: Starting backup my server...
Feb 27 19:16:37 server systemd[1]: Started backup my server.
Feb 27 19:16:37 server bash[2528]: job 1 at Mon Feb 27 19:16:00 2017

为什么 Active 是 inactive 呢?这是因为我们的服务谨是一个简单的 script

因此执行完毕就完毕了,不会缓存在记录中!

总结
早期的服务管理使用 systemV 的机制,透过 /etc/init.d/*, service, chkconfig, setup 等指令来管理服务的启动/关闭/预设启动;
从 RHEL 7.x 开始,採用 systemd 的机制,此机制最大功能为平行处理,并採单一指令管理 (systemctl),开机速度加快!
systemd 将各服务定义为 unit,而 unit 又分类为 service, socket, target, path, timer 等不同的类别,方便管理与维护
启动/关闭/重新启动的方式为: systemctl [start|stop|restart] unit.service
设定预设启动/预设不启动的方式为: systemctl [enable|disable] unit.service
查询系统所有启动的服务用 systemctl list-units --type=service 而查询所有的服务 (含不启动) 使用 systemctl list-unit-files --type=service
systemd 取消了以前的 runlevel 概念 (虽然还是有相容的 target),转而使用不同的 target 操作环境。常见操作环境为 multi-user.targer 与 graphical.target。 不重新开机而转不同的操作环境使用 systemctl isolate unit.target,而设定预设环境则使用 systemctl set-default unit.target
systemctl 系统预设的设定档主要放在 /usr/lib/systemd/system,管理员若要修改或自行设计时,则建议放在 /etc/systemd/system/ 目录下。
管理员应使用 man systemd.unit, man systemd.service, man systemd.timer 查询 /etc/systemd/system/ 底下配置文件的语法, 并使用 systemctl daemon-reload 载入后,才能自行撰写服务与管理服务!
除了 atd 与 crond 之外,可以 透过 systemd.timer 亦即 timers.target 的功能,来使用 systemd 的时间管理功能。
一些不需要的服务可以关闭!
第十一章计划任务
让系统,在什么时候,要去做什么事情!
在Linux系统中,通过atd、crond这两个系统服务实现一次性、周期性计划任务的功能,并分别通过at、crontab命令进行计划任务的设定。
学习目标:
熟悉掌握RHEL7例行性工作排程
熟练在RHEL7中执行一次的工作排程
熟练在RHEL7中循环执行的例行性工作排程
本章重点回顾
11.1 Linux例行性工作排程
11.1.1Linux工作排程的种类
at:可以处理仅运行一次就结束排程的命令!且需要开启atd服务。
cron :持续例行性的做下去!即循环计划任务。
11.1.2常见的例行性工作的应用
1、进行登录档的轮替 (log rotate):
Linux 会主动的将系统所发生的各种资讯都记录下来,这就是登录档。大型文件不但占容量还会造成读写效能的困扰,因此适时的将登录档数据挪一挪,让旧的数据与新的数据分别存放,则比较可以有效的记录登录资讯。
2、登录档分析logwatch的任务:
如果系统发生了软件问题、硬件错误、资安问题等,绝大部分的错误资讯都会被记录到登录档中,因此系统管理员的重要任务之一就是分析登录档。
3、创建 locate 的数据库:
该命令是透过已经存在的档名数据库来进行系统上档名的查询。
4、whatis数据库的创建:
使用whatis命令时,必须要拥有whatis数据库,而这个数据库也是透过系统的例行性工作排程来自动运行的。
5、RPM 软件登录档的创建:
RPM是一种软件管理的机制。由于系统可能会常常变更软件,包括软件的新安装、非经常性升级等,都会造成软件档名的差异。为了方便未来追踪,系统也帮我们将档名作个排序的记录。有时候系统也会透过排程来帮忙 RPM 数据库的重新建置。
6、移除缓存档:
系统透过例行性工作排程运行名为tmpwatch的命令来删除这些缓存档。
7、与网络服务有关的分析行为
Linux 系统通常就会主动的分析该软件的登录档,关于凭证与认证的网络资讯是否过期的问题。
11.2一次性计划任务
11.2.1一次性计划任务概念
一次性的计划任务是指当你通过at的方式配置一个计划任务,并且被调用执行之后,该计划任务的配置文件会被删除,所以只能执行一次。称为一次性计划任务。为了安全性考虑,可用/etc/at.allow与 /etc/at.deny这两个文件来针对用户做限制。
①、先找寻 /etc/at.allow 这个文件,写在这个文件中的使用者才能使用 at ,没有在这个文件中的使用者则不能使用 at (即使没有写在at.deny当中);
②如果 /etc/at.allow不存在,就寻找 /etc/at.deny 这个文件,若写在这个at.deny的使用者则不能使用 at ,而没有在这个at.deny文件中的使用者,就可以使用 at ;
③如果两个文件都不存在,那么只有 root 可以使用 at 这个命令。

11.2.2单一工作排程运行方式
1、一次性计划任务,前提是Linux 系统上面必须要有负责这个排程的服务atd。
[root@server0 ~]# systemctl enable atd#每次开机都正常启动atd服务
ln -s '/usr/lib/systemd/system/atd.service' '/etc/systemd/system/multi-user.target.wants/atd.service'
[root@server ~]# systemctl restart atd.service#重新启动atd服务
[root@server0 ~]# systemctl status atd#检查atd目前的状态
atd.service - Job spooling tools
Loaded: loaded (/usr/lib/systemd/system/atd.service; enabled)
Active: active (running) since Tue 2017-02-28 01:40:49 CST; 1h 22min ago
Main PID: 561 (atd)
CGroup: /system.slice/atd.service
└─561 /usr/sbin/atd -f
Feb 28 01:40:49 localhost systemd[1]: Started Job spooling tools.

2、at创建计划任务存放路径
创建计划任务at now + 10 min
终止任务编写 ctrl +d
[root@server ~]# ls -l /var/spool/at/
total 4
-rwx------. 1 root root 2778 Feb 27 17:02 a00002017a7728
drwx------. 2 daemon daemon 6 Jan 29 2014 spool
说明:每创建一个计划任务就会在该目录下创建一个文件,一旦该计划任务被执行,时间一过,文件就会被删除。

3、at的使用方式及参数:
at -c 工作编号

选项与参数:
-m :当 at 的工作完成后,即使没有输出信息,亦以 email 通知使用者该工作已完成。
-l :at -l 相当于atq,列出目前系统上面的所有该使用者的 at 排程;
-d :at -d 相当于atrm ,可以取消一个在 at 排程中的工作;
-v :可以使用较明显的时间格式列出 at 排程中的工作列表;
-c :可以列出后面接的该项工作的实际命令内容。

TIME:时间格式,这里可以定义出『什么时候要进行 at 这项工作』的时间,格式有:
HH:MM ex> 04:00
在今日的 HH:MM 时刻进行,若该时刻已超过,则明天的 HH:MM 进行此工作。
HH:MM YYYY-MM-DD ex> 04:00 2017-03-17
强制规定在某年某月的某一天的特殊时刻进行该工作!
HH:MM[am|pm] [Month] [Date] ex> 04pm March 17
也是一样,强制在某年某月某日的某时刻进行!
HH:MM[am|pm] + number [minutes|hours|days|weeks]
ex> now + 5 minutes ex> 04pm + 3 days
就是说,在某个时间点『再加几个时间后』才进行。

4、应用例子
1、查询目前主机上面有多少的 at工作排程
[root@server ~]# atq
4 Sun Mar 26 23:00:00 2017 a root
5 Mon Feb 27 17:27:00 2017 a root
You have new mail in /var/spool/mail/root

2、将上述的第 5 个工作移除!
[root@server ~]# atrm 5

3、再过五分钟后,将 /root/.bashrc 寄给root自己
[root@server ~]# at now + 5 min
at> /bin/mail root -s "hello,world" < /root/.bashrc
at>
job 5 at Mon Feb 27 17:27:00 2017

4、将上述的第 4 项工作内容列出来查阅
[root@server ~]# at -c 4

!/bin/sh

atrunuid=0 gid=0

mail root 0

umask 22
……

5、由机房预计2017/03/27停电,打算在2017/03/26 23:00关机?
[root@server ~]# at 23:00 2017-3-26
at> /bin/sync
at> /sbin/shutdown -h 0 now
at>
job 4 at Sun Mar 26 23:00:00 2017
11.3循环性计划任务
11.3.1循环性计划任务概念
循环的计划任务crontab来实现,循环的计划任务是指,当你利用crontab创建一个计划任务,并且该任务被调度执行完之后不会被删除,等待下一次满足该计划任务被调度的时间条件,一旦时间条件被满足,将会再一次被执行。所以称为循环的计划任务!
crontab包含cron守护进程的一系列作业和指令。
1、每个用户可以拥有自己的crontab文件;
2、同时,操作系统保存一个针对整个系统的crontab文件,该文件通常存放于/etc/crontab,而这个文件只能由系统管理员来修改。

11.3.2使用者的配置:

1、启动/重启cron服务
[root@server0 ~]# systemctl enable crond
[root@server0 ~]# systemctl restart crond.service

2、默认情况下,任何使用者只要不被列入 /etc/cron.deny当中,那么他就可以直接下达『 crontab -e 』去编辑自己的例行性命令了!整个过程就如同上面提到的,会进入 vi 的编辑画面,然后以一个工作一行来编辑,编辑完毕之后输入『 :wq』储存后离开 vi 就可以了!而每项工作 (每行) 的格式都是具有六个栏位,这六个栏位的意义为:
crontab 的语法
Crontab -e-------------分钟小时,日期,月,星期,action
(日、月、星期不要同时设置!别搞混了!)

代表意义 分钟 小时 日期 月份 周 命令
数字范围 0-59 0-23 1-31 1-12 0-7 action

选项与参数:
-e :编辑 crontab 的计划任务
[root@server0 ~]# crontab -e
crontab: installing new crontab

-l :浏览当前用户的crontab,即浏览已存在的计划任务列表
[root@server0 ~]# crontab -l
/10 /bin/echo hello >> /tmp/f6
00,30
* run_daily_cmd

-r :移除所有的 crontab 的工作内容,若仅要移除一项,请用 -e 去编辑
[root@server0 ~]# crontab -r
[root@server0 ~]# crontab -l
no crontab for root

-u :指定计划任务属于哪个用户
[root@server0 ~]# crontab -e -u cxt
[root@server0 ~]# crontab -l -u cxt

  • 15,18 * run_daily_cmd
    注意:只有root用户才能通过-u选项为普通用户创建计划任务,普通用户可以通过crontab-e为自己创建计划任务。

3、所有的计划任务存放的路径:
[root@server0 ~]# ls -l /var/spool/cron/
total 8
-rw-------. 1 root root 37 Feb 28 02:46 cxt
-rw-------. 1 root root 38 Feb 28 04:00 root

4、为了安全性的问题,将可以使用 crontab 的普通用户写入/etc/cron.allow中,若不在这个文件内的使用者则不可使用 crontab;如果将crontab 的普通用户写入 /etc/cron.deny中,使用者则不可使用 crontab。
[root@server0 ~]# vim /etc/cron.deny
cxt
[root@server0 ~]# su - cxt
[cxt@server0 ~]$ crontab -e
You (cxt) are not allowed to use this program (crontab)
See crontab(1) for more information
[cxt@server0 ~]$ exit
logout
[root@server0 ~]# useraddJohn
[root@server0 ~]# su - John
[a@server0 ~]$ crontab -e #如果在/etc/cron.deny没有写入用户John,/etc/cron.allow要写入该普通用户,不然也不可crontab -e
You (a) are not allowed to use this program (crontab)
See crontab(1) for more information

5、应用实例
1、每隔10分钟执行任务计划
/10 * /bin/echo hello >> /tmp/f6

2、每隔半个小时执行任务计划
00,30 run_daily_cmd

3、每天的 15点和18点执行任务计划

  • 15,18 * run_daily_cmd

4、每天的15点到18点,每隔一个小时执行一次计划任务

  • 15-18 * run_daily_cmd

(星号) 代表任何时刻都接受的意思!举例来说,范例一内那个日、月、周都是 ,就代表著『不论何月、何日的礼拜几的 12:00 都运行后续命令』的意思!
,(逗号) 代表分隔时段的意思。举例来说,如果要下达的工作是 3:00 与 6:00 时,就会是:
0 3,6 command
-(减号) 代表一段时间范围内,举例来说, 8 点到 12 点之间的每小时的 20 分都进行一项工作:
20 8-12
command
/n(斜线) 那个 n 代表数字,亦即是『每隔 n 单位间隔』的意思,例如每五分钟进行一次,则:
/5 * command

11.3.3系统的配置文件
1、在 Linux 中的 crontab 会自动的帮我们每分钟重新读取一次 /etc/crontab 的例行工作事项,但是某些原因或者是其他的 Unix 系统中,由于 crontab 是读到内存当中的,所以在你修改完 /etc/crontab 之后,可能并不会马上运行,这个时候需要重新启动crond这个服务!
[root@www ~]# cat /etc/crontab
SHELL=/bin/bash <==使用哪种 shell 介面
PATH=/sbin:/bin:/usr/sbin:/usr/bin <==运行档搜寻路径
MAILTO=root <==若有额外STDOUT,以 email将数据送给谁
HOME=/ <==默认此 shell 的家目录所在

run-parts

01 root run-parts /etc/cron.hourly<==每小时
02 4 root run-parts /etc/cron.daily<==每天
22 4
0 root run-parts /etc/cron.weekly<==每周日
42 4 1
* root run-parts /etc/cron.monthly<==每个月 1 号
分 时 日 月 周 运行者身份 命令串

MAILTO=root:
当 /etc/crontab 这个文件中的例行性工作的命令发生错误时,或者是该工作的运行结果有 STDOUT/STDERR 时,会将错误信息或者是萤幕显示的信息传给谁?默认当然是由系统直接寄发一封 mail 给 root 。
PATH=....:
01 root run-parts /etc/cron.hourly:
这个 /etc/crontab 里面预配置义出四项工作任务,分别是每小时、每天、每周及每个月分别进行一次的工作!系统默认的例行性工作是以 root 的身份来进行的。

2、/etc/crontab 这个文件里面支持两种下达命令的方式,
一种是直接下达命令,一种则是以目录来规划,例如:
命令型态:1 dmtsai mail -s "testing" kiki< /home/dmtsai/test.txt
以dmtsai这个使用者的身份,在每小时运行一次 mail 命令。

目录规划:/5 * root run-parts /root/runcron
创建一个 /root/runcron的目录,将要每隔五分钟运行的『可运行档』都写到该目录下,就可以让系统每五分钟运行一次该目录下的所有可运行档。
11.3.4一些注意事项
有的时候,我们以系统的cron来进行例行性工作的创建时,要注意一些使用方面的特性。举例来说,如果我们有四个工作都是五分钟要进行一次的,那么是否这四个动作全部都在同一个时间点进行?如果同时进行,该四个动作又很耗系统资源,如此一来,每五分钟不是会让系统忙得要死?
资源分配不均的问题
当大量使用 crontab 的时候,总是会有问题发生的,最严重的问题就是『系统资源分配不均』的问题,侦测主机流量的资讯,包括:
流量
区域内其他 PC 的流量侦测
CPU 使用率
RAM 使用率
线上人数即时侦测
如果每个流程都在同一个时间启动的话,那么在某个时段时,我的系统会变的相当的繁忙,所以,这个时候就必须要分别配置啦!我可以这样做:

11.4本章重点回顾
一、系统可以通过at这个指令来排程单一工作的任务!
1、[at TIME]为指令下达的方法,当at进入排程后,系统执行该排程工作时,会到下达时的目录进行任务;
2、at 的执行必须要有atd服务的支援,且 /etc/at.deny为控制是否能够执行的使用者帐号;
3、通过atq, atrm可以查询与删除 at 的工作排程;

二、系统的循环例行性工作排程使用crond这个服务,同时利用 crontab -e及 /etc/crontab 进行排程的安排;
1、crontab -e 设定项目分为六栏,『分、时、日、月、周、指令』为其设定依据;
2、/etc/crontab 设定分为七栏,『分、时、日、月、周、执行者、指令』为其设定依据;

第十二章、正则表达式与文字处理
正规表示法对于系统管理员来说实在是很重要!!!!
因为系统会产生很多的信息,这些信息有的重要有的仅是告知,此时,管理员可以透过正规表示法的功能来将重要信息撷取出来,并产生便于查阅的报表来简化管理流程。此外,很多的套装软件也都支持正规表示法的分析,例如邮件服务器的过滤机制(过滤垃圾信件)就是很重要的一个例子。所以,您最好要了解正规表示法的相关技能,在未来管理主机时,才能够更精简处理您的日常事务!
学习目标:
熟悉正表达式的概念及其字符
熟练使用sed结合正则表达式
熟练使用grep结合正则表达式
熟练使用awk结合正则表达式
11.1正则表达式
12.1.1正则表达式概念
正则表达式 (Regular Expression, RE, 或称为常规表示法)是透过一些特殊字节的排列,用以『搜寻/取代/删除』一列或多列文字字串,正则表达式就是用在字串的处理上面的一项『表示式』。正规表示法并不是一个工具程序,而是一个字串处理的标准依据,如果您想要以正规表示法的方式处理字串,就得要使用支持正则表达式的工具程序才行,这类的工具程序很多,例如 vi, sed, awk,grep等等

简单说,正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符、及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑。

12.1.2正则表达式的组成
正则表达式有三部分组成:
1,字符类
2,数量限定符
3,位置限定符

例如:找出多有符合xxxxx@xxxx.xxx模式的字符串(也就是mail地址),要求x可以是字母、数字、下划线、小数点、短划线,email地址的每一部分可以有一个或多个x字符,例如abc@ed.com、1_2@789-6.54等,当然,符合这个模式的并不一定是合法的mail地址,但至少可以做一次初步的筛选,筛选掉类似于a.b、c@d等不符合的字符串。再比如说,找出所有符合yyy.yyy.yyy.yyy模式的字符串(IP地址),要求y是0~9的数字,IP地址的每一部分可以有1~3个y字符

1、字符类
字符类(Character Class):上例中的x和y,他们在模式中表示一个字符,但是取值范围是一类字符中的任意一个。
常用的字符类有以下:
符号 描述
[] 匹配括号中的任意一个字符

  • 在[]中使用,表示字符范围
    ^ 在[]括号年内的家头,表示匹配括号中字符外的任意一个字符
    . 表示意一个字符;
    [[:alpha:]] 表示任意一个字母;
    [[:alnum:]] 表示任意一个字母或者数字;
    [[:space:]] 表示空格;
    [[:punct:]] 表示任意一个除数字字母和空格以外的可打印字符;
    [[:digit:]] 表示数字
    [[:upper:]] [A-Z]
    [[:lower:]] [a-z]

举例:example.txt的内容如下

abc9
abcd
ab
bd
cd
hello,world
hello,xy
xy
xy,hello
xy567 hello
567
~
1、验证“.”在shell输入cat example.txt |grep 'abc.',结果如下
[root@rhel7 tmp]# cat example.txt |grep 'abc.'
abc9
abcd
可以看到abc9和abcd都被输出
2、验证“[]”在shell输入cat example.txt |grep '^[abc]d',结果如下
[root@rhel7 tmp]# cat example.txt |grep '^[abc]d'
bd
cd
bd,cd,均被输出
3、验证“特殊字符”在shell输入cat example.txt |grep 'abc[[:digit:]]',结果如下
[root@rhel7 tmp]# cat example.txt |grep 'abc[[:digit:]]'
abc9
[root@rhel7 tmp]#

2、数量限定符
数量限定符(Quantifier): 邮件地址的每一部分可以有一个或多个x字符,IP地址的每一部分可以有1-3个y字符
常用的数量限定符如下:
符号 描述

  • 重复零次或更多次:
  • 重复一次或更多次
    ? 重复零次或一次
    {n} 重复n次
    {n,} 重复n次或更多次
    {n,m} 重复n到m次 :[0-9]{11}连续的11的数字

举例:
源文件内容如下
b124230
b034325
a081016
m7187998
m7282064
a022021
a061048
m9324822
b103303
a013386
b044525
m8987131
B081016
M45678
B103303
BADc2345
1.more size.txt | grep '[a-b]' 范围;如[A-Z]即A,B,C一直到Z都符合要求
b124230
b034325
a081016
a022021
a061048
b103303
a013386
b044525

2.more size.txt | grep '[bB]'
b124230
b034325
b103303
b044525
B081016
B103303
BADc2345
3.more size.txt | grep -iv 'b1..*3' -v :查找不包含匹配项的行
b034325
a081016
m7187998
m7282064
a022021
a061048
m9324822
a013386
b044525
m8987131
B081016
M45678
BADc2345

3、位置限定符
位置限定符(Anchor):描述各种字符类以及普通字符之间的位置关系,例如邮件地址分三部分,用普通字符@和.隔开,IP地址分四部分,用.隔开,每一部分都可以用
字符类和数量限定符描述。为了表示位置关系,需要位置限定符的概念,将在下面介绍。
符号 描述
^ 以什么开头; eg:^content 匹配行首为content的行
& 以什么结尾;eg: ;$ 匹配行末为;的行
^& 匹配空行;
\ 表示转义;
\<,> ”表示左右边界;

4、特殊字符
符号 描述
\ 转义字符,普通字符转为特殊字符,特殊字符转为普通字符
() 将正则表达式的一部分括起来组成一个单元,可以对整个单元使用数量限定符
| 连接两个表达式,表示或的关系

举例:
1,n(o|either)表示匹配no或者neither
2,([0-9]{1,3}.){3}[0-9]{1,3}表示匹配一个ip地址

12.2文字处理工具
12.2.1grep 工具
Linux系统中grep命令是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹配的行打印出来。grep全称是Global Regular Expression Print,表示全局正则表达式版本2,它的使用权限是所有2用户。
grep 是一个很常见也很常用的命令,他最重要的功能就是进行字串数据的比对,然后将符合使用者需求的字串列印出来。需要说明的是『grep 在数据中查寻一个字串时,是以 "整行" 为单位来进行数据的撷取的!』也就是说,假如一个文件内有 10 行,其中有两行具有你所搜寻的字串,则将那两行显示在萤幕上,其他的就丢弃了

1.grep : 最早的文本匹配程序,使用POSIX定义的基本正则表达式(BRE)来匹配文本。
2.egrep : 扩展式grep,其使用扩展式正规表达式(ERE)来匹配文本。
3.fgrep :快速grep,这个版本匹配固定字符串而非正则表达式。并且是唯一可以并行匹配多个字符串的版本。

如下简单的介绍grep命令:
语法格式:
grep [options ...] pattern-spec [files ...]
用途:
匹配一个或多个模式的文本行。
options:列举常用的参数

常用参数及意义:
-i 忽略大小写;
-v 反选;
-A n:抓取含关键字的行和此行后n行;
-B n:抓取含关键字的行和前n行;
-E 抓取多个关键字:grep “root|0|ftp” /tmp/passwd;==egrep
-n 输出带关键字行和行号;
-s 不显示错误信息;
-x 全列符合的列;
-c 输出匹配的行数;
-o 仅显示匹配到的内容
-C 连同匹配行的上下n行一并显示

GREP实例
Eg:源文件url.txt内容如下:
www.baidu.com
http://www.baidu.com
https://www.baidu.com
http://wwwbaiducom
baidu.com
baidu

1.url匹配
匹配以http或者https开头,并且其后为:并且含有.的串
BRE匹配:
grep '^https{0,1}...' url.txt
匹配结果如下:
http://www.baidu.com
https://www.baidu.com

2.Email匹配
示例文件内容为:
hfutwyy@qq.com
aaaa@
aaa@.com
aaa@gmail.com
@@baidu.com

匹配以字母数字或者下划线开头的多个字符,其后有一个@之后有多个字母数字或者下划线,其中有一个.号
grep '^[[:alpha:][:digit:]_]@[[:alpha:][:digit:]]..*' email.txt

 匹配结果:

hfutwyy@qq.com
aaa@.com
aaa@gmail.com

12.2.2 sed工具
1. Sed简介  
sed 是一种在线编辑器,它一次处理一行内容。处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。2接着处理下一行,这样不断重复,直到文件末尾。文件内容并没有 改变,除非你使用重定向存储输出。Sed主要用来自动编辑一个或多个文件;简化对文件的反复操作;编写转换程序等。以下介绍的是Gnu版本的Sed 3.02。  
2. 定址  
可以通过定址来定位你所希望编辑的行,该地址用数字构成,用逗号分隔的两个行数表示以这两行为起止的行的范围(包括行数表示的那两行)。如1,3表示1,2,3行,美元符号($)表示最后一行。范围可以通过数据,正则表达式或者二者结合的方式确定 。  
  
3. Sed命令  
调用sed命令有两种形式:  
sed [options] 'command' file(s)  
sed [options] -f scriptfile file(s) 

sed常用参数

符号 描述
-n 使用安静(silent)模式。
-e 直接在指令列模式上进行 sed 的动作编辑;
-f 直接将 sed 的动作写在一个档案内, -f filename 则可以执行 filename 内的sed 动作;
-r sed 的动作支援的是延伸型正规表示法的语法。(预设是基础正规表示法语法)
-i 直接修改读取的档案内容,而不是由萤幕输出。

Sed常用命令

符号 描述
d 删除行:sed 1,3d /tmp/passwd 删除1到3行;
s 替换:sed 1,2s/原/新/g /tmp/passwd;g位表示一行中的所有,n表示第n个
y 字符转换:sed ‘y/adc/123/’/tmp/passwd;将adc逐字替换为123;
i\ 在前面插入一行:sed ‘2i 1root’/tmp/passwd;在第二行前插入root;
a\ 追加:sed '/^test/a\this is a example' example :this is a example'被追加到以test开头的行后面,sed要求命令a后面有一个反斜杠。
r 读入文本并插入到匹配行后: sed '/ftp/r aa' passwd
p 打印:sed 1,2p /tmp/passwd ;打印第一到第二行;
c\ 以行为单位的替换与显示:nl /etc/passwd | sed '2,5c No 2-5 number'
{} 在定位行执行的命令组
n 读取一下个输入行,用下一个命令处理新的行
w 将文本写入到一个文件
h 将模式缓冲区的文本复制到保持缓冲区
x 互换模式缓冲区和保持缓冲区的内容
! 对所选行以外的行进行处理

4. 实例  
删除:d命令  
  
$ sed '2d' example-----删除example文件的第二行。  
  
$ sed '2,$d' example-----删除example文件的第二行到末尾所有行。  
  
$ sed '$d' example-----删除example文件的最后一行。  
  
$ sed '/test/'d example-----删除example文件所有包含test的行。  
替换:s命令  
  
$ sed 's/test/mytest/g' example-----在整行范围内把test替换为mytest。如果没有g标记,则只有每行第一个匹配的test被替换成mytest。  
  
$ sed -n 's/^test/mytest/p' example-----(-n)选项和p标志一起使用表示只打印那些发生替换的行。也就是说,如果某一行开头的test被替换成mytest,就打印它。  
  
$ sed 's/^192.168.0.1/&localhost/' example-----&符号表示替换换字符串中被找到的部份。所有以192.168.0.1开头的行都会被替换成它自已加 localhost,变成192.168.0.1localhost。  
  
$ sed -n 's/(love)able/\1rs/p' example-----love被标记为1,所有loveable会被替换成lovers,而且替换的行会被打印出来。  
  
$ sed 's#10#100#g' example-----不论什么字符,紧跟着s命令的都被认为是新的分隔符,所以,“#”在这里是分隔符,代替了默认的“/”分隔符。表示把所有10替换成100。  
选定行的范围:逗号  
  
$ sed -n '/test/,/check/p' example-----所有在模板test和check所确定的范围内的行都被打印。  
  
$ sed -n '5,/^test/p' example-----打印从第五行开始到第一个包含以test开始的行之间的所有行。  
  
$ sed '/test/,/check/s/$/sed test/' example-----对于模板test和west之间的行,每行的末尾用字符串sed test替换。  
多点编辑:e命令  
  
$ sed -e '1,5d' -e 's/test/check/' example-----(-e)选项允许在同一行里执行多条命令。如例子所示,第一条命令删除1至5行,第二条命令用check替换test。命令的执 行顺序对结果有影响。如果两个命令都是替换命令,那么第一个替换命令将影响第二个替换命令的结果。  
  
$ sed --expression='s/test/check/' --expression='/love/d' example-----一个比-e更好的命令是--expression。它能给sed表达式赋值。  
从文件读入:r命令  
$ sed '/test/r file' example-----file里的内容被读进来,显示在与test匹配的行后面,如果匹配多行,则file的内容将显示在所有匹配行的下面。  
写入文件:w命令  
  
$ sed -n '/test/w file' example-----在example中所有包含test的行都被写入file里。  
追加命令:a命令  
  
$ sed '/^test/a\--->this is a example' example<-----'this is a example'被追加到以test开头的行后面,sed要求命令a后面有一个反斜杠。  
插入:i命令  
$ sed '/test/i\  
new line  
-------------------------' example  
如果test被匹配,则把反斜杠后面的文本插入到匹配行的前面。  
下一个:n命令  
  
$ sed '/test/{ n; s/aa/bb/; }' example-----如果test被匹配,则移动到匹配行的下一行,替换这一行的aa,变为bb,并打印该行,然后继续。  
变形:y命令  
  
$ sed '1,10y/abcde/ABCDE/' example-----把1--10行内所有abcde转变为大写,注意,正则表达式元字符不能使用这个命令。  
退出:q命令  
*  
$ sed '10q' example-----打印完第10行后,退出sed。  
保持和获取:h命令和G命令

$ sed -e '/test/h' -e '$G example-----在sed处理文件的时候,每一行都被保存在一个叫模式空间的临时缓冲区中,除非行被删除或者输出被取消,否则所有被处理的行都将 打印在屏幕上。接着模式空间被清空,并存入新的一行等待处理。在这个例子里,匹配test的行被找到后,将存入模式空间,h命令将其复制并存入一个称为保 持缓存区的特殊缓冲区内。第二条语句的意思是,当到达最后一行后,G命令取出保持缓冲区的行,然后把它放回模式空间中,且追加到现在已经存在于模式空间中 的行的末尾。在这个例子中就是追加到最后一行。简单来说,任何包含test的行都被复制并追加到该文件的末尾。

12.2.3 awk 工具
简介
awk是一个强大的文本分析工具,相对于grep的查找,sed的编辑,awk在其对数据分析并生成报告时,显得尤为强大。简单来说awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行各种分析处理。
awk有3个不同版本: awk、nawk和gawk,未作特别说明,一般指gawk,gawk 是 AWK 的 GNU 版本。
awk其名称得自于它的创始人 Alfred Aho 、Peter Weinberger 和 Brian Kernighan 姓氏的首个字母。实际上 AWK 的确拥有自己的语言: AWK 程序设计语言,三位创建者已将它正式定义为“样式扫描和处理语言”。它允许您创建简短的程序,这些程序读取输入文件、为数据排序、处理数据、对输入执行计算以及生成报表,还有无数其他的功能。

格式
awk '{pattern + action}' {filenames}

尽管操作可能会很复杂,但语法总是这样,其中 pattern 表示 AWK 在数据中查找的内容,而 action 是在找到匹配内容时所执行的一系列命令。花括号({})不需要在程序中始终出现,但它们用于根据特定的模式对一系列指令进行分组。 pattern就是要表示的正则表达式,用斜杠括起来。
awk语言的最基本功能是在文件或者字符串中基于指定规则浏览和抽取信息,awk抽取信息后,才能进行其他文本操作。完整的awk脚本通常用来格式化文本文件中的信息。
通常,awk是以文件的一行为处理单位的。awk每接收文件的一行,然后执行相应的命令,来处理文本。

awk命令形式:
awk [-F|-f|-v] ‘BEGIN{} //{command1; command2} END{}’ file

 [-F|-f|-v]   大参数,-F指定分隔符,-f调用脚本,-v定义变量 var=value
'  '          引用代码块
BEGIN   初始化代码块,在对每一行进行处理之前,初始化代码,主要是引用全局变量,设置FS分隔符
//           匹配代码块,可以是字符串或正则表达式
{}           命令代码块,包含一条或多条命令
;          多条命令使用分号分隔
END      结尾代码块,在对每一行进行处理之后再执行的代码块,主要是进行最终计算或输出结尾摘要信息

入门实例
假设last -n 5的输出如下
[root@www ~]# last -n 5 <==仅取出前五行
root pts/1 192.168.1.100 Tue Feb 10 11:21 still logged in
root pts/1 192.168.1.100 Tue Feb 10 00:46 - 02:28 (01:41)
root pts/1 192.168.1.100 Mon Feb 9 11:41 - 18:30 (06:48)
dmtsai pts/1 192.168.1.100 Mon Feb 9 11:41 - 11:41 (00:00)
root tty1 Fri Sep 5 14:09 - 14:10 (00:01)

如果只是显示最近登录的5个帐号和ip
[root@www ~]# last -n 5 | awk '{print $1 "\t" $3}'
root 192.168.1.100
root 192.168.1.100
root 192.168.1.100
dmtsai 192.168.1.100
root Fri

上表是 awk 最常使用的动作!透过 print 的功能将栏位数据列出来!栏位的分隔则以空白键或 [tab] 按键来隔开

整个 awk 的处理流程是:
1,读入第一行,并将第一行的数据填入 $0, $1, $2.... 等变量当中;
2,依据 "条件类型" 的限制,判断是否需要进行后面的 "动作";
3,做完所有的动作与条件类型;
4,若还有后续的『行』的数据,则重复上面 1~3 的步骤,直到所有的数据都读完为止。

经过这样的步骤,你会晓得, awk 是『以行为一次处理的单位』,而『以栏位为最小的处理单位』。

awk 的内建变量
变量名称 代表意义
NF 每一行 ($0) 拥有的栏位总数
NR 目前 awk 所处理的是『第几行』数据
FS 目前的分隔字节,默认是空白键

我们继续以上面 last -n 5 的例子来做说明,如果我想要:
列出每一行的帐号(就是 $1);
列出目前处理的行数(就是 awk 内的 NR 变量)
并且说明,该行有多少栏位(就是 awk 内的 NF 变量)

root@www ~]# last -n 5| awk '{print $1 "\t lines: " NR "\t columns: " NF}'
root lines: 1 columns: 10
root lines: 2 columns: 10
root lines: 3 columns: 10
dmtsai lines: 4 columns: 10
root lines: 5 columns: 9

注意,在 awk 内的 NR, NF 等变量要用大写,且不需要有 $ !

特殊要点:
$0      表示整个当前行
$1      每行第一个字段
NF      字段数量变量
NR      每行的记录号,多文件记录递增
FNR     与NR类似,不过多文件记录不递增,每个文件都从1开始
\t      制表符
\n      换行符
FS      BEGIN时定义分隔符
RS       输入的记录分隔符, 默认为换行符(即文本是按一行一行输入)
==      等于,必须全部相等,精确比较
!=       不等于,精确比较
&&    逻辑与
||       逻辑或

  •       匹配时表示1个或1个以上
    /[0-9][0-9]+/   两个或两个以上数字
    /[0-9][0-9]*/   一个或一个以上数字
    FILENAME 文件名
    OFS    输出字段分隔符, 默认也是空格,可以改为制表符等
    ORS    输出的记录分隔符,默认为换行符,即处理结果也是一行一行输出到屏幕
    -F'[:#/]'   定义三个分隔符

统计/etc/passwd:文件名,每行的行号,每行的列数,对应的完整行内容:

awk -F ':' '{print "filename:" FILENAME ",linenumber:" NR ",columns:" NF ",linecontent:"$0}' /etc/passwd

filename:/etc/passwd,linenumber:1,columns:7,linecontent:root:x:0:0:root:/root:/bin/bash
filename:/etc/passwd,linenumber:2,columns:7,linecontent:daemon:x:1:1:daemon:/usr/sbin:/bin/sh
filename:/etc/passwd,linenumber:3,columns:7,linecontent:bin:x:2:2:bin:/bin:/bin/sh
filename:/etc/passwd,linenumber:4,columns:7,linecontent:sys:x:3:3:sys:/dev:/bin/sh
省略ing---

打印print
print 是awk打印指定内容的主要命令
awk '{print $0}' /etc/passwd ##表示整行输出
awk中同时提供了print和printf两种打印输出的函数。
其中print函数的参数可以是变量、数值或者字符串。字符串必须用双引号引用,参数用逗号分隔。如果没有逗号,参数就串联在一起而无法区分。这里,逗号的作用与输出文件的分隔符的作用是一样的,只是后者是空格而已。
printf函数,其用法和c语言中printf基本相似,可以格式化字符串,输出复杂时,printf更加好用,代码更易懂。

print 是awk打印指定内容的主要命令
awk '{print}'  /etc/passwd   ==   awk '{print $0}'  /etc/passwd  
awk '{print " "}' /etc/passwd                                           //不输出passwd的内容,而是输出相同个数的空行,进一步解释了awk是一行一行处理文本
awk '{print "a"}'   /etc/passwd                                        //输出相同个数的a行,一行只有一个a字母
awk -F":" '{print $1}'  /etc/passwd 
awk -F: '{print $1; print $2}'   /etc/passwd                   //将每一行的前二个字段,分行输出,进一步理解一行一行处理文本
awk  -F: '{print $1,$3,$6}' OFS="\t" /etc/passwd       //输出字段1,3,6,以制表符作为分隔符

-f指定脚本文件
格式:awk -f script.awk  file
BEGIN{
FS=":"
}
{print $1}         //效果与awk -F":" '{print $1}'相同,只是分隔符使用FS在代码自身中指定
 
awk 'BEGIN{X=0} /^$/{ X+=1 } END{print "I find",X,"blank lines."}' test 
I find 4 blank lines.
 ls -l|awk 'BEGIN{sum=0} !/^d/{sum+=$5} END{print "total size is",sum}'           //计算文件大小
total size is 17487

-F指定分隔符
$1 指指定分隔符后,第一个字段,$3第三个字段, \t是制表符
一个或多个连续的空格或制表符看做一个定界符,即多个空格看做一个空格

awk -F":" '{print $1}'  /etc/passwd
awk -F":" '{print $1 $3}'  /etc/passwd             //$1与$3相连输出,不分隔
awk -F":" '{print $1,$3}'  /etc/passwd             //多了一个逗号,$1与$3使用空格分隔
awk -F":" '{print $1 " " $3}'  /etc/passwd          //$1与$3之间手动添加空格分隔
awk -F":" '{print "Username:" $1 "\t\t Uid:" $3 }' /etc/passwd     //自定义输出  
awk -F: '{print NF}' /etc/passwd                  //显示每行有多少字段
awk -F: '{print $NF}' /etc/passwd                 //将每行第NF个字段的值打印出来
 awk -F: 'NF==4 {print }' /etc/passwd              //显示只有4个字段的行
awk -F: 'NF>2{print $0}' /etc/passwd             //显示每行字段数量大于2的行
awk '{print NR,$0}' /etc/passwd                   //输出每行的行号
awk -F: '{print NR,NF,$NF,"\t",$0}' /etc/passwd    //依次打印行号,字段数,最后字段值,制表符,每行内容
awk -F: 'NR==5{print}'  /etc/passwd              //显示第5行
awk -F: 'NR==5 || NR==6{print}'  /etc/passwd     //显示第5行和第6行
route -n|awk 'NR!=1{print}'                      //不显示第一行

//匹配代码块
//纯字符匹配   !//纯字符不匹配   ~//字段值匹配   !~//字段值不匹配   ~/a1|a2/字段值匹配a1或a2   

awk '/mysql/' /etc/passwd
awk '/mysql/{print }' /etc/passwd
awk '/mysql/{print $0}' /etc/passwd           //三条指令结果一样
awk '!/mysql/{print $0}' /etc/passwd           //输出不匹配mysql的行
awk '/mysql|mail/{print}' /etc/passwd
awk '!/mysql|mail/{print}' /etc/passwd
awk -F: '/mail/,/mysql/{print}' /etc/passwd      //区间匹配
awk '/[2][7][7]*/{print $0}' /etc/passwd         //匹配包含27为数字开头的行,如27,277,2777...
awk -F: '$1~/mail/{print $1}' /etc/passwd       //$1匹配指定内容才显示
awk -F: '{if($1~/mail/) print $1}' /etc/passwd    //与上面相同
awk -F: '$1!~/mail/{print $1}' /etc/passwd      //不匹配
awk -F: '$1!~/mail|mysql/{print $1}' /etc/passwd  

IF语句
必须用在{}中,且比较内容用()扩起来

awk -F: '{if($1~/mail/) print $1}' /etc/passwd                     //简写
awk -F: '{if($1~/mail/) {print $1}}'  /etc/passwd                   //全写
awk -F: '{if($1~/mail/) {print $1} else {print $2}}' /etc/passwd       //if...else...
awk -F: '{if($3>100) print "large"; else print "small"}' /etc/passwd

条件表达式
==   !=  > >=  
awk -F":" '$1=="mysql"{print $3}' /etc/passwd  
awk -F":" '{if($1=="mysql") print $3}' /etc/passwd      //与上面相同 
awk -F":" '$1!="mysql"{print $3}' /etc/passwd          //不等于
awk -F":" '$3>1000{print $3}' /etc/passwd            //大于
awk -F":" '$3>=100{print $3}' /etc/passwd            //大于等于
awk -F":" '$3<1{print $3}' /etc/passwd                //小于
awk -F":" '$3<=1{print $3}' /etc/passwd              //小于等于
逻辑运算符
&& 相与的条件同时成立结果才为真
|| 相或的条件一个成立结果及为真
awk -F: '$1~/mail/ && $3>8 {print }' /etc/passwd      //逻辑与,$1匹配mail,并且$3>8
awk -F: '{if($1~/mail/ && $3>8) print }' /etc/passwd
awk -F: '$1~/mail/ || $3>1000 {print }' /etc/passwd     //逻辑或
awk -F: '{if($1~/mail/ || $3>1000) print }' /etc/passwd 

数值运算

awk -F: '$3 > 100' /etc/passwd   
awk -F: '$3 > 100 || $3 < 5' /etc/passwd  
awk -F: '$3+$4 > 200' /etc/passwd
awk -F: '/mysql|mail/{print $3+10}' /etc/passwd           //第三个字段加10打印 
awk -F: '/mysql/{print $3-$4}' /etc/passwd                //减法
awk -F: '/mysql/{print $3*$4}' /etc/passwd                //求乘积
awk '/MemFree/{print $2/1024}' /proc/meminfo          //除法
awk '/MemFree/{print int($2/1024)}' /proc/meminfo       //取整

输出分隔符OFS

awk -F: '$6~/\/sbin/ || NR==1 {print NR,$4,$5,$6}' OFS="\t" /etc/passwd
打印/etc/passwd中第六哥字段为/sbin和第一行的4,5,6字段并且以制表符为间隔

输出处理结果到文件
①在命令代码块中直接输出    route -n|awk 'NR!=1{print > "./fs"}'   
②使用重定向进行输出       route -n|awk 'NR!=1{print}'  > ./fs

while语句
与if语句作用相同
awk -F: 'BEGIN{i=1} {while(i<NF) print NF,$i,i++}' /etc/passwd
打印出总共的字段数和每个字段的内容及字段号

BEGIN,END
BEGIN在命令前执行的操作
END在命令执行后的操作
 ls -l|awk 'BEGIN{sum=0} !/^d/{sum+=$5} END{print "total size is",sum}'           //计算文件大小
total size is 17487
BEGIN初始化变量sum
END打印出变量的值

第十二章节总结:

作为系统管理员每都要处理大量的文字信息,正则表达式和文字处理工具的结合能帮助我们更快的找到自己需要的信息,如查看日志,所以熟练使用正则和文字工具对于系统管理员式十分重要的,我们需要通过练习使用来快速熟悉,最后做下重点回顾:

正规表示法就是处理字串的方法,他是以行为单位来进行字串的处理行为;
正规表示法透过一些特殊符号的辅助,可以让使用者轻易的达到『搜寻/删除/取代』某特定字串的处理程序;
只要工具程序支持正规表示法,那么该工具程序就可以用来作为正规表示法的字串处理之用;
正则表达式与万用字节是完全不一样的东西!万用字节 (wildcard) 代表的是 bash 操作介面的一个功能, 但 正则表达式是一种字串处理的表示方式!
grep 与 egrep 在正规表示法里面是很常见的两支程序,其中, egrep 支持更严谨的正规表示法的语法;
由於严谨度的不同,正规表示法之上还有更严谨的延伸正规表示法;
基础正规表示法的特殊字符有: *, ?, [], [-], [^], ^, $ 等!
常见的正规表示法工具有: grep , sed, vim 等等
printf 可以透过一些特殊符号来将数据进行格式化输出;
awk 可以使用『栏位』为依据,进行数据的重新整理与输出

第十三章无人值守安装
要利用kickstart进行无人值守部署大量用户操作系统,需要具备以下两点:1)用户端的网卡必须支持pxe的功能,并且设备网卡为第一启动项;2)网络中PXE服务器必须含有DHCP,TFTP,FTP等服务。本章主要讲解利用kickstart无需手动操作安装Linux操作系统。
学习目标:
了解什么是pxe
熟练DHCP,TFTP在无人值守安装等服务的作用
了解ks文件
13.1 利用PXE环境网络安装系统
13.1.1 什么是PXE
PXE的英文全称:Preboot Execution Environment(开机前的执行环境)。无人值守安装依赖PXE机制从网络获取开机管理程序并载入系统核心程序。要实现这个PXE需要具备:1)用户端的网卡必须支持pxe用户端的功能,并且它必须作为开机的第一启动项,这样系统才能通过网络进入pxe用户端的程序。2)网络中的kickstart服务器必须要有DHCP,TFTP等服务,为了完成无人值守安装,还需要有ftp或者nfs等服务提供ks文件的传输。
13.1.2 PXE工作流程
首先,PXE客户端向网络中DHCP服务器的UDP port 67要求IP等网络参数,DHCP服务器会回应客户端想要网络参数;PXE客户端向DHCP服务器要求开机管理程序与相关的参数,DHCP会提供TFTP服务器的地址也就是开机管理程序所在的位置;PXE客户端会访问TFTP服务器的地址(通过UDP port 69),要求下载开机管理程序,TFTP服务器会响应开机管理程序的程序码,并且告知内核等相关文件的位置;PXE客户端取得开机管理程序之后,并下载内核等文件,开始执行操作。
13.2 安装DHCP,TFTP和FTP服务器
13.2.1 DHCP在kickstart中的作用
可以发现,DHCP在kickstart无人值守安装的过程中,负责提供IP地址给PXE客户端,并且告诉客户端TFTP的地址和告知BootLoader文件的名字。在Redhat中,BootLoader的文件名一般为:pxelinux.0。客户端可以通过DHCP服务渠道到TFTP服务器下载pxelinux.0文件。
1.安装DHCP服务。
[root@server ~]# yum install -y dhcp
2.配置DHCP服务。
[root@server ~]# vim /etc/dhcp/dhcpd.conf

DHCP Server Configuration file.

see /usr/share/doc/dhcp*/dhcpd.conf.example

see dhcpd.conf(5) man page

subnet 172.25.0.0 netmask 255.255.255.0
{
range 172.25.0.100 172.25.0.200;
option broadcast-address 255.255.255.255;
option routers 172.25.0.254;
default-lease-time 3600;
max-lease-time 7200;
next-server 172.25.0.11;
filename "pxelinux.0";
}
注意:next-server就是指定TFTP的地址,filename表示到TFTP服务器地址下载pxelinux.0的文件。
3.关闭防火墙和SELinux。
[root@server ~]# systemctl disable firewalld
rm '/etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service'
rm '/etc/systemd/system/basic.target.wants/firewalld.service'
[root@server ~]# systemctl stop firewalld
[root@server ~]# setenforce 0
[root@server ~]# sed s/SELINUX\=enforcing/SELINUX\=disable/g /etc/selinux/config -i

4.重启DHCP服务。
[root@server ~]# systemctl enable dhcpd
ln -s '/usr/lib/systemd/system/dhcpd.service' '/etc/systemd/system/multi-user.target.wants/dhcpd.service'
[root@server ~]# systemctl start dhcpd
5.验证
注意:客户端需要在BIOS里面设置开机第一启动项为网卡。

这里可以看到PXE客户端获取到172.25.0.100的地址。但是连接TFTP服务是超时,原因是我们目前为止还没有安装TFTP服务器,所以接下来需要安装TFTP服务。
13.2.2 TFTP在kickstart中的作用。
利用kickstart无人值守部署系统的时候,由于kickstart的局限性,必须使用TFTP服务提供引导文件pxelinux.0等文件给客户端。在DHCP服务的配置文件里面,我们可以发现TFTP服务必须提供pxelinux.0文件。所以必须把pxelinux.0文件添加到在TFTP的根目录。同时,我们也通过TFTP服务把安装系统所需要的kernel等文件提供给客户端。
1.安装TFTP以及TFTP的守护进程xinetd。
[root@server ~]# yum install -y tftp-server xinetd
2.编辑TFTP配置文件。
[root@server ~]# vim /etc/xinetd.d/tftp

default: off

description: The tftp server serves files using the trivial file transfer \

protocol. The tftp protocol is often used to boot diskless \

workstations, download configuration files to network-aware printers, \

and to start the installation process for some operating systems.

service tftp
{
socket_type = dgram
protocol = udp
wait = yes
user = root
server = /usr/sbin/in.tftpd
server_args = -s /var/lib/tftpboot #这是TFTP默认的根目录
disable = yes #改为no
per_source = 11
cps = 100 2
flags = IPv4
}
3.安装syslinux并把pxelinux.0文件cp到TFTP的根目录。
Ps:syslinux是一个功能强大的引导加载程序,安装完syslinux之后会出现p
xelinux.0文件。
[root@server ~]# yum install -y syslinux

[root@server ~]# cp /usr/share/syslinux/pxelinux.0 /var/lib/tftpboot/
4.重启TFTP的守护进程。
[root@server ~]# systemctl restart xinetd
5.验证客户端。
客户机已经成功引导,但是没有获取到配置文件isolinux.cfg(用来指定内核文件在哪里),把isolinux.cfg文件放在/var/lib/tftpboot/pxelinux.cfg目录下并命名为default

6.创建/var/lib/tftpboot/pxelinux.cfg目录,并且把镜像文件中的isolinux.cfg拷贝进来,把它改名为default。最后重启xinetd服务。
[root@server ~]# mkdir /var/lib/tftpboot/pxelinux.cfg
[root@server ~]# cp /mnt/iso/isolinux/isolinux.cfg /var/lib/tftpboot/pxelinux.cfg/default
[root@server ~]# systemctl restart xinetd
[root@server ~]#
7.验证客户端。
客户端可以加载locate配置文件,但是vesamenu.32找不到,也就是菜单模块找不到,所以我们必须把菜单模块放置在tftp默认目录下

8.把菜单模块传入TFTP的根目录。再重启xinetd服务。
[root@server ~]# cp /mnt/iso/isolinux/vesamenu.c32 /var/lib/tftpboot/
[root@server ~]# systemctl restart xinetd
9.验证客户端
系统已经成功引导,可以找到配置文件和菜单,但是没有找到Linux的内核文件,无法进入系统,所以我们必须要把vmlinux加入到TFTP根目录。

10.把镜像文件里面的内核文件拷贝到TFTP根目录,再重启xinetd服务。
[root@server ~]# cp /mnt/iso/isolinux/vmlinuz /var/lib/tftpboot/
[root@server ~]# systemctl restart xinetd
[root@server ~]#
11.验证客户端。
可以发现成功找到内核,但是找不到驱动文件。找不到驱动文件,把驱动文件拷贝到tftp默认目录

12.把镜像文件里面的驱动文件拷贝到TFTP根目录,在重启xinetd服务。
[root@server ~]# cp /mnt/iso/isolinux/initrd.img /var/lib/tftpboot/
root@server ~]# systemctl restart xinetd
[root@server ~]#
13.验证客户端。

13.2.3FTP在kickstart中的作用。
ftp服务器作用:作为文件传输的服务器,我们用到它传输镜像文件,和ks.cfg配置文件等等。
1.安装ftp服务。
[root@server ~]# yum install -y *ftp*
[root@server ~]#
拷贝镜像文件LiveOS内容到ftp的根目录。
2.在ftp的根目录创建LiveOS目录,并且把镜像文件都拷贝到里面
[root@server ~]# mkdir /var/ftp/pub/LiveOS
[root@server ~]# cp /mnt/iso/LiveOS/* /var/ftp/pub/LiveOS/
[root@server ~]#
3.启动vsftpd服务。
[root@server ~]# systemctl start vsftpd
[root@server ~]# systemctl enable vsftpd
ln -s '/usr/lib/systemd/system/vsftpd.service' '/etc/systemd/system/multi-user.target.wants/vsftpd.service'
[root@server ~]#
4.修改default文件,把伪根文件的路劲修改为ftp的根目录。
[root@server ~]# vim /var/lib/tftpboot/pxelinux.cfg/default
label linux
  menu label ^Install Red Hat Enterprise Linux 7.1
  kernel vmlinuz
  append initrd=initrd.img inst.stage2=ftp://172.25.0.11/pub quiet
5.重启xinetd服务。
[root@server ~]# systemctl restart xinetd
[root@server ~]#
6.验证。

13.3 kickstart的配置以及ks文件
13.3.1 kickstart的原理
kickStart是一种无人职守安装方式。KickStart的工作原理是通过记录典型的安装过程中所需人工干预填写的各种参数,并生成一个名为ks.cfg的文件;在其后的安装过程中(不只局限于生成KickStart安装文件的机器)当出现要求填写参数的情况时,安装程序会首先去查找KickStart生成的文件,当找到合适的参数时,就采用找到的参数,当没有找到合适的参数时,才需要安装者手工干预。这样,如果KickStart文件涵盖了安装过程中出现的所有需要填写的参数时,安装者完全可以只告诉安装程序从何处取ks.cfg文件,然后去忙自己的事情。等安装完毕,安装程序会根据ks.cfg中设置的重启选项来重启系统,并结束安装。
13.3.2 kickstart的工作流程。
客户机先从网络上启动,执行pxe程序(PXE的作用就像是在网卡ROM里的一个小小的操作系统,它把自己的网络引导功能提供给系统的BIOS,就可以通过网络启动linux),再向dhcp服务器请求IP地址,获得到dhcp服务器发来的IP地址之后会请求引导文件(pxelinux.0),服务器发送引导文件;客户机引导成功之后,再向服务器请求配置文件(pxelinux.cfg),服务器发送配置文件,再请求内核文件(vmlinuz),发送内核文件,请求传送根文件系统(initrd.img),然后内核启动,请求ks文件,安装程序会根据ks.cfg中设置的选项来安装系统。
13.3.3 kickstart的作用
在red hat enterprise Linux中,可以使用Kickstart功能自动执行Linux系统的安装。系统安装程序anaconda需要知道如何安装系统:磁盘如何分区,配置网络接口,选择要安装的软件包等,默认情况下,这是一种交换式的过程。但是kickstar安装使用一个文本文件,这个文件中提供这些问题的所有答案,因此无需进行交换。
13.3.4 ks文件创建
1.安装kickstart。
[root@server ~]# yum install -y *kickstart*
已加载插件:langpacks, product-id, subscription-manager
This system is not registered to Red Hat Subscription Management. You can use subscription-manager to register.
软件包 pykickstart-1.99.43.17-1.el7.noarch 已安装并且是最新版本
正在解决依赖关系
--> 正在检查事务

作为依赖被安装:
system-config-date.noarch 0:1.10.6-2.el7
system-config-date-docs.noarch 0:1.0.11-4.el7
system-config-keyboard.noarch 0:1.4.0-4.el7
system-config-keyboard-base.noarch 0:1.4.0-4.el7
system-config-language.noarch 0:1.4.0-6.el7

完毕!
2.利用system-config-kickstart工具创建ks文件。
利用system-config-kickstart生成ks文件。

注意:相对应的选择配置必须正确。配置完之后,保存在指定目录,然后需要修改保存的ks文件(由于图形化配置ks文件的时候,不能将安装包写入,所以需要修改保存的ks文件将安装包部分加入),如下如所示:
[root@server ~]# cat ks.cfg

platform=x86, AMD64, 或 Intel EM64T

version=DEVEL

Install OS instead of upgrade

install

Keyboard layouts

keyboard 'us'

Halt after installation

halt

Root password

rootpw --plaintext redhat

System timezone

timezone Asia/Shanghai

Use network installation

url --url="ftp://172.25.0.11/pub"

System language

lang en_US

Firewall configuration

firewall --disabled

Network information

network --bootproto=dhcp --device=eth0

System authorization information

auth --useshadow --passalgo=sha512

Use graphical install

graphical

SELinux configuration

selinux --enforcing

Do not configure the X Window System

skipx

System bootloader configuration

bootloader --location=none

Partition clearing information

clearpart --all
autopart --type=lvm

以下加粗部分为修改部分

%packages
@base
@core
@desktop-debugging
@dial-up
@fonts
@gnome-desktop
@guest-agents
@guest-desktop-agents
@input-methods
@internet-browser
@multimedia
@print-client
@x11
kexec-tools

%end

[root@server ~]#
注意:我们这里URL必须要指定为ftp的根目录。并且这个根目录里面必须要有镜像文件。
13.3.5 将kickstart配置文件发布到安装程序。
以上,我们可以发现我们利用ftp服务提供ks文件给客户端。所以,我们必须要把ks文件传输到ftp的根目录。并且,需要把镜像文件里面的内容全部拷贝到ftp的根目录。
1.复制ks文件到ftp的根目录。
[root@server ~]# cp ks.cfg /var/ftp/pub/
[root@server ~]#
2.复制镜像文件的内容到ftp的根目录。
[root@server ~]# cp -r /mnt/iso/* /var/ftp/pub/
[root@server ~]#
13.3.6 利用kickstart无人值守安装系统
1.修改pxelinux.cfg/default配置文件,指定ks文件的路径。
[root@server ~]# vim /var/lib/tftpboot/pxelinux.cfg/default
label linux
menu label ^Install Red Hat Enterprise Linux 7.1
kernel vmlinuz
append ks=ftp://172.25.0.11/pub/ks.cfg initrd=initrd.img inst.stage2=ftp://172.25.0.11/pub quiet
2.重启xinetd和ftp服务。
[root@server ~]# systemctl restart xinetd
[root@server ~]# systemctl restart vsftpd
[root@server ~]#
3.开启客户端验证