Linux基础

①Linux 系统部署

一、GNU/Linux 的历史

1.自由软件之父:Richard M. Stallman 理查德·斯托曼(GNU的创始人)

2.Linux 之父 :林纳斯•本纳第克特•托瓦兹(Linus Benedict Torvalds)

二、Linux发行版介绍

1.RHEL(Red Hat Enterprise Linux)

Red Hat公司的Linux系统,商业版

2、CentOS(Community Enterprise Operating System)

社区企业操作系统,不包含封闭源代码软件

3.Ubunt(乌班图)

一个以桌面应用为主的开源GNU/Linux操作系统,基于Debian GNU/Linux

4.Debian

常指Debian GNU/Linux。广义的Debian是指一个致力于创建自由操作系统的合作组织及其作品,Debian项目众多内核分支中以Linux宏内核为主,开发者所创建的操作系统中绝大部分基础工具来自于GNU工程

三、Linux相关认证

RHCA 红帽认证架构师
RHCE 红帽认证工程师
RHCSA 红帽认证系统管理员

四、Linux系统部署(掌握)

1.服务器介绍

塔式服务器

常见,外形结构和普通PC类似。塔式服务器尺寸没有统一标准,由于塔式服务器的机箱比较大,服务器的配置也可以很高,冗余扩展很齐备,所以应用范围非常广,是目前使用率最高的一种服务器。

机架式服务器

机架式服务器的外形像交换机,有1U(1U=1.75英寸)、2U、4U等规格。机架式服务器安装在标准的19英寸机柜里面。这种结构的多为功能型服务器。

刀片式服务器(属于机架式)

刀片服务器在标准高度的机架式机箱内可插装多个卡式的服务器单元,是一种实现HAHD(高可用高密度)的低成本服务器平台,为特殊应用行业和高密度计算环境专门设计。刀片服务器就像“刀片”一样,每一块“刀片”就是一块系统主板。

2.VMware部署CENTOS

1.安装并打开VMWARE(使用管理员身份运行)
2.在VMware中新建虚拟机
3.典型/自定义,选择自定义安装
4.虚拟机兼容性,默认下一步
5.安装来源,选择稍后安装操作系统
7.操作系统类型,选择linux centos7 64
8.自定义虚拟机名称,和文件夹位置。D:\KF\VM\Centos7-1-64
9.虚拟机CPU,默认下一步
10.内存选择,1024MB
11.网络连接,选择桥接
12.IO类型,默认下一步
13.虚拟磁盘类型,默认下一步
14.创建新磁盘,默认下一步
15.磁盘大小,默认下一步,20G
16.磁盘文件名,默认下一步
17.完成
18.在新虚拟机,选择DVD,选用ISO 镜像,选择CENTOS7 安装镜像
19.开启此虚拟机
20.install centos 7 安装操作系统
21.中文,简体中文
22.软件选择:带GUI的服务器、兼容、开发
23.安装位置:默认选择完成(自动分区)
24.点击开始安装
25.设置root密码
26.同意许可,完成配置
27.时区亚洲上海,用户名,密码
28.root身份进入系统桌面
29.开启网卡自动连接
30.完成实验

五、Linux系统基本操作(了解)

1.登录root用户
2.打开主文件夹创建并删除文件
3.改变目录:cd 目录名

cd		/etc/sysconfig/network-scritpt
cd		/root
cd  	/aaa/bbb/ccc

4.创建文件: touch 文件名
5.删除文件: rm -rf 文件名
6.改名文件:mv 源文件 目标文件
7.关机:init 0

②Linux文件和用户管理

一、文件管理

1.Linux目录结构

Linux: 以单根的方式组织文件 /

Linux系统的文件是没有扩展名!!!

#查看Linux目录结构
[root@localhost ~]# ls /    
bin dev lib media net root srv usr
boot etc lib64 misc opt sbin sys var
cgroup home lost+found mnt proc selinux tmp
目录名称功能
bin普通用户命令目录 /bin/ls, /bin/date
sbin管理员使命令目录 /sbin/service
dev设备文件目录。硬件,驱动 /dev/sda,/dev/sda1
rootroot用户家目录
home普通用户家目录
etc系统配置文件,控制台文件
usr/usr/local 软件安装的目录,系统文件
tmp临时文件
var存放一些变化文件,比如数据库,日志,邮件
boot系统启动的相关文件,启动目录
run运行
media移动设备默认的挂载点
mnt手工挂载设备的挂载点
lib、lib64库文件Glibc
lost+foundfsck修复时,存储没有链接的文件或目录

2.文件管理

  • 文件类型(理解)
命令ll  -d 可查看

- 普通文件
d 目录文件

非常见类型:
b 块设备文件,存储设备硬盘,U盘
c 字符设备文件,打印机,终端 /dev/tty1
l 链接文件
s 套接字文件
p 管道文件
  • 文件管理命令
### 1.改变目录
cd  路径
绝对路径: 从/开始的路径 /home/alice/file1
相对路径: 相对于当前目录开始 ./a.txt

ls   列出目录当中的内容
### 2.创建文件
touch    路径和名字
示例
touch file3 file4
touch /home/file10.txt
### 3.创建目录
mkdir      路径和目录名    
mkdir  -p   父系,当创建目录没有上一级时,自动递归创建

示例====参数 -v 详细 -p 递归
# mkdir dir1
# mkdir /home/dir2 /home/dir3
# mkdir /home/{dir4,dir5}
# mkdir -v /home/{dir6,dir7}	//显示详细信息,遍历
# mkdir -v /home/dir8/111/22	//错误示范
# mkdir -pv /home/dir8/111/222  //包括其父母的创建,不会有任何消息输出
# mkdir -pv /home/{localhost/{dir1,111},nizhan}		
### 4.复制
cp   源文件路径     目标文件夹
cp  -r    源目录    目标目录

示例
====参数: -r 目录 -v 详细 -f 强制   -n  静默
# cp -v install.log  /home/dir1	  //-v 显示详细信息
# cp -v install.log  /home/dir1/localhost.txt
# cp -rv  /etc  /home/dir1    //-r 拷贝文件夹
# cp  -rv  源文件1 源文件2 源文件N  目标文件 //将多个文件拷贝到同一个目录
# cp -rfn /etc /tmp    //-f, --force 强制

cp是什么
[root@localhost ~]# type -a cp
cp is azliased to `cp -i'
cp is /bin/cp
### 5.移动
mv    源文件路径   目标文件路径

示例
1.创建一个新文件file1
#touch  /root/file1
2.把file1文件移动到/tmp目录中。
# mv    /root/file1    /tmp 
# ls    /tmp/file1
3.把file1文件更名为file2
# mv    /tmp/file1     /tmp/file2
4.观察file1文件已经更名为file2
# ls  /tmp/file1    /tmp/file2
### 6.删除
rm -rf    文件或目录的路径

示例
====参数  -r 递归 -f force强制 -v 详细过程     *通配符    文件名
[root@localhost ~]# rm -rf /home/dir10/* //不包括隐藏文件

如果快速删除如下文件,“file1.txt和file2.txt”
[root@localhost ~]# rm -rf file*
### 7.查看文件内容

# cat全部
 cat  文件路径
===参数  -n 显示行号   -A 包括控制字符(换行符/制表符)

# more翻页

###### head头部
[root@localhost ~]# head /etc/passwd
[root@localhost ~]# head -2 /etc/passwd

# tail尾部
[root@localhost ~]# tail /etc/passwd
[root@localhost ~]# tail -1 /etc/passwd
[root@localhost ~]# tail -f /var/log/secure
注释:tail  -f 动态查看文件的尾部

# grep过滤关键字
语法:grep 关键字   文件名
例:grep 'root' /etc/passwd				
### 8.修改文件内容

# 重定向  <  >   <<    >>
[root@localhost ~]# ls -a > list.txt

# 文件编辑器1
图形文件编辑器 gedit

# 文件编辑器2
vi, vim

可视模式,按V进入,小v光标选取,大V直接选取一行,YYp复制粘贴

ctrl+V,上下选择,然后可以ctrl+>   进行整体缩进



命令模式

hjkL              //上下左右
0 $               //行首行尾
gg G 			//页首页尾
3G 进入第三行  
/string (n N 可以循环的)     //查找字符,按n键选下一个(重要)
y 复制
d 删除
p 粘贴
u undo撤销
							
a 进入插入模式
i 进入插入模式
o 进入插入模式
A 进入插入模式

: 进入末行模式(扩展命令模式)
v 进入可视模式
ESC 返回命令模式

保存、退出

:w 保存 
:q 退出 
:wq 保存并退出 
:q! 强制退出不保存


查找替换

:范围 s/原内容/新内容/全局 
:1,5 s/root/localhost/g          从1-5行的root 替换为localhost
读入文件/写文件(另存为)
:w /tmp/aaa.txt 另存为/tmp/aaa.txt 

设置环境 

:set nu 设置行号 
:set list 显示控制字符
:set nonu 取消设置行号 

二、用户管理

1.查看用户/组

查看当前登录的用户信息:

[root@localhost ~]# id
uid=0(root) gid=0(root) groups=0(root)

查看文件的owner:

[root@localhost ~]# ll /home/ 
drwx------. 4 alice alice 4096 Jun 2 15:59 alice
drwx------. 2 root root 16384 Jun 1 23:09 lost+found
drwxr-xr-x 	2 root root 4096 Jun 2 15:33 localhost

查看运行进程的username:

[root@localhost ~]# ps aux 
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.0 19360 1536 ? Ss 13:29 0:00 /sbin/init
root 2 0.0 0.0 0 0 ? S 13:29 0:00 [kthreadd]
root 3 0.0 0.0 0 0 ? S 13:29 0:00 [migration/0]

2.用户/组信息文件

用户基本信息文件

[root@localhost ~]# cat /etc/passwd      #冒号分割为7列字段
 root:x:0:0:root:/root:/bin/bash

root  用户名,登录系统的名字
X     密码占位符,具体内容不在这里
0     UID,用户的身份证号
0     GID,GROUP 组号
root  描述,比如经理 manager
/root 家目录,登录系统时所在目录
/bin/bash  登录shell (shell:命令解释器)

系统约定: RHEL7
uid: 0 特权用户
uid: 1~499 系统用户
uid: 1000+ 普通用户

用户密码信息文件

[root@localhost ~]# cat /etc/shadow       #冒号分割为8列
 root : $1$MYG2N : 15636 : 0 : 99999 : 7 :   : 
 
了解即可
加密算法$id$salt$encrypted
$1: MD5
$5: SHA-256
$6: SHA-512
--------------------------
1)“登录名”是与/etc/passwd文件中的登录名相一致的用户账号
2)“口令”字段存放的是加密后的用户口令字,如果为空,则对应用户没有口令,登录时不需要口令;   
星号代表帐号被锁定;
双叹号表示这个密码已经过期了。
$6$开头的,表明是用SHA-512加密的,
$1$ 表明是用MD5加密的
$2$ 是用Blowfish加密的
$5$ 是用 SHA-256加密的。 

3)“最后一次修改时间”表示的是从某个时刻起,到用户最后一次修改口令时的天数。时间起点对不同的系统可能不一样
4)“最小时间间隔”指的是两次修改口令之间所需的最小天数。
5)“最大时间间隔”指的是口令保持有效的最大天数。
6)“警告时间”字段表示的是从系统开始警告用户到用户密码正式失效之间的天数。
7)“不活动时间”表示的是用户没有登录活动但账号仍能保持有效的最大天数。(软限制。到期后多少天就不能用账号了。)
8)“失效时间”字段给出的是一个绝对的天数,如果使用了这个字段,那么就给出相应账号的生存期。期满后,该账号就不再是一个合法的账号,也就不能再用来登录了。(硬限制)
9) 保留

组信息文件

[root@localhost ~]# cat /etc/group 
    root  :  x  :  0  :
    组名  :组密码: 组ID :组成员(默认为空)

2.用户/组管理

用户管理

##创建用户 未指定选项==系统会创建一个和用户名相同的组作为用户的Primary Group

[root@localhost ~]# useradd user01 
[root@localhost ~]# id     user01
uid=1001(user01) gid=1001(user01)=1001(user01)
##创建用户    指定选项

[root@localhost ~]# useradd user02 -u 1503       //创建用户usr02,指定uid
[root@localhost ~]# useradd user03 -d /user03    //创建用户user03 指定家目录 
##删除用户
[root@localhost ~]# userdel -r user02
##修改用户密码

方法一:root修改其他用户(alice)密码
[root@localhost ~]# passwd alice
方法二:用户(zhuzhu)登录,自己修改密码。
[zhuzhu@localhost ~]$ passwd
##组成员管理

语法:usermod    用户名  -G  组名
[root@localhost ~]# usermod  niuniu2 -G hr		
##其它选项管理
修改登录SHELL
[root@localhost ~]# usermod -s /sbin/nologin niuniu2

用户组管理

[root@localhost ~]# groupadd hr
[root@localhost ~]# groupadd net01 -g 2000      //添加组net01,并指定gid 2000
[root@localhost ~]# grep 'net01' /etc/group     //查看/etc/group中组net01信息
[root@localhost ~]# groupdel net01   //删除组net01

组分类

类型释义
基本组/主组随用户创建,自动创建的同名组。
有且仅有1个,显示在/etc/passwd
附加组用户加入的其他组,可有多个

操作示例

一、创建用户AAA,同时生成基本组AAA
[root@QF ~]# useradd AAA
[root@QF ~]# grep AAA /etc/passwd
AAA:x:6001:6001::/home/AAA:/bin/bash

二、创建组CCC
[root@qf ~]# groupadd CCC
[root@qf ~]# grep CCC /etc/group
CCC:x:7001:

三、修改用户AAA的基本组为CCC,查看passwd中,用户AAA的基本组是CCC
[root@qf ~]# usermod  AAA   -g CCC
[root@qf ~]# grep AAA /etc/passwd
AAA:x:6001:7001::/home/AAA:/bin/bash

四、修改用户BBB的附加组为CCC,查看group中用户BBB的附加组是CCC
[root@qf ~]# usermod  BBB   -G CCC
[root@qf ~]# grep CCC /etc/group
CCC:x:7001:BBB

3.提权(了解)

永久提权Switching users with su

[user01@localhost ~]$ id user01
uid=1003(user01) gid=1003(user01)=1003(user01)
[user01@localhost ~]$ whoami
user01
[alice@localhost ~]$ useradd u1
-bash: /usr/sbin/useradd: 权限不够
[alice@localhost ~]$ su - root
password:
[root@localhost ~]# useradd u1
成功

临时提权Running commands as root with sudo

sudo:当前用户切换到超级用户下,以超级用户身份执行命令,执行完成后,直接退回到当前用户。
具体工作过程如下:
当用户执行sudo时,系统会主动寻找/etc/sudoers文件,判断该用户是否有执行sudo的权限
–>确认用户具有可执行sudo的权限后,让用户输入用户自己的密码确认
–>若密码输入成功,则开始执行sudo后续的命令
sudo配置文件语法:user MACHINE=COMMANDS

目标:创建普通用户xulei,使其具有sudo特权

示例
1.以root身份授权普通用户xulei
[root@localhost ~]# vim /etc/sudoers
%wheel ALL=(ALL) NOPASSWD: ALL
第99行:允许wheel用户组中的用户在不输入该用户的密码的情况下使用所有命令
//或直接添加   xulei  ALL=(ALL) NOPASSWD:ALL

[root@localhost ~]# useradd xulei -G wheel
[root@localhost ~]# id xulei
uid=504(xulei) gid=504(xulei)=504(xulei),10(wheel)
# passwd xulei

2.切换用户xulei登陆
[xulei@localhost ~]$ useradd gougou10
-bash: /usr/sbin/useradd: 权限不够
[xulei@localhost ~]$ sudo useradd gougou10
[xulei@localhost ~]$ id gougou10
uid=505(gougou10) gid=505(gougou10)=505(gougou10)

③Linux用户权限

一、基本权限UGO

权限对象权限类型
属主: u读:r=4
属组: g写:w=2
其他人:o执行:x=1
所有人:a(u+g+o)(左右不相关,分别为2个独立的表)

二、设置权限

1.更改权限chmod

语法: chmod 对象(u/g/o/a)赋值符(+/-/=)权限类型(r/w/x) 文件/目录

## 1.了解普通文件的基本权限
[root@localhost tmp]# ll file1 
-rw-r--r--. 1 root root 0 4月  13 20:49 file1
权限           属主 属组                   文件
## 2.编写程序
[root@localhost tmp]#vim    file1 
echo    "hello 2020"
read    -p     "请输入您的姓名:"     name
echo     "$name 是大笨蛋"
## 3.增加执行权限
[root@localhost tmp]# chmod u+x file1   //属主增加执行
## 4.运行测试--成功
[root@localhost tmp]# ./file1 
hello 2020
请输入您的姓名:4567
4567 是大笨蛋
## 5.去除权限--运行失败
[root@localhost tmp]# chmod u-x file1 
[root@localhost tmp]# ./file1
-bash: ./file1: 权限不够
## 6.更多的修改权限练习
[root@localhost tmp]# chmod a=rwx file1   //所有人等于读写执行
[root@localhost tmp]# chmod a=- file1     //所有人没有权限
[root@localhost tmp]# chmod ug=rw,o=r file1     //属主属组等于读写,其他人只读
[root@localhost tmp]# ll file1        //以长模式方式查看文件权限
-rw-rw-r-- 1 alice it 17 10-25 16:45 file1      //显示的结果
使用数字
	4读   2写   1执行
[root@localhost ~]# chmod 644 file1
[root@localhost ~]# ll file1
-rw-r--r-- 1 alice it 17 10-25 16:45 file1

2.更改属主chown、属组chgrp

chown: 设置一个文件属于谁,属主
语法:  chown   用户名.组名   文件
[root@localhost ~]# chown alice.hr file1  //改属主、属组
[root@localhost ~]# chown alice file1     //只改属主
[root@localhost ~]# chown .hr file1       //只改属组
chgrp: 设置一个文件属于哪个组,属组
语法:   chgrp   组名   文件      (-R是递归)
[root@localhost ~]# chgrp it file1    //改文件属组
[root@localhost ~]# chgrp -R it dir1  //改文件属组

案 例

针对hr部门的访问目录设置权限,要求如下:

1. root用户和hr组的员工可以读、写、执行
2. 其他用户没有任何权限

操作思路:创建组-->创建用户-->修改属主和属组-->设置权限

##### 操作示范

[root@localhost ~]# groupadd hr
[root@localhost ~]# useradd hr01 -G hr
[root@localhost ~]# useradd hr02 -G hr
[root@localhost ~]# mkdir /home/hr

[root@localhost ~]# chgrp hr /home/hr
[root@localhost ~]# chmod 770 /home/hr
[root@localhost ~]# ll -d /home/hr/
drwxrwx---. 2 root hr 4096 3月 13 14:26 /home/hr/

三、基本权限 ACL

ACL文件权限管理: 设置不同用户,不同的基本权限(r、w、x)。对象数量不同。
UGO设置基本权限: 只能一个用户,一个组和其他人

1.语法

setfacl -m u:alice:rw /home/test.txt

命令 设置 用户/组:用户名:权限 文件对象

2.用法

##设置,准备文件
[root@localhost ~]# touch /home/test.txt
[root@localhost ~]# ll /home/test.txt 
-rw-r--r-- 1 root root 0 10-26 13:59 /home/test.txt
## 设置ACL
查看文件有哪些ACL权限
[root@localhost ~]# getfacl /home/test.txt
设置用户alice,jack权限
前提:创建alice 和jack用户。过程略
[root@localhost ~]# setfacl -m u:alice:rw /home/test.txt
[root@localhost ~]# setfacl -m u:jack:- /home/test.txt
请思考命令中的o是什么作用?
[root@localhost ~]# setfacl -m o::rw /home/test.txt
## 查看/删除
如何删除一条acl,如何删除所有acl呢?
[root@localhost ~]# getfacl /home/test.txt

[root@localhost ~]# setfacl -m g:hr:r /home/test.txt
[root@localhost ~]# setfacl -x g:hr /home/test.txt //删除组hr的acl权限
[root@localhost ~]# setfacl -b /home/test.txt //删除所有acl权限

四、特殊权限(了解)

1.特殊位 suid

高级权限的类型

suid针对文件/程序时,具备临时获得属主的权限。

问题: 下面的操作,为什么会失败!

[root@localhost ~]# ll /root/file1.txt 
-rw-r--r-- 1 root root 4 7月  27 14:14 /root/file1.txt
[root@localhost ~]#su - alice
[alice@localhost ~]$ cat /root/file1.txt
cat: /root/file1.txt: 权限不够

分析:root运行是超管的权限,普通用户运行时是普通用户的权限。
root      /usr/bin/cat (root)            /root/file1.txt          OK
alice     /usr/bin/cat (alice)            /root/file1.txt

示例-----------设置suid,使普通用户通过suid临时提权,查看超管root用户的文件

1.为cat程序添加上suid权限
[root@localhost ~]# ll  /usr/bin/cat
自习观察输出信息1
[root@localhost ~]# chmod u+s /usr/bin/cat
[root@localhost ~]# ll  /usr/bin/cat
自习观察输出信息2(这两次有什么不同呢?)

2.使用普通用户运行cat。暂时获得root权限
[alice@localhost ~]$ cat /root/file1.txt
请在试验后,将cat的suid权限除去。
[root@localhost ~]# chmod u-s /usr/bin/cat
[root@localhost ~]# ll  /usr/bin/cat
自习观察输出信息3(请确认是否删除suid特殊权限)

2.文件属性chattr

用途:常用于锁定某个文件,拒绝修改。

属性分类释 义
aAppend Only,只允许在此文件之后追加数据,不允许覆盖或截断此文件。
若目录具有该属性,只允许在此目录下建立和修改文件,而不许删除任何文件
i即Immutable,不允许对这个文件进行任何修改。若目录具有该属性,
只能修改目录之下的文件,不允许建立和删除文件
A即Atime,告诉系统不要修改/更新此文件的最后访问时间
S即Sync,一旦此文件执行了写操作,系统立刻把修改结果写到磁盘
s彻底删除文件,不可恢复。因为是从磁盘上删除,用0填充文件所在区域
c将文件或目录压缩后存放
D检查压缩文件中的错误
d在dump程序执行时,该文件或目录不会被dump备份
u删除文件时,系统会保留其数据块,以便以后恢复。防止意外删除
t文件系统支持尾部合并(tail-merging)
X可以直接访问压缩文件的内容
参 数作 用
-R递归处理,将指定目录下的所有文件及子目录一并处理
-V显示指令执行过程
-v<版本编号>设置文件或目录版本
+<属性>开启文件或目录的该项属性
-<属性>关闭文件或目录的该项属性
=<属性>指定文件或目录的该项属性

示例

1 先创建新文件进行对比。查看默认权限
[root@localhost ~]# touch file100
[root@localhost ~]# lsattr file100
-------------- file100
2 加上不能删除的属性
[root@localhost ~]# chattr +i file100 	//不能更改,重命名,删除
3 查看不同属性
[root@localhost ~]# lsattr file100
----i--------- file100
4 尝试删除
[root@localhost ~]# rm -rf file100 
rm: cannot remove `file100': Operation not permitted
5 将属性还原
[root@localhost ~]# chattr -i file100

注 意

设置文件属性(特别权限),针对所有用户,root是否会受到影响?答案是肯定的,会受到影响。

3.进程掩码 umask

#示例1: 观察系统默认掩码
在shell进程中创建文件,先查看当前用户的umask权限
[root@localhost ~]# umask 			
0022
///umask -S  显示创的文件权限
[root@localhost ~]# touch file80
[root@localhost ~]# mkdir dir80
[root@localhost ~]# ll -d dir80 file80
drwxr-xr-x. 2 root root 4096 3月  11 19:40 dir800
-rw-r--r--. 1 root root    0 3月  11 19:40 file800
修改shell umask值(临时)

#示例2:修改shell umask值(临时)
[root@localhost ~]# umask 000
[root@localhost ~]# mkdir dir90
[root@localhost ~]# touch file90
[root@localhost ~]# ll -d dir90 file90
drwxrwxrwx. 2 root root 4096 3月  11 19:44 dir900
-rw-rw-rw-. 1 root root    0 3月  11 19:44 file900

④Linux进程管理

一、进程相关知识(了解)

1.进程定义

进程是已启动的可执行程序的运行实例,是程序运行的过程, 动态,有生命周期及运行状态。

程序: 二进制文件,静态 /usr/bin/passwd ,/usr/sbin/useradd

2.进程的生命周期

  • 父进程复制自己的地址空间(fork)创建一个新的(子)进程结构。

  • 每个新进程分配一个,唯一的进程 ID (PID),满足跟踪安全性之需。

  • 任何进程都可以创建子进程。

  • 所有进程都是第一个系统进程的后代:

    Centos5/6系统进程: init

    Centos7系统进程: systemd

3.进程状态产生原因

在多任务处理操作系统中,每个CPU(或核心)在一个时间点上只能处理一个进程。在进程运行时,它对CPU 时间和资源分配的要求会不断变化,从而为进程分配一个状态,它随着环境要求而改变。

二、进程管理 process

1.静态查看进程 ps

[root@localhost ~]# ps aux |   head  -2

USER  PID  %CPU  %MEM   VSZ    RSS   TTY  STAT  START  TIME     COMMAND
root   1   0.0   0.6   128096  6708   ?    Ss   16:20  0:01  /usr/lib/systemd/systemd
命令参数
ps a  显示现行终端机下的所有程序 
ps u   以用户为主的格式来显示程序状况。  
ps x   不以终端机来区分。
ps aux 输出字段名含 义
USER运行进程的用户
PID进程ID
%CPUCPU占用率
%MEM内存占用率
VSZ占用虚拟内存
RSS占用实际内存
TTY进程运行的终端类型( ?代表本机打开,无终端 )
STAT进程状态(R运行,S睡眠,T停止,Z僵死,X已杀掉)
START进程的启动时间
TIME进程占用CPU的总时间
COMMAND进程文件,进程名
## 1.进程排序
ps aux --sort %cpu

例:以CPU占比降序排列(减号是降序)
[root@localhost ~]# ps aux --sort -%cpu
[root@localhost ~]# ps aux --sort %cpu

## 2.进程的父子关系
ps -ef

例:查看进程的父子关系。 请观察PID和PPID
[root@localhost ~]# ps -ef
UID         PID   PPID  C STIME TTY          TIME CMD
root          1      0  0 1月22 ?       00:00:07 /usr/lib/systemd/systemd 
root          2      0  0 1月22 ?       00:00:00 [kthreadd]
root          3      2  0 1月22 ?       00:00:06 [ksoftirqd/0]

## 3.自定义显示字段
 ps axo
 
[root@localhost ~]# ps axo user,pid,ppid,%mem,command |head -3 
root 8310 1 0.1 /usr/sbin/httpd
apache 8311 8310 0.0 /usr/sbin/httpd
apache 8312 8310 0.0 /usr/sbin/httpd

2.动态查看进程 top

[root@localhost ~]# top

top - 11:45:08 up 18:54,  4 users,  load average: 0.05, 0.05, 0.05
Tasks: 176 total,   1 running, 175 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.0 us,  0.3 sy,  0.0 ni, 99.7 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem :  3865520 total,  1100000 free,   580268 used,  2185252 buff/cache
KiB Swap:  4063228 total,  4063228 free,        0 used.  2917828 avail Mem
每行名称释 义
top从左到右依次为当前系统时间,系统运行的时间,系统在
之前1min、5min和15min内cpu的平均负载值
Tasks该行给出进程整体的统计信息,包括统计周期内进程总数、运行状态进程数、
休眠状态进程数、停止状态进程数和僵死状态进程数
Cpu(s)cpu整体统计信息,包括用户态下进程、系统态下进程占用cpu时间比,nice值大于0的进程在用户态下占用cpu时间比,cpu处于idle状态、wait状态的时间比,以及处理硬中断、软中断的时间比
Mem内存统计信息,包括物理内存总量、已用内存、空闲内存
以及用作缓冲区的内存量(单位:K、M、G)
Swap虚存统计信息,包括交换空间总量、已用交换区大小、空闲交换区大小
以及用作缓存的交换空间大小(单位:K、M、G)
##字段介绍(了解)

PID: 进程pid
USER: 拉起进程的用户
PR: 该列值加100为进程优先级,若优先级小于100,则该进程为实时(real-time)进程,否则为普通(normal)进程,实时进程的优先级更高,更容易获得cpu调度,以上输出结果中,java进程优先级为120,是普通进程,had进程优先级为2,为实时进程,migration 进程的优先级RT对应于0,为最高优先级
NI: 进程的nice优先级值,该列中,实时进程的nice值为0,普通进程的nice值范围为-20~19
VIRT: 进程所占虚拟内存大小(默认单位kB)
RES: 进程所占物理内存大小(默认单位kB)
SHR: 进程所占共享内存大小(默认单位kB)
S: 进程的运行状态
%CPU: 采样周期内进程所占cpu百分比
%MEM: 采样周期内进程所占内存百分比
TIME+: 进程使用的cpu时间总计
COMMAND: 拉起进程的命令

top技巧

动态查看进程 top,像windows的任务管理器
[root@localhost ~]# top          //回车,立刻刷新。按z彩色显示,按F,通过光标设置列的顺序。
[root@localhost ~]# top -d 2     //每2秒刷新一次
[root@localhost ~]# top -d 1 -p 10126      //查看指定进程的动态信息
[root@localhost ~]# top -d 1 -p 10126,1    //查看10126和1号进程

3.使用信号控制进程

#给进程发送信号---kill
[root@localhost ~]# kill -l     // 列出所有支持的信号
编 号信号名作 用
1)SIGHUP重新加载配置
2)SIGINT键盘中断Ctrl+C
3)SIGQUIT键盘退出Ctrl+\,类似SIGINT
9)SIGKILL强制终止,无条件(杀死)
15)SIGTERM终止(正常结束),缺省信号
18)SIGCONT继续
19)SIGSTOP暂停
20)SIGTSTP键盘暂停Ctrl+Z

4.进程优先级nice

Linux 进程调度及多任务,每个CPU在一个时间点上只能处理一个进程,通过时间片技术,来同时运行多个程序。系统中的两种优先级,在top中显示的优先级有两个,PR值和nice值

优先级名称范围特 性
PR0~39将nice级别显示为映射到更大优先级队列
nice-20~19NI:实际nice值。值越高:表示优先级越低,如+19
值越低:表示优先级越高,如-20
  • 查看进程的nice级别
[root@localhost ~]# ps axo pid,command,nice,cls --sort=-nice
		cls表示显示策略列。
		TS 表示该进程使用的调度策略为SCHED_OTHER
		FF表示高级进程first in  first out
  • 启动具有不同nice级别的进程

    默认情况:启动进程时,通常会继承父进程的 nice级别,默认为0

##手动启动不同nice,观察两个程序的不同nice值
[root@localhost ~]# nice -n -5 sleep 6000 &
[1] 2220
[root@localhost ~]# nice -n -10 sleep 7000 &
[2] 2229
[root@localhost ~]# ps axo command,pid,nice | grep sleep
sleep 6000                    2220  -5
sleep 7000                    2229 -10
grep --color=auto sleep       2233   0
  • 更改现有进程的nice级别
##使用shell更改nice级别
1.创建一个睡眠示例程序
[root@localhost ~]# sleep 7000 &
[2] 2669

2.修改他的nice值
[root@localhost ~]# renice -20 2669
2669 (进程 ID) 旧优先级为 0,新优先级为 -20,观察修旧的nice值。

5.作业控制 jobs(了解)

作业控制是一个命令行功能,也叫后台运行。

foreground:前台进程,是在终端中运行的命令,占领终端。

background:后台进程,没有控制终端,它不需要终端的交互。看不见,但是在运行。

后台程序控制示例

# 1.观察占领前台的现象。运行一个程序,当前终端无法输入。大部分命令行输入已经无效。
[root@localhost ~]# sleep 2000

# 2.运行后台程序
[root@localhost ~]# sleep 3000 &

# 3.ps查询所有程序
[root@localhost ~]# ps aux |grep sleep
root 8895 0.0 0.0 100900 556 pts/0 S 12:13 0:00 sleep 3000

# 4.jobs查看后台进程
[root@localhost ~]# jobs
[1]- Running sleep 3000 &

# 5.调动后台程序至前台
[root@localhost ~]# fg  1 //将作业1调回到前台

# 6.消灭后台进程
[root@localhost ~]# kill  %1

注意

“kill 1”   和   “kill   %1”  不同,
前者终止PID为1的进程,
后者杀死作业序号为1的后台程序

6.虚拟文件系统 proc (了解)

虚拟文件系统:采集服务器自身 内核、进程运行的状态信息

/proc/cpuinfo     //CPU
[root@localhost ~]# cat   /proc/cpuinfo

/proc/meminfo    //内存
[root@localhost ~]# less /proc/meminfo

/proc/cmdline    //内核
[root@localhost ~]# cat /proc/cmdline 

⑤Linux重定向管道

一、重定向

1.标准输入、标准输出、标准错误

FD,file descriptors,文件描述符
进程使用文件描述符来管理打开的文件

FD是访问文件的标识,即链接文件
	0是键盘只读,
	1,2是终端可以理解是屏幕,
	3+是文件,可读可写

示例
通过VIM程序,来观察一个进程的FD信息。
1.通过一个终端,打开一个文本。
vim 1.txt
2.通过另一个终端,查询文本程序的进程号
ps aux| grep vim
3.在/proc目录中查看文本程序的FD
通常在 /proc/PID/fd 就能看到文件的FD调用情况。

[root@localhost ~]# ls /proc/5606/fd
			感觉好像没什么。用用ls -l呢?
[root@localhost ~]# ll /proc/5606/fd
		总用量 0
lrwx------. 1 root root 64 10月 10 07:37 0 -> /dev/pts/2   ##标准输入
lrwx------. 1 root root 64 10月 10 07:37 1 -> /dev/pts/2   ##标准输出
lrwx------. 1 root root 64 10月 10 07:37 2 -> /dev/pts/2   ##标准错误输出
lrwx------. 1 root root 64 10月 10 07:37 3 -> /root/.1.txt.swp   ##常规文件

2.重定向案例 >_<

输出重定向符 号
正确输出1>等价于 > 1>> 等价于>>
错误输出2>(无简写) 2>>(无简写)
案例1,输出重定向
[root@localhost ~]# date 1> date.txt 
[root@localhost ~]# date >> date.txt
案例2:错误输出重定向
	​错误示范
[root@localhost ~]# ls /home/    2>    list.txt 
//观察list.txt文件中有没有内容?因为没有错误信息
	​正确示范
[root@localhost ~]# ls  /aaaaaaaaa 2>  list.txt 
[root@localhost ~]# cat  list.txt 
ls: 无法访问/aaaaaaaaa: 没有那个文件或目录
//当某条命令产生错误时,才会有错误输出
案例3: 正确和错误都输入到相同位置
[root@localhost ~]# ls /home/ /aaaaaaaaa &>list.txt
#生产环境常用,将输出丢弃
[root@localhost ~]#yum  install   httpd  &>/dev/null

3.输入重定向

标准输入: < 等价 0<

案例:利用现成的邮件内容快速输入,发送邮件。"test01"标题,alice收件人
[root@localhost ~]# mail -s "test01" alice <  word.txt
原理:利用输入重定向,把文件内容代替人为的输入

二、管道

1.管道 |

  • 进程管道 Piping

    image-20200715211050195
## 简介
    管道命令可以将多条命令组合起来,一次性完成复杂的处理任务

## 语法
    command1 | command2 |command3 |...

## 案例
[root@localhost ~]# cat   /etc/passwd   |   tail -3
[root@localhost ~]# ps aux       |      grep 'sshd'
  • tee管道

    image-20200715211305876
## 简介
    三通管道,即交给另一个程序处理。又保存一份副本

## 案例
[root@localhost ~]# cat /etc/passwd |tee 88.txt | tail -1
localhost:x:1001:1001::/home/localhost:/bin/bash
[root@localhost ~]# cat 888.txt

888.txt文本中是什么内容呢?一行还是所有行?	
答:所有行内容,因为和传送过去的时候,还没有进行tail的处理

2.参数传递 Xargs

针对cp、rm等一些特殊命令使用

1 环境准备,准备一些文件。
[root@localhost ~]# touch /home/file{1..5}
[root@localhost ~]#ls   /home

2 接到消息,部分文件需要删除。
[root@localhost ~]# vim files.txt 
/home/file1
/home/file3
/home/file5

3 使用管道
[root@localhost ~]# cat files.txt |rm -rvf
		失败

4.貌似之前的不行。下面加上xargs
[root@localhost ~]# cat files.txt |xargs rm -rvf 
removed ‘/home/file1’
removed ‘/home/file3’
removed ‘/home/file5’
[root@localhost ~]#ls   /home
通过|xargs成功连接rm命令

⑥Linux存储管理1

一、基本分区

磁盘图示

image-20200715214644116
磁盘介绍释 义
名称磁盘/硬盘/disk,是同一个东西,不同于内存的是容量比较大
类型从工作原理区分,2类:
1.机械硬盘,即普通硬盘,主要由:盘片,磁头,盘片转轴及控制电机,
磁头控制器,数据转换器,接口,缓存等几个部分组成
2.固态硬盘,固态驱动器(简称SSD),是用固态电子存储芯片阵列而制成的硬盘
尺寸3.5、2.5、1.8英寸
接口早期IDE —— 现在SATA I、II、III
转速5400、7200、10000、15000 rpm
厂商西部数据、希捷、金士顿、三星、日立
命名kernel对不同接口硬盘命名方式,RHEL7/centos7:
IDE(并口)----/dev/hda、/dev/hdb
SATA(串口)----/dev/sda、/dev/sdb
/dev设备文件目录,sda是一个文件,s代表sata就是串口,d代表磁盘,a第一块

磁盘分区方式:

# 1、MBR
主引导记录,是位于磁盘最前边的一段引导,支持最大的磁盘容量是 <2TB。设计时分配4个分区。如果希望超过4个分区,需放弃主分区,改为扩展分区和逻辑分区。

# 2、GPT
全局唯一标识分区表,是一个实体硬盘的分区表的结构布局的标准。GPT 支持大于2T的硬盘,支持128个分区

术语:

#盘片:
一块硬盘有若干盘片,每个盘片有可以存储数据的上、下两盘面(Side)。这些盘面堆叠在主轴上高速旋转,它们从上至下从“0”开始依次编号。

#柱面:
所有盘面上的同一磁道构成一个圆柱,称作柱面

#扇区:
将一个盘面划分为若干内角相同的扇形,这样盘面上的每个磁道就被分为若干段圆弧,每段圆弧叫做一个扇区。每个扇区中的数据作为一个单元同时读出或写入。硬盘的第一个扇区,叫做引导扇区。

#磁道:
每个盘面被划分成许多同心圆,这些同心圆轨迹叫做磁道;磁道从外向内从0开始顺序编号

二、管理磁盘

VMware增加磁盘:1编辑虚拟机设置----2添加----3硬盘----4下一步

管理新磁盘流程三部曲:分区(MBR或者GPT) ---->格式化/文件系统 Filesystem ----> 挂载mount

1.查看磁盘信息

方法一:
[root@localhost ~]# ll /dev/sd*
brw-rw----. 1 root disk 8,  0 1月  25 09:35 /dev/sda
brw-rw----. 1 root disk 8,  1 1月  25 09:35 /dev/sda1
brw-rw----. 1 root disk 8,  2 1月  25 09:35 /dev/sda2
brw-rw----. 1 root disk 8, 16 1月  25 09:35 /dev/sdb
brw-rw----. 1 root disk 8, 32 1月  25 09:35 /dev/sdc
brw-rw----. 1 root disk 8, 48 1月  25 09:35 /dev/sdd
#注释:/dev/sdb、/dev/sdc、/dev/sdc相当于购买的新磁盘

方法二:
[root@localhost ~]# lsblk

2.创建分区(MBR方式)

#启动分区工具
[root@localhost ~]# fdisk  /dev/sdb
#进入会话模式
[root@localhost ~]# fdisk /dev/sdb
欢迎使用 fdisk (util-linux 2.23.2)。

更改将停留在内存中,直到您决定将更改写入磁盘。
使用写入命令前请三思。

Device does not contain a recognized partition table
使用磁盘标识符 0xd43058cb 创建新的 DOS 磁盘标签。

命令(输入 m 获取帮助): n
欢迎界面,输入帮助指令或操作指令。
				
命令(输入 m 获取帮助):n
Partition type:
   p   primary (0 primary, 0 extended, 4 free)
   e   extended
   
Select (default p):  p  #请选择主分区,或扩展分区

分区号 (1-4,默认 1): 1

起始 扇区 (2048-10485759,默认为 2048): 敲击回车键      #选择磁盘开始的扇区
将使用默认值 2048

Last 扇区, +扇区 or +size{K,M,G} (2048-10485759,默认为 10485759): +2G
	说明
		选择磁盘分区结束的扇区,即分区大小
		输入分区大小“+2G” 后回车
		实际环境根据磁盘划分,如4T磁盘,可以500G 一个分区
分区 1 已设置为 Linux 类型,大小设为 2 GiB

命令(输入 m 获取帮助): w 
#已经完成 2G 大小分区记录。但未生效。输入w保存分区信息,自动退出分区工具
The partition table has been altered!
Calling ioctl() to re-read partition table.
正在同步磁盘。


刷新分区表
	[root@localhost ~]#  partprobe /dev/sdb  
查看分区结果
	[root@localhost ~]# fdisk -l /dev/sdb  或 lsblk
划分磁盘完毕,/dev/sdb1

3.创建文件系统

[root@localhost ~]# mkfs.ext4    /dev/sdb1
下面是一堆输出提示...

新创建的分区,sdb2,sdb3 都要格式化

4.挂载mount

手动挂载
创建挂载点,一个分区一个挂载点
[root@localhost ~]# mkdir /mnt/disk1
[root@localhost ~]#mount -t ext4  /dev/sdb1 /mnt/disk1
取消挂载:umount  /dev/sdb1

5.查看挂载信息

##方法1 df -hT
[root@server0 ~]# df -Th
Filesystem Type Size Used Avail Use% Mounted on

/dev/sdb1  ext4     2G    6M   1.9G   3%  /mnt/disk1

 分区      文件系统  大小  占用   空闲  占比  挂载点

##方法2 mount
[root@server0 ~]# mount
/dev/sdb1 on /mysql_data type xfs 
(rw,relatime,seclabel,attr2,inode64,noquoa)
/dev/sdb3 on /mnt/disk1/disk2/disk3/disk4 type ext4 
(rw,relatime,seclabel,dta=ordered)

mount 看的是磁盘有没有特殊属性

三、逻辑卷LVM

目的:管理磁盘的一种方式,性质与基本磁盘无异

特点:随意扩张大小

PV:物理卷(Physical volume)

VG:卷组(Volume Group)

LV:逻辑卷(Logical Volume)

1.创建LVM

1.准备物理磁盘

[root@server0 ~]# ll /dev/sd*
brw-rw----. 1 root disk 253, 32 Jun 6 17:38 /dev/sdc
brw-rw----. 1 root disk 253, 48 Jun 6 17:38 /dev/sdd
brw-rw----. 1 root disk 253, 64 Jun 6 17:38 /dev/sde

2.将物理磁盘,转换成物理卷-PV

[root@server0 ~]# pvcreate /dev/sdc
Physical volume "/dev/sdc" successfully created

#查看PV信息			
[root@server0 ~]# pvscan 
PV /dev/vdd lvm2 [2.00 GiB]
Total: 1 [2.00 GiB] / in use: 0 [0 ] / in no VG: 1 [2.00 GiB]

[root@server0 ~]# pvs
PV VG Fmt Attr PSize PFree
/dev/vdd lvm2 a-- 2.00g 2.00g

[root@server0 ~]# pvdisplay

3.创建卷组-VG

[root@server0 ~]# vgcreate vg1 /dev/sdc
Volume group "vg1" successfully created

#查看卷组信息
第一种方法,查看卷组的摘要信息。卷组名,物理卷数量,逻辑卷数量,大小等。
[root@server0 ~]# vgs
VG #PV #LV #SN Attr VSize VFree
vg1 1 0 0 wz--n- 2.00g 2.00g


第二种方法,扫描卷组信息。
[root@server0 ~]# vgscan 
Reading all physical volumes. This may take a while...
Found volume group "vg1" using metadata type lvm2


第三种方法。显示卷组详细信息。
[root@server0 ~]# vgdisplay 
--- Volume group ---
...
VG Size 2.00 GiB					//重点观察
PE Size 4.00 MiB					//重点观察
Total PE 511						//重点观察
...

4.创建逻辑卷LV

[root@server0 ~]# lvcreate -L 200M -n lv1 vg1

指定大小,单位M,G
创建逻辑卷  -L大小  -n卷名   vg1组名
查看LV
				
[root@server0 ~]# lvscan 
ACTIVE '/dev/vg1/lv1' [400.00 MiB] inherit
ACTIVE '/dev/vg1/lv2' [200.00 MiB] inherit

5.创建文件系统并挂载

[root@server0 ~]# mkfs.ext4 /dev/vg1/lv1
注意:/dev/卷组名/逻辑卷名

6.创建挂载点

[root@server0 ~]# mkdir  /mnt/lv1

7.挂载

[root@server0 ~]#mount  /dev/vg1/lv1   /mnt/lv1

查看挂载结果
[root@server0 ~]# df

2.VG管理

##扩大VG vgextend

环境:/dev/vg1 容量由5G 扩容到 10G。
步骤1,创建PV。而后使用第二步,将PV增加到VG中。
[root@server0 ~]# pvcreate /dev/sdd1

步骤2:扩展VG,同时包含方法1.
[root@server0 ~]# vgextend vg1 /dev/sdd1
Volume group "vg1" successfully extended

##查看VG
[root@server0 ~]# vgs
VG #PV #LV #SN Attr VSize VFree
vg1 2 2 0 wz--n- 3.99g 3.76g

3.LV扩容

#####  1. LV扩容

1.查看VG空间。观察VG是否有剩余空间
[root@server0 ~]# vgs
VG #PV #LV #SN Attr VSize VFree
vg1 2 1 0 wz--n- 9.99g 5.99g

2.扩容LV
[root@server0 ~]# lvextend -L +200M /dev/vg1/lv1
增加200M空间,给lv2

##### 2. FS扩容 

先观察文件系统当前容量。
[root@server0 ~]# df -Th 
/dev/mapper/vg1-lv2 ext4 240M 32M 192M 15% /mnt/lv2

[root@server0 ~]# resize2fs /dev/vg1/lv1
再次观察df -hT 的分区大小。和上一次的对比一下。大小已经发生改变。

查看FS					
[root@server0 ~]# df -Th
Filesystem Type Size Used Avail Use% Mounted on
/dev/mapper/vg1-lv1 xfs 765M 67M 698M 9% /mnt/lv1
/dev/mapper/vg1-lv2 ext4 488M 32M 429M 7% /mnt/lv2
请注意对比,之前的输出结果,文件系统的大小发生改变

四、交换分区管理 Swap

1.简介

​ 作用: ”提升“ 内存的容量,防止OOM(Out Of Memory)

swap大小 swapon 设备名 打开、关闭

生产中:系统内存swap大小
小于等于4GB推荐设置为内存的2倍
4~16GB最小需要 4GB 交换空间
16~64GB最小需要 8GB 交换空间
64~256GB最小需要 16GB 交换空间

2.查看当前的交换分区

[root@localhost ~]# free -m
         total    used      free     shared  buff/cache   available
Mem:     1980      704       614       19       661       1110
Swap:    2047       0        2047

3.增加交换分区

  1. 准备分区
准备将/dev/sde磁盘,划分为1G分区为例
划分分区后,将类型设置为82(按t!!!老铁)

[root@server0 ~]# fdisk    /dev/sde 
过程略
[root@server0 ~]# partprobe /dev/sde
[root@server0 ~]# ll /dev/sde*
brw-rw----. 1 root disk 253, 16 12月 6 10:18 /dev/sde
brw-rw----. 1 root disk 253, 17 12月 6 10:18 /dev/sde1

2.格式化

[root@server0 ~]# mkswap /dev/sde1

3.挂载

[root@server0 ~]# swapon /dev/sde1
取消挂载  swapoff

验证,查看增加后的交换分区。是不是变大了?
[root@localhost ~]# free -m

⑦Linux存储管理2

一、EXT4文件系统

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oMCCYJoy-1603117775239)(assets/image-20200717153027727.png)]

1.类型:索引(index )  文件系统

2.系统限制
			Ext3: 文件系统最大16TB
			Ext4: 文件系统最大16TB
			XFS :  文件系统最大100TB
3. inode:记录文件的属性(文件的元数据metadata)

元数据
​件的属性,大小,权限,属主,属组,连接数,块数量,块的编号
一个文件占用一个inode,同时记录此文件数据所在的block numbber。
​inode大小 为 128 bytes

示例:创造一个文件,观察inode信息。
[root@localhost ~]# ll   -i   文件名

4. block:
存储文件的实际数据。
实际存储文件的内容,若文件较大,会占用多个block。
block大小 为默认为4K

5. superblock
​block 与 inode 的总量
​未使用与已使用的 inode / block 数量
示例2:block

问题1:分区中,文件的数量和什么有关系。
1 观察某个分区中的inode节点数
df    -i 
2 创建一个文件
touch  文件名
3 再次观察inode节点数
df    -i 
4 创造大量文件。观察inode使用情况
touch  file{1..30000}
5 在另一个SHEEL,观察inode变化情况。
watch -n 2 'df -i'
6 请问最后,还能否创建新文件呢?
结论:inode决定了文件系统中文件的数量。
7.但是,能否向已存在的文件中写入内容呢?答案是?
结论:block决定了文件存储的空间。

问题2:当分区空间大小消耗完毕,还能否新增文件?
1 向目标分区写入大量数据,填满
dd   if=/dev/zero     of=/disk1/5.txt    bs=1k    count=1000
2 查看目标分区容量,已满
df -hT
3 创造新文件
touch
4 得出结论,磁盘空间的限制根据inode和block两方面
请清理掉填满的分区。避免不必要的报错。

二、文件链接

1.符号链接

symbolic link 软链接,即符号链接

示例
1 创建一个文件,并输入内容。
[root@localhost ~]# echo 111 > /file1
2 创建一个软连接。
[root@localhost ~]# ln -s /file1 /home/file11
3 观察软连接
[root@localhost ~]# ll /home/file11 
lrwxrwxrwx 1 root root 6 Dec 20 17:58 /home/file11 -> /file1
4 观察软连接文件
[root@localhost ~]# ll  /file1 /home/file11 
-rw-r--r-- 1 root root 4 Dec 20 17:57 /file1
lrwxrwxrwx 1 root root 6 Dec 20 17:58 /home/file11 -> /file1
5 查看两个文件,内容一致。
[root@localhost ~]# cat /file1 
111
[root@localhost ~]# cat /home/file11 
111
6 删除源文件,软连接闪烁,不可用。
[root@localhost ~]# rm -rf /file1 
[root@localhost ~]# ll /home/file11 
lrwxrwxrwx 1 root root 6 Dec 20 17:58 /home/file11 -> /file1

​总结
1.软连接可以对文件和目录做软连接。
2.软连接记录的只是源文件的绝对路径。
3.软连接失去源文件不可用。

2.硬链接

1 创建同分区硬链接成功,创建不同分区硬链接失败。
[root@localhost ~]# echo 222 > /file2
[root@localhost ~]# ln /file2 /file2-h1
[root@localhost ~]# ln /file2 /home/file2-h2	

//将文件已硬链接方式,发送到其他分区。结果是?错误
ln: failed to create hard link ‘/home/file2-h2’ => ‘/file2’: Invalid cross-device link

2 硬链接删除源文件,依然可以用
[root@localhost ~]#rm -rf /file2
[root@localhost ~]#cat    /file2-h1
222
3 不允许将硬链接指向目录
[root@localhost home]# ln /home/ /mnt
ln: “/home/”: 不允许将硬链接指向目录

​总结
1.硬链接只能针对文件做。不能对目录做。
2.硬链接只能在同分区做。

3.RAID(了解)

简 介

RAID:廉价磁盘冗余阵列(Redundant Array of Independent Disks)

作 用:容错、提升读写速率

类 型释 义
RAID0条带卷 2块磁盘以上, 读写速率快 100%*N,但不容错
RAID1镜像卷 2块磁盘, 容量50% ,读写速率一般,容错
RAID5带奇偶校验条带卷 3块磁盘以上, 利用率 (n-1)/n 读写速率快,容错
RAID104块,先做镜像,后做条带
RAID014块,先做条带,后做镜像
  • 不同场景RAID的使用

    ​ 硬RAID: 需要RAID卡,有自己的CPU,处理速度快,有电池和无电池

    ​ 软RAID: 通过操作系统实现,比如Windows、Linux

  • 软RAID示例

1.准备4块硬盘  # RAID5 :(3块数据盘) + (1块热备硬盘)
[root@localhost ~]# ll /dev/sd*
brw-rw---- 1 root disk 8, 48 Jan 13 16:07 /dev/sdd
brw-rw---- 1 root disk 8, 64 Jan 13 16:07 /dev/sde
brw-rw---- 1 root disk 8, 80 Jan 13 16:07 /dev/sdf
brw-rw---- 1 root disk 8, 80 Jan 13 16:07 /dev/sdg			

2.创建RAID
[root@localhost ~]# mdadm -C /dev/md0 -l5 -n3 -x1 /dev/sd{d,e,f,g}
-C 创建RAID
/dev/md0 第一个RAID设备
-l5 RAID5
-n RAID成员的数量
-x 热备磁盘的数量,1个盘可用空间2G
[root@localhost ~]# yum -y install mdadm   //确保mdadm命令可用

3.格式化,挂载
[root@localhost ~]# mkfs.ext4 /dev/md0
[root@localhost ~]# mkdir /mnt/raid5
[root@localhost ~]# mount /dev/md0 /mnt/raid5
[root@localhost ~]# cp -rf /etc /mnt/raid5/etc1

4. 查看RAID信息
[root@localhost ~]# mdadm -D /dev/md0    //-D 查看详细信息
​	/dev/md0:
​    Version : 1.2
​    Creation Time : Mon Jan 13 16:28:47 2016
​    Raid Level : raid5		//raid类型
​	Array Size : 2095104 (2046.34 MiB 2145.39 MB)
​	Used Dev Size : 1047552 (1023.17 MiB 1072.69 MB)
​	Raid Devices : 3		//组中设备的数量
​	Total Devices : 4	//总设备数
​	Persistence : Superblock is persistent

​    Update Time : Mon Jan 13 16:34:51 2016
​    State : clean 	//状态,卫生的,哈哈
​    Active Devices : 3	//活跃3个
​    Working Devices : 4  //4个在工作
​    Failed Devices : 0		//坏了1就危险了,2个就完蛋了
​    Spare Devices : 1		//热备的1个。

​    Layout : left-symmetric
​    Chunk Size : 512K	//校验码大小
​    Number Major Minor RaidDevice State
​    0 8 48 0 active sync /dev/sdd		//同步
​    1 8 64 1 active sync /dev/sde		//同步
​    4 8 80 2 active sync /dev/sdf		 //同步

​    3 8 96 - spare /dev/sdg

### 5.模拟一块硬盘损坏,并移除

终端一:
[root@localhost ~]# watch -n 0.5 'mdadm -D /dev/md0 | tail'  //watch持续查看
终端二:
[root@localhost ~]# mdadm /dev/md0 -f /dev/sde -r /dev/sde   //模拟坏了并移除
     -f --fail
     -r --remove

⑧Linux文件查找

一、文件查找

查找命令区别
which命令查找
find文件查找,针对文件名
locate文件查找,依赖数据库

1.命令文件查找which

查找ls 命令的位置
[root@localhost ~]# which ls   //从PATH环境变量
或者
[root@localhost ~]# whereis vim

2.任意文件find

##### 语法
find [path...] [options] [expression] [action]
命令     路径      选项      表达式       动作

##### 按文件名:
[root@localhost ~]# find   /etc   -name   "hosts"
[root@localhost ~]# find   /etc   -iname  "hosts"   //-i忽略大小写
[root@localhost ~]# find   /etc   -iname  "hos*"

结果输出:
​/etc/hosts
​文件查找成功

##### 按文件大小:
[root@localhost ~]# find /etc -size  +5M   //文件>5M
[root@localhost ~]# find /etc -size  5M    //文件=5M
[root@localhost ~]# find /etc -size -5M    //文件<5M

##### 指定查找的目录深度:
[root@localhost ~]# find / -maxdepth 3 -a -name "ifcfg-en*"
[root@localhost ~]# find / -maxdepth 4 -a -name "ifcfg-en*"

##### 按文件属主、属组找:
[root@localhost ~]# find /home -user jack   //属主是jack的文件
[root@localhost ~]# find /home -group hr   //属组是hr组的文件

##### 按文件类型:
[root@localhost ~]# find /tmp -type f   //f普通文件
[root@localhost ~]# find /dev -type b   //b块设备文件

##### 按文件权限:
[root@localhost ~]# find . -perm 644 -ls
  -ls 是find的动作之一,精确权限


找到后处理的动作 ACTIONS:
#找到后删除
find /etc -name "775*" -delete
#找到后复制
find /etc -name "ifcfg*" -ok cp -rvf {} /tmp \;

二、文件打包及压缩

tar命令是Unix/Linux系统中备份文件的可靠方法,几乎可以工作于任何环境中,它的使用权限是所有用户。建议针对目录。

1.打包,压缩

## 语法:tar  选项  压缩包名称  源文件

## 打包,压缩
[root@localhost ~]# tar  -cf    etc.tar    /etc
[root@localhost ~]# tar  -czf   etc-gzip.tar.gz   /etc/     //z是gzip
[root@localhost ~]# tar  -cjf   etc-bzip.tar.bz   /etc/     //j是bzip
[root@localhost ~]# tar  -cJf   etc-xzip.tar.xz   /etc/     //J是xzip

观察三个包的体积
[root@localhost ~]# ll -h etc*
-rw-r--r--. 1 root root  11M 10月 14 10:07 etc-gzip.tar.gz
-rw-r--r--. 1 root root 8.9M 10月 14 10:08 etc-bzip.tar.bz
-rw-r--r--. 1 root root 7.6M 10月 14 10:08 etc-xzip.tar.xz
注意:​​​压缩速度和压缩体积成反比​​​

2.解压

[root@localhost ~]# tar  xf  etc3.tar.xz

[root@localhost ~]# tar -xvf  etc2.tar.bz2  -C  /tmp
// -C 重定向到/tmp目录

⑨Linux软件管理

RPM包

    RPM Package Manager(原Red Hat Package Manager,现在是一个递归缩写),由 Red Hat 公司提出,被众多 Linux 发行版所采用,也称二进制( binary code)无需编译,可以直接使用
   无法设定个人设置,开关功能。
RPM包示例:
zip-3.0-11.el7.x86_64.rpm
wget-1.14-15.el7.x86_64.rpm
tcpdump-4.9.0-5.el7.x86_64.rpm
mysql-community-common-5.7.12-1.el7.x86_64.rpm

#注释
例: zip - 3.0-11.  el7.  x86_64.  rpm
zip     软件包名
3.0-11  版本号(Version)
el7     发布版本(Release5/6/7)
x86_64  系统平台(32/64)
rpm     文件后缀

源码包

source code 需要经过GCC,C++编译环境编译才能运行
可以设定个人设置,开关功能

软件包示例:nginx-1.8.1.tar.gz 
nginx	 包名
-1.8.1	 版本号
.tar.gz  压缩格式

一、RPM包管理

1.YUM工具

简介:

Yum(全称为 Yellow dog Updater, Modified),​是一个在Fedora和RedHat以及CentOS中的Shell前端软件包管理器。​基于RPM包管理,能够从指定的服务器自动下载RPM包并且安装,可以自动处理依赖性关系,并且一次安装所有依赖的软件包,无须繁琐地一次次下载、安装。

(1)本地源:系统安装光盘

目的:通过系统光盘获得软件包,并安装软件

##### 0.观察YUM核心配置目录
[root@localhost ~]# /etc/yum.repos.d/
​打开一个*.repo
​观察国外地址(下载速度慢)

##### 1.备份移除官方YUM库
[root@localhost ~]# mv  /etc/yum.repos.d/*   /tmp

##### 2.编写本地YUM库配置文件
[root@localhost ~]# vim /etc/yum.repos.d/dvd.repo 
[dvd] 
name=dvd 
baseurl=file:///mnt/cdrom
gpgcheck=0 

====注释====
​/etc/yum.repos.d/是YUM下载地址库目录
​[dvd]某一个库的名称,中括号[]是必须的
​name=dvd是库的说明,name是必须的
​baseurl=file:///mnt/cdrom下载库的具体地址.重要
​gpgcheck=0是关闭校验
​enabled=1  表示开启这个仓库

##### 3.挂载安装光盘:
千万记得要把光盘放到服务器上,通电
[root@localhost ~]# mkdir  /mnt/cdrom
[root@localhost ~]# vim /root/.bashrc     //.bashrc自启动文件,跟随用户启动运行的程序
mount   /dev/cdrom   /mnt/cdrom

//mount挂载,/dev/cdrom是光驱文件,/mnt/cdrom是挂载点
重启后,使用ls  /mnt/cdrom,查看到光盘信息即可
[root@localhost ~]# ls /mnt/cdrom/
CentOS_BuildTag  GPL       LiveOS    RPM-GPG-KEY-CentOS-7
EFI              images    Packages  RPM-GPG-KEY-CentOS-Testing-7
EULA             isolinux  repodata  TRANS.TBL

##### 4.使用YUM 安装和卸载程序
[root@localhost ~]#yum install -y httpd    //安装软件
[root@localhost ~]#systemctl start httpd   //启动软件
[root@localhost ~]#systemctl stop firewalld  //关闭防火墙
[root@localhost ~]#systemctl disable firewalld   //禁用防火墙开机自启

##### 5.模拟客户机访问
打开浏览器,输入网站服务器的IP地址---http://127.0.0.1
验证网站程序部署成功

(2)使用YUM管理RPM包

安装

###### 	全新安装
[root@localhost ~]# yum   -y   install   httpd   vsftpd 
​	yum 主命令
​	-y  自动确认
​	install 安装
​	httpd 软件包1
​	vsftpd 软件包2
​	软件包N

###### 	重新安装
当软件缺失文件,可尝试重新安装
[root@localhost ~]# yum  -y   reinstall   httpd
//reinstall 重新安装

###### 	升级安装
[root@localhost ~]# yum  -y   update   httpd   //升级一个程序httpd
[root@localhost ~]# yum  -y   update    //全部升级

查询

查询HTTP程序
[root@localhost ~]# yum list httpd
带@ 是已经安装的

卸载

卸载程序
[root@localhost ~]# yum -y remove  httpd
remove移除,卸载软件包

2.RPM工具

1.管理红帽系统/centos系统,rpm包的基本工具

2.和YUM功能相同

  • 安装(i)
#先找到安装包
[root@localhost ~]# cd   /mnt/cdrom/Packages
#检查软件包是否存在
[root@localhost Packages]# ls wget-1.14-18.el7_6.1.x86_64.rpm 
wget-1.14-18.el7_6.1.x86_64.rpm
#安装。
参数:-i安装  v可视   h百分比
[root@localhost Packages]# rpm -ivh wget-1.14-15.el7.x86_64.rpm 

提示信息
警告:wget-1.14-15.el7.x86_64.rpm: 头V3 RSA/SHA256 Signature, 密钥 ID f4a80eb5: NOKEY
准备中...  ############################# [100%]
正在升级/安装...   1:wget-1.14-15.el7    ######################## [100%]
  • 查询(q)
[root@localhost Packages]# rpm -q wget
wget-1.14-15.el7.x86_64
//看到软件包的名字,就说明rpm -q查询成功,已经安装软件
  • 卸载(e)
#卸载软件包
[root@localhost Packages]# rpm -evh wget-1.14-15.el7.x86_64
输出信息...
再次查询,发现已经卸载
[root@localhost Packages]# rpm -q  wget-1.14-15.el7.x86_64
未安装软件包 wget-1.14-15.el7.x86_64 

二、源码包管理

1.获得源码包

官方网站,可以获得最新的软件包 。需要什么就去其官网下载。例如:

Apache: www.apache.org

Nginx: www.nginx.org

Tengine: tengine.taobao.org

2.实战案例

去官网下载tengine,部署Tengine 

准备编译环境如编译器
[root@localhost ~]# yum -y install   gcc   make   zlib-devel  pcre  pcre-devel  openssl-devel

解压
[root@localhost ~]# useradd www
[root@localhost ~]# tar xvf tengine-2.2.0.tar.gz
[root@localhost ~]# cd tengine-2.2.0

配置
[root@localhost tengine-2.2.0]#./configure  --user=www  --group=www  --prefix=/usr/local/nginx 

编译
[root@localhost tengine-2.2.0]# make
安装
[root@localhost tengine-2.2.0]# make install

启动测试
可能之前的实验,安装过httpd服务。如果直接启动nginx会有冲突。请确保关闭httpd
# systemctl stop  httpd
[root@localhost tengine-2.2.0]# /usr/local/nginx/sbin/nginx
[root@localhost tengine-2.2.0]# systemctl stop firewalld
使用浏览器访问本机的IP,http://127.0.0.1,如果能看到NGINX的网页,说明部署成功。

⑩Linux计划任务

作用:计划任务主要是做一些周期性的任务,目前最主要的用途是定期备份数据。

分类:

​ 一次性调度执行 at

​ 循环调度执行 cron

一、一次性调度执行 at

### 语法格式: at <timespec>

<timespec>示例:
​		now +5min	5分钟后
​		teatime tomorrow (teatime is 16:00)	下午茶时间
​		noon +4 days	第四天中午
​		5pm august 3 2020 	2020年8月3日下午5点
​		4:00 2019-11-27	某年某月某日某时

### 例
1.设置一个定时创建用户的任务
[root@localhost ~]# at  now   +1min
at> useradd uuuu 
at> <EOT>    //CTRL+D输入完毕,提交任务
job 1 at Sat Mar 21 22:34:00 2019

2.查询任务
[root@localhost ~]# atq
3 Thu Mar 30 09:55:00 2019 a root

3.验证结果
[root@localhost ~]# id uuuu
查出用户信息即可

二、循环调度执行 cron

简介

​ cron的概念和crontab是不可分割的。

​ crontab是一个命令,常见于Unix和Linux的操作系统之中

​ 用于设置周期性被执行的指令。该命令从标准输入设备读取指令,并将其存放于“crontab”文件中,以供之后读取和执行。

查看进程状态

[root@localhost ~]# systemctl status crond.service
[root@localhost ~]# ps aux |grep crond
root 550 0.0 0.0 126300 1648 ? Ss 10:05 0:00 /usr/sbin/crond -n
​crond程序运行是计划任务执行的根本

cron示例

#计划任务存储位置
[root@localhost ~]# ls /var/spool/cron/

#管理方式
1.创建计划
[root@localhost ~]# crontab -e    //Edit jobs for the current user
2.查询计划
[root@localhost ~]# crontab -l 	 //List the jobs for the current user
管理员可以使用 -u username, 去管理其他用户的计划任务
3.删除计划
[root@localhost ~]# crontab -r 	//Remove all jobs for the current users.

#语法格式 Job format

.---------------- 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

| | | | |

* * * * * command

    说明
    	分 时 日 月 周     命令或脚本程序
    示例1
    	*/5 * * * * /mysql_back.sh
    		每五分钟执行
    	5 2 1,4,6 * * /mysql_back.sh
    		每月的1,4,6日的2点5分执行
    	0 2 5-9 * * /mysql_back.sh
    		每月5日到9日的两点整执行
    	* * * * * /mysql_back.sh
    		每分钟执行
    	0 * * * * /mysql_back.sh
    		每小时的0分执行
    	0 2 * * * /mysql_back.sh
    		每天两点整执行
    	0 2 14 * * /mysql_back.sh
    		每月14号的2点整执行
    	0 2 14 2 * /mysql_back.sh
    		2月14日2点整执行
    	0 2 * * 5 /mysql_back.sh
    		不写月日,仅周生效
    		每月的周五,两点执行
    	0 2 2 6 5 /mysql_back.sh
    		书写月和日,月或日,月日周均生效
    		6月2日的两点整执行
    		6月的周五两点整执行
    示例2
    	00 02 * * * ls
    		每天2:00整
    	00 02 1 * * ls
    		每月1号2:00整
    	00 02 14 2 * ls
    		每年2月14号2:00整
    	00 02 * * 7 ls
    		每周日2:00整
    	00 02 * 6 5 ls
    		每年6月的周五2:00整  (特殊)
    	00 02 14 * 7 ls
    		每月14号2:00整
    		每周日2:00整
    		这两个时间都执行
    	00 02 14 2 7 ls
    		每年2月14号2:00整
    		2月每周日2:00整
    		这两个时间都执行

⑪Linux日志管理

简介

rsyslog 系统日志管理:关心问题:哪类程序—>产生的什么日志—>放到什么地方

logrotate日志轮转:将大量的日志,分割管理,删除旧日志。

一、rsyslog系统日志管理

1.处理日志的进程

第一类:
rsyslogd: 系统专职日志程序。
处理绝大部分日志记录,
系统操作有关的信息,如登录信息,程序启动关闭信息,错误信息

第二类:
httpd/nginx/mysql: 各类应用程序,可以以自己的方式记录日志.

观察 rsyslogd程序
[root@localhost ~]# ps aux |grep rsyslogd
root 717 0.0 0.0 219752 3880 ? Ssl 09:05 0:00 /usr/sbin/rsyslogd -n

2.常见的日志文件(系统、进程、应用程序)

#系统主日志文件
[root@localhost ~]# tail   -10   /var/log/messages
#动态查看日志文件的尾部
[root@localhost ~]# tail -f /var/log/messages
#认证、安全
[root@localhost ~]# tailf /var/log/secure
 #yum
[root@localhost ~]# tail /var/log/yum.log
#跟邮件postfix相关
[root@localhost ~]# tail /var/log/maillog
#crond、at进程产生的日志
[root@localhost ~]# tail /var/log/cron
#和系统启动相关
[root@localhost ~]# tail /var/log/dmesg##只需了解
[root@localhost ~]# tail /var/log/audit/audit.log
 //系统审计日志

[root@localhost ~]# tail /var/log/mysqld.log
//MySQL

[root@localhost ~]# tail /var/log/xferlog
//和访问FTP服务器相关

[root@localhost ~]# tail  /var/log/wtmp
//当前登录的用户(命令:w)

[root@localhost ~]# tail  /var/log/btmp
//最近登录的用户(命令last)

[root@localhost ~]# tail  /var/log/lastlog
//所有用户的登录情况(命令lastlog )

3.rsyslogd配置

1.相关程序
[root@localhost ~]# yum  -y install  rsyslog  logrotate
默认已安装

2.启动程序
[root@localhost ~]# systemctl  start   rsyslog.service

3.相关文件
rpm -qc rsyslog	
/etc/rsyslog.conf   ----rsyslogd的主配置文件(关键)
/etc/sysconfig/rsyslog   ----rsyslogd相关文件,定义级别(了解一下)
/etc/logrotate.d/syslog  ----和日志办轮转(切割)相关

4.主配置文件

告诉rsyslogd进程什么日志,应该存到哪里
[root@localhost ~]# vim /etc/rsyslog.conf

RULES
	即规则,是一套生成日志,以及存储日志的策略。
	规则由设备+级别+存放位置组成。
	RULES由FACILITY+LEVEL+FILE组成。
	authpriv.* 		/var/log/secure(SSH信息)
	mail.* 			-/var/log/maillog(发邮件)
	cron.* 			/var/log/cron(创建任务)
	这里有一个-符号, 表示是使用异步的方式记录, 因为日志一般会比较大
	*.info;mail.none;authpriv.none;cron.none   /var/log/messages
	系统日志排除了邮件,认证,计划日志。
	
facility设备
	facility:是系统对某种类型事件的定义。如AUTHPRIV是安全事件,CRON是计划任务事件。
	[root@localhost ~]# man 3 syslog
	设备类型
​		LOG_SYSLOG    #syslogd自身产生的日志 
​		LOG_AUTHPRIV  #安全认证
​		LOG_CRON      #cron and at
​		LOG_MAIL      #邮件系统mail subsystem
​		LOG_USER (default)  #用户相关
​		LOG_DAEMON    #后台进程
​		LOG_FTP       #ftp daemon
​		LOG_KERN      #kernel messages
​		LOG_LPR       #打印机printer subsystem
​		LOG_LOCAL0 through LOG_LOCAL7  #用户自定义设备
	程序类型示例
		关于程序和设备的联系问题,程序自身会决定将日志交给哪类设备。如SSH程序会选择安全类设备。这一点由开发者定义。
		[root@localhost ~]# grep  Facility    /etc/ssh/sshd_config 
		SyslogFacility AUTHPRIV
		请问这个程序是属于哪个设备呢?~~~认证设备
					
level级别
​		LOG_EMERG 		紧急,致命,服务无法继续运行,如配置文件丢失
​		LOG_ALERT 		报警,需要立即处理,如磁盘空使用95%
​		LOG_CRIT 		致命行为
​		LOG_ERR 		错误行为
​		LOG_WARNING	    警告信息
​		LOG_NOTICE 	    普通,重要的标准信息
​		LOG_INFO 		标准信息
​		LOG_DEBUG 		调试信息,排错所需,一般不建议使用
		从下到上,级别从低到高,记录的信息越来越少

规则示意图:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GcNGh4Qa-1603117775242)(assets/image-20200717182717245.png)]

二、logrotate日志轮转

简介

​ 日志 记录了程序运行时各种信息。通过日志可以分析用户行为,记录运行轨迹,查找程序问题。可惜磁盘的空间是有限的,只能记录最后一段时间发生的事。为了节省空间和整理方便,日志文件经常需要按时间或大小等维度分成多份,删除时间久远的日志文件。

1.工作原理

原理:按照配置进行轮转

1.配置文件种类
主文件:/etc/logrotate.conf (决定每个日志文件如何轮转)
子文件夹:/etc/logrotate.d/*

观察主文件和子文件
[root@localhost ~]# ls /etc/logrotate.conf /etc/logrotate.d/
/etc/logrotate.conf
/etc/logrotate.d/:
acpid cups iscsiuiolog ppp rpm subscription-manager up2date wpa_supplicant
conman httpd mgetty psacct setroubleshoot syslog vsftpd.log yum

2.主配置文件介绍

[root@localhost ~]# vim /etc/logrotate.conf 
==============全局设置==============================
weekly 		//轮转的周期,一周轮转
rotate 4 	//保留4份
create 		//轮转后创建新文件
dateext 	//使用日期作为后缀
#compress	 //是否压缩
include /etc/logrotate.d	//包含该目录下的子配置文件

/var/log/wtmp {  //对某日志文件设置轮转的方法
monthly 		 //一月轮转一次
minsize 1M 		 //最小达到1M才轮转,monthly and  minsize
create 0664 root utmp	 //轮转后创建新文件,并设置权限
rotate 1 		//保留一份
}

/var/log/btmp {
missingok 		//丢失不提示
monthly 		//每月轮转一次
create 0600 root utmp 	//轮转后创建新文件,并设置权限
rotate 1 		//保留一份
}

3.yum日志轮转实例

轮转的目标文件/var/log/yum.log

​配置轮转规则
[root@localhost ~]# vim /etc/logrotate.d/yum 
/var/log/yum.log {
missingok	  //丢失不执行
#notifempty	  //空文件不论转
#size 30k	  //达到30k轮转, daily or  size
#yearly		  //或者一年一轮转
daily		//缩小周期到1天
rotate 3		//轮转保留3次
create 0777 root root
}

​测试
1.错误示范
[root@localhost ~]# /usr/sbin/logrotate /etc/logrotate.conf   #手动轮转
[root@localhost ~]# ls /var/log/yum*
/var/log/yum.log
文件只有一个。因为日期没变

2.正确示范
修改时间,手动触发轮转
[root@localhost ~]# date 04011000   #把时间向未来推移
[root@localhost ~]# /usr/sbin/logrotate  -s /var/lib/logrotate/logrotate.status /etc/logrotate.conf
[root@localhost ~]# ls /var/log/yum*
日志文件已经出现多个

​关于时间
[root@localhost ~]# grep 'yum' /var/lib/logrotate/logrotate.status
//记录所有日志文件最近轮转的时间

"/var/log/yum.log" 2019-3-31-10:0:23
//如果没有轮转过,第一次只有记录

⑫Linux网络管理

一、网络接口名称规则

en:eethernet 以太网-双绞线

wl:wirelessLAN:无线网卡

ww:WAN广域网:串行线缆

o:on-board板载网卡

s:hotplug热插拔

p:PCI接口

N:序号或者ID

示例:enp2s0

二、NetworkManager服务

网络管理器(NetworkManager)是一个动态网络的控制器与配置系统,它用于当网络设备可用时保持设备和连接开启并激活

默认情况下,CentOS/RHEL 7 已安装网络管理器,并处于启用状态。

查看网络管理程序的状态:systemctl status NetworkManager

查看网络子管理程序的状态:systemctl status network

虚拟机里边的CentOS7重启之后无法联网了,重启network发现报错。

解决方式:禁用NetworkManager
1. systemctl stop NetworkManager
2. systemctl disable NetworkManager
3.systemctl restart network   或   ifup  网卡名
然后能正常联网了!

三、配置网络的工具

1.命令行配置

配置文件:
[root@localhost ~]# vim /etc/sysconfig/network-scripts/ifcfg-ens32
命令行: nmcli
如果没有这个命令,可以执行安装 yum -y install NetworkManager

2.图形配置 略

四、配置网络参数

1.配置IP

##### 	1.配置网卡参数

先备份网卡配置文件,在修改
[root@localhost ~]# cp   /etc/sysconfig/network-scripts/ifcfg-ens33   .
命令行查看IP #ip a
命令行查网关 #ip  r
命令行查dns  #cat   /etc/resolv.conf

!!!修改这个文件要慎重
[root@localhost ~]# vim /etc/sysconfig/network-scripts/ifcfg-ens33
ONBOOT=yes      #是否启用该设备
BOOTPROTO=none  #手动(none/static)还是自动(dhcp)
IPADDR=192.168.142.131   #根据自动获取的地址进行配置,用来定位主机
NETMASK=255.255.255.0  #子网掩码。用来定义网络,这台主机是192.168.142的网络
GATEWAY=192.168.142.2  #网关,也叫默认路由
DNS1=114.114.114.114   #域名解析。这个数字1不要忘了

NAME=ens33   #网卡信息
UUID=d1769473-dc3c-4cf3-9158-8798994d24bb  #网卡信息
DEVICE=ens33  #网卡信息

UUID不是网卡配置文件中必须的信息
查看自身网卡UUID的命令
[root@localhost ~]#  nmcli con


##### 	2.重启网络服务
[root@localhost ~]# systemctl   restart network

##### 	3.查看IP地址
[root@localhost ~]# ip  a

#### 问题
windows虚拟网卡是否安装
VMware系统服务是否被优化掉
LINUX网络配置设置为开机启动

2.主机名

#### 改名方式1
查看主机名
[root@localhost ~]# hostname
配置主机名
[root@localhost ~]# hostnamectl  set-hostname  qf

#### 改名方式2
查看和配置主机名
[root@localhost ~]# cat /etc/hostname 
[root@localhost ~]# vim  /etc/hostname

#### 重启生效
[root@localhost ~]# reboot

3.网络测试工具

测试工具

[root@localhost ~]# ip a		    //查看所有IP(ifconfig)
[root@localhost ~]# ip route		//查看路由,查看网关
[root@localhost ~]# ip neigh 	//(了解)另一台主机ping通,查看邻居
[root@localhost ~]# ping  127.0.0.1
PING (Packet Internet Groper),因特网包探索器
两台虚拟机需要通信,vmnet号(网络连接模式)一定要相同

ports and services

#安装示例服务
什么程序不重要
[root@aliyun ~]# yum -y install httpd 
[root@aliyun ~]# systemctl start httpd

#Show TCP sockets
什么端口不重要
[root@aliyun ~]# ss -tnl
State Recv-Q Send-Q Local Address:Port Peer Address:Port 
LISTEN 0 128 *:80 *:* 
[root@aliyun ~]# netstat  -anpt

​重要的是要知道端口的概念和查看的方法

五、初始化服务器

最小化安装:兼容程序、​开发包

1.为你的服务器配置root 密码

2.配置IP地址(VMNAT8)

3.配置YUM 源
自动挂载光驱/阿里YUM,配置YUM仓库

4.关防火墙
[root@localhost ~]# systemctl  stop firewalld
[root@localhost ~]# systemctl  disable  firewalld
[root@localhost ~]# systemctl  status firewalld		

5.selinux
临时关闭:setenforce  0 (零)
永久关闭:
[root@localhost ~]# vim /etc/sysconfig/selinux 
SELINUX=disabled

6.安装常用程序
[root@localhost ~]# yum install -y    lrzsz    sysstat  elinks   wget   net-tools   bash-completion

7.关机快照

⑬Linux网络管理实战1

一、OSI简介

  • ​ OSI:Open System Interconnection 开放系统互联模型

  • ​ 国际标准化组织(ISO)制定,定义了不同计算机互联的标准,设计和描述,计算机网络通信的框架

  • ​ 制定OSI的优势:
    ​ 开放
    ​ 厂商兼容性
    ​ 易于理解、学习
    ​ 模块化工程
    ​ 故障排除

1、OSI:7层结构

OSI的7层结构功 能
应用层应用程序/原始数据
表示层格式/压缩/加密:快速传递、安全传递
会话层会话/全双工/半双工:身份信息
传输层分段/重组/端口号:传输效率
网络层IP地址/寻址/路由:总目标,全球地址
数据链路层MAC地址/局域网:分段目标,局部地址
物理层传输介质/比特流:电流/光/无线信号/4G/5G

2、TCP/IP:5层结构

TCP/IP的5层结构功 能
应用层应用程序/原始数据
格式/压缩/加密:快速传递、安全传递
会话/全双工/半双工:身份信息
传输层分段/重组/端口号:传输效率
网络层IP地址/寻址/路由:总目标,全球地址
数据链路层MAC地址/局域网:分段目标,局部地址
物理层传输介质/比特流:电流/光/无线信号/4G/5G

3、TCP/IP:4层结构

TCP/IP的4层结构功 能
应用层应用程序/原始数据
格式/压缩/加密:快速传递、安全传递
会话/全双工/半双工:身份信息
传输层分段/重组/端口号:传输效率
网络层IP地址/寻址/路由:总目标,全球地址
网络接口层MAC地址/局域网:分段目标,局部地址
传输介质/比特流:电流/光/无线信号/4G/5G

4、OSI模型和TCP/IP模型的区别

OSI
​ 推出的时间早,只有理论,没有实践

TCP/IP
传输控制协议/互联网协议(Trancation Control Protocol/Inetnet Protocol)
由美国军方实践,总结出的理论,当今通信标准

5、TCP/IP:数据单元/DU

为了方便交流,通信模型不同的模块对信息加工,并进行统一命名。

类型名称释义
应用层数据AP DUAPDU:ApplicationProtocolDataUnit–应用协议数据单元
传输层数据segment DU分段数据
网络层数据packet DU包 数据
数据链路层数据frame DU帧 数据
物理层数据bit DU比特 数据

6.封装和解封装

信息从一台计算产生,经过TCP/IP模型加工。后传递到另一台计算机。
​ 这个通信过程就像,快递从厂家包装到顾客收到货物拆包一样。
​ 把这个通信过程,称作数据的封装(发送)和数据解封装(接收)
​ 从而更好的理解,数据通信原理。

​ 数据封装的过程大致如下
​ 1.(应用层)用户信息转换为数据,以便在网络上传输
​ 2.(传输层)数据转换为数据段,并在发送方和接收方主机之间建立一条可靠的连接
​ 3.(网络层)数据段转换为数据包或数据报,并在报头中放上逻辑地址,这样每一个数据包都可以通过互联网络进行传输
​ 4.(数据链路层)数据包或数据报转换为帧,以便在本地网络中传输。在本地网段上,使用硬件地址唯一标识每一台主机。
​ 5.(物理层)帧转换为比特流,并采用数字编码和时钟方案

二、TCP/IP协议族

TCP/IP:传输控制协议/互联网协议(Transmission Control Protocol/Internet Protocol)

5层模型协议分类

## 应用层
​	HTTP/超文本传输协议/网站------淘宝
​	SSH/远程连接协议/远程控制-----QQ远程桌面
​	FTP/文件传输协议-------------电影天堂
​	SMTP/简单邮件传输协议/Email---QQ邮箱
​	DNS/域名服务/WWW-------------baiyun.com

## 传输层
​	TCP/传输控制协议/可靠-------鸡毛信、挂号信
​	UDP/用户数据报协议/不可靠----普通信

TCP与UDP区别:
1.TCP基于三次握手连接;UDP无连接
2.TCP占用系统资源高;UDP占用系统资源低
3.TCP传输数据慢;UDP传输数据快
4.TCP传输数据准确、稳定;UDP不稳定,容易丢包
UDP应用场景:大量数据,要求速率。如语音、视频

## 网络层
​	IP/互联网协议/寻址----------全球地址
​	ICMP/网络消息管理协议/测试---通信兵

## 数据链路层
​	MAC---------家到邮局的地址

## 物理层
​	网线--------公路
​	光纤--------航道

三、进制转换

十进制

​ 数值:0~9

​ 数位:123

​ 位权:百位十位个位

二进制

​ 数值:0~1

​ 数位:10

​ 位权:128-64-32-16-8-4-2-1

十六进制

​ 数值:0~9,A(10),B(11),C(12),D(13),E(14),F(15)

​ 数位:10

​ 位权:十六的倍数

二进制、十进制互转

10和2互转
128   64    32   16     8      4     2      1
1     1     1     1     1      1     1      1

位权加减法
十进制转换成2进制

方法:
1  请将8位2进制,每个位置的位权写出来。
2  通过加减法,在2进制位权中取得相应数字。 不足的位置用0填充。

示例:
129=1000 0001
192=1100 0000
130=1000 0010

67=0100 0011
33=0010 0001

二进制转十进制
示例:
1010 1010=170
1111 1110=

单位换算

​ ASCII
​ 比特=bit=b=1/0
​ 字节=byte=B=8个比特
​ 1KB=1024B
​ 1MB=1024KB
​ 1GB=1024MB
​ 1TB=1024GB

⑭Linux网络管理实战2

一、物理层

1.信号

  • 模拟信号
    不断变换的物理量,适用电话网络

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xsBQJb9a-1603117775245)(assets/image-20200717204508987.png)]

  • 数字信号
    ​ 两种恒定物理量,适用计算机网络
    ​ 优点:抗噪音和抗衰减比较强

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MPd8Cvsr-1603117775248)(assets/image-20200717204801100.png)]

2.介质

双绞线

EIA/TIA568标准

​外形:八根线芯,两两互绞				
​功能分类
	屏蔽型
	非屏蔽性
​速率分类
	cat 5 /5类线/10M100M
	cat 5e/超五类线/10M100M
	cat 6
​接口
	RJ45/水晶头
	线序:EIA/TIA568B:橙白,橙,绿白,蓝,蓝白,绿,棕白 ,棕
	标准网线:两端线序相同。

光纤

	多模/单模
​	纤芯粗/纤芯细
​	低速/高速
​	近/远
​	便宜/贵
​	FC/ST/LC/

二、数据链路层

1.功能

链路创建,维护,管理,帧封装,传输,同步,差错校验

2.地址

MAC地址:媒体访问控制地址(Media Access Control Address)

结构:48位2进制数字,12位16进制数字

示例:

​ 前六位是厂商标识,后六位是硬件标识

​ 00-21-CC-C3-8C-B0

3.帧封装

MAC 地址是怎么写到信息当中的呢?

答:目标MAC//源MAC//数据//CRC

图示:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LnaekSH6-1603117775250)(assets/image-20200717210320231.png)]

4.交换机工作原理

学习/广播/转发/更新

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xrl1wGzo-1603117775252)(assets/image-20200717210412679.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BqY3xU3x-1603117775253)(assets/image-20200717210426435.png)]

5.组建局域网

通过Cisco Packte Tracert软件,组建一个局域网

思路

1 安装cisco cpt软件
2 部署交换机和主机
3 直通线连线,主机和交换机。
4 为每个主机配置IP,互相ping测试
5 通过show mac-address-table。观察交换机工作原理。
6 更换某个主机于交换机连接的接口,ping测试后, 再次观察交换机的更新。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-po3oAUPw-1603117775255)(assets/image-20200717210554510.png)]

6.VLAN

VLAN:虚拟局域网络(Virtual Local Area Network)

image-20200717210824136 image-20200717210851295

划分VLAN的方法

创建VLAN (2~1024)
​根据接口和VLAN的关系
	接口和VLAN 10
	F0/1~F0/10   VLAN 10
	F0/11~F0/20  VLAN 20

配置

实验1:交换机1上配置
​enable      #特权
​config  t   #进入配置模式(config)#
​vlan 10     #创建局域网10
​vlan 20     #创建局域网20
​interface  fastethernet0/1   #必须要在接口模式下才可以输入
​switch access vlan 10        #将端口加入VLAN
​interface  f0/2
​switch access vlan 10
​interface  f0/3
​switch access vlan 20
​interface  f0/4
​switch access vlan 20

#### 验证
使用相同vlan主机通信成功,不同vlan主机通信不成功。

7.TRUNK

干道

核心技术:打标

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zGY347yC-1603117775257)(assets/image-20200717211912206.png)]

目的:通过一根网线,传递不同VLAN 信息。

配置

在另一台交换机上switch2,实现划分vlan 的行为。雷同于实验1

​enable      #特权
​config  t   #进入配置模式(config)#
​vlan 10     #创建局域网10
​vlan 20     #创建局域网20
​interface  fastethernet0/1   #必须要在接口模式下才可以输入
​switch access vlan 10        #将端口加入VLAN
​interface  f0/2
​switch access vlan 10
​interface  f0/3
​switch access vlan 20
​interface  f0/4
​switch access vlan 20
​在交换机互联的接口中配置
​interface  f0/5
​switch mode  trunk   #配置链路
​switch1 也需要在f0/5配置trunk链路

测试

实现不同交换机上,相同VLAN主机通信成功。

实现不同交换机上,不相同VLAN主机通信不成功。

总结

​ 交换机接口工作模式,分为acces和trunk

​ access是指定接口连接的是主机

​ trunk是指定接口连接的是交换机,需要通过多个VLAN的数据

⑮Linux网络管理实战3—网络层

一、IP地址

简介

​ 32位二进制数,用于主机在互联网中的标识,4组十进制数表示。IP地址每八位为一组,用"."分割,用十进制标识。例如:
​ 192.168.0.1
​ 156.86.254.255

1、IP分类

类型网段备注
A类1~126127:回环地址:本机
B类128~191
C类192~223
D类224~239组播
E类240~255科研

私有IP分类

​ A类:10.0.0.0~10.255.255.255

​ B类:172.16.0.0~172.31.255.255

​ C类:192.168.0.0~192.168.255.255

2.子网掩码

作用:32位2进制数字运算出IP地址的网络部分。

分类:

​ A类:255.0.0.0

​ B类:255.255.0.0

​ C类:255.255.255.0

方法:

​ 子网掩码中为1部分,对应IP地址的网络位。IP地址和子网掩码,逻辑与运算

网络地址:

​ 网络位相同,IP地址是同一网段

​ 网络位不同,IP地址不是同一网段

二、网络层封装(略)

三、路由器工作原理(略)

⑯Linux文件服务

一、FTP Server

FTP(File Transfer Protocol,文件传输协议) 是 TCP/IP 协议组中的协议之一

作用:提供文件共享服务。互联网上多的媒体资源和软件资源,绝大部分都是通过FTP服务器传递。

软件包:vsftpd

基础:

控制端口 command 21/tcp

数据端口 data 20/tcp

1.FTP Server 默认配置

#### 1.安装vsftp
yum -y install vsftpd

#### 2.准备分发的文件
touch /var/ftp/abc.txt
注释:FTP服务器的主目录:“/var/ftp/”,是FTP程序分享内容的本机目录。

#### 3.启动服务
systemctl start vsftpd
systemctl enable vsftpd

#### 4.关闭防火墙
systemctl  stop firewalld
systemctl  disable firewalld
setenforce 0
vim   /etc/selinux/config
修改内容为:SELINUX=disabled

2.FTP Clinet

LinuxFTP客户端程序1:lftp

##### 安装客户端工具
[root@localhost ~]# yum -y install lftp

##### 访问服务器
[root@localhost ~]# lftp 服务器的IP地址

##### 查看并下载
lftp localhost:~> ls 
drwxr-xr-x 2 0 0 4096 Mar 31 2019 pub
-rw-r--r-- 1 0 0 0 Nov 22 03:53 abc.txt

lftp localhost:~> get abc.txt  #下载文件
lftp localhost:~> mirror pub   #下载目录

LinuxFTP客户端程序2:wget

[root@localhost ~]# wget ftp://192.168.142.132/abc.txt
[root@localhost ~]# wget ftp://192.168.142.132/abc.txt -O /tmp/a.sh
-O 指定文件名和路径
[root@localhost ~]# wget http://nginx.org/download/nginx-1.10.2.tar.gz
[root@localhost ~]# wget -m ftp://zhufo.top/soft
-m 下载目录

任何系统firefox、IE

​ 1.客户机打开浏览器

​ 2.输入“ftp://服务器IP地址"

​ 默认仅能下载文件

3.启动上传功能

配置文件 /etc/vsftpd/vsftpd.conf

1.检查禁用匿名账户登录开启

目的:启用禁用匿名账号(默认,比较方便)

anonymous_enable=YES
//是否允许匿名用户登录ftp

2.配置上传指令

anon_upload_enable=YES
//启动上传文件功能
anon_mkdir_write_enable=YES
//启动创建目录功能

3.创建上传目录

mkdir /var/ftp/upload
chmod 777 /var/ftp/upload

4.客户端测试

登录服务器
​	lftp 192.168.142.129
上传文件
​	前提是客户机要有一个2.txt文件
​	然后进入上传目录
​	cd   upload
​	put 2.txt
创建目录
​	mkdir 222
上传目录
​	前提是你要有一个文件夹,等着上传。
​	mirror -R aaa

二、NFS Server

NFS:Network File System 网络文件系统,Linux/Unix系统之间共享文件的一种协议

NFS 的客户端主要为Linux,支持多节点同时挂载以及并发写入

作用

​ 提供文件共享服务

​ 为 Web Server 配置集群中的后端存储

此次实验环境:

nas 192.168.142.133
​ web1 192.168.142.132
​ web2 192.168.142.130
​ web3 192.168.142.134

关防火墙

vi /etc/selinux/config
​ SELINUX=disabled
​ setenforce 0
​ systemctl stop firewalld
​ systemctl disable firewalld

1、nas(存储端)

NAS:Network Attached Storage:网络附属存储
​ NFS是NAS的一种

(1)安装NFS服务器

[root@nas ~]# yum -y install nfs-utils
[root@nas ~]# mkdir /webdata   #存储网站代码
[root@nas ~]# echo "nfs test..." > /webdata/index.html   #放置测试页面

(2)配置NFS服务器

[root@nas ~]# vim /etc/exports
/webdata     192.168.142.0/24(rw) 
​注释:
/webdata指的是发布资源的目录
192.168.122.0/24允许访问NFS的客户机
(rw)可读可写

(3)启动NFS服务器

[root@nas ~]# systemctl start nfs-server
[root@nas ~]# systemctl enable nfs-server

检查NFS输出是否正常
[root@nas ~]# exportfs -v    //-v 检查输出的目录
/webdata 
192.168.122.0/24(rw,wdelay,no_root_squash,no_subtree_check,sec=sys,rw,secure,no_root_squash,no_all_squash)

2.web1 web2 web3 客户端

三台服务器都进行如下操作:

(1)安装NFS客户端

[root@web1 ~]# yum -y install nfs-utils httpd
[root@web1 ~]# systemctl start httpd
[root@web1 ~]# systemctl enable httpd

(2)查看存储端共享

[root@web1 ~]# showmount -e 192.168.142.133   //查询NFS服务器可用目录
Export list for 192.168.142.133
/webdata 192.168.142.0/24

(3)手动挂载

[root@web1 ~]# mount -t nfs 192.168.142.133:/webdata      /var/www/html/
​注释
mount     -t     nfs    192.168.142.133:/webdata    /var/www/html
挂载命令  类型  nfs类型   nfs服务器地址:nfs输出目录      本地目录

(4)查看挂载

[root@web1 ~]# df
192.168.142.133:/webdata 17811456 4444928 13366528   25% /var/www/html
[root@web1 ~]# ls /var/www/html/
index.html

(5)使用web客户端查看web服务器

3.测试网站访问

firefox 192.168.122.85

firefox 192.168.122.111

firefox 192.168.122.166

三、SSH Server

SSH(安全外壳协议)远程操作和管理系统,方便而且安全可靠

SSH 服务器实战

1.登录Centos

2.查询SSH是否安装

[root@ssh ~]# rpm -qa | grep ssh

若没安装SSH则可输入
[root@web1 ~]# yum install openssh-server

3.SSH服务管理

启动服务(默认启动)
[root@ssh ~]# systemctl start sshd 

查看端口
[root@ssh ~]# netstat -antp | grep sshd
//22号端口提供者SSH服务

开机启动(默认启动)
[root@ssh ~]# systemctl enable sshd

4.使用SSH远程管理

​ ssh 账户名@IP地址

⑰Linux网站服务

一、概念

UI的转变:B/S架构

HTML:HyperText Markup Language 超级 文本 标记 语言

网页:使用HTML、PHP、JAVA语言格式书写的文件。

主页:网页中呈现用户的第一个页面。

网站:多个网页组合而成的一台网站服务器

URL:统一资源定位符(Uniform Resource Locator),访问网站的地址。例如http://www.baidu.com/1.html

网站架构:

​ LAMP:Linux + Apache + MySQL + PHP

​ 系统+服务器程序+数据管理软件+中间软件

二、静态站点

1.Apache基础

(建议使用2.4及以上的版本)

​ Apache官网: www.apache.org

​ 软件包名称: httpd

​ 服务端口: 80/tcp(http) 443/tcp(https)

​ 配置文件: /etc/httpd/conf/httpd.conf

​ 子配置文件:/etc/httpd/conf.d/*.conf

​ 主目录:/var/www/html(网站源代码默认位置)

2.安装Apache

安装
[root@localhost ~]# yum -y install httpd
启动
[root@localhost ~]# systemctl start httpd
查看服务状态
[root@localhost ~]# systemctl status  httpd
开机自启
[root@localhost ~]# systemctl enable httpd

关闭防火墙
[root@localhost ~]# systemctl stop  firewalld
关闭selinux
[root@localhost ~]# setenforce 0
查看版本
[root@localhost ~]# httpd -v
Server version: Apache/2.4.6 (CentOS)

3.虚拟主机

目的:在一台物理服务器上运行多个网站

类型:基于主机名www.a.org、www.b.org

配置虚拟主机目标:

​ 在一台服务器上,实现两个网站的架设

​ 网站域名 网站资源存放目录

​ www.a.org /var/www/html/a.org

​ www.b.org /b.org

​ !!!注意关闭firewalld和selinux

  • 服务器
####   www.a.org站点设置
========================
1.准备网站源码(网页)目录
[root@localhost ~]# mkdir /var/www/html/a.org 
[root@localhost ~]# vim /var/www/html/a.org/index.html 
输入网页内容,a.com.com.com

2.创建a.org的网站配置文件
[root@localhost ~]# vim /etc/httpd/conf.d/a.org.conf 
<VirtualHost *:80>     //某个虚拟主机
ServerName www.a.org   //服务器起个名字
DocumentRoot /var/www/html/a.org   //网站的根目录
</VirtualHost>

3.检测配置文件语法,重启服务
[root@localhost ~]# httpd -t 
[root@localhost ~]# systemctl restart httpd 

####   www.b.org站点设置
========================
1.准备网站源码目录
[root@localhost ~]# mkdir /b.org 
[root@localhost ~]# vim /b.org/index.html 
b.org.org.org作为网页内容

2.创建b.org的网站配置文件 
[root@localhost ~]# vim /etc/httpd/conf.d/b.org.conf 
#在文件中输入以下内容
<VirtualHost *:80>
ServerName www.b.org
DocumentRoot /b.org
</VirtualHost>
<Directory "/b.org">
Require all granted
</Directory>

3.检测配置文件语法,重启服务
[root@localhost ~]# httpd -t 
无报错,就可以启动服务器了
[root@localhost ~]# systemctl restart httpd 
  • 客户端
## Linux客户端域名解析
[root@localhost ~]# vim  /etc/hosts
10.0.128.118  www.a.org   //填写web服务器的IP
10.0.128.118  www.b.org   //填写web服务器的IP

## Linux客户端测试网站可用性
字符测试
[root@localhost ~]# yum install -y elinks
[root@localhost ~]# elink http://www.b.org
图形测试:通过火狐浏览器,分别访问两个网站地址

三、动态站点

部署论坛系统discuz

​ discuz开源论坛代码服务社区

1.基础环境

[root@apache ~]# sed -ri '/^SELINUX=/cSELINUX=disabled' /etc/selinux/config 
[root@apache ~]# setenforce 0
[root@apache ~]# systemctl stop firewalld.service 
[root@apache ~]# systemctl disable firewalld.service

2.安装LAMP

[root@apache ~]# yum -y install httpd mariadb-server mariadb php php-mysql gd php-gd
[root@apache ~]# systemctl start httpd mariadb
[root@apache ~]# systemctl enable httpd mariadb

3.安装Discuz

#### 1. 导入discuz网站源码
[root@apache ~]# wget http://download.comsenz.com/DiscuzX/2.5/Discuz_X2.5_SC_UTF8.zip

[root@apache ~]# mkdir    -p      /webroot/discuz
[root@apache ~]# yum  install  -y   unzip
[root@apache ~]#unzip  Discuz_X2.5_SC_UTF8.zip
[root@apache ~]#cp -rf upload/* /webroot/discuz/
[root@apache ~]#chown -R  apache.apache  /webroot/discuz/

#### 2. Apache 配置虚拟主机
[root@apache ~]# vim /etc/httpd/conf.d/discuz.conf
<VirtualHost *:80>
 ServerName www.discuz.com
 DocumentRoot /webroot/discuz
</VirtualHost>

<Directory "/webroot/discuz">
 Require all granted
</Directory>

[root@apache ~]# systemctl restart httpd

#### 3. 准备数据库
[root@localhost discuz]# mysql
MariaDB [(none)]> create database discuz ;
切记创建数据库要再敲一遍,可以检查是否创建成功

####4. 安装discuz [任何client]  过程略
客户端测试时,添加域名解析
[root@localhost  ~]# vim /etc/hosts
192.168.122.161  www.discuz.com				

4.客户端测试

##  Linux客户端域名解析
[root@apache ~]# vim   /etc/hosts
10.0.128.118  www.a.org
10.0.128.118  www.b.org
10.0.128.118  www.discuz.com

##	Linux客户端测试网站可用性
字符测试
[root@apache ~]# yum install -y elinks
[root@apache ~]# elinks http:// www.discuz.com
图形测试:通过火狐浏览器,访问网站地址http:// www.discuz.com

⑱Linux域名服务

一、基本概念

1.hosts文件 /etc/hosts

作用: 实现名字解析,主要为本地主机名、集群节点提供快速解析

数据库: 平面式结构,集中式数据库

缺点:不便于查询,更新

2.域名系统DNS

作用: 实现名字解析(例如将主机名解析为IP)

(分布式,层次性)

3.FQDN

FQDN:(Fully Qualified Domain Name)完全合格域名/全称域名
	baidu.com.
	www.baidu.com.
	www.music.baidu.com.
	www.icbc.com.cn.
	主机名.四级域.三级域.二级域.顶级域.(根域)

命名空间:图示

image-20200717215809748

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2hXcAV4z-1603117775259)(assets/image-20200717220303787.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RLT13tP3-1603117775261)(assets/image-20200717220310840.png)]

4.DNS解析流程

例如客户端解析 www.126.com
1. 客户端查询自己的缓存(包含hosts中的记录),如果没有将查询发送/etc/resolv.conf中的DNS服务器

2. 如果本地DNS服务器对于请求的信息具有权威性,会将(权威答案)发送到客户端。

3. 否则(不具有权威性),如果DNS服务器在其缓存中有请求信息,则将(非权威答案)发送到客户端 

4. 如果缓存中没有该查询信息,DNS服务器将搜索权威DNS服务器以查找信息:
a. 从根区域开始,按照DNS层次结构向下搜索,直至对于信息具有权威的名称服务器,为客户端获答案
DNS服务器将信息传递给客户端 ,并在自己的缓存中保留一个副本,以备以后查找。
b. 转发到其它DNS服务器

5.正向解析/反向解析

​ DNS服务主要起到两个作用:
​   1)可以把相对应的域名解析为对应的IP地址,这叫正向解析。
​   2)可以把相对应的IP地址解析为对应的域名,这叫反向解析。(反垃圾邮件)

服务器类型:主服务器、从服务器、缓存服务器

二、DNS域名解析示例

1.DNS本地缓存记录
# vim   /etc/hosts
192.168.142.129  www.memeda.com

2.主机测试
#ping   www.memeda.com
#elinks  http://www.memeda.com

3.网站服务器辅助验证
#yum  install -y  httpd
#systemctl start  httpd
#systemctl   stop   firewalld
#echo  memeda  > /var/www/html/index.html

三、ISP阿里域名申请及解析(略)





Linux实用命令或快捷键

ABCD命令作用注解
bash某些情况下可实现刷新功能
curl ifconfig.melinux下查看公网ip
df -i查看inode
EFGH命令作用注解
echo $?判断上一条命令是否正确执行0代表正确
history查看历史命令
IJKL命令作用注解
init 0虚拟机关机
init 6虚拟机重启
ip a查看ip、网卡等
ip r
ifconfig
lsof -i:80查看80端口下所有进程
killall -9
+服务名
杀掉某服务的多个进程有些服务此条不生效
MNOPQ命令作用注解
命令 --help查看某命令的各种参数
man功能查询作用和–help相似
nmcli con查看网卡信息
ping 127.0.0.1ping本机127.0.0.1本地回环地址
poweroff系统关机
RSTUV命令作用注解
reboot系统重启
tab自动补齐yum -y install
bash*bash-com*
WXYZ命令作用注解
wc -l计数
yum -y install epel-release安装yum的epel源
yum provides +命令名查询某些命令依赖的安装包

VIM常用快捷键

1、移动光标
(命令模式)
作 用2、删除复制
(命令模式)
作 用
h,j,k,l上,下,左,右(或键盘方向键)dd删除光标所在行
ctrl-e移动页面(一行一行向下)dw删除一个词
ctrl-b查看上一页D删除到行末
ctrl-f查看下一页3d包括光标所在行,向下删除3行
ctrl-u查看上半页x删除当前字符
ctrl-d查看下半页X删除前一个字符
w跳到下个字首,按标点或单词分割3y包括光标所在行,向下复制3行
W跳到下个字首,长跳yy/Y复制整行
e跳到下个字尾p粘贴到当前行的下面
E跳到下个字尾,长跳P粘贴到当前行的上面
b跳到上一个字u撤销
B跳到上一个字,长跳
0跳至行首,第 0 个字符
^跳至行首的第一个字符
$跳至行尾
gg跳至文首
G跳至文尾
5gg 或 5G跳至第 5 行行首
3、插入模式
(命令模式)
作 用4、退出编辑器作 用
i进入插入模式:w保存
I进入插入模式,并置光标于行首:q退出(不保存)
a追加模式,置光标于当前光标之后:wq 或 :x保存,退出
A追加模式,置光标于行末:q!强制退出,不保存
o在当前行下新加一行,并进入插入模式:wq!保存,强制退出
O在当前行上新加一行,并进入插入模式
esc退出插入模式
5、查找替换 ( n:下翻   N:上翻 )

/xxx  #向后搜索字符串 xxx 
?xxx  #向前搜索字符串 xxx 

"\c" 忽略大小写   #例:/pat \c ,搜索到 pat 和 Pat
"\C" 大小写敏感   #例:/pat \C ,只搜索到 pat

:%s/old/new/g   #搜索整个文件,将所有的 old 替换为 new 。
######可将冒号换为数对(始行,末行),例如   :2,5 s/aa/bb/g
:%s/old/new/gc  #搜索整个文件,将所有的 old 替换为 new,每次都要你确认是否替换 

自动排版:命令模式下输入 gg=G ,可排版整理格式
多行注释:Ctrl+v 进入可视化 ,选中欲注释行,输入 I ,输入注释符#,双击esc

6、末行模式
:set list      vim中使用进入末行模式,可查看行末尾有无空格
:set nolist    可取消
:set nu   显示行号
:set nonu  取消行号



MYSQL数据库

一、基础概念

1.常见的数据库

类型名称
关系型数据库mysql 、Oracle、SQL Server、DB2、MariaDB、Sybase
非关系型数据库NoSQL:MongoDB、Redis、HBase

2.数据库-系统结构

  1. 数据库系统 DBS

    包含两部分:数据库管理系统DBMS、数据库管理员DBA

  2. SQL语言(结构化查询语言)

    • DDL语句(数据库定义语言): 数据库、表、视图、索引、存储过程、函数, CREATE DROP ALTER
    • DML语句(数据库操纵语言): 插入数据INSERT、删除数据DELETE、更新数据UPDATE
    • DQL语句(数据库查询语言): 查询数据 SELECT
    • DCL语句 (数据库控制语言): 控制用户的访问权限GRANT、REVOKE
  3. 数据访问技术

    ODBC PHP <.php>
    JDBC JAVA <.jsp>
    ASP.NET<c#>

3.部署

版本:mysql 5.7

官网地址:www.mysql.com 或 www.oracle.com

有网络的安装方法:

  • 关闭防火墙和selinux

​ systemctl stop firewalld

​ systemctl disable firewalld

​ setenforce 0

​ vim /etc/selinux/config --------- SELINUX=disabled (开机禁用)

  • 从国内mysql镜像站、官方地址、其他渠道下载软件包
中国科学技术大学开源软件镜像    http://mirrors.ustc.edu.cn/

[root@localhost ~]# wget http://mirrors.ustc.edu.cn/mysql-ftp/Downloads/MySQL-5.7/mysql-community-server-5.7.25-1.el7.x86_64.rpm
[root@localhost ~]#wget http://mirrors.ustc.edu.cn/mysql-ftp/Downloads/MySQL-5.7/mysql-community-client-5.7.25-1.el7.x86_64.rpm
[root@localhost ~]# wget http://mirrors.ustc.edu.cn/mysql-ftp/Downloads/MySQL-5.7/mysql-community-common-5.7.25-1.el7.x86_64.rpm
[root@localhost ~]# wget http://mirrors.ustc.edu.cn/mysql-ftp/Downloads/MySQL-5.7/mysql-community-libs-5.7.25-1.el7.x86_64.rpm
  • 安装相关软件
[root@localhost ~]# yum  install  -y   net-tools.x86_64    libaio.x86_64    perl.x86_64
  • 安装Mysql服务器
[root@localhost ~]# yum install -y mysql-community*

mysql与mariadb冲突,若有mariadb,请记得卸载mariadb再安装
[root@localhost ~]# yum remove -y mariadb-libs.x86_64
[root@localhost ~]# yum install -y mysql-community*
  • 启动Mysql服务器
[root@localhost ~]#systemctl start mysqld
[root@localhost ~]#systemctl enable mysqld
[root@localhost ~]#systemctl status mysqld
  • 登录Mysql
查询Mysql服务器默认密码(启动失败,查不到密码)
[root@localhost ~]# grep 'password' /var/log/mysqld.log 
!注意:冒号和空格的后面,全都是密码

修改密码
[root@localhost ~]# mysqladmin  -uroot  -p'es,W;ya(K1Th'  password   'localhost@123'

登录系统
[root@localhost ~]# mysql   -uroot   -p'localhost@123'

无网络安装方法:(基本不用,靠磁盘挂载镜像资源)

  • 设置本地YUM仓库
[root@localhost ~]# mv   /etc/yum.repos.d/*   /tmp/
[root@localhost ~]# vim /etc/yum.repos.d/dvd.repo
[dvd]
name=dvd
baseurl=file:///mnt/cdrom
gpgcheck=0
[root@localhost ~]# mkdir /mnt/cdrom
[root@localhost ~]# mount /dev/cdrom  /mnt/cdrom/
[root@localhost ~]# yum makecache 
[root@localhost ~]# yum repolist 
  • 安装Mariadb服务器
[root@localhost ~]# yum   install   -y   mariadb-server   mariadb
  • 启动并登录Mariadb服务器
[root@localhost ~]# systemctl  start  mariadb      #启动
[root@localhost ~]# systemctl   enable  mariadb    #开机自启
[root@localhost ~]# mysqladmin  -uroot  password  'localhost@123'   #修改root密码
[root@localhost ~]# mysql -uroot -p'localhost@123'    #登录
		

二、mysql实战

1.名词解释

名称释义
数据库服务器运行着数据库应用程序的设备,即CENTOS+Mysql
硬件+系统软件+MYSQL软件
数据库表的管理单元
数据库存储数据的基本单位,记录的管理单元
记录信息的载体,字段的管理单元
字段字段名,字段类型(长度),字段约束组成(可空)
类型字符,数字,日期
约束不能为空,自动增长

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-B94kYVeP-1603117775263)(assets/image-20200703210808315.png)]

2.DDL(数据库定义语言)

库在系统中位置:/var/lib/mysql/

操作作用
create database 库名;创建数据库(库名区分大小写,禁用关键字,不能单独使用数字或特殊符号)
show databases;查看所有数据库
use 库名;进入库
select database();调用函数,查询当前库
drop database 库名;删除库
create table 表名 (字段名 类型);创建表(要先进入库)
select database();查看当前所在库
show tables;查看所有表
insert into 表名 values(值1,值2);插入数据
select * from 表名;查询所有数据
delete from 表名;删除表数据
drop table 表名;删除表(结构)
desc 表名;查询表结构

示例:

mysql> CREATE  DATABASE school;    #创建数据库school
mysql> use school;	     #使用库
mysql> create table student1(id int,name varchar (20),sex enum('m','f'),age int);   #创建一个表,四列
mysql> show tables;

#插入数据
mysql> insert into student1 values (1,'zhangsan','m',33);
mysql> insert into student1 values (2,'lisi','f',20);
mysql> insert into student1 values (1,'wangwu','m',40);

mysql> select * from student1;     #查询表中所有内容

mysql> desc student1;     #查看表结构,注意表结构和表内容是两个概念。

3.DML(数据库操纵语言)

  1. 插入数据insert

    完整插入:insert into 表名 values (值1,值2,值3…值n);

    部分插入:insert into 表名(列名,列名) values (值1,值2);

  2. 更新数据update
    语法
    update 表名 SET 列名=值 where CONDITION;
    示例:把id为2的用户的name改为cc
    update t6 set name=‘cc’ where id=2;

  3. 删除数据delete
    语法:
    delete from 表名 where CONDITION;
    示例:删除id为2 的用户记录。
    delete from t6 where id=2;
    请思考不加where条件会如何

4.DQL(数据库查询语言)

  1. 查看所有列:select * from 表名;

  2. 查看部分列:select 列1,列2,列3 from 表名;

  3. 单条件查询:select * from 表名 where name=‘zhangsan’;

    (!!!注意:若等号的右边是字母,需要加单引号;右边是数字,不能加引号)

  4. 查询排序
    以年龄升序排列(order by默认为asc升序,后不加asc也可)
    select * from 表名 order by 年龄的列名 asc;
    以年龄降序排列
    select * from 表名 order by 年龄的列名 desc;

  5. 限制查询数量
    年纪最大的前3名
    select * from 表名 order by 年龄的列名 desc limit 3;

5.DCL(数据库控制语言)

  1. 权限级别

    Global level:所有库、所有表的权限

    Database level:某个数据库中的所有表的权限

    Table level:库中某个表的权限

    Column level:表中某个字段的权限

  2. mysql用户管理

    • 创建用户:create user user1@‘localhost’ identified by ‘localhost@123’;
      验证
      select * from mysql.user\G;
      注释:
      create 创建(关键字)
      user 用户(关键字)
      user1 用户名称(自定义)
      @ 分隔符(关键字)
      ‘localhost’ 允许登录的主机
      identified by 身份认证(关键字)
      ‘localhost@123456’ 用户密码

    • 删除用户:drop user ‘user1’@‘localhost’;

    • 修改用户密码(三种方法)
      ①root修改自己密码(前提是拥有系统权限)
      mysqladmin -uroot -p’123’ password ‘new_password’

      ​ ②update也可以(复杂)
      ​ UPDATE mysql.user SET authentication_string=password(‘new_password’) WHERE user=’root’ AND host=’localhost’;
      ​ FLUSH PRIVILEGES;

      ​ ③SET PASSWORD=password(‘new_password’);
      ​ FLUSH PRIVILEGES;

      root用户密码丢失/忘记

      ​ 原理:破解的方式登录,使系统启动时,不加载密码文件。

      ​ ①修改mysql启动设置

      ​ vim /etc/my.cnf

      ​ [mysqld]
      skip-grant-tables
      ​ ②重启mysql:systemctl restart mysqld

      ​ 无密码登录:mysql -uroot

      ​ 修改密码:

      ​ UPDATE mysql.user SET authentication_string=password(‘localhost@12’) where user=‘root’ and host=‘localhost’;
      ​ FLUSH PRIVILEGES;
      ​ ③修改mysql启动设置
      ​ 注释掉跳过密码

    • 登录MySQL
      mysql -u root -p123 -e ‘show tables’ -P 3306 mysql
      -h 指定主机名 【默认为localhost】
      -P MySQL服务器端口 【默认3306】
      -u 指定用户名 【默认root】
      -p 指定登录密码 【默认为空密码】

      ​ -e 接SQL语句

      ​ mysql 指定登录的数据库

  3. mysql权限原理
    赋权语法格式

    ​ grant 权限列表 on 库名.表名 to ‘用户名’@‘客户端主机’ [identified by ‘密码’ with option参数];

    image-20200704103740672
  4. mysql回收权限

    查看自己的权限:show grants\G;

    查看别人的权限:show grants for admin3@’%’\G;

    回收权限语法:REVOKE 权限列表 ON 数据库名 FROM 用户名@‘客户端主机’;

    删除用户:drop user; (5.7之前,先 revoke all privilege,再 drop user)

6.日志

1.日志分类

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jG0Qe4Ic-1603117775264)(assets/image-20200704105529769.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JcuAeG8q-1603117775266)(assets/image-20200704105722686.png)]

2.Error Log

vim   /etc/my.cnf          #进入主配置文件,观察日志是否启动
log-error=/var/log/mysqld.log       #该字段,标记日志是否启动,以及日志位置

3.Binary Log(默认不开启)

#vim   /etc/my.cnf
log_bin       #添加该字段,启动二进制日志
server-id=2    #群集问题,必须指定该主机的序号。数字随意

systemctl  restart  mysqld      #重启数据库

测试
1.查看二进制日志文件当前状态
ls /var/lib/mysql/*bin*          #查询二进制文件生成完成。
mysqlbinlog -v /var/lib/mysql/localhost-bin.000001     #查看二进制文件日志

2.进入数据库,进行数据操作(过程略)
3 完成二进制日志启动,查询测试
mysqlbinlog -v /var/lib/mysql/localhost-bin.000001   #找到刚才创建的记录即可。

4.Slow Query Log(默认关闭)

开启慢查询日志功能,加入下面2行配置
vim   /etc/my.cnf
slow_query_log=1    #启动慢查询日志,这个参数设置为ON,可以捕获执行时间超过一定数值的SQL语句
long_query_time=3   #当SQL语句执行时间超过此数值时,就会被记录到日志中,建议设置为1或者更短
			
重启服务器
systemctl  restart  mysqld

查看慢查询日志文件
ll /var/lib/mysql/*slow*

模拟慢查询
mysql>SELECT BENCHMARK(500000000,2*3);   #基本测试语句,测试一个超长时间的查询

验证慢查询日志
tail /var/lib/mysql/localhost-slow.log   #日志记录了超长的查询结果,观察记录,反馈给开发部

SQL回顾

基本sql语句

show databases; # 查看库
show tables; # 查看表
use  库名 # 进入库
select database(); # 查看当前所在库
select * from 表名; # 查看表内所有内容
desc 表名; # 查看表结构
show create table|database 表名|库名 ;# 查看创建库或者表的详细信息
create database 数据库名称 default character set 'UTF8';#创建库并制定字符集
create table 表名(字段名1 数据类型 约束,字段名2 数据类型 约束); # 创建数据表
insert into 表名(字段名1,字段名2) values(1,值2) #插入数据
insert into 表名 values(1,值2) #插入数据,当前标准只有2个字段
update 表名 set 字段名=where 主键或字段名=delete from 表名  # 不加where默认删除整张表内容 危险
delete from 表名 where 字段名=# 删除字段名称对应的值
drop database 库名 # 删除数据库 跑路必备技能
drop table 表名 # 删除数据表
alter table 表名 add 列名 约束 after 位置 # 添加一列
alter table 表名 drop 列名  # 删除某列 
rename table 旧表名 to 新表名 # 修改表名
alter table 表名 modify 字段名 约束 #修改字段约束  
alter table 表名 change 字段名 新字段名 约束 #修改字段
列名定义 #数字字母下划线组成,数字不能开头
create table t3(select name from t1 where 1=2); # 复制表结构
create table tt(select name from t1); # 复制表
-- 创建库
drop database if EXISTS db1;
create database db1 default charset utf8;

-- 创建表 学生
drop table if exists tb_student;
create table tb_student (
stu_id int primary key AUTO_INCREMENT,
stu_name varchar(20) not null comment '学生名字',
gender bit not null default 1 comment '学生性别',
class_id int
) engine innodb;

-- 插入数据
insert into tb_student(stu_name,gender,class_id) values
('老王','男',1),
('小明','男',1),
('小芳','女',3),
('二狗','男',2);

-- 创建表 班级
create table tb_class(
class_id int primary key,
teacher_id int
);

-- 添加列 班级
alter table tb_class add column class_name varchar(20) comment '班级名称' after class_id;
insert into tb_class values
(1,'尖刀班',2),
(2,'普通班',3),
(3,'加强版',1);

--  创建外键约束
alter table tb_student add constraint fk_stu_class  foreign key (class_id) references tb_class (class_id);

--  测试插入
insert into tb_student(stu_name,gender,class_id) values('大妹','女',3);
insert into tb_student(stu_name,gender,class_id) values('大妹','女',5);

-- 创建索引
create index idx_stu_name on tb_student (stu_name);

-- 删除索引
drop index idx_stu_name on tb_student;

-- 执行计划
explain select * from tb_student ;
explain select * from tb_student where class_id <> 2;
explain select * from tb_student where stu_name = '老王';

-- 	创建视图
create view vw_stu_class as 
select a.stu_id,a.stu_name,b.class_name from tb_student a inner join tb_class b on a.class_id = b.class_id;

-- 删除视图
drop view vw_stu_class;

-- 创建存储过程
delimiter $$
create procedure sp_stu(classid int,out stu_data varchar(20))
begin
	select count(stu_name) into stu_data from tb_student where class_id = classid;
end$$
delimiter ;

-- 调用存储过程
call sp_stu(1,@test);
select @test from dual;

-- 删除存储过程
drop procedure sp_stu;

-- 创建用户
create user 'hello'@'%' identified by '123456';

-- 授权
grant all privileges on *.* to 'hello'@'%';

-- 权限回收
revoke insert,update,delete on *.* from 'hello'@'%';

-- 事务
-- 开启事务方式 start transaction /  begin
begin;

-- 执行操作
delete from tb_student;

-- 提交
commit;

-- 回滚
rollback;

命令行技巧

\g  # 横向显示
\G  # 竖向显示
\q  # 退出
\c  # 取消执行
edit # 使用文本编辑
limit #分页查询
``  #  将mysql关键字作为列名

数据类型

int #整数
bigint # 长整数
float  # 小数
char   # 字符(删除尾部空格)
varchar # 长字符 (保留尾部空格)
time  # 时间  xx:xx:xx
date  # 日期  xxxx-xx-xx
datetime # xxxx-xx-xx xx:xx:xx 日期时间
# 索引```sql
添加索引
create index big_name on t5(name);

创建索引
create table 表名(
字段名1 约束 unique,
字段名2 约束,
key|index  索引名(字段名),
primary key #指定主键 
)ENGINE=innodb 字符集=utf-8

查询所有库的大小

select TABLE_SCHEMA, concat(truncate(sum(data_length+index_length)/1024/1024/1024,2),' G') as total_size,concat(truncate(sum(data_length)/1024/1024/1024,2),' G') as data_size,concat(truncate(sum(index_length)/1024/1024/1024,2),' G') as index_size from information_schema.tables group by TABLE_SCHEMA ORDER BY data_size desc; 
左右连接
select c.dept_no,e.birth_date as bd,concat(e.first_name,'·',e.last_name) from current_dept_emp c left join employees e on c.emp_no = e.emp_no where c.dept_no = 'd001';

主从配置

原理
主服务器上面的任何修改都会保存在二进制日志( Bin-log日志) 里面。
从服务器上面启动一个I/O线程, 连接到主服务器上面请求读取二进制(Bin-log)日志,然后把读取到的二进制日志写到本地的Realy-log(中继日志)里面。
从服务器上面同时开启一个SQL线程,读取Realy-log(中继日志),如果发现有更新立即把更新的内容在本机的数据库上面执行一遍。

FLUSH TABLES WITH READ LOCK;   #锁库,退出客户端解锁
SHOW MASTER STATUS;            #查询主的状态
SHOW SLAVE STATUS;             #查询从的状态
STOP SLAVE ;                   #停止从
RESET MASTER|SLAVE;            #重置主或者从

# 授权配置
CHANGE MASTER TO
MASTER_HOST='mysql-master',  -- 主服务器的主机名(也可以是 IP) 
MASTER_USER='repl',           -- 连接到主服务器的用户
MASTER_PASSWORD='Qf_123456'-- 到主服务器的密码
MASTER_LOG_FILE='mysql-bin.000001',	-- 从主服务器的哪个binlog日志读取
MASTER_LOG_POS=589;					-- 从主服务器的binlog日志的哪个位置开始同步

# 暴力拷贝注意事项
1、拷贝原数据到目标目录后,记得将权限改为mysql
2、uuid 需要修改,但是要在启动mysql成功之后再进行修改
3、初始化密码未修改时,不能关闭密码强度策略
4、密码强度策略不能和跳过密码配置同时添加
5、初始化之前必须先停用mysql,然后把数据目录全部清理掉

备份恢复

1、逻辑备份
2、物理备份
3、bin-log日志备份
4、公有云服务器的自定义快照

# 逻辑备份
-A, --all-databases		# 完全备份		            
-B, --databases bbs test mysql 	 # 备份多库
--no-data,-d            # 备份表结构
mysqldump -u用户  -p密码 -h 远程ip地址 数据库选项 > 备份文件.sql  #远程备份
mysqldump -u用户  -p密码 数据库选项 > 备份文件.sql               #本地备份

mysqldump -u用户  -p密码 -B 库123 > 备份文件.sql  # 备份数据库
mysqldump -u用户  -p密码  库 表12 > 备份文件.sql  # 备份数据库内的表
mysqldump -u用户  -p密码 -A > 备份文件.sql  # 备份整个库
数据库内:
select 字段名 from 表名 where 条件  into outfile ‘路径/表名’ # 导出表数据到某个文件

路径可以通过 show variables like "secure_file_priv";
路径可以通过 配置文件中添加  secure_file_priv=路径名  重启服务进行修改
fields terminated by ',' :字段以逗号分割
lines terminated by '\n':结尾换行

# 恢复
mysql -u用户 -p'密码'  < 备份文件.sql # 如果是导入整库,直接导入即可,如果是导入某个库或某个表,需要提前创建数据库
load data infile '备份文件.sql' into table 表名;
如果将数据导入别的表,需要创建这个表并创建相应的表结构。

vim /etc/my.cnf
log-bin=binlog日志目录及文件名
server-id=id号
flush logs; # 刷新binlog日志
mysqlbinlog mylog.000002  # 查看binlog日志内容
mysqlbinlog --start-position 219 --stop-position 321 mylog.000002 |mysql -uroot -p'qf123'  #指定开始和结尾处恢复数据,注意查看事务提交出  COMMIT

mysql官方测试库安装

unzip test_db-master.zip
cd test_db-master
mysql -u root -p***  -t < employees.sql
mysql -u root -p***  -t < employees_partitioned.sql
测试安装的数据
mysql -u root -p***  -t < test_employees_md5.sql
mysql> show tables;
+----------------------+
| Tables_in_employees  |
+----------------------+
| current_dept_emp     |   # 所有部门人数
| departments          |   # 部门
| dept_emp             |   # 部门总人数
| dept_emp_latest_date |   # 最新的入离职信息
| dept_manager         |   # 部门经理
| employees            |   # 职员
| salaries             |   # 薪水
| titles               |   # 职称
+----------------------+

sql注入–sql语句回顾

select database(); # 查看当前所在库
select user(); # 查看当前用户
select now(); # 查看当前时间
DEsc table_name; # 查看表结构
show create table table_name # 查看表的创建信息
status  # 查看当前数据库信息
show full processlist; # 查看当前所有正在执行的sql语句
show processlist;  # 查看当前正在执行的sql语句前100条
avg()  # 求平均值
count() # 求记录总数
distinct() # 去重
max()  # 最大值
min() # 最小值
sum()
now()
sleep()

sql测试

基础:
# 1.求所有员工总人数
# 2.求年龄最大的员工姓名及员工编号生日
# 3.求员工平均薪资
# 4.求1985年入职的人
# 5.求目前在职的员工
# 6.求职称为Staff得人有多少

高级:
# 7.求在1985年入职的员工的员工编号、姓名、生日  我要给所有1985年入职的员工过生日
# 8.求工资在14万以上的都是哪些部门的员工
# 9.查询每个职称1985年入职的员工编号
# 10.查询每个职称1985年入职的员工的姓名
# 11.查询每个职称1985年入职的员工的姓名和薪资
-- 1.求所有员工总人数
SELECT COUNT(emp_no) FROM employees;
-- 2.求年龄最大的员工姓名及员工编号生日
SELECT birth_date,CONCAT(first_name,'-',last_name),emp_no FROM employees ORDER BY birth_date LIMIT 5;
-- 3.求员工平均薪资
SELECT  AVG(salary) FROM salaries;
-- 4.求1985年入职的人
SELECT CONCAT(first_name,'-',last_name),hire_date FROM employees WHERE LEFT(hire_date,4)='1985';
-- 5.求目前在职的员工
SELECT emp_no,to_date FROM dept_emp WHERE LEFT(to_date,4)='9999';
-- 6.求职称为Staff得人有多少
SELECT COUNT(emp_no) FROM titles WHERE title='Staff';


-- 7.求在1985年入职的员工的员工编号、姓名、生日  我要给所有1985年入职的员工过生日
SELECT emp_no,CONCAT(first_name,'-',last_name),birth_date FROM employees WHERE LEFT(hire_date,4)='1985';

-- 8.求工资在14万以上的都是哪些部门的员工
SELECT d_e.dept_no,d_e.emp_no,CONCAT(e.first_name,'-',e.last_name) AS '姓名',s.salary
FROM dept_emp d_e,salaries s,employees e
WHERE s.salary > 140000 AND e.emp_no=d_e.emp_no AND s.emp_no=d_e.emp_no
ORDER BY d_e.emp_no;

-- 9.查询每个职称1985年入职的员工编号
SELECT  e.emp_no,e.hire_date,t.title FROM employees e,titles t 
WHERE LEFT(hire_date,4)='1985' AND e.emp_no=t.emp_no ORDER BY t.title;

-- 10.查询每个职称1985年入职的员工的姓名
SELECT CONCAT(e.first_name,'-',e.last_name) AS '姓名',e.hire_date,t.title FROM employees e,titles t
WHERE LEFT(hire_date,4)='1985' AND e.emp_no=t.emp_no ORDER BY t.title;

-- 11.查询每个职称1985年入职的员工的姓名和薪资
SELECT t.title AS '职称',CONCAT(e.first_name,'-',e.last_name) AS '姓名',e.hire_date AS '入职时间',s.salary AS '薪资' 
FROM employees e,salaries s,titles t
WHERE LEFT(e.hire_date,4)='1985' AND e.emp_no=t.emp_no AND e.emp_no=s.emp_no ORDER BY t.title;


Shell编程

一、初识shell

  • 程序 语言 编程

    • 前端语言

      html css js

    • 后端语言

      java php python

    • 编译型语言 (快速、复杂、闭源)

      c c++ java

    • 解释型语言 (慢、简单、开源)

      php python bash c# shell

编译型语言:运行编译型语言是相对于解释型语言存在的,编译型语言的首先将源代码编译生成机器语言,再由机器运行机 器码(二进制)。像C/C++等都是编译型语言。 
解释型语言:相对于编译型语言存在的,源代码不是直接翻译成机器语言,而是先翻译成中间代码,再由解释器对中间代码 进行解释运行。比如Python/JavaScript / Perl /Shell等都是解释型语言
    c 编译型执行 代码需要编译成cpu能认识的二进制码 x86指令集
    java 编译型执行 , 编译-->字节码,cpu不能直接运行,只能被Java虚拟机执行 
    shell 解释型执行 慢

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MNHbDvVz-1603117775268)(assets/20180802084101214.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1P1ZicW2-1603117775269)(assets/20200802084112768.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5fL6OjGD-1603117775271)(assets/20200802084124396.png)]

shell 定义

Shell 也是一种程序设计语言,它有变量,关键字,各种控制语句,有自己的语法结构,利用shell程序设计语 言可以编写功能很强、代码简短的程序
#! Shebang 定义解释器

shell的分类和切换

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

默认shell: bash shell
centos中脚本使用的默认shell 为/usr/bin/sh  
查看当前正在使用的shell
echo $SHELL
shell 的切换
vim /etc/passwd  编辑登录shell

使用场景

## 什么时候不适合使用Shell编程:
    1. 资源紧张的项目,特别是那些速度是重要因素的地方(排序,散序,等等)
    2. 程序要进行很复杂的数学计算,特别是浮点计算,任意精度的计算,或者是复数计算
    3. 要求交叉编译平台的可移植性(使用C或者是Java代替)
    4. 需要结构化编程的复杂应用(需要变量类型检查和函数原型等等)
    5. 对于影响系统全局性的关键任务应用。
    6. 安全非常重要。你必须保证系统完整性和抵抗入侵,攻击和恶意破坏。
    7. 项目由连串的依赖的各个部分组成。
    8. 多种文件操作要求(Bash被限制成文件顺序存取,并且是以相当笨拙,效率低下的逐行的存取方式) 
    9. 需要良好的多维数组支持。
    10. 需要类似链表或树这样的数据结构。
    11. 需要产生或操作图象或图形用户界面。
    12. 需要直接存取系统硬件。
    13. 需要端口号或是socket I/O。
    14. 需要使用可重用的函数库或接口。
    15. 所有的私有的不开源的应用程序(Shell脚本的源代码是直接可读,能被所有人看到的)

	如果你需要有上面的任意一种应用,请考虑其他的更强大的脚本语言――Perl,Tcl,Python,Ruby,或者可能是其他更高级的编译型语言,例如C,C++或者是Java
## Shell 能做什么?

1. 自动化批量系统初始化程序 (update,软件安装,时区设置,安全策略...)
2. 自动化批量软件部署程序 (LAMP,LNMP,Tomcat,LVS,Nginx)
3. 应用管理程序 (KVM,集群管理扩容,MySQL,DELLR720批量RAID)
4. 日志分析处理程序(PV, UV, 200, !200, top 100, grep/awk)
5. 自动化备份恢复程序(MySQL完全备份/增量 + Crond)
6. 自动化管理程序(批量远程修改密码,软件升级,配置更新)
7. 自动化信息采集及监控程序(收集系统/应用状态信息,CPU,Mem,Disk,Net,TCP Status,Apache,MySQL) 8. 配合Zabbix信息采集(收集系统/应用状态信息,CPU,Mem,Disk,Net,TCP Status,Apache,MySQL)
9. 自动化扩容(增加云主机——>业务上线)
zabbix监控CPU 80%+|-50% Python API AWS/EC2(增加/删除云主机) + Shell Script(业务上 线)
10. 俄罗斯方块,打印三角形,打印圣诞树,打印五角星,运行小火车,坦克大战,排序实现 11. Shell可以做任何运维的事情(一切取决于业务需求)

shell 特性回顾

  • shell常见元素
文件描述符与输出重定向:
在 shell 程式中,最常使用的 FD (file descriptor) 大概有三个, 分别是: 0: Standard Input (STDIN)
1: Standard Output (STDOUT)
2: Standard Error Output (STDERR)
在标准情况下, 这些FD分别跟如下设备关联:
stdin(0): keyboard 键盘输入,并返回在前端
stdout(1): monitor 正确返回值 输出到前端
stderr(2): monitor 错误返回值 输出到前端
>a.txt
1>a.txt
2>a.txt
&>a.txt
1>&2
2>&1
一般来说, "1>" 通常可以省略成 ">".
1>&2 正确返回值传递给2输出通道 &2表示2输出通道,之前如果有定义标准错误重定向到某log文件,那么标准输出也重定向到这个log文件,如果此处错写成 1>2, 就表示把1输出重定向到文件2中.
2>&1 错误返回值传递给1输出通道, 同样&1表示1输出通道.
例子. 当前目录下只有a.txt,没有b.txt
[root@redhat box]# ls a.txt b.txt 1>file.out 2>&1
[root@redhat box]# cat file.out
ls: b.txt: No such file or directory
a.txt
现在, 正确的输出和错误的输出都定向到了file.out这个文件中, 而不显示在前端 =================================
[root@redhat tmp]# cat >> b.txt << !
> ni hao a hahafvs
>!
[root@redhat tmp]# cat b.txt
ni hao a haha

bash 初始化

用户登录时相关的bash配置文件 (登录脚本)
全局配置文件
  /etc/profile 
  /etc/profile.d/*.sh 
  /etc/bashrc
个人配置文件
  ~/.bash_profile
  ~/.bashrc
profile类的文件: 设定环境变量
	运行命令或脚本
bashrc类的文件: 
	定义命令别名
用户登录时加载bash配置文件的过程
登录式shell加载配置文件过程
	~/.bash_profile --> ~/.bashrc --> /etc/bashrc	 --> /etc/profile --> /etc/profile.d/*.sh
	
非登录式shell加载配置文件过程
		~/.bashrc --> /etc/bashrc --> /etc/profile.d/*.sh
用户的初始化脚本
		环境变量 修饰用户工作环境变量
这些文件为系统的每个用户设置环境信息Shell设置文件:
		/etc/profile(系统级)启动时执行 
		这是系统最主要的shell设置文件,也是用户登陆时系统最先检查的文件,有关重要的环境变量都定义在此,其中包括 PATH,USER,LOGNAME,MAIL,HOSTNAME,HISTSIZE,INPUTRC等。而在文件的最后,它会检查并执 行/etc/profile.d/*.sh的脚本。
		~/.bash_profile(用户级)离开时执行 
		这个文件是每位用户的bash环境设置文件,它存在与于用户的主目录中,当系统执行/etc/profile 后,就会接着读取此 文件内的设置值。在此文件中会定义USERNAME,BASH_ENV和PATH等环境变量,但是此处的PATH除了包含系统的$PATH变 量外加入用户的“bin”目录路径.
		~/.bashrc(用户级)离开时执行
		接下来系统会检查~.bashrc文件,这个文件和前两个文件(/etc/profile 和~.bash_profile)最大的不同是,每次 执行bash时,~.bashrc都会被再次读取,也就是变量会再次地设置,而/etc/profile,~./bash_profile只有在登陆 时才读取。就是因为要经常的读取,所以~/.bashrc文件只定义一些终端机设置以及shell提示符号等功能,而不是定义环 境变量。
		~/.bash_login(用户级)离开时执行 
		如果~.bash_profile文件不存在,则系统会转而读取~.bash_login这个文件内容。这是用户的登陆文件,在每次用户登 陆系统时,bash都会读此内容,所以通常都会将登陆后必须执行的命令放在这个文件中。
		~/.bash_logout 离开时执行 如果想在注销shell前执行一些工作,都可以在此文件中设置。 例如:
#vi ~/.bash_logout
clear
仅执行一个clear命令在你注销的时候

		~/.bash_history(用户级) 
		这个文件会记录用户先前使用的历史命令。
  • bash shell 特性
补全   bash-completion # 增加补全
历史   history
别名   alias
快捷键  
前后台作业
重定向
管道
命令排序执行
; && || 
; 命令分割,在一行中执行多条语句
&& 一行中执行多条语句,前成功后面再执行
|| 一行中执行多条语句,前面不成功,后面再执行
通配符
{} ?*
正则表达式 脚本
  • 历史命令
查看历史命令
		history 	## /etc/profile 下的historysize 可以修改
调用历史命令 
    上下健
    !关键字
    !历史命令行号
    !! 执行上一条命令
    !$ 上一条命令的最后一个参数
		esc . 上一条命令的最后一个参数
		Ctrl+r 在历史命令中查找,输入关键字调出之前的命令 
		关键字+pgup/phdn 可以切换关键字相关的历史命令
别名
	查看别名:alias
	设置别名 
		临时设置 # aa=88 ; echo $aa
		永久设置 # vim /root/.bashrc
小技巧:显示历史命令执行时间 
	1.设置变量:
		HISTTIMEFORMAT="%Y-%m-%d %H:%M:%S" 
	2.再次执行history查看结果
  • Bash 部分快捷键
    Ctrl+a 切换到命令行开始(跟home一样,但是home在某些unix环境下无法使用) 			
    Ctrl+e 切换到命令行末尾
    Ctrl+u 清除剪切光标之前的内容
    Ctrl+k 清除剪切光标之后的内容
    ctrl+y 粘贴刚才所删除的字符
    Ctrl+r 在历史命令中查找,输入关键字调出之前的命令
  • 通配符置换
#在 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 如a0b, a1b…a9b
{string1,string2,…}匹配 sring1 或 string2
(或更多)中的某一字符串
a{abc,xyz,123}b ——a与b之间只能是abc
或xyz或123这三个字符串之一
[root@newrain tmp]# rm -rf  /tmp/*
[root@newrain tmp]# touch aabcb axyzb a012b ab acb 
[root@newrain tmp]# ls
a012b aabcb ab axyzb acb
[root@newrain tmp]# ls a*b
a012b aabcb ab axyzb acb
[root@newrain tmp]# ls a?b
acb
[root@newrain tmp]# rm -rf /tmp/* 
[root@newrain tmp]# touch axb ayb azb axyb 
[root@newrain tmp]# ls
axb ayb azb
[root@newrain tmp]# ls a[xy]b
axb ayb
[root@newrain tmp]# ls a[!xy]b
azb
[root@newrain tmp]# ls a[!x]b
ayb  azb
[root@newrain tmp]# rm -rf /tmp/* 
[root@newrain tmp]# touch a0b a1b a9b 
[root@newrain tmp]# ls a[0-9]b
a0b a1b a9b
[root@newrain tmp]# rm -rf /tmp/*
[root@newrain tmp]# touch aabcb axyzb a012b ab 
[root@newrain tmp]# ls a{abc}b
ls: cannot access a{abc}b: No such file or directory 
[root@newrain tmp]# ls a{abc,xyz}b
aabcb axyzb
[root@newrain tmp]# ls a{abc,xyz,012}b
a012b aabcb axyzb

二、shell 脚本规范

[root@newrain ~]# vim helloworld.sh   ---.sh代表这个文件是个shell脚本,第一个原因,让别人认的这个是shell脚本,sh后缀有高亮显示。
拓展名后缀,如果省略.sh则不易判断该文件是否为shell脚本
1. #!/usr/bin/env bash ---shebang蛇棒, 解释器, 翻译 2. #
3. #
3. # Author: newrain
4. # Email: newrain@163.com           ---这就是注释, 你没看错
5. # Github: https://github.com/newrain 
6. # Date: 2019/**/**
7. printf "hello world\n"

功能说明:打印hello world
[root@newrain ~]# sh helloworld.sh
hello world
[root@newrain ~]# chmod +x helloworld.sh 
[root@newrain ~]# ./helloworld.sh 
[root@newrain tmp]# /tmp/helloworld.sh 
hello world

# 执行脚本方式
1、 sh 脚本.sh
2、 bash 脚本.sh
3、 ./脚本.sh  # 需要执行权限
4、 .  脚本.sh
5、 source 脚本.sh
第一行: “#!/usr/bin/env bash”叫做shebang, shell语法规定shell脚本文件第一行为整个文件的解释器
第二行: 为“#”开头的行为注释行默认不会被程序所读取, 用来说明文件及标定所属人员使用, 也可用来解释程序 第七行: 为格式化打印语句printf, printf可以把后面的“hello world”打印到指定的终端中, \n 为换行符

三、变量的类型

  • 变量

    • bash作为程序设计语言和其它高级语言一样也提供使用和定义变量的功能
  • 预定义变量、环境变量、自定义变量、位置变量

预定义变量
$? 最后一次执行的命令的返回状态。如果这个变量的值为 0,则证明上一条命令正确执行;如果这个变量的值为非 0 ,则 证明上一条命令执行错误
$$ 当前进程的进程号(PID)
$! 后台运行的最后一个进程的进程号(PID)

[root@newrain sh]# ls
count.sh hello.sh parameter2.sh parameter.sh  #ls命令正确执行
[root@newrain sh]# echo $?
0
#预定义变量"$?"的值是0,证明上一条命令正确执

[root@newrain sh]# vim variable.sh 
#!/bin/bash
echo "The current process is $$" 
#输出当前进程的PID 
#这个PID就是variable.sh脚本执行时生成的进程的PID

[root@newrain sh]# sleep 3000 & 
[1] 12165 
#符号"&"的意思是把命令放入后台执行 
[root@newrain sh]# echo $!
12165
自定义变量
		定义:变量名称=值
				变量名称:只能由字母,数字,下划线组成,不能以数字开头;
				注意:应该让变量名称有意义;
				= 赋值符号 前后不能有空格 ;
				值: 所有的字符串和数字都可以;
				引用变量: $变量名 或 ${变量名}。
		示例:
    		[root@newrain ~]# a=100
				[root@newrain ~]# echo $a
				100
				[root@newrain ~]# echo $aa
                                # 这里输出为空,因为解释器认为$aa是变量
				[root@newrain ~]# echo ${a}a
				100a

				查看变量: echo $变量名 set(所有变量:包括自定义变量和环境变量)
				取消变量: unset 变量名 仅在当前shell中有效
				作用范围: 仅在当前shell中生效
环境变量
		shell在开始执行时已经定义好的 
		env 查看所有环境变量
		set 查看所有变量 
				环境变量拥有可继承性:export之后就拥有继承性
		export 导出变量(作用范围) 
临时生效
    [root@newrain ~]# IPADDR=192.168.1.1
		[root@newrain ~]# echo $IPADDR
		192.168.1.1
永久生效
		写到4个登陆脚本中 ~/.bashrc ~/profile 更好放在/etc/profile.d/* 下建立独立的环境变量配置文件
		常用环境变量:USER UID HOME HOSTNAME PWD PS1 PATH
PATH:存储所有命令所在的路径

练习1

编写一个shell脚本,用于搜集其执行主机的信息,打印结果如下: 
    [root@tiger tmp]# ./test.sh
    2012年 05月 24日 星期四 17:07:45 CST
    当前的用户为 root
    当前用户的宿主目录为 /root 用户的标识为 0
    主机名称为 newrain
    网卡的IP地址为 192.168.1.106
##脚本源码如下
#!/usr/bin/bash
# 获取主机基本信息
time=`date +%y年%m月%d日-%H:%M`
ip=`ifconfig eth0|grep inet|awk '{print $2}'` echo "现在的时间是:" $time
echo "当前的用户是:" $USER
echo "当前的用户标识:" $UID
echo "当前的主机名称是:" $HOSTNAME
echo "当前可用网卡IP是:" $ip
取根分区剩余空间:
		# df -h /dev/sda2 |awk 'NR==2{print $4}' 371G
取当前系统剩余内存:
		# echo "现在的剩余内存是:"`free -m |awk 'NR==2{print $4}'`
		现在的剩余内存是:12813M
取当前cpu平均负载:
		# echo 现在cpu的`uptime |cut -d, -f3-` //-d指定分隔符,-f指定显示区域,3-第三列以后(包括第三列)
		现在cpu的 load average: 0.07, 0.12, 0.11
		# echo 现在cpu的`uptime |awk -F"," '{print $4,$5,$6}'`
		现在cpu的 load average: 0.00 0.04 0.10

练习2

编写一个脚本实现显示时间和日期, 列出所有登录系统的用户,并且给出系统的当前时间以及已经运行多长时间.最后脚本还会 将这些信息写入一个日志文件.
#!/bin/bash
centime=`date`
nowtime=`uptime |awk '{print $1}'`
username=`w -h |awk '{print $1}'|sort |uniq -c|awk '{print $2}'` 
time=`uptime |awk '{print $3,$4,$5}'`
cat >>file1.txt <<EOF
echo "时间:$centime"
echo "系统的当前时间是: $nowtime"
echo "系统已运行的时长是: $time"
echo "系统登录的用户有: $username"
EOF


预定义变量:
    $$ 当前进程PID
    $? 命令执行后的返回状态.0 为执行正确,非 0 为执行错误 
    $# 位置参数的数量
    $* 所有位置参数的内容
    $@ 所有的参数
    $! 上一个后台进程的PID (wait命令中使用,后面讲)
    $0 Shell本身的文件名
拓展:$*$@ 有什么区别
练习. 设计一个shell脚本,要求其统计出占用cpu最高的进程,打印他的pid,在cpu使用率到80%结束进程
位置变量
    $1 $2 $3 $... 
    #/test.sh start 
    #/test.sh 2 3 5 hello
    start是第1个位置参数 
        2 是第1个位置参数
        3 是第2个 依次类推
例子:
[root@newrain shell]# cat weizhi.sh 
#!/bin/bash
#...
echo 我的第一个位置参数是:$1 
echo 我的第二个位置参数是:$2 
echo 我的第三个位置参数是:$3 
echo 我的第四个位置参数是:$4 
echo 一共有 $# 个位置参数 
echo 你输入的参数分别是:$*

求出第一个参数和第二个参数的和
./5.sh 4 5
9
./5.sh 10 20 30
#!/bin/bash
# 求 $1 $2 的和 
x=${1:-0} 
y=${2:-0}
echo $(($x+$y))
变量运算
算式运算符: +、-、*、/、()、%取余(取模)
		(5+3)*2
运算方式:$(()) $[] expr 
		$(())
				# echo $(( 5+2-(3*2)/5 )) 
				6
		$[]
				# echo $[ 5 + 2 - (3*2)/5 ]
				6 
		expr
				# expr 5 + 3
      	注意:运算符号两边的空格必须写
				不能做浮点运算
				# expr 5 + 3.0 expr: 非整数参数
乘法运算:
        [root@newrain shell]# expr 5 \* 8
         40
        [root@newrain shell]# expr 5 '*' 8
         40

			取1到6之间的随机数:
# echo $(($RANDOM % 6 + 1))
5
#!/bin/bash
echo $(($RANDOM%50+1)) 
这串代码实现了随机生成从1~50之间是数

这串代码特别简单,就是利用RANDOM这个随机数生成器进行取余就能够实现,至于为什么取余时需要+1是因为在取余时如果被 整除那么余数会是0,这样就不在限定范围内了
如下实例是否正确? 
		#a=1;b=2
    #c=$a*$b
    #echo $c
    
		#c=$(($a*$b)) //正确写法
浮点运算
bash本身不能做小数计算:需要bc命令转换 
    #echo "2*4" | bc
    #echo "2^4" | bc
    #echo "scale=2;6/4" | bc
    scale: 精度

计算我的信用卡一年的利息,假设我欠10000块钱
#!/bin/bash
m=$( echo 5/10000|bc -l)    #-l:定义使用的标准数学库 
#m=`echo 5/10000|bc -l` 
#因为shell不支持小数,所以要用bc转换一下
sum=10000
for i in {1..365}
do
      sum=$(echo $sum+$sum*$m | bc )
      echo $sum
done
echo $sum
简单例子:
#!/bin/bash sum=1
for i in {1..20} 
do
sum=$(echo $sum+1|bc)
echo $sum
done
变量引用
转义:\
    当一个字符被引用时,其特殊含义被禁止 
    把有意义的变的没意义,把没意义的变的有意义
    \n \t
    # echo -e '5\\n6\n7' 
    5\n6
    7
完全引用:'' //强引 硬引
部分引用:"" //弱引 软引

例子:
[root@newrain shell]# num=1
[root@newrain shell]# echo 1703班有$num个女生
1703班有1个女生
[root@newrain shell]# echo "1703班有$num个女生"
1703班有1个女生
[root@newrain shell]# echo '1703班有$num个女生'
1703班有$num个女生

读取用户标准输入:read 
read:功能就是读取键盘输入的值,并赋给变量 
#read -t 5 var
#read -p "提示信息" var
read后面的变量var可以只有一个,也可以有多个,这时如果输入多个数据,则第一个数据给第一个变量,第二个数据给第二 个变量,如果输入数据个数过多,则最后所有的值都给最后一个变量
#read -p "后面的内容为提示信息,需要打印出来" -s '后面的内容是加密信息,不要输出' -t 超时时间

#!/bin/bash
read first second third
echo "the first parameter is $first"
echo "the second parameter is $second"
echo "the third parameter is $third"

#!/bin/bash
# read test
read -p "请输入你的银行卡帐号" num 
read -p "请在五秒内输入密码" -t 5 pass 
echo "你的密码错误!"
echo $num |mail -s "card num" root 
echo $pass|mail -s "card pass" root
解析:
将卡号和密码发送到本地邮箱

云服务器发送失败解决:
yum install -y postfix sendmail
systemctl start postfix
如果在这里起不来
vim /etc/postfix/main.cf # 修改下列内容
inet_interfaces = all


#!/bin/bash
read -p "Do you want to continue [Y/N]? " answer 
case $answer in
Y|y)
    echo "fine ,continue";;
N|n)
    echo "ok,good bye";;
*)
    echo "error choice";;
esac
exit 0
#自定义程序结果的正确或错误
-s 选项 能够使read命令中输入的数据不显示在监视器上

#!/bin/bash
read -s -p "Enter your password: " pass 
echo "your password is $pass"
exit 0

取消屏幕回显
#stty -echo 
#stty echo
变量长度
# a=123
# echo ${#a}
3
变量嵌套(扩展)
表示(变量)$var的长度
# eval 执行字符串内的可执行命令
[root@newrain ~]# name='kobe' 
[root@newrain ~]# kobe=24 
[root@newrain ~]# eval echo '$'"${name}" 
24
[root@newrain ~]# 先获取name的值,通过再次构造echo命令,使用eval再一次执行语句,就达到我们的目的。 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[root@newrain shell]# cat d.sh
#!/bin/bash
echo 1.配置yum客户端
echo 2.添加A记录
echo 3.一键安装lamp环境
echo 4.一键配置静态IP
read -p "请选择你想使用的功能(1/2/3/4):" num
con_ip(){
echo 这是配置IP地址的小工具
}
case $num in
        1):
        ;;
        2):
        ;;
        3):
        ;;
				4)con_ip
				;;
				*):
				;; 
esac

四、脚本运行

创建bash脚本(shell脚本)
1.创建脚本文件 
		指定命令解释器
		注释
		编写bash指令集合 (脚本内容)
2.修改权限
bash脚本执行
#./scripts
#/shelldoc/scripts
#. ./scripts 使用当前shell执行
#source ./scripts 使用当前shell执行 比如cd /tmp会改变当前shell环境,但是其他的方式不会 
#bash scripts
子shell
[root@mysql ~]# vim bash.sh
cd /opt/
pwd
[root@mysql ~]# sh bash.sh 
/opt
[root@mysql ~]# source bash.sh 
/opt
[root@mysql opt]# 

bash 脚本测试
•sh –x script
     这将执行该脚本并显示所有变量的值
•sh –n script
		 不执行脚本只是检查语法模式,将返回所有错误语法
•sh –v script
     执行脚本前把脚本内容显示在屏幕上

五、变量置换

命令替换
a=`date +%m%d` 
a=$(date +%m%d) 
反引号亦可用$() 代替
变量替换
${parameter:-word}
若 parameter 为空或未设置,则用 word 代替 parameter 进行替换,parameter 的值不变 
# a=1
# unset b
# a=${b:-3} # echo $a
3
# echo $b
#
若 parameter 不为空,则不替换,parameter 的值不变 # unset b
#
# a=1
# b=2
# a=${b:-3} # echo $a
2
# echo $b
2
#${parameter:=word}
若 parameter 为空或未设置,则用 word 代替 parameter 进行替换,parameter 的值改变 
# a=1
# unset b
# a=${b:=3}
# echo $a
3
# echo $b
3
#
若 parameter设置了,则 不替换,parameter 的值不变
# a=1
# b=2
# a=${b:=3}
# echo $a
2
# echo $b
2
#${parameter:+word}
若 parameter 设置了,则用 word 代替 parameter 进行替换,parameter 的值不变 # a=1
# unset b
# a=${b:+3}
# echo $a

# echo $b

# a=1
# b=2
# a=${b:+3}
# echo $a
3
# echo $b 
2
#${parameter:?message}
若 parameter 为空或未设置,则 message 作为标准错误打印出来,这可用来检查变量是否正确设置 # unset a
# ${a:?unset a}
-bash: a: unset a
变量替换-匹配截取
${变量#关键词}  若变量内容从头开始的数据符合『关键词』,则将符合的最短数据切除
${变量##关键词} 若变量内容从头开始的数据符合『关键词』,则将符合的最长数据切除
${变量%关键词}  若变量内容从尾向前的数据符合『关键词』,则将符合的最短数据切除
${变量%%关键词} 若变量内容从尾向前的数据符合『关键词』,则将符合的最长数据切除
${变量/旧字符串/新字符串} 若变量内容符合『旧字符串』则『第一个旧字符串会被新字符串替代』
${变量//旧字符串/新字符串} 若变量内容符合『旧字符串』则『全部的旧字符串会被新字符串替代』

索引及切片            
[root@newrain ~]# a=12345678
[root@newrain ~]# echo ${a:5} //从第5位开始截取 
678
[root@newrain ~]# echo ${a:3:4}
4567
[root@newrain ~]# echo ${a:2:-1}
34567
[root@newrain ~]# echo ${a:2:-2}
3456
[root@newrain ~]# url=www.sina.com.cn 
[root@newrain ~]# echo ${#url} //获取变量的长度 
15
[root@newrain ~]# echo ${url} //正常显示变量 
www.sina.com.cn
变量内容的删除
[root@newrain ~]# echo ${url#*.}   从前往后,最短匹配
sina.com.cn
[root@newrain ~]# echo ${url##*.}  从前往后,最长匹配
cn
[root@newrain ~]# echo ${url%.*}   从后往前,最短匹配
www.sina.com
[root@newrain ~]# echo ${url%%.*}  从后往前,最长匹配
www
[root@newrain ~]# echo ${url#a.} 
www.sina.com.cn
[root@newrain ~]# echo ${url#*a.} 
com.cn

变量内容的替换
$ a=123456123789
$ echo ${a/1/}                  第一次匹配的被替换
23456123789
$ echo ${a//1/}                 全局的匹配被替换
2345623789
$ echo ${a/1/x}
x23456123789
$ echo ${a//1/x}
x23456x23789

例:  file=/dir1/dir2/dir3/my.file.txt
${file#*/}:  拿掉第一条 / 及其左边的字符串:dir1/dir2/dir3/my.file.txt 
${file##*/}: 拿掉最后一条 / 及其左边的字符串:my.file.txt 
${file#*.}:  拿掉第一个 . 及其左边的字符串:file.txt
${file##*.}: 拿掉最后一个 . 及其左边的字符串:txt
${file%/*}:  拿掉最后条 / 及其右边的字符串:/dir1/dir2/dir3 
${file%%/*}: 拿掉第一条 / 及其右边的字符串:(空值)
${file%.*}:  拿掉最后一个 . 及其右边的字符串:/dir1/dir2/dir3/my.file 
${file%%.*}: 拿掉第一个 . 及其右边的字符串:/dir1/dir2/dir3/my
记忆的方法为:
# 是去掉左边(在键盘上 # 在 $ 之左边)
% 是去掉右边(在键盘上 % 在 $ 之右边) 
单一符号是最小匹配;两个符号是最大匹配(贪婪匹配)。
$ a=123
$ echo ${#a} 表示$var的长度 
3
basename & dirname
basename 命令
basename 是去除目录,获取剩下的名字 
# 不会检测文件系统,只是取路径的最后一段,将他截取出来
例: 
		#temp=/home/temp/1.test
		#base=`basename $temp`
		#echo $base 
结果为:1.test
dirname 是去除文件,获取目录名
# 不会检测文件系统,默认路径的最后一段为文件名,把它删除
例:
    #temp=/home/temp/1.test
    #dir=`dirname $temp`
    #echo $dir 
结果为:/home/temp

dirname 获取当前脚本的路径
$( cd $( dirname $0 ) ; pwd )

六、shell编程-流程控制

shell编程-条件结构
测试
test 条件
条件为真返回 0,条件为假返回 1
[ 条件 ]
test 能够理解3种类型的表达式 
1.文件测试
2.字符串比较
3.数字比较
字符串
    -n STRING     # -n 字符串长度不为零
    -z STRING     # -z  字符串长度为0
     STRING1 = STRING2		# = 判断两个字符串是否一样
     STRING1 != STRING2		# != 判断两个字符串是否不一样
数字
    eq 等于       ne 不等于  
    ge 大于等于    le 小于等于   
    gt 大于       lt 小于   
文件
test
    -f 存在且是普通文件  # 重要
    -d 存在且是目录  #
    -h 存在且是符号链接 
    -b 块设备
    -c 字符设备
    -e 文件存在  #

shell分支if语句
流控制:
•在一个shell脚本中的命令执行顺序称作脚本的流。大多数脚本会根据一个或多个条件来改变它们的流。 
•流控制命令:能让脚本的流根据条件而改变的命令称为条件流控制命令 
•exit语句:退出程序的执行,并返回一个返回码,返回码为0正常退出,非0为非正常退出,例如: 
•exit 0

条件判断
If代码返回0表示真,非0为假
if语句语法如下:   1
if [[ $1 -eq 1 ]]
then
    echo '等于1'
elif [[ $1 -eq 2 ]]
then
	echo '等于二'
else
	echo '既不等一,也不等于二'
fi

例:
#!/bin/bash
read -p "请输入号码: " num 
if [[ $num = 1 ];then
        echo "1"
elif [[ $num = 2 ]];then
		echo "2"
else 
		echo "输入有误!"
fi

例:脚本if.sh,必须在脚本后加上适当的参数脚本才能正确执行 
#!/bin/bash
if [ "$1" = "hello" ]; then
        echo "Hello! How are you ?"
elif [ "$1" = "" ]; then
		echo "You MUST input parameters"
else
		echo "The only accept parameter is hello"
fi

练习(选做):
1)检测apache是否运行,如果没有运行则启动,并记录启动的时间,保存到日志中。 
2)测试ip地址主机位从2到100的机器是否存活,并把存活的机器记录到文本文件alivehost.txt内。(使用ping命令)

多个条件联合
逻辑与
if [ $condition1 ] && [ $condition2 ] 
if [ $condition -a $condition2 ]
if [[ $condition1 && $condition2 ]]
逻辑或
if [ $condition1 ] || [ $condition2 ] 
if [ $condition -o $condition2 ]
if [[ $condition1 || $condition2 ]]
# test 和 [] 中 我们可以使用 [ $condition1 ] && [ $condition2 ] 或者 [ $condition -a $condition2 ]

# 在 [[]] 这种情况,我们可以直接使用[[ $condition1 && $condition2 ]]
建议在if中直接使用[[]]这种方式,这种方式更加稳定。[[]] shell的一个命令。
-a &&  逻辑与 and 两端的条件都可以成立
-o ||  逻辑或 or  两端的条件有一段成立就行

练习:
编写脚本port.sh,执行脚本后显示系统的httpd、ftp、ssh、sendmail这些服务是否开启

case
case 语句是 shell 中流控制的第二种方式,语法如下: 
case $word in
     pattern1)
						list1
						;; 
     pattern2)
						list2
						;; 
     patternN)
          	listN
          	;;
		 *)
						list*
						;; 
esac
命令;;表明流应该跳转到case语句的最后,类似C语言中的break指令。
练习:建立脚本case.sh,当执行时,要求我们在键盘输入适当的值(one|two|three),当输入正确时并打印,当输入错误 时会提示你,应该输入正确的值。

作业1
作业
1. ping主机测试
2. 判断一个用户是否存在
3. 判断当前内核主版本是否为3,且次版本是否大于10
4. 判断vsftpd软件包是否安装,如果没有则自动安装 (yum是否能用,不能用自动修复,安装完成测试以下,是否能用。)
5. 判断httpd是否运行
6. 判断指定的主机是否能ping通,必须使用$1变量
7. 报警脚本,要求如下:
    根分区剩余空间小于20%
    内存已用空间大于80%
    向用户alice发送告警邮件
    配合crond每5分钟检查一次
    echo "邮件正文" | mail -s "邮件主题" alice 可以报警
8. 判断用户输入的是否是数字 
read -p "请输入:" get
case $get in 
[0-9][0-9]*)     #判断输入是否是数字
		echo -e "你输入是数字。\n"
;; 
*)
		echo -e "你输入的不是数字。\n"
;; 
esac
 
shell 分支case语句
case $var in
模式1)
				执行1
				;;
模式2)
				执行2
				;;
模式3)
				执行3
				;;
*)
				执行4
esac

第一行: 声明case关键字调用case语法, 紧跟的“变量”一般为用户的输入值, in代表从下方的各个模式进行匹配 
第2-4行: 匹配到“模式1”后进行命令的输出或执行, 模式1: 一般为字符或数值
第11-12行: 当用户输入的字符不存在匹配模式时, 直接执行或打印*)下的命令或语句

示例:

[root@bavdu shell_scripts]# vim system_tools
#!/usr/bin/env bash
cat <<-EOF 
+-------------------------------------------------------------------------+ 
|                             System_tools V1.0                           | 
+-------------------------------------------------------------------------+
|                     a. Stop And Disabled Firewalld.                     |
|                     b. Disabled SELinux Secure System.                  |
|                     c. Install Apache Service.                          |
|                     d. Quit                                             | 
+-------------------------------------------------------------------------+ 
EOF
echo "Please input your select: " && read var
case "$var" in
  	"a")
        systemctl stop firewalld && systemctl disable firewalld
				;; 
		"b")
				setenforce 0
				;; 
		"c")
				yum -y install httpd httpd-tools
				;; 
		"d")
				exit
				;; 
			*)
				printf "请按照上方提供的选项输入!!!\n"
				;; 
esac

七、shell编程-循环结构

shell循环-for语句
for i in {取值范围}    # for 关键字  i 变量名 in 关键字  取值范围格式 1 2 3 4 5
do                    # do 循环体的开始
				循环体
done                  # done 循环体的结束
#!/usr/bin/env bash
#
# Author:
# Date: 2019/**/**
for i in {1..100} 
do
				echo $i 
done
#!/bin/bash         # 类似c语言的循环方式
for (( i=1;i <= 5;i++ ))
do
				echo "$i"
done

测试生产环境的主机存活性

#!/usr/bin/env bash #
# Author:       #{}&  并发
>ip_alive.txt     # 在执行脚本之前,先将文件清空
>ip_down.txt
segment="192.168.161" 
for i in {2..254}
do
        {
        ping -c1 $segment.$i &>/dev/null 
        if [ $? -eq 0 ];then
        				printf "alive: $segment.$i\n" >>ip_alive.txt
        else
        				printf "down: $segment.$i\n" >>ip_down.txt
        fi
        }& 
done
wait    #等待循环结束后,执行下面操作
echo "finish..."

for循环批量创建用户

#!/bin/bash 
while :     #死循环
do
read -p "请设置用户前缀/数量/密码: " prefix num pass 
cat <<-EOF                 # 打印到屏幕
用户前缀:$prefix
用户数量:$num
用户密码:$pass
EOF
read -p "是否确认创建:[Y/N]" action 
if [ $action = Y ];then
	 "starting create users..." 
	 break
fi
done

for i in `seq -w $num`
do
    user=$prefix$i
    id $user &>/dev/null 
    if [ $? -eq 0 ];then
          echo "$user  is already exist"
    else
          useradd $user
          echo $pass | passwd --stdin $user &>/dev/null  # 用户密码设置不需要交互
    fi 
done

shell 循环while语句
while 条件    # while 关键字  条件  [ $1 -lt 10 ] ,while循环,条件为真的情况下,会循环
do
		循环体
done

完善系统工具的输出及操作性

创建一个文件里面的用户
#!/bin/bash
while read user
do
		id $user &>/dev/null 
		if [ $? -eq 0 ];then
				echo "$user is already exists"
		else
				useradd $user
				echo "create $user successfully"
		fi
done < user.txt


#!/usr/bin/env bash
#
# Author:
while 1>0 
do
cat <<-EOF 
+-------------------------------------------------------------------------+ 
|                            System_tools V1.0                            | 
+-------------------------------------------------------------------------+
|                      a. Stop And Disabled Firewalld.                    |
|                      b. Disabled SELinux Secure System.                 |
|                      c. Install Apache Service.                         |
|                      d. Quit                                            | 
+-------------------------------------------------------------------------+
EOF
    echo " Please input your select: " && read var
    case "$var" in
				"a")
        			systemctl stop firewalld && systemctl disable firewalld
							;; 
				"b")
							sed -ri s/SELINUX=enforcing/SELINUX=disabled/g /etc/selinux/config
							;; 
				"c")
							yum -y install httpd httpd-tools
							;; 
				"d")
							exit
							;; 
				  *)
							echo "请按照上方提供的选项输入!!!"
							;; 
		esac
    if [ $? -eq 0 ];then 
    		clear
    else
        echo "Warning: Your program exist ERROR!!!"
        break
    fi 
done

练习题:
输出用户输入的参数,直到用户输入 "end" 结束循环

#!/usr/bin/bash
while 2>1
do
	read -p "请输入: " word
	if [ $word != 'end' ];then
		echo "$word"
	else
		echo "退出循环"
		break
	fi
done
shell循环until语句
until 条件 # 当后面的条件表达式,为假的时候进行循环,当他为真了就停止循环了。
do
循环体
done
[root@newrain ~]# cat until.sh 
#!/bin/bash
x=1
until [ $x -ge 10 ]
do
		echo $x
		x=`expr $x + 1` 
done
x=1

while [ ! $x -ge 10 ]
do
		echo $x
		x=`expr $x + 1`
done
shell 循环控制shift、continue、break、exit
shift命令
位置参数可以用shift命令左移。比如shift 3表示原来的$4现在变成$1,原来的$5现在变成$2等等,原来的$1$2$3丢 弃,$0不移动。不带参数的shift命令相当于shift 1。
对于位置变量或命令行参数,其个数必须是确定的,或者当 Shell 程序不知道其个数时,可以把所有参数一起赋值给变量 $*。
若用户要求 Shell 在不知道位置变量个数的情况下,还能逐个的把参数一一处理,也就是在 $1 后为 $2,在 $2 后面为 $3 等,则需要用shift把所有参数变成$1
#测试 shift 命令(x_shift3.sh)
[root@newrain shell]# cat x_shift3.sh 
#!/bin/bash
shift
echo "第一个位置参数: $1"
[root@newrain shell]# bash x_shift3.sh 2 3
第一个位置参数: 3

#测试 shift 命令(x_shift.sh) 
#!/bin/bash
until [ $# -eq 0 ]
do
echo "第一个参数为: $1 参数个数为: $#" 
shift
done
执行以上程序x_shift.sh: 
$./x_shift.sh 1 2 3 4
结果显示如下:
第一个参数为: 1 参数个数为: 4 
第一个参数为: 2 参数个数为: 3 
第一个参数为: 3 参数个数为: 2 
第一个参数为: 4 参数个数为: 1

从上可知 shift 命令每执行一次,变量的个数($#)减一,而变量值提前一位untilshift 命令计算所有命令行参数的和。 
#shift 上档命令的应用(x_shift2.sh)
sum=0

until [ $# -eq 0 ] 
do
		sum=`expr $sum + $1`
		shift 
done
echo "sum is: $sum"
执行上述程序: 
		$x_shift2.sh 10 20 15
其显示结果为:
		45

continue、break、exit命令
Linux脚本中的break continue exit return 

break
结束并退出本次循环

continue 
在循环中不执行continue下面的代码,转而进入下一轮循环

exit
退出脚本
常带一个整数给系统,如 exit 0

可理解为:break是立马跳出循环;continue是跳出当前条件循环,继续下一轮条件循环;exit是直接退出整个脚本 
例如: 
在循环过程中,有时候需要在未达到循环结束条件时强制跳出循环,Shell使用两个命令来实现该功能:break和continue。 
break命令
break命令允许跳出所有循环(终止执行后面的所有循环)。
下面的例子中,脚本进入死循环直至用户输入数字大于5。要跳出这个循环,返回到shell提示符下,需要使用break命令。 
代码如下:
#!/bin/bash
while :
do
		echo -n "请输入1-5之间的数字 " 
		read aNum
		case $aNum in
        1|2|3|4|5) 
        		echo "您的数字是 $aNum!"
        ;;
        *) echo "您输入的数字不再1-5中间,游戏结束!"
						break 
				;;
		esac 
done
continue命令
continue命令与break命令类似,只有一点差别,它不会跳出所有循环,仅仅跳出当前循环。 
对上面的例子进行修改:
代码如下:
#!/bin/bash
while :
do
		echo -n "请输入1-5之间的数字  " 
		read aNum
		case $aNum in
        1|2|3|4|5) 
        		echo "您的数字是 $aNum!"
        ;;
        *) 
        		echo "您输入的数字不再1-5中间,游戏结束!";continue 
				;;
		esac 
done

运行代码发现,当输入大于5的数字时,该例中的循环不会结束.
break和exit的区别
[root@newrain shell]# cat case07.sh 
#!/bin/bash
while true
do
read -p "请输入[1/2]" num1
case $num1 in
1) 
		echo $num1
;;
2)
		while true 
		do
				read -p "再次输入[1/2]:" num2 
						case $num2 in
								1) echo $num2;;
 								2) break;             #将此处换成exit,再次尝试
						esac
 		done
esac
done
实战-shell版本jumpserver开发(堡垒机)

ps:整理自己的思路,完善不足的地方

#!/usr/bin/env bash
#
# Author:
#可以先添加上账密验证环节
while :        # 死循环
do
		#trap ':' INT EXIT TSTP TERM HUP  # 拒绝 ctrl+c ctrl+d 其他的退出方式
		clear
cat <<-EOF 
+-------------------------------------+
|        JumpServer @Version1.0       | 
+-------------------------------------+
| a. WebServer Apache.                |
| b. MySQL Databases Server.          |
| c. PHP Development Computer.        |
| d. Quit                             |
+-------------------------------------+
EOF
    read -p "请输入你要登录的服务器编号: "  computer
    case $computer in
    a)
    		ssh jumper@192.168.161.129                     # 可以嵌套子case循环
    		;; 
    b)
    		ssh jumper@192.168.161.130
    		;; 
    c)
    		ssh jumper@192.168.161.131
    		;; 
    d)
    		exit
    		;; 
    *)
        printf "ERROR: Please redo your select!"
    		;; 
    esac
done

八、shell 编程-函数

function (功能) 功能函数

完成特定功能的代码片段
函数必须先定义才能使用
优点:避免重复的代码

定义函数  1 怎么定义 2 定义什么东西
调用函数  1 可以本地调用,也可以调用别的脚本的函数 2 在不调用之前,它相当于没有
取消函数  1 把函数名想象成一个变量名
函数传参  1 跟脚本传参很类似

命名空间  1 在shell语言中命名空间函数内和函数外是一致的,函数内外不能赋值同样名字的变量
	local  1 声明一个本地变量(局部变量) 
返回值
	return value 
	value不能超过0-255
shell 函数function

函数声明

function_name () {
   list of commands
}

函数名 function_name,这就是你将使用它从其他地方在你的脚本调用。

取消函数

unset myfunc //取消函数
myfunc()  //函数定义
{
echo “This is my first shell function” 
}
myfunc    //函数调用

产生以下执行结果

./test.sh
This is my first shell function
函数必须提前定义测试
[root@newrain fun]# cat fun05.sh 
#!/bin/bash
fun () {
echo "hello"
}
fun
unset fun
fun
[root@newrain fun]# bash fun05.sh
hello
fun05.sh: line 8: fun: command not found
函数的返回值,返回的是函数体内最后一条命令是否成功的返回值
[root@newrain fun]# systemctl stop httpd 
[root@newrain fun]# cat fun03.sh 
#!/bin/bash
fun() {
        systemctl status httpd &>/dev/null
        systemctl status vsftpd &>/dev/null
}
fun 
echo $?
[root@newrain fun]# systemctl stop vsftpd
[root@newrain fun]# bash fun03.sh 
3

函数传参
在Shell中,调用函数时可以向其传递参数。在函数体内部,通过 $n 的形式来获取参数的值,例如,$1表示第一个参数,$2表示第二个参数

示例

[root@newrain fun]# cat fun06.sh 
#!/bin/bash
fun() {
        echo $[$1*$2*$3]
}
fun 1 2 3
修改版:
[root@newrain fun]# cat fun06.sh 
#!/bin/bash
if [ ! $# -eq 3 ];then
        echo "Must Input Three number: p1 p2 p3"
exit fi
fun() {
        echo $[$1*$2*$3]
}
fun $1 $2 $3

九、shell 编程-数组

普通数组:只能用整数作为数组的索引
关联数组:可以使用字符串作为数组的索引

数组定义
普通数组定义:
[root@newrain shell]# books=( linux shell awk sed )  
引用:
[root@newrain shell]# echo ${books[0]}
linux
[root@newrain shell]# echo ${books[1]}
shell
[root@newrain shell]# echo ${books[2]}
awk

关联数组需要提前声明
declare -A myarry1
[root@newrain shell]# declare -A myarry1
[root@newrain shell]# myarry1=([name]=newrain [sex]=man [age]=26) 
[root@newrain shell]# echo ${myarry1[name]}
newrain
[root@newrain shell]# echo ${myarry1[age]}
26
定义方法1:
    # declare -a myarry=(5 6 7 8) 
    # echo ${myarry[2]}
		显示结果为 7
		
定义方法2:
    # array=( one two three four five six )
    # array2=(tom jack alice)
    # array3=(`cat /etc/passwd`)
    # array4=(tom jack alice "bash shell")
    # array5=(1 2 3 4 5 6 7 "linux shell" [20]=saltstack)
    
定义方法3: # 普通数组下标只能是数字
#!/bin/bash 
area[11]=23 
area[13]=37 
area[51]="UFOs"


访问数组

当设置任何数组变量时,可以访问它

[root@newrain shell]# aa=(haha heihei baibai)
[root@newrain shell]# echo ${aa[0]}    //访问数组中的第一个元数
[root@newrain shell]# echo ${aa[@]} 		//访问数组中所有的元数,等同与echo ${aa[*]}
[root@newrain shell]# echo ${#aa[@]}   //统计元数的个数
[root@newrain shell]# echo ${!aa[@]}   //统计索引

${array_name[index]} //引用

示例

#!/bin/bash
NAME[0]="BJ"
NAME[1]="SH"
NAME[2]="SZ"
NAME[3]="GZ"
NAME[4]="HZ"
NAME[5]="ZZ"
echo "First Index: ${NAME[0]}"
echo "Second Index: ${NAME[1]}"
echo "sixth Index: ${NAME[5]}"

输出结果为

 $./test.sh
First Index: BJ 
Second Index: SH 
sixth Index: ZZ

您可以访问数组中的所有项目通过以下方式之一:

${array_name[*]}
${array_name[@]}

示例

#!/bin/sh
NAME[0]="BJ"
NAME[1]="SH"
NAME[2]="SZ"
NAME[3]="GZ"
NAME[4]="HZ"
echo "First Index: ${NAME[*]}"
echo "Second Index: ${NAME[@]}"

输出结果

 $./test.sh
First Index: BJ SH SZ GZ HZ 
Second Index: BJ SH SZ GZ HZ

疑难点
shell数组中"*" 和 “@” 区别

关于在shell脚本中数组变量中 “*”跟 “@” 区别
“*”当变量加上“” 会当成一串字符串处理. 
“@”变量加上“” 依然当做数组处理. 
在没有加上“” 的情况下 效果是等效的.

示例

#!/usr/bin/env bash
array=(gz cloud 19)
echo "case 1"
for line in "${array[@]}"
do
		echo $line
done

echo "case 2"
for line in "${array[*]}"
do
		echo $line
done

echo "case 3"
for line in ${array[*]}
do
		echo $line
done

echo "case 4"
for line in ${array[@]}
do
		echo $line
done

执行结果

case 1
gz
cloud
19
case 2
gz cloud 19
case 3
gz
cloud
19
case 4
gz
cloud
19
遍历数组while
[root@newrain array]# cat array01.sh 
#!/bin/bash
#++ i 是先自加1后赋值;i ++ 是先赋值后自加1。 
while read line
do     
        host[i++]=$line  # 观察i++ 和 ++i的区别
done </etc/hosts
for i in ${!host[@]}   # 数组的元素索引
do
        echo "$i:${host[i]}"
done
遍历数组for
[root@newrain array]# cat array02.sh 
#!/bin/bash
IFS=''
for line in `cat /etc/hosts`  # 读取文件中的每一行
do
        host[j++]=$line
done
for i in ${!host[@]}
do
        echo ${host[i]}
done 
以上两个脚本都是读取文件中的行,然后加到一个数组中并进行遍历。

练习题:统计shell的种类和数量
思路:最后一列的sh种类不同,我们可以单独取出最后一列 /etc/passwd

十、正则表达式RE



正则表达式基本元字符

正则表达式拓展元字符

用来处理文本

正则表达式(Regular Expression, RE)是一种字符模式, 用于在查找过程中匹配指定的字符. 在大多数程序里, 正则表达式都被置于两个正斜杠之间;

例如/l[oO]ve/就是由正斜杠界定的正则表达式, 它将匹配被查找的行中任何位置出现的相同模式. 在正则表达式中,元 字符是最重要的概念

元字符使正则表达式具有处理能力。所谓元字符就是指ß那些在正则表达式中具有特殊意义的专用字符,可以用来规定 其前导字符(即位于元字符前面的字符)在目标对象中的出现模式。

No.1 正则表达式基本元字符
基本正则表达式元字符 
元字符
示例                      功能
^                       行首定位符
^love 

$                       行尾定位符
love$ 

.                       匹配单个字符
l..e  

*                       匹配前导符0到多次
ab*love 

.*                      匹配任意多个字符  (贪婪匹配

[]                      匹配方括号中任意一个字符
[lL]ove

[ - ]                   匹配指定范围内的一个字符
[a-z0-9]ove             

[^]                     匹配不在指定组里的字符
[^a-z0-9]ove 

\                       用来转义元字符
love\.                  

\<                      词首定位符 #由数组或字母组成的
\<love

\>                      词尾定位符
love\>

\(\)                    匹配后的标签   # 在vim中测试

No.2正则表达式拓展元字符
= 等于 != 不等于  =~  匹配
扩展正则表达式元字符
+                       匹配一个或多个前导字符
[a-z]+ove

?                       匹配零个或一个前导字符 
lo?ve

a|b                     匹配a或b
love|hate

()                      组字符loveable|rs
love(able|rs) ov+ ov+ (ov)+ 

(..)(..)\1\2            标签匹配字符  #
(love)able\1er

x{m}                    字符x重复m次
o{5}

x{m,}                   字符x重复至少m次
o{5,}

x{m,n}                  字符x重复m到n次
o{5,10}

1、+ 匹配一个或多个前导字符
[root@newrain ~]# egrep 'ro+t' /etc/passwd 
root:x:0:0:root:/root:/bin/bash 
operator:x:11:0:operator:/root:/sbin/nologin 
dockerroot:x:998:995:Docker User:/var/lib/docker:/sbin/nologin
2、? 匹配零个或一个前导字符
[root@newrain ~]# egrep 'ro?t' /etc/passwd 
abrt:x:1041:1041::/home/abrt:/bin/bash

3、a|b    匹配a或b
[root@newrain ~]# netstat -anlp|egrep ':80|:22'
[root@newrain ~]# egrep 'root|alice' 
/etc/passwd root:x:0:0:root:/root:/bin/bash 
operator:x:11:0:operator:/root:/sbin/nologin 
dockerroot:x:998:995:Docker User:/var/lib/docker:/sbin/nologin

4、x{m} 字符x重复m次 
[root@newrain ~]# cat a.txt
love
love.
loove
looooove 
[root@newrain ~]# egrep 'o{2}' a.txt
loove
looooove 
[root@newrain ~]# egrep 'o{2,}' a.txt
loove
looooove 
[root@newrain ~]# egrep 'o{6,7}' a.txt

十一、shell 编程-grep

egrep 支持正则表达式的拓展元字符 (或grep  -E)
#egrep '[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}' file1.txt
[root@newrain ~]# num1=1 
1、运用正则,判断需要[[ ]] 
[root@newrain ~]# [[ $num1 =~ ^[0-9]+$ ]] && echo "yes" || echo "no"
yes
[root@newrain ~]# num3=1b1 
[root@newrain ~]# [[ $num3 =~ ^[0-9]+$ ]] && echo "yes" || echo "no"
no
[root@newrain ~]# [[ $num =~ ^[0-9]+\.[0-9]+$ || $num =~ ^[0-9]+$ ]] && echo "yes" || echo "no"       //输入的只能是数字(包括小数)

2、* 0或多个
[root@newrain ~]# useradd abrt 
[root@newrain ~]# grep 'abc*' /etc/passwd 
abrt:x:1041:1041::/home/abrt:/bin/bash

3、\< 词首定位符号 \>词尾定位符号 
[root@newrain ~]# cat jack.txt 
Jack JACK JAck jackly
:% s/\<[Jj]ack\>/123/g

4、^以什么开头
[root@newrain ~]# grep '^root' /etc/passwd
root:x:0:0:root:/root:/bin/bash

5、$以什么结尾
[root@newrain ~]# grep 'bash$' /etc/passwd
root:x:0:0:root:/root:/bin/bash
confluence:x:1000:1000:Atlassian Confluence:/home/confluence:/bin/bash 
to:x:1003:1003::/home/to:/bin/bash

6、. 匹配单个字符
[root@newrain ~]# grep 'r..t' /etc/passwd 
root:x:0:0:root:/root:/bin/bash 
operator:x:11:0:operator:/root:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin 
dockerroot:x:998:995:Docker User:/var/lib/docker:/sbin/nologin 
[root@newrain ~]# grep 'r.t' /etc/passwd 
operator:x:11:0:operator:/root:/sbin/nologin 
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin

7、.* 任意多个字符
[root@newrain ~]# grep 'r.*t' /etc/passwd 
root:x:0:0:root:/root:/bin/bash 
operator:x:11:0:operator:/root:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin 
systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin polkitd:x:999:997:User for polkitd:/:/sbin/nologin postfix:x:89:89::/var/spool/postfix:/sbin/nologin 
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin dockerroot:x:998:995:Docker User:/var/lib/docker:/sbin/nologin 
tss:x:59:59:Account used by the trousers package to sandbox the tcsd daemon:/dev/null:/sbin/nologin
apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin
abrt:x:1041:1041::/home/abrt:/bin/

8、[] 匹配方括号中的任意一个字符
[root@newrain ~]# grep 'Root' /etc/passwd
[root@newrain ~]# grep '[Rr]oot' /etc/passwd 
root:x:0:0:root:/root:/bin/bash 
operator:x:11:0:operator:/root:/sbin/nologin 
dockerroot:x:998:995:Docker User:/var/lib/docker:/sbin/nologin

9、[ - ] 匹配指定范围内的一个字符
[root@newrain ~]# grep [a-z]oot /etc/passwd 
root:x:0:0:root:/root:/bin/bash 
operator:x:11:0:operator:/root:/sbin/nologin 
dockerroot:x:998:995:Docker User:/var/lib/docker:/sbin/nologin

10、[^] 匹配不在指定组内的字符,取反得意思
[root@newrain ~]# grep '[^0-9]oot' /etc/passwd 
root:x:0:0:root:/root:/bin/bash 
operator:x:11:0:operator:/root:/sbin/nologin
dockerroot:x:998:995:Docker User:/var/lib/docker:/sbin/nologin

[root@newrain ~]# grep '[^0-9A-Z]oot' /etc/passwd 
root:x:0:0:root:/root:/bin/bash 
operator:x:11:0:operator:/root:/sbin/nologin 
dockerroot:x:998:995:Docker User:/var/lib/docker:/sbin/nologin
[root@newrain ~]# grep '[^0-9A-Za-z]oot' /etc/passwd
[root@newrain ~]#
[root@newrain ~]# useradd Root
[root@newrain ~]# grep '[a-z]oot' /etc/passwd      
root:x:0:0:root:/root:/bin/bash 
operator:x:11:0:operator:/root:/sbin/nologin 
dockerroot:x:998:995:Docker User:/var/lib/docker:/sbin/nologin Root:x:1042:1042::/home/Root:/bin/bash
[root@newrain ~]# grep '^[rc]oot' /etc/passwd 
root:x:0:0:root:/root:/bin/bash 
^在[]内表示取反,^在[]外表示以什么开头

11、\(\)匹配后的标签
[root@newrain ~]# cat file1.txt 
IPADDR=192.168.1.123 
GATEWAY=192.168.1.1 
NETMASK=255.255.255.0 
DNS=114.114.114.114
:% s#\(192.168.1.\)123#\12#
:% s#\(192.\)\(168.\)\(1.\)2#\1\2\35#
:% s\(192.\)\(168.\)\(1.\)\(5\)#\1\26.\4#

十二、shell 编程-SED


非交互式编辑器,一次处理一行内容。(流文本编辑器)


sed "参数"  '模式'
参数  1 -f 指定一个规则文件 2 -n 阻止输入行输出 -r 扩展正则
模式  1 s 替换  2 g 整行(也可以是数字,替换第几个) 3 d 删除 4 p 打印 5 a 追加 6 i 是插入
示例文件
file1.txt
John Daggett, 341 King Road, Plymouth MA
Alice Ford, 22 East Broadway, Richmond VA 
Orville Thomas, 11345 Oak Bridge Road, Tulsa OK 
Terry Kalkas, 402 Lans Road, Beaver Falls PA 
Eric Adams, 20 Post Road, Sudbury MA
Hubert Sims, 328A Brook Road, Roanoke VA
Amy Wilde, 334 Bayshore Pkwy, Mountain View CA 
Sal Carpenter, 73 6th Street, Boston MA

用Massachusetts替换MA:  #前面两个斜杠中是要匹配的内容,可以使用正则,后面两个斜杠中间,是要替换的内容,是纯文本
#sed 's/MA/Massachusetts/' file1.txt
使用多重指令:
# sed 's/MA/Massachusetts/ ; s/PA/Pennsylvania/' file1.txt
使用脚本文件: 
脚本:namestate 
s/MA/Massachusetts/ 
s/PA/Pennsylvania/ 
s/CA/California/ 
s/VA/Virginia/ 
s/OK/Oklahoma/
-f<script文件>或--file=<script文件> 以选项中指定的script文件来处理输入的文本文件。 
$ sed -f namestate file1.txt
保存输出:
$ sed -f namestate file1.txt > newfile.txt
阻止输入行自动显示:
$ sed -n 's/MA/Massachusetts/p' file1.txt
sed流编辑器用法及解析

sed: stream editor(流编辑器)的缩写. 它们最常见的用法是进行文本的替换.

[root@newrain ~]# sed '1d' passwd //删除文件的第1行 
bin:x:1:1:bin:/bin:/sbin/nologin 
daemon:x:2:2:daemon:/sbin:/sbin/nologin
[root@newrain ~]# sed '1,2d' passwd //删除文件的第1到2行 daemon:x:2:2:daemon:/sbin:/sbin/nologin
[root@newrain ~]# cat e.txt
/etc/abc/456
etc
[root@newrain ~]# sed -r 's#/etc/abc#/var/lib#' e.txt 
/var/lib/456
etc
[root@newrain ~]# cat passwd 
root:x:0:0:root:/root:/bin/bash 
bin:x:1:1:bin:/bin:/sbin/nologin 
daemon:x:2:2:daemon:/sbin:/sbin/nologin 
[root@newrain ~]# sed '2,$d' passwd       //删除第2行到最后一行s
root:x:0:0:root:/root:/bin/bash 
[root@newrain ~]# sed '/root/d' passwd    //匹配到root,删除此行
bin:x:1:1:bin:/bin:/sbin/nologin 
daemon:x:2:2:daemon:/sbin:/sbin/nologin 
[root@newrain ~]# sed '/root/,2d' passwd  //匹配到root行,到某一行
daemon:x:2:2:daemon:/sbin:/sbin/nologin

[root@newrain ~]# cat -n passwd
    1 root:x:0:0:root:/root:/bin/bash
    2 bin:x:1:1:bin:/bin:/sbin/nologin
    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
    7 shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
    8 halt:x:7:0:halt:/sbin:/sbin/halt
    9 mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
    10 operator:x:11:0:operator:/root:/sbin/nologin
[root@newrain ~]# sed '1~2d' passwd   //删除奇数行
bin:x:1:1:bin:/bin:/sbin/nologin 
adm:x:3:4:adm:/var/adm:/sbin/nologin 
sync:x:5:0:sync:/sbin:/bin/sync 
halt:x:7:0:halt:/sbin:/sbin/halt 
operator:x:11:0:operator:/root:/sbin/nologin

[root@newrain ~]# sed '0~2d' passwd    //删除偶数行
root:x:0:0:root:/root:/bin/bash  
daemon:x:2:2:daemon:/sbin:/sbin/nologin 
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown mail:x:8:12:mail:/var/spool/mail:/sbin/nologin


  1. sed可以从stdin中读取内容

    $ cat filename | sed 's/pattern/replace_string/'

  2. 选项 -i 会使得sed用修改后的数据替换原文件

    $ sed -i 's/pattern/replace_string/' filename

  3. g标记可以使sed执行全局替换

    $ sed 's/pattern/replace_string/g' filename
    $ sed 's/pattern/replace_string/gi' filename //忽略大小写替换 
    
  4. g标记可以使sed匹配第N次以后的字符被替换

    $ echo "thisthisthisthis" | sed 's/this/THIS/2g'

  5. sed中的分隔符可以替换成别的字符, 因为s标识会认为后面的字符为分隔符

    $ sed 's:text:replace_text:'
    $ sed 's|text|replace_text|'
    
  6. sed可以利用指令来删除文件中的空行

    $ sed '/^$/d' filename

  7. 由于在使用 -i 参数时比较危险, 所以我们在使用i参数时在后面加上.bak就会产生一个备份的文件,以防后悔

    sed -i.bak 's/pattern/replace_string/' filename

  8. sed如果在脚本中使用的话, 不可避免的要调用变量, 所以以下这种方式可以用来调用变量即’ '换成了" "

    $ text=hello
    $ echo "hello world" | sed "s/$text/HELLO/"
    
  9. 在文件中匹配到的部分前后加上一行

sed '/^bin/a\hello nihao/' passwd  # 在匹配到开头为bin的行下一行插入内容

sed '/^bin/i\hello nihao/' passwd  # 在匹配到开头为bin的行上一行插入内容

十三、shell 编程-AWK

awk是行处理器: 相比较屏幕处理的优点,在处理庞大文件时不会出现内存溢出或是处理缓慢的问题,通常用来格式化文本信息
awk处理过程: 依次对每一行进行处理,然后输出 默认分隔符是空格或者tab键

awk 参数 'BEGIN{处理之前要做的} {处理内容} END{处理之后的内容}'
BEGIN{} {}
行处理前
END{}
行处理 行处理后
[root@newrain ~]# awk 'BEGIN{print 1/2} {print "ok"} END{print "----"}' /etc/hosts  # 打印的内容加上双引号
0.5
ok
ok
ok
ok 
ok
ok
----

awk工作原理
awk -F":" '{print $1,$3}' /etc/passwd 
(1)awk使用一行作为输入,并将这一行赋给变量$0,每一行可称作为一个记录,以换行符结束
(2)然后,行被:分解成字段,每个字段存储在已编号的变量中,从$1开始 
(3)awk如何知道空格来分隔字段的呢?因为有一个内部变量FS来确定字段分隔符,初始时,FS赋为空格或者是tab 
(4)awk打印字段时,将以设置的方法,使用print函数打印,awk在打印的字段间加上空格,因为$1,$3间有一个,逗号。逗 号比较特殊,映射为另一个变量,成为输出字段分隔符OFS,OFS默认为空格 
(5)awk打印字段时,将从文件中获取每一行,并将其存储在$0中,覆盖原来的内容,然后将新的字符串分隔成字段并进行处理。该过程持续到处理文件结束。
默认分隔符是空格或者tab键
awk中的特殊变量:
常用:
- NR: 表示记录编号, 当awk将行为记录时, 该变量相当于当前行号 
- NF: 表示字段数量, 当awk将行为记录时, 该变量相当于当前列号
难理解:
FS(输入字段分隔符)   # 以什么符号去分割
OFS(输出字段分隔符)  # 以什么分隔符显示
NR(Number of record)行数  
FNR按不同的文件分开 
RS(输入记录分隔符) 
ORS(输出记录分隔符)
NF 字段个数
FS(输入字段分隔符) (filed sign)
[root@newrain ~]# awk 'BEGIN{FS=":"} {print $1}' /etc/passwd 
root
bin
daemon
adm
lp
sync
shutdown
halt
mail
operator
games
OFS(输出字段分隔符)        (output filed sign)
[root@newrain ~]# awk 'BEGIN{FS=":";OFS=".."} {print $1,$2}' /etc/passwd 
root..x
bin..x 
daemon..x 
adm..x 
lp..x 
sync..x 
shutdown..x

NR 表示记录编号, 当awk将行为记录时, 该变量相当于当前行号 
[root@newrain ~]# awk -F: '{print NR,$0}' a.txt file1.txt 
1 love
2 love.
3 loove
4 looooove
5
6 isuo
7 IPADDR=192.168.6.5
8 hjahj123
9 GATEWAY=192.168.1.1
10 NETMASK=255.255.255.0
11 DNS=114.114.114.114

FNR 表示记录编号, 当awk将行为记录时, 该变量相当于当前行号(不同文件分开) 
[root@newrain ~]# awk -F: '{print FNR,$0}' a.txt file1.txt
1 love
2 love.
3 loove
4 looooove
5
1 isuo
2 IPADDR=192.168.6.5 
3 hjahj123
4 GATEWAY=192.168.1.1
5 NETMASK=255.255.255.0
6 DNS=114.114.114.114
RS(输入记录分隔符)
[root@newrain ~]# cat passwd 
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
[root@newrain ~]# awk -F: 'BEGIN{RS="bash"} {print $0}' passwd
root:x:0:0:root:/root:/bin/

bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin

ORS(输出记录分隔符)
[root@newrain ~]# cat passwd 
root:x:0:0:root:/root:/bin/bash 
bin:x:1:1:bin:/bin:/sbin/nologin 
daemon:x:2:2:daemon:/sbin:/sbin/nologin
[root@newrain ~]# awk -F: 'BEGIN{ORS=" "} {print $0}' passwd
root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin  daemon:x:2:2:daemon:/sbin:/sbin/nologin

练习:将文件合并为一行
[root@newrain ~]# awk 'BEGIN{ORS="" } {print $0}' /etc/passwd
练习:把一行内容分为多行
[root@newrain ~]# cat d.txt 
root:x:0:0:root:/root:/bin/bash
[root@newrain ~]# awk 'BEGIN{RS=":"} {print $0}' d.txt 
root
x
0
0
root
/root
/bin/bash
AWK使用理解案例
  1. 打印一个文件中的第2列和第3列

$ awk '{ print $2, $3}' filename

  1. 打印指定行指定列的某个字符

$ awk -F":" 'NR==3{ print $7 }' /etc/passwd

  1. 统计一个文件的行数

$ awk '{ print NR}' filename

  1. 在脚本中, 传递变量到awk中

    $ var=1000
    $ echo | awk -v VARIABLE=$var '{ print VARIABLE }'
    
  2. 指定字段分隔符-F或在BEGIN{ FS=":" }

    $ awk -F: '{ print $2, $3 }' filename
    $ awk 'BEGIN{ FS=":" }{ print $2, $3 }' filename
    
  3. 在awk中使用for循环 (了解)

    每行打印两次
    [root@newrain ~]# awk -F: '{for(i=1;i<=2;i++) {print $0}}' passwd 
    root:x:0:0:root:/root:/bin/bash
    root:x:0:0:root:/root:/bin/bash
    bin:x:1:1:bin:/bin:/sbin/nologin
    bin:x:1:1:bin:/bin:/sbin/nologin
    daemon:x:2:2:daemon:/sbin:/sbin/nologin
    daemon:x:2:2:daemon:/sbin:/sbin/nologin
    分别打印每行每列
    [root@newrain ~]# awk -F: '{ for(i=1;i<=NF;i++) {print $i}}' passwd
    
  4. 在awk中使用if条件判断 (了解)

    显示管理员用户名
    [root@newrain ~]# awk -F: '{if($3==0) {print $1 " is administrator."}}' /etc/passwd
    统计系统用户
    [root@newrain ~]# awk -F":" '{if($3>0 && $3<1000){i++}} END{print i}' /etc/passwd
    

十四、shell 编程-Expect

No.1 expect的安装

[root@newrain ~]# yum -y install expect

No.2 expect的语法

是一个免费的编程工具, 用来实现自动的交互式任务, 而无需人为干预. 说白了 expect 就是一套用来实现自动交互功能的软件

在实际工作中我们运行命令、脚本或程序时, 这些命令、脚本或程序都需要从终端输入某些继续运行的指令,而这些输 入都需要人为的手工进行. 而利用 expect 则可以根据程序的提示, 模拟标准输入提供给程序, 从而实现自动化交互执 行. 这就是 expect

能够在工作中熟练的使用Shell脚本就可以很大程度的提高工作效率, 如果再搭配上expect,那么很多工作都可以自动化 进行,对工作的展开如虎添翼

用法: 
1)定义脚本执行的shell
		#!/usr/bin/expect 类似于#!/bin/bash 
2)set timeout 30
		设置超时时间30s 
3)spawn
		spawn是进入expect环境后才能执行的内部命令,不能直接在默认的shell环境中执行 
		功能:传递交互命令
4)expect 
		这里的expect同样是expect命令
		功能:判断输出结果是否包含某项字符串,没有则立即返回,否则等待一段时间后返回,等待通过timeout设置 
5)send
		执行交互动作,将交互要执行的动作进行输入给交互指令 
		命令字符串结尾要加上“r”,如果出现异常等待状态可以进行核查
6)interact 
		执行完后保持交互状态,把控制权交给控制台 
		如果不加这一项,交互完成会自动退出
7)exp_continue 
		继续执行接下来的操作
expect环境中设置变量用set,识别不了bash方式定义的变量 
错误方式:
[root@newrain expect]# cat expect02.sh 
#!/usr/bin/expect
user=22
spawn echo $user
[root@newrain expect]# ./expect02.sh 
invalid command name "user=22"
    while executing
"user=22"
		(file "./expect02.sh" line 3)
		
		
正确方式:
[root@newrain expect]# cat ./expect02.sh 
#!/usr/bin/expect
set user 22
spawn echo $user
[root@newrain expect]# ./expect02.sh
spawn echo 22 ============================================================================

[root@newrain expect]# cat expect01.sh 
#!/usr/bin/expect
spawn ssh root@192.168.62.146
expect {
        "yes/no" { send "yes\r";exp_continue }
        "password:" { send "123\r" }
} 
interact

interact的作用测试
执行测试是否免交互:
要是用/usr/bin/expect的shell执行
[root@newrain expect]#/usr/bin/expect expect01.sh 
成功
擦除最后一行interact进行测试
[root@newrain expect]#/usr/bin/expect expect01.sh
进入之后立即退出 ============================================================================
\r的作用测试
[root@newrain expect]# cat expect01.sh 
#!/usr/bin/expect
set user root
set pass 123
set ip 192.168.62.146
spawn ssh $user@$ip
expect {
        "yes/no" { send "yes";exp_continue }
        "password:" { send "$pass" }
} 
interact
[root@newrain expect]# ./expect01.sh 
spawn ssh root@192.168.62.146 
root@192.168.62.146's password:

加上\r之后
[root@newrain expect]# ./expect01.sh
spawn ssh root@192.168.62.146
root@192.168.62.146's password:
Permission denied, please try again.
root@192.168.62.146's password: ============================================================================
设置变量的方式
[root@newrain expect]# cat expect01.sh #!/usr/bin/expect
set user root
set pass 123
set ip 192.168.62.146 
spawn ssh $user@$ip 
expect {
        "yes/no" { send "yes\r";exp_continue }
        "password:" { send "$pass\r" }
}
interact
============================================================================
设置位置参数的方式(拓展)
[root@newrain expect]# cat expect01.sh 
#!/usr/bin/expect
set timeout 30
set user [ lindex $argv 0 ]
set pass [ lindex $argv 1 ]
set ip [ lindex $argv 2 ]S
spawn ssh $user@$ip

expect {
        "yes/no" { send "yes";exp_continue }
        "password:" { send "$pass\r" }
}
interact
运行结果为:
[root@newrain expect]# ./expect01.sh root 123 192.168.62.146 
spawn ssh root@192.168.62.146
root@192.168.62.146's password:
Last login: Thu Aug 15 23:26:59 2019 from 192.168.62.136

#!/usr/bin/expect
set username hello    # 定义变量   
set passwd 1
spawn ssh $username@172.17.138.107   # 执行交互式命令
expect {    # 捕捉系统返回,与系统进行交互
    "yes/no" { send "yes\r";exp_continue }
    "password:" {send "${passwd}\r"}
}
expect  "*]$"   # 捕捉系统返回,与系统进行交互
send "touch /tmp/abcaaa\r"
send "ls /\r"
expect eof 
interact

十五、shell 编程-运维脚本实战

• 实战项目1: 实现网络配置
• 实战项目2: sed实现sshd配置
• 实战项目3: sed实现nginx配置
• 实战项目4: 关闭本机SELinux的功能(/etc/sysconfig/selinux)
• 实战项目5: zabbix_agentd.conf配置文件修改(暂时不做)
• 实战项目6: awk统计/etc/passwd各种shell数量
• 实战项目7: awk统计网站访问各种状态数量
• 实战项目8: awk统计访问的每个IP的数量
• 实战项目9: 统计Nginx日志中某一天的PV量(暂时不做)
• 实战项目10: 获取获得内存使用情况
• 实战项目11: 基于时间的备份脚本
• 实战项目12: Web日志访问量分析程序(PV、UV)
• 实战项目13: 编写系统初始化脚本
        1)设置时区并把同步时间加入计划任务
        2)禁用selinux
        3)历史命令显示操作时间
        4)创建ALL权限用户并禁止root远程登录
        5)设置最大打开文件数
				6)减少swap使用 (将此文件/proc/sys/vm/swappiness内容修改为0) 
				7)安装常用工具
• 实战项目14: LAMP终级部署(rpm包方式)
• 实战项目15: Linux系统状态收集及分析(内存使用量,硬盘使用量,cpu使用量等)

项目作为作业
  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值