赞
踩
目录
2.1.5 RHEL/CENTOS Linux网络相关的配置文件
3.1 Linux终端介绍、Shell提示符、Bash基本语法
5.1.7 实战1:在windows中编辑好的汉字文本文档,上传到Linux下打开乱码。
5.1.8 实战2:解决将公司Linux服务器上脚本导到windows上打开串行的问题
5.2 实战:在Centos6/RHEL6上恢复ext4文件系统下误删除的文件
5.2.2 复制一些测试文件,然后把这些文件再删除,然后演示恢复
6.2.10 控制添加用户规则文件的两个文件:/etc/default/useradd 和 /etc/login.defs
7.2 文件的特殊权限:suid sgid sticky和文件扩展权限ACL
7.2.1 文件的特殊权限:suid sgid sticky
9.3 了解gzip-bzip2- xz管理压缩文件-file-sort查看文件
10.3 前后台进程切换- nice进程优先级-实战screen后台执行命令
10.3.5 实战:使用screen后台实时执行命令备份命令
11.3 which-whereis-locate-grep-find查找命令
11.3.1 which-whereis-locate-grep find命令使用
12.1 SAS-SATA-SSD-SCSI-IDE硬盘讲解
13.4 实战:解决磁盘有空间但创建不了文件-修复服务器文件系统
14.2 RAID-0-1-5-10搭建及使用-删除RAID及注意事项
15.3 实战-使用SSM工具为公司的邮件服务器创建可动态扩容的存储池
15.3.2 实战:为公司的邮件服务器创建基于LVM的邮件存储
16.2 日志的种类和记录的方式-自定义ssh服务日志类型和存储位置
16.3.3 实战-使用 logrotate 进行ssh日志分割
17.3 实战-加密grub防止黑客通过单用户系统破解root密码
17.4 实战-通过liveCD进入救援模式-重装grub修复损坏的系统
17.4.2 实战-当MBR引导记录损坏后-重装grub进行修复
17.4.3 实战-在centOS7下误删除grub文件进行修复
18.3 实战-在局域网中使用 awl伪装MAC地址进行多线程SYN洪水攻击
18.3.2 实战:在局域网中使用 awl伪装IP地址进行多线程SYN洪水攻击
19.4 实战-升级系统中的java版本到1.8版本-为后期安装Hadoop集群做准备
20.5.3 实战3:每周一晚上3:00 ,备份数据库服务器上webdb库的所有数据到系统的/mysqlbak目录里,使用系统日期做备份文件名。
21.4.1 实战-将/opt目录下所有的日志文件全自动打包
21.4.2 实战-找出192.168.1.1-10网段中,服务器已经关机的IP地址
22.4 实战-自动备份mysql数据库脚本和nginx服务启动脚本
23.4.2 cut命令可以将一串字符作为列来显示,字符字段的记法
主讲人:学神IT-MK
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
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
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地址+主板信息计算得出唯一的序列。
注意:下面操作使用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 --》传输队列的长度
第五六行:网卡接收数据包的统计信息和接收错误的统计信息
第七八行:网卡发送数据包的统计信息和发送错误的统计信息
方法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)
NeworkManager服务是管理和监控网络设置的守护进程,CENTOS7更加注重使用NetworkManager服务来实现网络的配置和管理,7.0以前是通过network服务管理网络,以后的版本,所有网络管理和设置统一由NetworkManager服务来维护。它是一个动态的,事件驱动的网络管理服务。
[root@localhost ~]# systemctl status NetworkManager #查看networkmanager服务是是否启动
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 #设置主机名
方法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 #开机自动启动
- 临时关闭
- [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
- [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
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
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
两种终端仿真器: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 " #广播,所有终端都能收到
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、对网络的管理
- [root@localhost ~]# #表示是root用户登录,管理员账号登陆
- [root@localhost ~]# su - admin #切换到admin普通用户
- [admin@localhost ~]$ #表示普通用户登录
上面各位置对应的内容代表的意思如下:
- [root @ localhost ~ ]#
- 用户名---@---主机名---当前所在目录(~表示当前用户的家目录)---(# root/$普通用户)
查看所有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
在LINUX中使用一个命令,命令格式如下:
命令 【选项】 【参数】
命令:具体执行的命令,比如pwd,head
选项:会影响到命令的一些形为操作,通常以- --实现
参数:命令作用的对象
作用:查看当前目录下有哪些文件(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'
定义一个别名:
- [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
作用:切换目录(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 -
- /
命令:history
4个快速查找Linux历史命令的技巧:
方法1: 光标上下键
方法2: ctrl+r -》输入某条命令的关键字-》找出来对应的命令,按右光标键
方法3: !数字 //执行历史命令中第N条命令
方法4:!字符串 //搜索历史命令中最近一个以xxxx字符开头的命令,例如!vim
都是用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只能补全命令和文件
在Linux中有硬件时钟与系统时钟等两种时钟。硬件时钟是指主机板上的时钟设备,也就是通常可在BIOS画面设定的时钟;系统时钟则是指kernel中 的时钟;所有Linux相关指令与函数都是读取系统时钟的设定
当Linux启动时,系统时钟会去读取硬件时钟的设定,之后系统时钟即独立运作
查看硬件时间:
[root@localhost etc]# hwclock
查看系统时间:
- [root@localhost mnt]# date
- 时区:
- UTC (Universal Time Coordinated):世界标准时间
- GMT (Greenwich Mean Time):格林尼治时间
- CST (China standard Time):中国标准时间
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
time 作用:一般用来测量一个命令的运行时间
使用方法:time 在后面直接跟上命令和参数
- [root@localhost ~]# time ls -l /etc/
- real 0m0.056s
- user 0m0.016s
- sys 0m0.040s
说明:
real:实际使用时间
user:用户状态使用的时间
sys:内核状态使用的时间
遇到命令不知道添加哪个参数,可以使用命令帮助查看相关介绍,常用的查看帮助信息命令有如下几个
[root@localhost ~]# man find
man命令查看帮助时,支持它支持上翻下翻,搜索(直接输入斜线),退出用q
[ ]:可选项
大写字母: 必选项
… :列表多个
a | b |c: 三选一
- [root@localhost ~]# find -h #不可以执行
- [root@localhost ~]# find --help
常用的几个关机,重启命令
shutdown
init
reboot
poweroff
作用:关机,重启,定时关机
语法: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 以后重启
作用:切换系统运行级别
语法: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级别图形界面
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
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
在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
文件管理方式有多种:
改变目录: cd
创建/修改/移动/删除: touch mkdir mv vi rm cp
命令之: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
用vim命令创建一个新文件
[root@localhost mnt]# vim test-1.txt
用重定向创建一新文件
[root@localhost mnt]#echo aaa > test-1.txt
作用:创建目录
语法: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
用到的命令: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 (慎用,一定要在删除以前确定一下所在目录,防止误删除重要数据)
命令:cp 源文件/目录 目录文件/目录
选项:-R/r:递归处理,将指定目录下的所有文件与子目录一并处理
例子:
- [root@localhost ~]# cp /etc/passwd /opt/ #复制文件
- [root@localhost ~]# cp -r /boot/grub /opt/ #复制目录
- [root@localhost opt]# mv passwd dir1
-
- [root@localhost opt]# mv admin.txt dir1/a.txt #在移动文件的时候支持改名操作
语法:cat 文件名
作用:查看文件内容,一次显示整个文件的内容
[root@localhost ~]# cat /etc/passwd
作用:以分页形式显示文件内容
语法:more + 文件名
说明: 按下回车刷新一行,按下空格刷新一屏,输入q键退出
作用:和more功能一样
语法:less +文件名
说明:linux中more与less的区别
more:不支持后退,但几乎不需要加参数,空格键是向下翻页,Enter键是向下翻一行,在不需要后退的情况下比较方便
less:支持前后翻滚,既可以向上翻页(pageup按键),也可以向下翻页(pagedown按键)。,空格键是向下翻页,Enter键是向下翻一行
作用: 用于显示文件的开头的内容。在默认情况下,head命令显示文件的头10行内容
语法:head(选项)文件名
参数: -n 显示从文件头开始的行数.
- [root@localhost opt]# head /etc/passwd
- [root@localhost opt]# head -n 3 /etc/passwd #显示前3行
作用: 用于显示文件中的尾部内容。默认在屏幕上显示指定文件的末尾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
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级别代表: 增量备份
扩展:
完全备份:每次都把指定的备份目录完整的复制一遍,不管目录下的文件有没有变化;
增量备份:每次将之前(第一次、第二次、直到前一次)做过备份之后有变化的文件进行备份;
差异备份:每次都将第一次完整备份以来有变化的文件进行备份。
实验环境:
系统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
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 ./*
语法: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 的文件系统
概念
增量备份是指在一次全备份或上一次增量备份后,以后每次的备份只需备份与前一次相比增加或者被修改的文件。这就意味着,第一次增量备份的对象是进行全备后所产生的增加和修改的文件;第二次增量备份的对象是进行第一次增量备份后所产生的增加和修改的文件,以此类推。
优缺点
优点:没有重复的备份数据,因此备份的数据量不大,备份所需的时间很短。
缺点:数据恢复相对比较麻烦,它需要上一次全备份和所有增量备份的内容才能够完全恢复成功,并且它们必须沿着从全备份到依次增量备份的时间顺序逐个反推恢复,因此可能会延长的恢复时间
实战: 增量备份文件系统
准备一个备份目录进行备份
- [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工具
- [root@panda ~]# rpm -qf `which vim`
- [root@panda ~]# rpm -qf `which vi`
扩展:
问:vi和vim是同一个软件包安装的吗?
答:NO,vim是vi的增加版,最明显的区别就是vim可以语法加亮,它完全兼容vi
首次进入文件 ---- 命令模式
出现 “Insert” ---- 编辑模式
输入: ---- 命令行模式
A:从编辑模式到命令行模式怎样切换?
编辑模式->esc->命令模式->: ->命令行模式
B:字符操作(怎样进入编辑模式?)
进入编辑模式 a i o A I O
说明:
i 当前字符之前插入 (光标前)
I 行首插入 (行首)
a 当前字符之后插入 (光标后)
A 行尾插入(行尾)
o下一行插入 (另起一行)
O上一行插入(上一行插入)
x 向后删除一个字符 等同于delete
X 向前删除一个字符
u 撤销一步 每按一次就撤销一次
r 替换
光标定位
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可以进行补全操作,所需要的内容必须是在当前打开的文件内存在的,它只针对当前文件
进入v模式 移动光标选择区域、
编程的时候需要进行多行注释: 1)、ctrl+v 进入列编辑模式
2)、向下或向上移动光标,把需要注释、编辑的行的开头选中起来
4)、然后按大写的I
5)、再插入注释符或者你需要插入的符号,比如"#"
6)、再按Esc,就会全部注释或添加了
删除:再按ctrl+v 进入列编辑模式;向下或向上移动光标 ;选中注释部分,然后按d, 就会删除注释符号。
: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
临时设置
: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
nano编辑器
emacs编辑器
GHOME编辑器gedit
例:
[root@localhost ~]# gedit /etc/passwd
实验环境: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 列举所有已知的字符集
原因:因为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类型。
- [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块:真正存储数据的地方
误删除文件后,第一件事要做什么??? 你不心删除把存了几十年的大片删除了。
避免误删除的文件内容被覆盖。 如何避免?
卸载需要恢复文件的分区或以只读的方式挂载
下载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/ #挂载
- [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
上传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/
方法一:通过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在恢复文件的时候能不能自动创建空文件和目录?
答:不能
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
用户一般来说是指使用计算机的人,计算机对针使用其的每一个人给了一个特定的名称,用户就可以使用这些名称来登录使用计算机,除了人之外,一些系统服务也需要含有部分特权的用户账户运行;因此出于安全考虑,用户管理应运而生,它加以明确限制各个用户账户的权限,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)
Linux用户三种角色
超级用户: root 拥有对系统的最高的管理权限 ID=0
普通用户:系统用户 UID:1-999(centos7版本) 1-499(centos6版本)
本地用户 UID:1000+ 500+
UID:即每个用户的身份标示,类似于每个人的身份证号码.
虚拟用户:伪用户 一般不会用来登录系统的,它主要是用于维持某个服务的正常运行.如:ftp,apache
下图是用户和组的关系:
一对一:一个用户可以存在一个组中; 一对多:一个用户可以存在多个组中
多对一:多个用户可以存在一个组中; 多对多:多个用户可以存在多个组中
名 称 | 帐号信息 | 说 明 |
用户配置文件 | /etc/passwd | 记录了每个用户的一些基本属性,并且对所有用户可读,每一行记录对应一个用户,每行记录通过冒号进行分隔 |
用户组文件 | /etc/group | 用户组的所有信息存放地儿,并且组名不能重复 |
用户对应的密码信息 | /etc/shadow | 因为passwd文件对所有用户是可读的,为安全起见把密码从passwd中分离出来放入这个单独的文件,该文件只有root用户拥有读权限,从而保证密码安全性 |
命令: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 就可以禁止用户登录。
例:添加一个名为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
- [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
- [root@localhost ~]# useradd -d /opt/yzh1 yzh1
- [root@localhost ~]# tail -1 /etc/passwd
- yzh1:x:1102:1102::/opt/yzh1:/bin/bash
- [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)
我们也可以把这个附属组称为补充组,用户可以有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 #在文件的最后
- [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的软链接
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 ~]#
- [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 defaultMinimum 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 #用于显示当前登录系统的所有用户的用户列表
- [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 #是否创建邮箱文件
语法: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 一样的。
- [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 ~]$
- groupadd
- -g:指定gid
- groupmod
- -n:修改组名
- groupdel
- 删除组
- groupmems
- -g:指定组
- -l:列出指定组的成员
- -d:删除指定组的某个成员
- -a:添加用户
- -p:清空指定组的成员
- gpassed:给组设置密码
- newgrp:登录组
实战场景:公司一台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重启系统
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
通过对文件设定权限可以达到以下三种访问限制权限:
只允许用户自己访问;
允许一个预先指定的用户组中的用户访问;
允许系统中的任何用户访问。
- [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
对于文件来说:
r:读
w:写
x:执行
对于目录来说:
r:读(看到目录里面有什么) ls
w:在目录里面建文件,删除,移动 touch mkdir rm mv cp
x:进入 cd cat
UGO:所有者--用户组--其它用户
所有者: 就是创建文件的用户,这个用户拥有对它所创建的文件的一切权限,所有者可以允许其所在的用户组可以访问所有者的文件。
用户组: 用户组是具有相同特征用户的逻辑集合,有时我们需要让多个用户具有相同的权限,比如查看、修改某一个文件的权限,一种方法是分别对多个用户进行文件访问授权,如果有10个用户的话,就需要授权10次,显然这种方法不太合理;另一种方法是建立一个组,让这个组具有查看、修改此文件的权限,然后将所有需要访问此文件的用户放入这个组中,那么所有用户就具有了和组一样的权限。这就是用户组。
其它用户:系统内的其他所有者用户就是other用户类
- 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
改变文件的所属关系用到命令:
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
修改权限用的命令: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
权限 | 二进制值 | 八进制值 | 描述 |
--- | 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
有三种权限可以应用:读取,写入与执行,这些权限对访问文件和目录的影响如下:
权限 | 对文件的影响 | 对目录的影响 |
r(读取) | 可以读取文件的内容 | 可以列出目录的内容(文件名) |
w(写入) | 可以更改文件的内容 | 可以创建或删除目录中的任意文件 |
x(执行) | 可以作为命令执行文件 | 可以访问目录的内容(取决于目录中文件的权限) |
为什么我们创建的文件的权限是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进制
其实文件与目录设置不止这些,还有所谓的特殊权限。由于特殊权限会拥有一些“特权”.
特殊权限:
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/
扩展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权限
- [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
发现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
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
软件包的类型
rpm二进制包------》已经使用GCC编译后的
tar源码包-----》需要编译
RPM概述:RPM是RPM Package Manager(RPM软件包管理器)的缩写,这一文件格式名称虽然打上了RedHat的标志,但是其原始设计理念是开放式的,现在包括OpenLinux、SUSE以及Turbo Linux等Linux的分发版本都有采用,可以算是公认的行业标准了。
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。 发布指的是:第几次发布。 发布时,可能只是对软件安装的默认参数做了修改,而没有其它改动
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源的扩展。
用法: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安装后,将生成哪些文件
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数据库信息
用法: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 包 来升级。
- [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
- [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
yum(全称为 Yellow dog Updater, Modified)是一个前端软件包管理器。基于RPM包管理,能够从指定的服务器自动下载RPM包并且安装,可以自动处理依赖性关系,并且一次安装所有依赖的软体包,无须繁琐地一次次下载、安装。yum提供了查找、安装、删除某一个、一组甚至全部软件包的命令,而且命令简洁而又好记
YUM:解决依赖关系问题,自动下载软件包,它是基于C/S架构
C=client S=ftp\http\file
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校验的公钥文件地址
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 #查看列表
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类似,只是会自动安装依赖项。
# 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再安装上了
- [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
- [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 //安装指定版本
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
安装完,删除:
make uninstall
有时删除不干净,所以建议大家安装时,在configure步骤添加一个: --prefix 参数。这样删除或备份时,直接删除--prefix指定的安装目录操作就可以了。
从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 架构时,我们会用
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 #安装
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
归档和压缩文件的好处:节约硬盘的资源 ,加快文件传输速率
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
语法: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 #这个压缩比例最高,压缩的时间是最长
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
我们创建压缩的TAR存档,TAR命令它支持三种不同的压缩方式。
gzip压缩速度最快;
bzip2压缩生成的文件比gzip小,但使用不如gzip广;
xz压缩工具相对较新,但是会提供最佳的压缩率
压缩工具: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
file命令
作用: file - determine file type #确定文件类型
用法: file /etc/passwd
注:linux系统不根据后缀名识别文件类型
用file命令查看文件的类型。
- [root@localhost ~]# file /etc/passwd
- /etc/passwd: ASCII text
查看文件:
- [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 可以快速查看磁盘大小的存储空间
例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目录下所有文件,按从大到小排序
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
进程是已启动的可执行程序的运行实例,进程有以下组成部分: • 已分配内存的地址空间; • 安全属性,包括所有权凭据和特权; • 程序代码的一个或多个执行线程; • 进程状态
程序: 二进制文件,静态 /bin/date,/usr/sbin/sshd 进程: 是程序运行的过程, 动态,有生命周期及运行状态。
下图所示的是进程的生命周期:
描述如下:
父进程复制自己的地址空间(fork [fɔ:k] 分叉)创建一个新的(子)进程结构。每个新进程分配一个唯一的进程 ID (PID),满足跟踪安全性之需。PID 和 父进程 ID (PPID)是子进程环境的元素,任何进程都可以创建子进程,所有进程都是第一个系统进程的后代。
centos5或6PID为1的进程是: init
centos7 PID为1的进程是: systemd
僵尸进程:一个进程使用fork创建子进程,如果子进程退出,而父进程并没有调用wait或waitpid获取子进程的状态信息,那么子进程的进程描述符仍然保存在系统中。这种进程称之为僵尸进程。
用自己的话表达:父进程退出了, 子进程没有退出, 那么这些子进程就没有父进程来管理了,就变成僵尸进程。
进程ID(PID):是唯一的数值,用来区分进程
父进程的ID(PPID)
启动进程的用户ID(UID)和所归属的组(GID)
进程状态:状态分为运行R、休眠S、僵尸Z
进程执行的优先级
进程所连接的终端名
进程资源占用:比如占用资源大小(内存、CPU占用量)
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 是用标准的格式显示进程
- [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
[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
运行top , 找出使用CPU最多的进程 ,按大写的P,可以按CPU使用率来排序显示
互动:在linux系统中一个进程,最多可以使用100%cpu对吗?
如下图,可以看到dirtycow(脏牛漏洞,用于提权) 进程使用196.8%
这是你第一次看见: 1
如果你的4核心的cpu,你可以运行400%
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 #用于查看端口,或查看黑客开启的后门端口是哪个进程在使用
pstree:(display a tree of processes)以树状图显示进程,只显示进程的名字,且相同进程合并显示。
格式:pstree 或 pstree -p
以树状图显示进程,还显示进程PID。
[root@localhost ~]# pstree -p
前台进程:是在终端中运行的命令,那么该终端就为进程的控制终端,一旦这个终端关闭,这个进程也随着消失
后台进程: 也叫守护进程(Daemon),是运行在后台的一种特殊进程,不受终端控制,它不需要与终端交互;Linux的大多数服务器就是用守护进程实现的。比如,Web服务器httpd等。
跟系统任务相关的几个命令(了解):
& | 用在一个命令的最后,可以把这个命令放到后台执行. |
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 #将后台挂起的进程恢复到前台运行
关闭进程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
优先级取值范围为(-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
实战场景:公司晚上需要备份1T数据,我在xshell上直接执行备份脚本back.sh可以吗? 或直接运行back.sh & 放到后台运行可以吗? 当关了xshell后,back.sh & 还在后台执行吗?
答:xshell长时间连接,如果本地网络偶尔断开或xshell不小心关闭,都会让后台运行的备份命令停止运行的。正确做法使用: srceen
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
直接在命令行键入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
文件描述符:是内核为了高效管理已被打开的文件所创建的索引,用于指向被打开的文件,所有执行I/O操作的系统调用都通过文件描述符;文件描述符是一个简单的非负整数,用以标明每一个被进程所打开的文件,程序刚刚启动的时候,第一个打开的文件是0,第二个是1,依此类推。也可以理解为是一个文件的身份ID
用户通过操作系统处理信息的过程中,使用的交互设备文件(键盘,鼠标,显示器)
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
永久修改,会在第三阶段讲系统调优时讲。
定义:将命令的正常输出结果保存到指定的文件中,而不是直接显示在显示器的屏幕上
重定向输出使用”>” “>>” 操作符号
语法: > 文件名 #表示将标准输出的内容,写到后面的文件中,如果此文件名已经存在,将会覆盖原文件中的内容
>> 文件名 #表示将标准输出的内容,追加到后面的文件中。若重定向的输出的文件不存在,则会新建该文件
例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
例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数据库中
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 #查看效果
将命令执行过程中出现的错误信息 (选项或参数错误) 保存到指定的文件,而不是直接显示到显示器
作用:错误信息保存到文件
操作符: 错误重定向符号: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>> 操作符
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
&表示等同于的意思
例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中,也就是将产生的所有信息丢弃.
语法: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
功能:读取标准输入的数据,并将其内容输出成文件。 语法: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
注: 可以使用来记录日志
查找文件一般有以下几个命令:
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加强版本
格式: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 #再修改过来
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
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
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硬盘被装上飞机,重量超过一吨
常见硬盘品牌:希捷 西数 日立 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快很多一样。
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 表示每块磁盘上划分的磁盘分区编号
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级别检验完成之后进行检验 |
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
Swap分区在系统的物理内存不够用的时候,把硬盘空间中的一部分空间释放出来,以供当前运行的程序使用。
mkswap /devices (格式化成swap格式)
swapon /swap (激活/swap,加入到swap分区中)
vim /etc/fstab (开机自启动新添加的swap分区) ,在最后追加:
/devices swap swap defaults 0 0
如果不想使用需要删除,只需要执行#swapoff /swap
- [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
- [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
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
文件系统结构,理解文件系统,要从文件储存说起。
硬盘结构:
互动:磁盘内部是真空的吗? 磁盘内部不是真空,只不过里面的空气很干净。如果是真空,还不利于散热
磁盘相关专业术语:
硬盘的内部是金属盘片,将圆形的盘片划分成若干个扇形区域,这就是扇区。若干个扇区就组成整个盘片。为什么要分扇区?是逻辑化数据的需要,能更好的管理硬盘空间。 以盘片中心为圆心,把盘片分成若干个同心圆,那每一个划分圆的“线条”,就称为磁道。
硬盘内的盘片有两个面,都可以储存数据,而硬盘内的盘片往往不止一张,常见的有两张,那么,两张盘片中相同位置的磁道,就组成一个“柱面”,盘片中有多少个磁道,就有多少个柱面。盘片两面都能存数据,要读取它,必须有磁头,所以,每一个面,都有一个磁头,一张盘片就有两个磁头。
硬盘的存储容量=磁头数×磁道(柱面)数×每道扇区数×每道扇区字节数。
磁道从外向内自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分区,装最外面
磁盘写数据时,先从外面往里。
簇类似于Linux系统中的block
例:在win10系统,新一个文本文件“新建文本文档.txt”,只输入aa两个字符。
右击属性查看大小: 说明我的NTFS文件系统中默认的簇大小为4KB
- [root@localhost ~]# stat /etc/passwd #查看Linux block 大小
- 文件:"/etc/passwd"
- 大小:2053 块:8 IO 块:4096 =4KB 普通文件
Linux文件系统由三部分组成 : 文件名,inode,block
Linux文件系统: ext3,ext4,xfs
windows文件系统: FAT32,NTFS
- [root@localhost ~]# cp /etc/passwd a.txt
- [root@localhost ~]# ls a.txt # a.txt 就是文件名
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
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已经用光,但是硬盘还未存满的情况。这时,就无法在硬盘上创建新文件。
Unix/Linux系统中,目录(directory)也是一种文件。打开目录,实际上就是打开目录文件。
目录文件的结构非常简单,就是一系列目录项的列表。每个目录项,由两部分组成:所包含文件的文件名,以及该文件名对应的inode号码。
- [root@localhost ~]# ls -id /etc
- 8388673 /etc
例:ls -i命令列出整个目录文件,即文件名和inode号码:
[root@localhost ~]# ls -i /etc
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设置小:效率低,利用率高。
Linux链接分两种,一种被称为硬链接(Hard Link),另一种被称为软链接,即符号链接(Symbolic Link)。默认情况下,ln命令产生硬链接。
【硬连接】:硬连接指通过索引节点号来进行连接。inode是可以对应多个文件名的
在Linux的文件系统中,保存在磁盘分区中的文件不管是什么类型都给它分配一个编号,称为索引节点号(Inode Index)。
在Linux中,多个文件名可以指向同一索引节点。一般这种连接就是硬连接。
硬连接的作用是允许一个文件拥有多个有效路径名,这样用户就可以建立硬连接到重要文件,以防止“误删”的功能。
只删除一个连接并不影响索引节点本身和其它的连接,只有当最后一个连接被删除后,文件的数据块及目录的连接才会被释放。也就是说,文件真正删除的条件是与之相关的所有硬连接文件均被删除。
【软连接】:另外一种连接称之为符号连接(Symbolic Link),也叫软连接。软链接文件有类似于Windows的快捷方式。它实际上是一个特殊的文件。在符号连接中,文件实际上是一个文本文件,其中包含的有另一文件的位置信息
语法格式: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/.
软链接:相当于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 #报错了
由于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
- 就是为什么每次修改完服务器的配置文件,都要重启服务,重新读一下配置文件。
实战场景:在一台配置较低的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 也强制进行检查
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
磁盘阵列(Redundant Arrays of Independent Disks,RAID),有“独立磁盘构成的具有冗余能力的阵列”之意。 磁盘阵列是由很多价格较便宜的磁盘,以硬件(RAID卡)或软件(MDADM)形式组合成一个容量巨大的磁盘组,利用多个磁盘组合在一起,提升整个磁盘系统效能。利用这项技术,将数据切割成许多区段,分别存放在各个硬盘上。 磁盘阵列还能利用同位检查(Parity Check)的观念,在数组中任意一个硬盘故障时,仍可读出数据,在数据重构时,将数据经计算后重新置入新硬盘中
注:RAID可以预防数据丢失,但是它并不能完全保证你的数据不会丢失,所以大家使用RAID的同时还是注意备份重要的数据
RAID的创建有两种方式:软RAID(通过操作系统软件来实现)和硬RAID(使用硬件阵列卡);在企业中用的最多的是:raid1、raid5和raid10。不过随着云的高速发展,供应商一般可以把硬件问题解决掉。
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相对于单个磁盘优点:
条带 (strping),也是我们最早出现的RAID模式
需磁盘数量:2块以上(大小最好相同),是组建磁盘阵列中最简单的一种形式,只需要2块以上的硬盘即可.
特点:成本低,可以提高整个磁盘的性能和吞吐量。RAID 0没有提供冗余或错误修复能力,速度快.
任何一个磁盘的损坏将损坏全部数据;磁盘利用率为100%。
mirroring(镜像卷),需要磁盘两块以上
原理:是把一个磁盘的数据镜像到另一个磁盘上,也就是说数据在写入一块磁盘的同时,会在另一块闲置的磁盘上生成镜像文件,(同步)
RAID 1 mirroring(镜像卷),至少需要两块硬盘,raid大小等于两个raid分区中最小的容量(最好将分区大小分为一样),数据有冗余,在存储时同时写入两块硬盘,实现了数据备份;
磁盘利用率为50%,即2块100G的磁盘构成RAID1只能提供100G的可用空间。如下图
需要三块或以上硬盘,可以提供热备盘实现故障的恢复;只损坏一块,没有问题。但如果同时损坏两块磁盘,则数据将都会损坏。 空间利用率: (n-1)/n 2/3 如下图所示
奇偶校验信息的作用:
当RAID5的一个磁盘数据发生损坏后,利用剩下的数据和相应的奇偶校验信息去恢复被损坏的数据。
扩展:异或运算
是用相对简单的异或逻辑运算(相同为0,相异为1)
A值 | B值 | Xor结果 |
0 | 0 | 0 |
1 | 0 | 1 |
0 | 1 | 1 |
1 | 1 | 0 |
RAID-10镜像+条带
RAID 10是将镜像和条带进行两级组合的RAID级别,第一级是RAID1镜像对,第二级为RAID 0。比如我们有8块盘,它是先两两做镜像,形成了新的4块盘,然后对这4块盘做RAID0;当RAID10有一个硬盘受损其余硬盘会继续工作,这个时候受影响的硬盘只有2块
几个方案对比下来, RAID5是最适合的,如下图:
一般两种处理方法:热备和热插拔
热备:HotSpare
定义:当冗余的RAID组中某个硬盘失效时,在不干扰当前RAID系统的正常使用的情况下,用RAID系统中另外一个正常的备用硬盘自动顶替失效硬盘,及时保证RAID系统的冗余性
全局式:备用硬盘为系统中所有的冗余RAID组共享
专用式:备用硬盘为系统中某一组冗余RAID组专用
如下图所示:是一个全局热备的示例,该热备盘由系统中两个RAID组共享,可自动顶替任何一个RAID中的一个失效硬盘
热插拔:HotSwap
定义:在不影响系统正常运转的情况下,用正常的物理硬盘替换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也就都坏了。
实验环境:
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
实验内容如下:
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
实验环境:
raid种类 | 磁盘 | 热备盘 |
raid5 | sdg、sdh、sdi | sdj |
1)创建RAID5, 添加1个热备盘,指定chunk大小为32K
-x或--spare-devicds= 指定阵列中备用盘的数量
-c或--chunk= 设定阵列的块chunk块大小 ,单位为KB
2)停止阵列,重新激活阵列
3)使用热备盘,扩展阵列容量,从3个磁盘扩展到4个
- [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 #热备盘
- [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
- [root@localhost ~]# mdadm -As
- mdadm: /dev/md5 has been started with 3 drives and 1 spare.
将热备盘增加到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)
实验环境:
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
- [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超级块
联想(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的基本概念
实战场景:对于生产环境下的服务器来说,如果存储数据的分区磁盘空间不够了怎么办?
答:只能换一个更大的磁盘。 如果用了一段时间后, 空间又不够了,怎么办?再加一块更大的?换磁盘的过程中,还需要把数据从一个硬盘复制到另一个硬盘,过程太慢了。
解决方案:使用LVM在线动态扩容
LVM( Logical Volume Manager)逻辑卷管理,是在磁盘分区和文件系统之间添加的一个逻辑层,来为文件系统屏蔽下层磁盘分区布局,提供一个抽象的盘卷,在盘卷上建立文件系统。管理员利用LVM可以在磁盘不用重新分区的情况下动态调整文件系统的大小,并且利用LVM管理的文件系统可以跨越磁盘,当服务器添加了新的磁盘后,管理员不必将原有的文件移动到新的磁盘上,而是通过LVM可以直接扩展文件系统跨越磁盘
它就是通过将底层的物理硬盘封装起来,然后以逻辑卷的方式呈现给上层应用。在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挂载使用
使用卷组,使多个硬盘空间看起来像是一个大的硬盘
使用逻辑卷,可以跨多个硬盘空间的分区 sdb1 sdb2 sdc1 sdd2 sdf
在使用逻辑卷时,它可以在空间不足时动态调整它的大小
在调整逻辑卷大小时,不需要考虑逻辑卷在硬盘上的位置,不用担心没有可用的连续空间
可以在线对LV,VG 进行创建,删除,调整大小等操作。LVM上的文件系统也需要重新调整大小。
允许创建快照,可以用来保存文件系统的备份。
RAID+LVM一起用:LVM是软件的卷管理方式,而RAID是磁盘管理的方法。对于重要的数据,使用RAID来保护物理的磁盘不会因为故障而中断业务,再用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数量,其过程不会丢失原始数据
功能 | 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 |
添加一个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
指定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
首先,确定一下是否有可用的扩容空间,因为空间是从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
- [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
互动: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了
创建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
安装SSM ssm工具了一下
[root@localhost ~]# yum -y install system-storage-manager
SSM:检查关于可用硬驱和LVM卷的信息。显示关于现有磁盘存储设备、存储池、LVM卷和存储快照的信息。
列出设备信息
- 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
- ----------------------------------------------------
实战场景:公司要搭建一台邮件服务器,考虑到后期公司发展规模扩张,需要你创建一个名为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
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
大家平常都会有一些比如说:你每天固定几点起床?每天按时上班打卡、每月15号准时开工资、每年2月14你俩口子某某纪念日等这些诸如此类,这些都是定时发生的。或者说是通俗点说:例行公事;还比如说我们还会遇到一些突发事件,临时几点过来加个班?刚好晚上几点聚个餐?
像上面这些情况,如果事少的话你大脑可以记住,如果事很多,像老板经理董事长每天的工作安排,通常都是记在一些本上,或者闹铃提醒等。
那么,咱们的LINUX系统和上面的情况也很类似,我们也可以通过一些设置。来让电脑定时提醒我们该做什么事了。或者我们提前设置好,告诉电脑你几点做什么几点做什么,这种我们就叫它定时任务。而遇到一些需要执行的事情或任务。我们也可以通过命令来告诉电脑一会临时把这个工作给做一下
总结:在我们LINUX中,我们可以通过crontab和at这两个东西来实现这些功能的
计划任务的作用:是做一些周期性的任务,在生产中的主要用来定期备份数据
CROND:这个守护进程是为了周期性执行任务或处理等待事件而存在
任务调度分两种:系统任务调度,用户任务调度
计划任务的安排方式分两种:
一种是定时性的,也就是例行。就是每隔一定的周期就要重复来做这个事情
一种是突发性的,就是这次做完了这个事,就没有下一次了,临时决定,只执行一次的任务
at和crontab这两个命令:
at:它是一个可以处理仅执行一次就结束的指令
crontab:它是会把你指定的工作或任务,比如:脚本等,按照你设定的周期一直循环执行下去
语法格式: 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来解除锁定,
这个查看,只能看到还没有执行的。如果这个任务已经开始执行或者执行完成了,是看不到的
- [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
/etc/at.deny黑名单和/etc/at.allow白名单(优先级高)
at是计划任务atd的管理工具,每编写一个计划任务,就会在“/var/spool/at/spool”目录下生成一个脚本,将atd服务停止之后,at任务不会执行,只要atd服务启动之后,任务就会立马执行,当任务过期之后,会在下一次atd启动时执行
crond命令定期检查是否黑名单有要执行的工作,如果有要执行的工作便会自动执行该工作
cron是一个linux下的定时执行工具,可以在无需人工干预的情况下运行作业。
linux任务调度的工作主要分为以下两类:
系统执行的工作:系统周期性所要执行的工作,如更新whatis数据库 updatedb数据库,日志定期切割,收集系统状态信息,/tmp定期清理
启动crond服务
- [root@localhost at]# systemctl start crond
- [root@localhost at]# systemctl enable crond
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 |
例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
所以后期可以使用这一招排查,黑客是否在你的机器中安装了定时任务
系统级别的计划任务
- [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 #主配置文件 也可添加任务;
常见写法:
每天晚上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目录
在centos7中,系统日志消息由两个服务负责处理:systemd-journald和rsyslog
系统日志文件概述:/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
分类 级别
日志的分类:
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 | 紧急,内核崩溃等严重信息 |
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进程的开销
数据存储在内存,如果关机不当数据消失
. info 大于等于info级别的信息全部记录到某个文件
.=级别 仅记录等于某个级别的日志
例:.=info 只记录info级别的日志
.! 级别 除了某个级别意外,记录所有的级别信息
例.!err 除了err外记录所有
.none 指的是排除某个类别 例: mail.none 所有mail类别的日志都不记录
- [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 #取消,这里一定要取消,不然后面做日志切割报错
互动:当日志太多,导致日志很文件大怎么办?
在linux下的日志会定期进行滚动增加,我们可以在线对正在进行回滚的日志进行指定大小的切割(动态),如果这个日志是静态的。比如没有应用向里面写内容。那么我们也可以用split工具进行切割;其中Logrotate支持按时间和大小来自动切分,以防止日志文件太大。
logrotate配置文件主要有:
/etc/logrotate.conf 以及 /etc/logrotate.d/ 这个子目录下的明细配置文件。
logrotate的执行由crond服务调用的。
[root@localhost ~]# vim /etc/cron.daily/logrotate #查看logrotate脚本内容
logrotate程序每天由cron在指定的时间(/etc/crontab)启动
日志是很大的,如果让日志无限制的记录下去 是一件很可怕的事情,日积月累就有几百兆占用磁盘的空间,
如果你要找出某一条可用信息:海底捞针
日志切割:
当日志达到某个特定的大小,我们将日志分类,之前的日志保留一个备份,再产生的日志创建一个同名的文件保存新的日志.
编辑配置文件
[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上次轮换日志文件的时间。
定义了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了。。。
实验拓扑图:
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
实战场景:为了节约公司开销,需要你设置公司的svn版本管理服务器,每天晚上23:00开机,每天早上9:00自动开机。
- [root@localhost ~]# crontab -e #写入以下内容
- 0 23 * * * /usr/sbin/shutdown -h now
这个可以通过设置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 进行保存,重启电脑后生效!希望各位能从本片经验中学会如何定时开机。
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
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 程序,最后就等待用户登入啦;
如图:
- [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级别
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
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
命令: 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:开机不启动,但可被另一个启用的服务激活
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 重启
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
在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
实战场景:如何防止别人恶意通过单用户系统破解root密码,进入系统窃取数据?
给grub加密,不让别人通过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
生成密码
- [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 开始启动
实战:使用系统光盘进入救援模式拯救坏掉的系统
实战场景:当系统坏了,进不去了,还需要把里面的数据复制出来,怎么办?
可以进入救援模式拷贝数据
修改BIOS启动顺序,直接以光盘引导系统
ramfs : 内存文件系统
chroot /mnt/sysimage # 切换文件系统根
使用场景: 修复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模式中,需要切换根目录,进行系统修复:
先退一下,再重启,修复完成
第一步:删除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相关的系统。
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
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 模型的层次数量与内容可能是最佳的选择,其实并非如此,其中会话层和表示层几乎是空的,而数据链路层和网络层包含内容太多,有很多的子层插入,每个子层都有不同的功能。
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传文件,数据完整性要求高。
(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端口都会监听的
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这个网段都用于环回口
- [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虚拟机网卡接口
方法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
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
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 就可以退出~
http://ssa.yundun.com/cc 云盾全球实时攻防图
你现在学得是第一阶段中的内容,这个案例是让你开眼界!
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:代表一个打开的连接
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是一个命令解释器,它在操作系统的最外层,负责直接与用户进行对话,把用户的输入解释给操作系统,并处理各种各样的操作系统的输出结果,输出到屏幕反馈给用户。这种对话方式可是交互也可以是非交互式的
我们所输入的命令计算机是不识别的,这时就需要一种程序来帮助我们进行翻译,变成计算机能识别的二进制程序,同时又把计算机生成的结果返回给我们。
编程语言主要用:低级语言和高级语言
1)低级语言:
机器语言:二进制语言
汇编语言:符号语言,使用助记符来代替操作码,也就是用符号代替机器语言的二进制码
它们都是面向机器的语言
2)高级语言:
它是比较接近自然语言或者说人类语言的一种编程,用人们能够容易理解的方式进行编写程序,
静态语言:编译型语言 如:c 、 c++ 、 java,
动态语言:解释型语言 如: php 、 shell 、 python 、 perl
gcc编译器:(解释器) 将人类理解的语言翻译成机器理解的语言
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)
变量是shell 传递数据的一种方法。变量是用来代表每个值的符号名。我们可以把变量当成一个容器,通过变量,可以在内存中存储数据。也可以在脚本执行中进行修改和访问存储的数据
变量的设置规则:
变量名称通常是大写字母,它可以由数字、字母(大小写)和下划线_组成。变量名区分大小写;但是大家要注意变量名称不能以数字开头
等号 = 用于为变量分配值,在使用过程中等号两边不能有空格
变量存储的数据类型是整数值和字符串值
在对变量赋于字符串值时,建议大家用引号将其括起来。因为如果字符串中存在空格隔符号。需要使用单引号或双引号
要对变量进行调用,可以在变量名称前加美元符号$
如果需要增加变量的值,那么可以进行变量值的叠加。不过变量需要用双引号包含“$变量名”或用${变量名}包含
变量的分类
按照变量的作用可以分成4类:
1、用户自定义变量
2、环境变量:这种变量中主要保存的是和系统操作环境相关的数据。
3位置参数变量:这种变量主要是用来向脚本当中传递参数或数据的,变量名不能自定义,变量作用是固定的。
4、预定义变量:是Bash中已经定义好的变量,变量名不能自定义,变量作用也是固定的。
按照变量作用域可以分成2类:全局变量和局部变量。
局部变量是shell 程序内部定义的,其使用范围仅限于定义它的程序,对其它程序不可见。包括:用户自定义变量、位置变量和预定义变量。
全局变量是环境变量,其值不随shell 脚本的执行结束而消失。
变量名命名规则:由字母或下划线打头,不允许数字开头,后面由字母、数字或下划线组成,并且大小写字母意义不同。在使用变量时,在变量名前加$
例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
例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
- [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 #解压成功
‘’ 在单引号中所有的字符包括特殊字符($,'',`和\)都将解释成字符本身而成为普通字符。
“” 在双引号中,除了$, '', `和\以外所有的字符都解释成字符本身,拥有“调用变量的值”、“引用命令”和“转义符”的特殊含义
注:\转义符,跟在\之后的特殊符号将失去特殊含义,变为普通字符。如\$将输出“$”符号,而不当做是变量引用
例:
- [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
在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文件
新打开的链接中,也有了
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 #重新加载配置文件,使用配置生效
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
有些变量是一开始执行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
(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
格式:$((表达式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
上传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。
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
从键盘读取变量的值,通常用在shell脚本中与用户进行交互的场合。该命令可以一次读取多个变量的值,变量和输入的值都需要使用空格隔开。在read命令后面,如果没有指定变量名,读取的数据将被自动赋值给特定的变量REPLY
read从键盘读入数据,赋给变量
例1:
- [root@localhost ~]# read a b
- hello world
- [root@localhost ~]# echo $a $b
- hello world
例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
- 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
语法格式:
- 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
语法结构:
- 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
Shell中的 test 命令用于检查某个条件是否成立,它可以进行数值、字符和文件三个方面的测试
格式:test 测试条件
如果结果是对的,也叫结果为真,用$?=0表示,反之为假,用非0表示
参数 | 说明 | 示例 |
-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
注意:在做数值比较时,只能用整数
参数. | 说明 | 示例 |
== | 等于则为真 | [ “$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
参数 | .说明 | 示例 |
-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
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、双方括号号[[ ]]用于高级字符串处理,比如“模糊匹配”
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
- [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
- [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
- [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是开关语句的一个组成部分;
它是根据变量的不同进行取值比较,然后针对不同的取值分别执行不同的命令操作
适用于多分支,是一个多选择语句
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
语法格式:
- 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
重复测试指令的条件,只要条件成立就反复执行对应的命令操作,直到命令不成立或为假;
语法格式如下:
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
例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
- [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 !"
- [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
- [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
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
在我们使用循环语句进行循环的过程中,有时候需要在未达到循环结束条件时强制跳出循环,那么Shell给我们提供了两个命令来实现该功能: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
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
函数是一个脚本代码块,你可以对它进行自定义命名,并且可以在脚本中任意位置使用这个函数,要使用这个函数,只要使用这个函数名称就可以了。使用函数的好处:模块化,代码可读性强。
方法1:
- function name {
- commands
- }
- 注意:name是函数唯一的名称
方法2:name后面的括号表示你正在定义一个函数
- name(){
- commands
- }
调用函数语法:
函数名 参数1 参数2 …
调用函数时,可以传递参数。在函数中用$1、$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
使用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 只是在函数最后添加一行,然后返回数字,只能让函数后面的命令不执行,无法强制退出整个脚本的。
例子: 函数名就相当于一个命令
- [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
第一种:通过脚本传递参数给函数中的位置参数$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
函数使用的变量类型有两种:
局部变量
全局变量
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
从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 "
此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 ([ɪkˈspekt] 期待 )是从它发展出来的。如果你想要写一个能够自动处理输入输出的脚本(如向用户提问并且验证密码)又不想面对C或者Perl,那么expect是你的最好的选择。它可以用来做一些linux下无法做到交互的一些命令操作
[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
正则表达式,又称规则表达式。(英语:Regular Expression [ˈreɡjulə] 规则的 [ iksˈpreʃən] 表达 ),在代码中常简写为regex、regexp或RE),计算机科学的一个概念。正则表达式通常被用来检索、替换那些符合某个模式(规则)的文本。
正则表达式不只有一种,而且LINUX中不同的程序可能会使用不同的正则表达式,如:
工具:grep sed awk
LINUX中常用的有两种正则表达式引擎
基础正则表达式:BRE
扩展正则表达式: ERE
基础正则表达式
特别字符 | 描述 |
$ | 匹配输入字符串的结尾位置。要匹配 $ 字符本身,请使用 \$ |
( ) | 标记一个子表达式的开始和结束位置。要匹配这些字符,请使用 \( 和 \) |
* | 匹配前面的子表达式零次或多次。要匹配 * 字符,请使用 \* |
+ | 匹配前面的子表达式一次或多次。要匹配 + 字符,请使用 \+ |
. | 匹配除换行符 \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
sed编辑器是一行一行的处理文件内容的。正在处理的内容存放在模式空间(缓冲区)内,处理完成后按照选项的规定进行输出或文件的修改。
接着处理下一行,这样不断重复,直到文件末尾。文件内容并没有改变,除非你使用重定向存储输出。Sed主要用来自动编辑一个或多个文件;简化对文件的反复操作;
sed也是支持正则表达式的,如果要使用扩展正则加参数-r
sed的执行过程:
一次读取一行数据
根据我们提供的规则来匹配相关的数据,比如查找root。
按照命令修改数据流中的数据,比如替换
将结果进行输出
重复上面四步
语法格式: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
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
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
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
检查语法是否有错:
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脚本中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"
grep和egrep:文本过滤的
sed:流编辑器,实现编辑的
awk:文本报告生成器,实现格式化文本输出
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 记录分隔符(默认是一个换行符)
常用的命令选项:
-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%
命令格式:
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
- --------------------------------
思路:通过: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
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。