centos运维操作笔记

服务器标准化

1. 关闭 firewall 、SElinux

systemctl stop firewalld.service 
systemctl disable firewalld.service

setenforce 0
vim /etc/selinux/config
修改SELINUX=disabled

2. 修改yum源

1. 手动修改CentOS-Base.repo

# 备份yum源配置文件
    mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup
# 进入yum源配置文件所在位置
    cd /etc/yum.repos.d/
# 编辑CentOS-Base.repo
    vi CentOS-Base.repo
# 修改baseurl
name=Centos7
baseurl=file:///mnt/centos7
enabled=1
gpgcheck=0

2. 配置本地yum源

# 使用VMware添加镜像,然后查看镜像盘
lsblk

# 使用虚拟机挂载DVD的iso文件,空间足够也可以直接拷贝到系统,然后修改yum源配置
mkdir /media/CentOS
mount -t auto /dev/sr0 /media/CentOS # 不加-t参数也可以

# 直接挂载ISO文件
mount -t iso9660 -o loop /mnt/XXXX.iso /media/CentOS


# 修改yum源配置
#备份你的原镜像文件CentOS-Base.repo,以免出错后可以恢复。
cd /etc/yum.repos.d/
cp CentOS-Base.repo CentOS-Base.repo.bak


#修改CentOS-Base.repo的内容,注释文档中的所有mirrorlist属性,把baseurl属性打开注释,并设置baseurl的属性值为挂载点 baseurl=file:///media/CentOS/,或直接配置一个本地repo的配置文件CentOS-Media.repo

vi CentOS-Media.repo
[C7-media]
name=CentOS-$releasever - Media
baseurl=file:///media/CentOS/
gpgcheck=0
enabled=1

# 清空yum已存在的所有源信息
yum clean all

# 缓存本地yum源
yum makecache

# 查看yum仓库列表
yum repolist

# 查看本地源的所有软件
yum list
注:如果想要恢复默认的源,把CentOS-Base.repo.bak重命名为CentOS-Base.repo就可以了;
系统重启之后,需要再次手动挂载,可以设置/media/CentOS自动挂载。

# 长期挂载
vim /etc/fatab
添加:
/media/CentOS   /dev/sr0    iso9660   loop  0  0

/mnt/CentOS-7-x86_64-DVD-1810.iso /mnt/cdrom iso9660 loop0 0 0

3. 替换repo文件方式

# 备份yum源配置文件
mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup

# 进入yum源配置文件所在位置
cd /etc/yum.repos.d/

# 下载网易的yum源配置文件,放入/etc/yum.repos.d/
wget http://mirrors.163.com/.help/CentOS6-Base-163.repo

# 清除yum缓存
yum clean all

# 生成缓存
yum makecache

# 更新系统
yum -y update

3. 破解root密码

1.重启系统,然后输入e
2.在linux16末尾加入 rd.break,按组合键crtl-x
3.mount -o remount,rw /sysroot
4.chroot /sysroot
5.passwd root
6.touch /.autorelabel
7.exit
8.exit 重启系统

4. fstab

<file system>	<dir>	<type>	<options>	<dump>	<pass>

<file systems> - 要挂载的分区或存储设备.


<dir> - <file systems>的挂载位置。


<type> - 要挂载设备或是分区的文件系统类型,支持许多种不同的文件系统:ext2, ext3, ext4, reiserfs, xfs, jfs, smbfs, iso9660, vfat, ntfs, swap 及 auto。 设置成auto类型,mount 命令会猜测使用的文件系统类型,对 CDROM 和 DVD 等移动设备是非常有用的。


<options> - 挂载时使用的参数,注意有些mount 参数是特定文件系统才有的。一些比较常用的参数有:
auto - 在启动时或键入了 mount -a 命令时自动挂载。
noauto - 只在你的命令下被挂载。
exec - 允许执行此分区的二进制文件。
noexec - 不允许执行此文件系统上的二进制文件。
ro - 以只读模式挂载文件系统。
rw - 以读写模式挂载文件系统。
user - 允许任意用户挂载此文件系统,若无显示定义,隐含启用 noexec, nosuid, nodev 参数。
users - 允许所有 users 组中的用户挂载文件系统.
nouser - 只能被 root 挂载。
owner - 允许设备所有者挂载.
sync - I/O 同步进行。
async - I/O 异步进行。
dev - 解析文件系统上的块特殊设备。
nodev - 不解析文件系统上的块特殊设备。
suid - 允许 suid 操作和设定 sgid 位。这一参数通常用于一些特殊任务,使一般用户运行程序时临时提升权限。
nosuid - 禁止 suid 操作和设定 sgid 位。
noatime - 不更新文件系统上 inode 访问记录,可以提升性能(参见 atime 参数)。
nodiratime - 不更新文件系统上的目录 inode 访问记录,可以提升性能(参见 atime 参数)。
relatime - 实时更新 inode access 记录。只有在记录中的访问时间早于当前访问才会被更新。(与 noatime 相似,但不会打断如 mutt 或其它程序探测文件在上次访问后是否被修改的进程。),可以提升性能(参见 atime 参数)。
flush - vfat 的选项,更频繁的刷新数据,复制对话框或进度条在全部数据都写入后才消失。
defaults - 使用文件系统的默认挂载参数,例如 ext4 的默认参数为:rw, suid, dev, exec, auto, nouser, async.


<dump> dump 工具通过它决定何时作备份. dump 会检查其内容,并用数字来决定是否对这个文件系统进行备份。 允许的数字是 01 。0 表示忽略, 1 则进行备份。大部分的用户是没有安装 dump 的 ,对他们而言 <dump> 应设为 0<pass> fsck 读取 <pass> 的数值来决定需要检查的文件系统的检查顺序。允许的数字是0, 1, 和2。 根目录应当获得最高的优先权 1, 其它所有需要被检查的设备设置为 2. 0 表示设备不会被 fsck 所检查。

5. 其他操作

1. 切换图形界面、蓝牙服务

# 登陆系统为图形/命令行界面
systemctl get-default
systemctl set-default graphical.target //图形
systemctl set-default multi-user.target //命令行

# 管理蓝牙服务
# 开启
systemctl enable bluetooth

systemctl start bluetooth

# 关闭
systemctl disable bluetooth

2. 安装开发工具包

yum groupinstall -y "Development Tools"
yum install -y vim wget net-tools bash-completion
source /usr/share/bash-completion/bash_completion

3. 配置静态地址

# 查看网络
ip add
ip a
ifconfig

# 查看端口号
vim /etc/services


# root下进入网络配置文件目录
vim /etc/sysconfig/network-scripts/ifcfg-ens33


BOOTPROTO=static
ONBOOT=yes
IPADDR=192.168.202.132
NETMASK=255.255.255.0
GATEWAY=192.168.202.2
DNS1=192.168.3.1 # DNS 配置
DNS1=8.8.8.8  #谷歌地址

4. 配置主备DNS

vim /etc/resolv.conf

添加nameserver

5. 禁止ctrl_del_alt重启

# 查看/etc/inittab确认Ctrl+Alt+Del相关配置文件
cat /etc/inittab 
# Ctrl-Alt-Delete is handled by /usr/lib/systemd/system/ctrl-alt-del.target    #相关配置文件存放位置

# 查看Ctrl+Alt+Del配置文件的属性信息
ls -ld /usr/lib/systemd/system/ctrl-alt-del.target
lrwxrwxrwx. 1 root root 13 Jun 14 02:20 /usr/lib/systemd/system/ctrl-alt-del.target -> reboot.target

# 删除软链接文件
rm -f /usr/lib/systemd/system/ctrl-alt-del.target或者mv /usr/lib/systemd/system/ctrl-alt-del.target /tmp

# 重新加载初始化守护进程配置文件(Reload init daemon configuration)
init q

常用工具

1. vim

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OCHpQj2k-1675241162745)(D:\运行培训\笔记\Linux\vim.png)]

# 永久显示行号
vim ~/.vimrc  //当前用户
写入set number
source ~/.vimrc

2. crontab

crontab -l  #列出计划作业
crontab -e  #创建计划作业
crontab -r  #删除计划作业
crontab -u  #指定用户
# 删除某个计划作业可以进入crontab -e,删除对应行


# 编写计划作业
*()     *()     *()     *()     *()     命令(绝对路径)
其中 f1 是表示分钟,f2 表示小时,f3 表示一个月份中的第几日,f4 表示月份,f5 表示一个星期中的第几天。
program 表示要执行的程序。
当 f1 为 * 时表示每分钟都要执行 program,f2 为 * 时表示每小时都要执行程序,其馀类推
当 f1 为 a-b 时表示从第 a 分钟到第 b 分钟这段时间内要执行,f2 为 a-b 时表示从第 a 到第 b 小时都要执行
当 f1 为 */n 时表示每 n 分钟个时间间隔执行一次,f2 为 */n 表示每 n 小时个时间间隔执行一次
当 f1 为 a, b, c,... 时表示第 a, b, c,... 分钟要执行,f2 为 a, b, c,... 时表示第 a, b, c...个小时要执行
# 查看绝对路径
which 命令

# 在crontab中使用变量$(), 但是记住百分号前面要加个\,如果不加会被当成新的一行而不是命令。

  15 0 1 * * nf=MailFeed-$( date +\%Y\%m ).mbx && cd Logs && mv MailFeed.mbx $nf && bzip2 -9 $nf

# 每隔10分钟完成将/var/log目录打包,文件名后缀带时间戳
*/10 * * * * tar -cvzf /root/DB_$( date +\%Y\%m\%d ).tar /var/log/

3. selinux

1. 基本

# 查看
ls  -Z

# 查看 当前 SELinux 模式
命令:getenforce

# selinux三个状态:
- enforcing 强制
- permissive 警告
- disabled 关闭selinux
# 临时修改
命令:setenforce [0|1]
0:转成 permissive 宽容模式;
1:转成 Enforcing 强制模式;
# 永久修改  
vim /etc/sysconfig/selinux
修改 SELINUX=disabled
reboot

# 安装semanage
yum -y install policycoreutils-python

选项	含义
-a	添加默认安全上下文配置
-d	删除指定的默认安全上下文
-m	修改指定的默认安全上下文
-t	设定默认安全上下文的类型


# 给/test/目录及目录下的所有内容
semanage fcontext -a -t system_cron_spool_t "/test(/.*)?"
# 重载
restorecon -FRv /test/
# 查看
ls -Zd /test/

2. 端口操作

semanage port -l   #查看selinux中给各个服务提供的默认端口
semanage port -l | grep http   #查看与http服务相关的端口
semanage port -a -t http_port_t -p tcp 8909
# 其中-a表示添加,-t表示类型也就是http_port_t,-p表示协议也就是tcp协议

3. 实例

# 准备工作,安装httpd服务,修改监听的端口号为80,考试不需要做。
[root@servera ~]# yum -y install httpd
[root@servera ~]# systemctl enable --now httpd
[root@servera ~]# echo hello wuhan > /var/www/html/index.html
[root@servera ~]# vim /etc/httpd/conf/httpd.conf # 修改监听的端口号
Listen 82
# 实际操作
[root@servera ~]# systemctl restart httpd #重启服务报错,原因是selinux
# 考试需要查看监听的端口号为多少,再将对应的端口号(82端口)设置为httpd的标准端口即可
[root@servera ~]# semanage port -a -t http_port_t -p tcp 82
#重启服务
[root@servera ~]# systemctl restart httpd
#查看端口号82已经监听
[root@servera ~]# netstat -tulnp | grep httpd
tcp6 0 0 :::82 :::* LISTEN
25747/httpd
[root@servera ~]# curl http://servera:82

4. 通配符

*   匹配任意字符(所有)
?  匹配任意一个字符
[abc]  匹配一组范围当中的任意一个字符。
[^] [!]   取反

5. 正则表达式

*	 重复前一个字符0次到多次(任意次)
\{n,m\}  ......最少n次最多M次
.(点)  匹配任意一个字符
.*    任意字符
^   匹配开头 
$ 匹配结尾
^$ 匹配空格
\<  \> 铆钉字符  边界字符


扩展正则
egrep 支持扩展
?  重复前一个字符0次到1次
+ ............1次到N次
(a|b)

\w :匹配任意英文,下划线,数字
\W
\d: 匹配数字
\D

常用命令

1. sort

sort #排序命令 
-nr #默认使用字符串排序n代表使用数值进行排序 默认从小到大排序 r代表反向排序
-k3 #以第3列进行排序

2. 查看系统信息

# 查看主机名
hostname 

# 修改主机名
hostnamectl set-hostname 主机名

# 查看CPU
cat /proc/cpuinfo
lscpu

# 查看内存
free 
 -b 选项 以字节为单位 显示 内存总和; -k 选项 (缺省的) 以 KB 为单位 显示; -m 选项 以 MB 为单位.

 -t 选项 显示 一个 总计行.

 -o 选项 禁止 "buffer adjusted" 行的显示. 除非 指定 free(相应的) 已用/未用的 内存 减去/加上 缓冲区内存.

 -s 使 free 以 delay 秒为间隔, 连续抽样显示. delay 可以设置成浮点数, 它用 usleep(3) 做 微秒级 延迟.

# 查看系统版本
cat /etc/redhat-release

# uname查看系统信息
uname [OPTION]...

描述
       显示相应的系统信息.  没有指定选项时,同 -s.

       -a, --all
              显示所有的信息

       -m, --machine
              显示机器(硬件)类型

       -n, --nodename
              显示机器的网络节点主机名

       -r, --release
              显示操作系统内核版本

       -s, --sysname
              显示操作系统名

       -p, --processor
              显示主机处理器(CPU)类型

       -v     显示操作系统版本

       --help 显示本帮助并退出

       --version
              显示版本信息并退出
# 查看各分区的使用情况              
df  -h
# 查看当前文件夹所占空间
du  -sh

# 关闭蓝牙
语法格式:hciconfig [参数]

常用参数:

参考实例

使用-a参数显示蓝牙设备信息: hciconfig -a

使用up参数,开启hci0蓝牙设备:hciconfig hci0 up

使用down参数,关闭hci0蓝牙设备:hciconfig hci0 down

使用reset参数,重置hci0蓝牙设备:hciconfig hci0 reset

3. grep

grep [选项]... 模式 [文件]...
选项: -i   忽略大小写
       -n   行号
       -c  次数 
       -v  取反   
       -e  后面跟多个 -e 表示匹配多个字符串,或的关系
       -o  只打印出匹配的内容

4. rpm

一、RPM 安装操作

命令:

rpm -i 需要安装的包文件名

举例如下:

rpm -i example.rpm 安装 example.rpm 包;

rpm -iv example.rpm 安装 example.rpm 包并在安装过程中显示正在安装的文件信息;

rpm -ivh example.rpm 安装 example.rpm 包并在安装过程中显示正在安装的文件信息及安装进度;

二、RPM 查询操作

命令:

rpm -q …

附加查询命令:

a 查询所有已经安装的包以下两个附加命令用于查询安装包的信息;

i 显示安装包的信息;

l 显示安装包中的所有文件被安装到哪些目录下;

s 显示安装版中的所有文件状态及被安装到哪些目录下;以下两个附加命令用于指定需要查询的是安装包还是已安装后的文件;

p 查询的是安装包的信息;

f 查询的是已安装的某文件信息;

举例如下:

rpm -qa | grep tomcat4 查看 tomcat4 是否被安装;

rpm -qip example.rpm 查看 example.rpm 安装包的信息;

rpm -qif /bin/df 查看/bin/df 文件所在安装包的信息;

rpm -qlf /bin/df 查看/bin/df 文件所在安装包中的各个文件分别被安装到哪个目录下;

rpm -ql package1 列出package1的所有文件

rpm -qi package1 列出package1的安装信息

三、RPM 卸载操作

命令:

rpm -e 需要卸载的安装包

在卸载之前,通常需要使用rpm -q …命令查出需要卸载的安装包名称。

举例如下:

rpm -e tomcat4 卸载 tomcat4 软件包

四、RPM 升级操作

命令:

rpm -U 需要升级的包

举例如下:

rpm -Uvh example.rpm 升级 example.rpm 软件包

五、RPM 验证操作

命令:

rpm -V 需要验证的包

举例如下:

rpm -Vf /etc/tomcat4/tomcat4.conf

输出信息类似如下:

S.5....T c /etc/tomcat4/tomcat4.conf

其中,S 表示文件大小修改过,T 表示文件日期修改过。限于篇幅,更多的验证信息请您参考rpm 帮助文件:man rpm

六、RPM 的其他附加命令

--force 强制操作 如强制安装删除等;

--requires 显示该包的依赖关系;

--nodeps 忽略依赖关系并继续操作

5. ssh

1. 基础命令

# 验证端口是否被使用
lsof -i:20022

# 查看ssh端口
semanage port -l|grep ssh 
# 如果没有装semanage
yum install policycoreutils-python

# 开放20022端口
semanage port -a -t ssh_port_t -p tcp 20022

# 查看20022端口监听状态
netstat -an | grep 20022

# 配置ssh
vi /etc/ssh/sshd_config
Port 22 //默认使用22端口,也可以自行修改为其他端口,但登录时要打上端口号
#ListenAddress //指定提供ssh服务的IP,这里我注释掉。
PermitRootLogin //禁止以root远程登录
PasswordAuthentication yes //启用口令验证方式
PermitEmptyPassword //禁止使用空密码登录
LoginGraceTime 1m //重复验证时间为1分钟
MaxAuthTimes 3 //最大重试验证次数

2. 限制远程登录

# 只允许oper1用户可以ssh远程登陆。
vim /etc/ssh/sshd_config
AllowUsers oper1  //加@可以限制IP
AllowUsers aliyun test@192.168.1.1

# 拒绝zhangsan、aliyun帐户通过SSH登录系统
DenyUsers zhangsan aliyun 

3. 配置免密互信

# 生成密钥(每个主机都要执行)
ssh-keygen -t rsa

# 发送到对端
ssh-copy-id 192.168.202.133

4. 远程执行命令

# 远程查看一下某台主机的磁盘使用情况
$ ssh root@ip "df -h"

# 一次执行多条命令,使用分号把不同的命令隔起来
$ ssh nick@ip "pwd; cat hello.txt"

6. sed

1. 元字符集

^ # 匹配行开始,如:/^sed/匹配所有以sed开头的行。
$ # 匹配行结束,如:/sed$/匹配所有以sed结尾的行。
. # 匹配一个非换行符的任意字符,如:/s.d/匹配s后接一个任意字符,最后是d。
* # 匹配0个或多个字符,如:/*sed/匹配所有模板是一个或多个空格后紧跟sed的行。
[] # 匹配一个指定范围内的字符,如/[sS]ed/匹配sed和Sed。  
[^] # 匹配一个不在指定范围内的字符,如:/[^A-RT-Z]ed/匹配不包含A-R和T-Z的一个字母开头,紧跟ed的行。
\(..\) # 匹配子串,保存匹配的字符,如s/\(love\)able/\1rs,loveable被替换成lovers。
& # 保存搜索字符用来替换其他字符,如s/love/ **&** /,love这成 **love** 。
\< # 匹配单词的开始,如:/\<love/匹配包含以love开头的单词的行。
\> # 匹配单词的结束,如/love\>/匹配包含以love结尾的单词的行。
x\{m\} # 重复字符x,m次,如:/0\{5\}/匹配包含5个0的行。
x\{m,\} # 重复字符x,至少m次,如:/0\{5,\}/匹配至少有5个0的行。
x\{m,n\} # 重复字符x,至少m次,不多于n次,如:/0\{5,10\}/匹配5~10个0的行。  

2. 使用参数

[root@www ~]# sed [-nefr] [动作]
选项与参数:
-n :使用安静(silent)模式。在一般 sed 的用法中,所有来自 STDIN 的数据一般都会被列出到终端上。但如果加上 -n 参数后,则只有经过sed 特殊处理的那一行(或者动作)才会被列出来。
-e :直接在命令列模式上进行 sed 的动作编辑;
-f :直接将 sed 的动作写在一个文件内, -f filename 则可以运行 filename 内的 sed 动作;
-r :sed 的动作支持的是延伸型正规表示法的语法。(默认是基础正规表示法语法)
-i :直接修改读取的文件内容,而不是输出到终端。

动作说明: [n1[,n2]]function
n1, n2 :不见得会存在,一般代表『选择进行动作的行数』,举例来说,如果我的动作是需要在 1020 行之间进行的,则『 10,20[动作行为] 』

function:
a :新增, a 的后面可以接字串,而这些字串会在新的一行出现(目前的下一行)~
c :取代, c 的后面可以接字串,这些字串可以取代 n1,n2 之间的行!
d :删除,因为是删除啊,所以 d 后面通常不接任何咚咚;
i :插入, i 的后面可以接字串,而这些字串会在新的一行出现(目前的上一行);
p :列印,亦即将某个选择的数据印出。通常 p 会与参数 sed -n 一起运行~

1,3 打印1到3行
1~3 步长为3进行打印
2!p 排除第二行打印
/ftp/p 打印ftp行

s :取代,可以直接进行取代的工作哩!通常这个 s 的动作可以搭配正规表示法!例如 1,20s/old/new/g 就是啦!
命令或动作必须放入单引号中。
= 打印出行号
r 读取文件内容
w 保存(覆盖)

3. 实操

1. 取出passwd文件中包含root的行?
sed -n '/root/p' ./passwd

2.  取出passwd文件中以root开头的行?
sed -n '/^root/p' ./passwd

3.  取出passwd文件中以root或sshd开头的行?
sed -n '/^root\|^sshd/p' ./passwd

4.  取出passwd文件中包含sync和mail的行?
sed -n '/.*sync.*/p' ./passwd
sed -n '/.*mail.*/p' ./passwd 

5.  取出passwd文件中前三行?
sed -n '1,3p' ./passwd

6.  取出passwd文件中第一行和第三行?  
sed -n '1p;3p' ./passwd 
或 sed -n -e '1p' -e '3p' ./passwd                                  
7.  取出passwd文件中第十行?
sed -n '10p' ./passwd               
8.  删除passwd包含root字符串的行?   
sed -e '/root/d' ./passwd

9.  删除passwd包含root和lp的行?  
sed -e '/root/d;/lp/d' ./passwd

10. 删除passwd中adm到ganes的行?    
sed -e '/^adm/,/^games/d' ./passwd                              

7. find

1. find名称关键字查找  -name
小选项:i 忽略大小写

格式:find 大体路径 -name “文件或目录名关键字”

find 大体路径 -iname “文件或目录名关键字”

例如:

1.1.  
[root@dazhu200 ~]# find /etc/ -name "rc.*"

1.2.  
[root@dazhu200 ~]# find ./ -iname "*u*"


2. find 类型查找 -type
小选项:f文件 d目录 l连接 b块设备 c字节设备 s网络套接字 p管道文件

格式:find 大概路径 -type 小选项

例:

[root@dazhu200 ~]# find /dev -type b


3. find 大小查找 -size
小选项:+量 -量 量

-size +量 -and  -size -量 (取间隔)

-and(并且,并集关系,默认为-a)

[root@dazhu200 ~]# find / -type f -size +100M -size -150M



[root@dazhu200 ~]# ll /usr/lib/locale/locale-archive



4. find 时间查找
以天为单位 

-mtime(修改时间) -ctime(属性改变时间)  -atime(查看时间)

以分钟为单位

-mmin (修改时间)-cmin(属性改变时间)  -amin(查看时间)

小选项:

-number  n天之内

+number n天之前

number 第几天n天之前不包括第n天   第n天不包括今天n天之内包括今天

格式:find 大概路径 -mtime 小选项

 [root@dazhu200 ~]# find ./ -mtime +2(不算当天过去两天之前的文件)


[root@dazhu200 ~]# find ./ -mtime -2(算上当天两天之内的内容)


[root@dazhu200 ~]# find ./ -mtime 2(过去第二天内容)



5. find 用户查找 -user
小选项:用户名

格式:find 大概路径 -user name

[root@dazhu200 ~]# find ./ -user root


6. find 属组查找 -group
小选项:属组

格式:find 大概路径 -group 属组

[root@dazhu200 ~]# find ./ -group root


7. 按深度等级查找
-maxdepth n

[root@dazhu200 ~]# find ./ -maxdepth 1 -type f



8. 按inode查找,删除特殊符号名文件
-inum

小选项:inode号

33617260 -rw-r--r-- 2 root root 8332 Aug  4 21:52 大柱英语

[root@dazhu200 ~]# find ./ -inum 33617252


[root@dazhu200 ~]# find ./ -inum 33617260



等特殊符号无法被删除时,使用find inum查找然后rm -rf `find...`删除。

9. 组合
且:-a(默认为-a,and)  或:-o(or)    无“选项”:-no”选项”

9.1. 查找属主是dazhu且属组是root的文件:
[root@dazhu200 ~]# find ./ -user dazhu -a -group root



9.2. 查找属主是大柱或属组是root的文件:
[root@dazhu200 ~]# find ./ -user 大柱 -o -group root



9.3. 查找两天内且文件名为“*n*”的文件:
[root@dazhu200 ~]# find ./ -name "*n*" -a -mtime 2


10. 查找没有属组且没有属主的文件
[root@dazhu200 ~]# find ./ -nouser -a -nogroup



11. find查找后的动作 
11.1. -exec
格式:find ... -exec 命令 {} ;

命令:几乎所有命令都可执行但是find不支持别名

[root@dazhu200 ~]# find ./ -type f -name "nu*" -exec cp {} /tmp \;

[root@dazhu200 ~]# ll /tmp|grep “nu*”


11.2. |xargs
...|xargs 后继命令(find不支持别名,所以rm慎用!)

选项: -i {} 将上一条命令执行结果插入{}

...|xargs -i 后继命令 {} ... (将上调命令执行结果插入{}使用)

[root@dazhu200 ~]# find ./ -type f -name "nu*"|xargs -i mv {} /tmp \;

[root@dazhu200 ~]# ll

total 20

-rw-r--r-- 1 root root   36 Jul 31 20:45 err.txt

-rw-r--r-- 1 root root    0 Jul 31 22:26 nUmber

-rw-r--r-- 1 root root   57 Jul 31 20:53 ok.txt

-rw-r--r-- 1 root root 8326 Jul 30 22:03 大柱英语

[root@dazhu200 ~]# ll /tmp

total 16

-rw-r--r--  1 root root  57 Jul 31 20:43 nu1

-rw-r--r--  1 root root  21 Jul 31 10:56 nu2

-rw-r--r--  1 root root 123 Jul 31 11:01 nu3

-rw-r--r--  1 root root 197 Aug  3 11:03 nu5

drwx------. 2 root root   6 Jul 27 08:29 vmware-root

选项:-t 默认t后直接借助上调命令执行结果

...|xargs cp或mv -t..

[root@dazhu200 ~]# find ./ -type f -name "nu*"|xargs cp -t /tmp \;

[root@dazhu200 ~]# ll /tmp

total 16

-rw-r--r--  1 root root  57 Aug  3 20:43 nu1

-rw-r--r--  1 root root  21 Aug  3 20:43 nu2

-rw-r--r--  1 root root 123 Aug  3 20:43 nu3

-rw-r--r--  1 root root 197 Aug  3 20:43 nu5

drwx------. 2 root root   6 Jul 27 08:29 vmware-root

[root@dazhu200 ~]#

其他功能:进一步过滤与批量修改文件名
find ./ -type f |xargs grep 文件名

 [root@dazhu200 ~]# find ./ -type f | grep nu*(grep默认只过滤当前目录,递归过滤文件内容需要使用-R选项)

nu5:-rw-r--r--  1 root root  57 Aug  3 10:40 nu1

find ./ -type f |xargs -i cp {} {}.test
[root@dazhu200 ~]# find ./ -type f |xargs -i cp {} {}.test

[root@dazhu200 ~]# ll

total 72

-rw-r--r-- 1 root root   36 Jul 31 20:45 err.txt

-rw-r--r-- 1 root root   36 Aug  3 21:18 err.txt.test

-rw-r--r-- 1 root root   57 Jul 31 20:43 nu1

-rw-r--r-- 1 root root   57 Aug  3 21:18 nu1.test

-rw-r--r-- 1 root root   21 Jul 31 10:56 nu2

-rw-r--r-- 1 root root   21 Aug  3 21:18 nu2.tes

11.3. `可执行命令`
[root@dazhu200 ~]# rm -rf `find /tmp/ -name "nu*"`

[root@dazhu200 ~]# ll /tmp

total 0

drwx------. 2 root root 6 Jul 27 08:29 vmware-root

[root@dazhu200 ~]#

11.4. ;
;在命令行中有特殊含义。并列执行多条命令,不管其他命令是否可以成功执行,可以执行的都会执行。

[root@dazhu200 ~]# ll;mkdir dazhu;touch dazhu/nu6

total 36

-rw-r--r-- 1 root root   36 Jul 31 20:45 err.txt

-rw-r--r-- 1 root root   57 Jul 31 20:43 nu1

-rw-r--r-- 1 root root   21 Jul 31 10:56 nu2

[root@dazhu200 ~]# ll dazhu

total 0

-rw-r--r-- 1 root root 0 Aug  3 21:28 nu6

11.5. &&
&& 串联多个命令,前边的无法成功执行后边的也就无法执行。

[root@dazhu200 ~]# mkdir dazhu&&mkdir xiaozhu

mkdir: cannot create directory ‘dazhu’: File exists

[root@dazhu200 ~]# find ./ -type d -name "xiaozhu"

[root@dazhu200 ~]#

11.6. ||
|| 前边的命令执行失败,后面的命令才会执行

[root@dazhu200 ~]# find ./ -type d -name "xiaozhu"

[root@dazhu200 ~]# cd xiaozhu|| mkdir xiaozhu

-bash: cd: xiaozhu: No such file or directory

[root@dazhu200 ~]# ll

drwxr-xr-x 2 root root    6 Aug  3 21:36 xiaozhu

-rw-r--r-- 1 root root 8326 Jul 30 22:03 大柱英语

[root@dazhu200 ~]# cd xiaozhu || mkdir xiaoming

[root@dazhu200 xiaozhu]# which xiaoming

/usr/bin/which: no xiaoming in (/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin)

1.1.1. 待续...动作:
u 直接跟命令选项:

l -print (默认为-print)

l -ls 以长格式显示

l -delete 删除文件但是仅能删除空目录

l -ok 实现文件cp但是会提示是否cp

 -ok cp

.....待续

12. 待续...  !...
#find /etc -type f | xargs grep “dazhu” --color=auto
find 的逻辑运算符 -a 与 and(且) -o 或 or (和) ! 非 -not
!取反
**实操**
# 1.查找/usr/bin下所有大于30K,但小于50K且具有suid权限的文件,将其放入/root/newfiles。
find /usr/bin -size +30k -size -50k -perm /4000 -exec cp {} /root/newfiles \;

# 2.请把系统上拥有者为tammy用户的所有文件,并将其拷贝到/root/findfiles目录中。
find / -user tammy -exec cp -a {} /root/findfiles/ \;

8. cut

1. 基本语法

$ cut OPTION... [FILE]...

-f : 提取指定的字段,cut 命令使用 Tab 作为默认的分隔符。

-d : Tab 是默认的分隔符,使用这一选项可以指定自己的分隔符。

-b : 提取指定的字节,也可以指定一个范围。

-c : 提取指定的字符,可以是以逗号分隔的数字的列表,也可以是以连字符分隔的数字的范围。

–complement : 补充选中的部分,即反选。

–output-delimiter : 修改输出时使用的分隔符。

--only-delimited : 不输出不包含分隔符的列。

2. 实操

# 打印出 /etc/passwd 文件每一行的第一个字段,用的分隔符是 :
cut -d ':' -f1 /etc/passwd

# 使用冒号(:)分隔符从文件 /etc/passwd 中包含字符串 /bin/bash 的行提取第一和第六个字段。
grep "/bin/bash" /etc/passwd | cut -d':' -f1,6

# 显示字段的某个范围,可以指定开始和结束的字段,中间用连字符(-)连接,如下所示:
grep "/bin/bash" /etc/passwd | cut -d':' -f1-4,6,7

# 输出 /etc/passwd 文件中包含 /bin/bash 的行中除了第二个字段以外的所有字段:
grep "/bin/bash" /etc/passwd | cut -d':' --complement -f2

# 提取 content.txt 文件每一行的第一,二,三个字节:
cut -b 1,2,3 content.txt

9. awk

一、基本用法
# 格式
$ awk 动作 文件名

# 示例
$ awk '{print $0}' demo.txt
上面示例中,demo.txt是awk所要处理的文本文件。前面单引号内部有一个大括号,里面就是每一行的处理动作print $0。其中,print是打印命令,$0代表当前行,因此上面命令的执行结果,就是把每一行原样打印出来。

下面,我们先用标准输入(stdin)演示上面这个例子。
$ echo 'this is a test' | awk '{print $0}'
上面代码中,print $0就是把标准输入this is a test,重新打印了一遍。


awk会根据空格和制表符,将每一行分成若干字段,依次用$1$2$3代表第一个字段、第二个字段、第三个字段等等。
$ echo 'this is a test' | awk '{print $3}'
上面代码中,$3代表this is a test的第三个字段a。


passwd文件的字段分隔符是冒号(:),所以要用-F参数指定分隔符为冒号。然后,才能提取到passwd的第一个字段。
$ awk -F ':' '{ print $1 }' demo.txt
root
daemon
bin
sys
sync

二、变量

# 变量NF表示当前行有多少个字段,因此$NF就代表最后一个字段。
$ echo 'this is a test' | awk '{print $NF}'
test


$(NF-1)代表倒数第二个字段。
$ awk -F ':' '{print $1, $(NF-1)}' demo.txt
root /root
daemon /usr/sbin
bin /bin
sys /dev
sync /bin
上面代码中,print命令里面的逗号,表示输出的时候,两个部分之间使用空格分隔。



# 变量NR表示当前处理的是第几行。
$ awk -F ':' '{print NR ") " $1}' demo.txt
1) root
2) daemon
3) bin
4) sys
5) sync
上面代码中,print命令里面,如果原样输出字符,要放在双引号里面。


awk的其他内置变量如下。

FILENAME:当前文件名
FS:字段分隔符,默认是空格和制表符。
RS:行分隔符,用于分割每一行,默认是换行符。
OFS:输出字段的分隔符,用于打印时分隔字段,默认为空格。
ORS:输出记录的分隔符,用于打印时分隔记录,默认为换行符。
OFMT:数字输出的格式,默认为%.6g。


三、函数
awk还提供了一些内置函数,方便对原始数据的处理。

函数toupper()用于将字符转为大写。
$ awk -F ':' '{ print toupper($1) }' demo.txt
ROOT
DAEMON
BIN
SYS
SYNC
上面代码中,第一个字段输出时都变成了大写。


其他常用函数如下。

tolower():字符转为小写。
length():返回字符串长度。
substr():返回子字符串。
sin():正弦。
cos():余弦。
sqrt():平方根。
rand():随机数。
awk内置函数的完整列表,可以查看手册。


四、条件
awk允许指定输出条件,只输出符合条件的行。

输出条件要写在动作的前面。


$ awk '条件 动作' 文件名
请看下面的例子。


$ awk -F ':' '/usr/ {print $1}' demo.txt
root
daemon
bin
sys
上面代码中,print命令前面是一个正则表达式,只输出包含usr的行。



下面的例子只输出奇数行,以及输出第三行以后的行。
# 输出奇数行
$ awk -F ':' 'NR % 2 == 1 {print $1}' demo.txt
root
bin
sync

# 输出第三行以后的行
$ awk -F ':' 'NR >3 {print $1}' demo.txt
sys
sync


下面的例子输出第一个字段等于指定值的行。
$ awk -F ':' '$1 == "root" {print $1}' demo.txt
root

$ awk -F ':' '$1 == "root" || $1 == "bin" {print $1}' demo.txt
root
bin


五、if 语句
awk提供了if结构,用于编写复杂的条件。


$ awk -F ':' '{if ($1 > "m") print $1}' demo.txt
root
sys
sync
上面代码输出第一个字段的第一个字符大于m的行。


if结构还可以指定else部分。
$ awk -F ':' '{if ($1 > "m") print $1; else print "---"}' demo.txt
root
---
---
sys
sync

10. alias

# 创建一个命令,名为centos,当student输入centos时,则会提示字符串:this is a test
Useradd student
Su -student
Vim .bashrc
添加 alias centos=’echo this is a test’
Source .bashrc

11. date

# 查看当前时间

# %F 等同于 +%Y-%m-%d
date "+%F"						#2022-07-01
date "+%Y-%m-%d"				#2022-07-01
date "+%Y-%m-%d %H:%M:%S"		#2022-07-01 00:00:00
date "+%F %H:%M:%S"				#2022-07-01 00:00:00

# 查看指定时间 -d

date -d "-1day" +%F		#前一天
date -d "-1month" +%F	#前一月
date -d "-1year" +%F	#前一年
date -d "-1year -1month -1day" +%F	#组合

# 设置日期
date -s "2021-12-04 00:00:40"

12. tar

tar命令选项:

选项	说明
-c	创建打包文件
-v	显示打包或者解包的详细信息
-f	指定文件名称, 必须放到所有选项后面
-z	压缩或解压缩(.gz)
-j	压缩或解压缩(.bz2)
-x	解包
-C	解压缩到指定目录

# 创建一个名为/root/backup.tar.bz2的tar归档,其应该包含/usr/local/的内容。此归档文件必须使用bzip2进行压缩。
[root@servera ~]# tar -jcf /root/backup.tar.bz2 /usr/local/
[root@servera ~]# file backup.tar.bz2 # 验证
backup.tar.bz2: bzip2 compressed data, block size = 900k

#输出带时间戳的打包文件
DATE=$(date "+%Y%m%d");tar -cvzf DB_$DATE.tar /var/log/

13. history

# 为所有用户设置历史记录的时间
vim /etc/profile    //在文件末尾添加以下内容,然后保存退出重新登陆即可

HISTTIMEFORMAT='%F %T '     //注意有个空格,为了显示时日期与命令之间有空格分割。
HISTSIZE="3000"    //默认保留1000条。

# 若想同时显示历史命令的时间、日期以及操作者,则这样添加:
HISTTIMEFORMAT="%Y-%m-%d %H:%M:%S:`whoami` "HISTTIMEFORMAT="%F %T:`whoami` "
HISTTIMEFORMAT='%F %T '
如果是
export HISTTIMEFORMAT='%F%T'   //%T少了个空格,日期与命令就连在一起了

# 使用 HISTFILE 更改保存历史记录文件
默认情况下命令历史存储在 ~/.bash_history 文件中。 添加下列内容到 .bash_profile 文件并重新登录bash shell, 将使用 /var/history/$USER-$UID.log 来存储命令历史 :

# vi ~/.bash_profile   //输入以下内容
HISTFILE=/var/history/$USER-$UID.log

14. wc

# wc的基本统计用法test cat temp.txt
what's your name?
my name is bcy
➜  test wc temp.txt
 2  7 33 temp.txt        # 没有选项,依次输出行数、单词数、字节数、文件名test wc -l temp.txt   # 统计行数
2 temp.txt
➜  test wc -w temp.txt   # 统计单词数
7 temp.txt
➜  test wc -c temp.txt   # 统计字节数
33 temp.txt
➜  test wc -m temp.txt   # 统计字符数
33 temp.txt
➜  test wc -L temp.txt   # 打印最长行的长度
17 temp.txt

# 使用wc命令只统计数字,不打印文件名test cat temp.txt|wc           # 使用管道符即可实现不打印文件名
      2       7      33test cat temp.txt|wc -l
2test cat temp.txt|wc -w
7test cat temp.txt|wc -c
33


# 统计当前目录下的文件数test ll|wc -l           # 当前目录下的文件数为:8-1=7(第一行删掉)
8test ll
total 28K      # 删掉本行
-rw-r--r-- 1 baichunyu.bcy baichunyu.bcy 139 Sep 20 12:23 data2.txt
-rw-r--r-- 1 baichunyu.bcy baichunyu.bcy  33 Sep 19 22:34 hello.txt
-rw-r--r-- 1 baichunyu.bcy baichunyu.bcy 225 Sep 20 17:31 mem.txt
-rw-r--r-- 1 baichunyu.bcy baichunyu.bcy 109 Sep 20 09:27 osix
-rw-r--r-- 1 baichunyu.bcy baichunyu.bcy  25 Sep 20 17:46 teefile.txt
-rw-r--r-- 1 baichunyu.bcy baichunyu.bcy  33 Sep 21 18:08 temp.txt
-rw-r--r-- 1 baichunyu.bcy baichunyu.bcy  38 Sep 20 09:26 test.txt

防火墙

1. 配置文件、区域

# 配置文件说明
firewalld 存放配置文件有两个目录,/usr/lib/firewalld 和 /etc/firewalld,前者存放了一些默认的文件,后者主要是存放用户自定义的数据,所以我们添加的service或者rule都在后者下面进行。

server 文件夹存储服务数据,就是一组定义好的规则。

zones 存储区域规则

firewalld.conf 默认配置文件,可以设置默认使用的区域,默认区域为 public,对应 zones目录下的 public.xml

# 区域

防火墙为了简化管理,将所有网络流量分为多个区域(zone),然后根据数据包的源ip地址或传入的网络接口条件等将流量传入相应区域,每个区域都定义了自己打开或者关闭的端口和服务列表。其中默认区域为public

区域名称	          默认配置说明
Trusted	          允许所有的传入流量
Block	            拒绝所有传入流量
Drop	            丢弃所有传入流量
Public	          允许与ssh、dhcpv6-client预定义服务匹配的传入流量,其余都拒绝,也是新添加网络接口的默认区域
Home	            允许与ssh、mdns、ipp-client、samba-client、dhcpv6-client预定义服务匹配的传入流量,其余都拒绝
Work	            允许与ssh、ipp-client、dhcpv6-client预定义服务匹配的传入流量,其余都拒绝
Internal	        默认值时与home相同
External	        允许与ssh预定义服务匹配的传入流量,其余都拒绝;默认将进过此区域转发的ipv4地址传出流量进行地址伪装
Dmz	              允许与ssh预定义服务匹配的传入流量,其余都拒绝


# 命令
这里需要首先说明的是,在执行命令时,如果没有带 --permanent 参数表示配置立即生效,但是不会对该配置进行存储,相当于重启服务器就会丢失。如果带上则会将配置存储到配置文件,但是这种仅仅是将配置存储到文件,却并不会实时生效,需要执行 firewall-cmd --reload 命令重载配置才会生效。

1.重载防火墙配置
firewall-cmd --reload
2.查看防火墙运行状态
firewall-cmd --state
3.查看默认区域的设置
firewall-cmd --list-all

2. 配置命令

1. 区域管理

# 查看默认区域
[root@server ~]# firewall-cmd --get-default-zone 

# 查看当前活动区域和接口网卡
[root@server ~]# firewall-cmd --get-active-zones 

# 查看所有区域
[root@server ~]# firewall-cmd --get-zones

# 设置默认区域
[root@server ~]# firewall-cmd --set-default-zone=work

2. 服务管理

# 查看预定义服务
[root@server ~]# firewall-cmd --get-services 

# 查看public区域的详细信息
[root@server ~]# firewall-cmd --list-all --zone=public 

# 把http服务加入到public区域中,永久生效
[root@server ~]# firewall-cmd --add-service=http --zone=public --permanent

[root@server ~]# firewall-cmd --reload 

[root@server ~]# firewall-cmd --list-all --zone=public 

# 把http服务从public区域中永久移除

[root@server ~]# firewall-cmd --remove-service=http --zone=public --permanent

[root@server ~]# firewall-cmd --reload 

# 在默认区域中添加http和https2个服务
[root@server ~]# firewall-cmd --add-service=http --add-service=https

[root@server ~]# firewall-cmd --list-all

3. 端口管理

# 在默认区域中添加/删除tcp的3306端口
[root@server ~]# firewall-cmd --add-port=3306/tcp

[root@server ~]# firewall-cmd --list-all

[root@server ~]# firewall-cmd --remove-port=3306/tcp

# 在默认区域中添加udp端口2048-2050
[root@server ~]# firewall-cmd --add-port=2048-2050/udp

[root@server ~]# firewall-cmd --list-all

4. 综合配置(包含网段)

# 将默认区域设置为dmz区域,来自192.168.100.0网段的流量全部分配给internal区域,并且打开internal区域的80端口供用户访问
[root@server ~]# firewall-cmd --set-default-zone=dmz

[root@server ~]# firewall-cmd --add-source=192.168.100.0/24 --zone=internal --permanent

[root@server ~]# firewall-cmd --add-service=http --zone=internal --permanent

[root@server ~]# firewall-cmd --reload 

[root@server ~]# firewall-cmd --list-all

[root@server ~]# firewall-cmd --list-all --zone=internal 

网络

1. 查看网络连通性(ping、traceroute)

1. ping

# 临时禁ping

将/proc/sys/net/ipv4/icmp_echo_ignore_all文件里面的0临时改为1,从而实现禁止ICMP报文的所有请求,达到禁止Ping的效果,网络中的其他主机Ping该主机时会显示“请求超时”,但该服务器此时是可以Ping其他主机的。

#禁ping
echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_all
#启用ping
echo 0 > /proc/sys/net/ipv4/icmp_echo_ignore_all



# 复制代码永久禁ping
#编辑配置
vim /etc/sysctl.conf
#设置禁ping(如果有此配置就无需重复添加,仅更新值即可)
net.ipv4.icmp_echo_ignore_all = 1
#刷新配置
sysctl -p

#启用ping
net.ipv4.icmp_echo_ignore_all = 0



# 复制代码IPTABLES防火墙禁ping
置禁ping
iptables -A INPUT -p icmp --icmp-type 8 -s 0/0 -j DROP
启用ping
iptables -D INPUT -p icmp --icmp-type 8 -s 0/0 -j DROP

#参数备注
-A:添加防火墙规则.
INPUT:入站规则.
-p icmp:指定包检查的协议为ICMP协议.
--icmp-type 8:指定ICMP类型为8.
-s:指定IP和掩码,“0/0”表示此规则针对所有IP和掩码.
-j:指定目标规则,即包匹配则应到做什么,"DROP"表示丢弃.

2. traceroute

跟踪数据包的路由途径traceroute命令
n:不执行DNS反向查找,直接显示数字形式的IP地址
[root@localhost ~]# traceroute -n www.baidu.com
常见的TTL (Time To Live)生存周期值:
windows: 128
linux: 64
unix: 255
cisco: 255

2. 查看网络连接情况(netstat和lsof)

1. lsof

lsof
  lsof(list open files)是一个列出当前系统打开文件的工具。

  lsof 查看端口占用语法格式:

lsof -i:端口号

2. netstat

netstat -tunlp 用于显示 tcp,udp 的端口和进程等相关情况。

# 查看端口占用语法格式:
netstat -tunlp | grep 端口号

-a: 显示当前主机中所有活动的网络连接信息
-n:不执行DNS反向查找,以数字的形式显示相关信息
-r:显示路由表信息
-t:显示TCP协议相关的信息
-u:显示UDP协议相关的信息
-p:显示与网络连接相关的进程号、进程名称信息(需要root权限)
-l :查看监听状态的网络连接信息

netstat -anpt
netstat -lnpt
netstat -anpu

# 例如查看 8000 端口的情况,使用以下命令:
netstat -tunlp | grep 8000
tcp        0      0 0.0.0.0:8000    

3. 查看进程端口号步骤

1、先查看tomcat的进程号

ps -ef | grep tomcat*

后面带*号,是为了查看多个tomcat,例如tomcat6,tomcat7。

2、根据进程号查看端口号
# 都可以
netstat -anop | grep 15161
netstat -tulnp | grep 15161


3、此外,还可以通过端口号,查看其所属的进程号相关信息

lsof -i:8080

3. 查看路由(route)

# 查看路由表,使用route命令查看路由表

-n:不执行DNS反向查找,直接显示数字形式的IP地址

[root@localhost ~]# route
[root@localhost ~]# route -n
[root@localhost ~]# route -rn

4. 测试DNS域名解析nslookup命令

[root@localhost ~]# nslookup www.baidu.com

5. 抓包(tcpdump)

1. 实操

# 抓取一个固定主机ip的端口号,并保存在本地
tcpdump -i 接口 -w 保存的路径 host 主机IP and port 端口号 -s0 -C 包大小

tcpdump -i any -w /test/test.pcap host 127.0.0.1 and port 8001 -s0 -C 100
# 抓取所有网络接口数据包,提取出包含127.0.0.1:8001的数据包,并以每个并保存在 /test/test.pcap文件下
# -C 100及每100个数据包保存为一个文件

# 后台抓取多个主机的数据包
nohup tcpdump -i ens3 host baidu.com or csdn.com -s0 -C 100 -w ~/test.pcap &
# 抓取 baidu.com 与 csdn.com 两个域名的地址
# 使用开头的nohup与结尾的&使tcpdump后台运行# 看后台正在执行的tcpdump:

ps -ef|grep tcpdump |grep -v 'grep'

直接kill掉进程号就可以关闭掉后台运行的tcpdump了

# 按抓包的时间保存数据包
tcpdump -i any -s0 -G 600 -w %Y_%m%d_%H%M_%S.pcap
# 每600秒保存一次文件

# 自定义操作
# 自定义网络接口
tcpdump -D # 列出所有可用的网络接口
tcpdump -i eth0 # 监听 eth0 接口


# 自定义端口
tcpdump -i eth1 host 192.168.0.11 and ! port 80 and ! port 25
# 抓取192.168.0.11除了80,25外的其他端口

# 自定义抓取数据包的个数
tcpdump -i eth1 host 192.168.0.11 -c 10000
# 抓取eth1网卡上包含192.168.0.11的数据包 10000个后退出

# 自定义指定协议
协议可以是:ether, fddi, tr, wlan, ip, ip6, arp, rarp, decnet, tcp and udp

sudo tcpdump -i ens33 tcp and ....(其他自定义内容)

2. 抓取

# 抓取内容
21:26:49.013621 IP 172.20.20.1.15605 > 172.20.20.2.5920: Flags [P.], seq 49:97, ack 106048, win 4723, length 48

第一列:时分秒毫秒 21:26:49.013621
第二列:网络协议 IP
第三列:发送方的ip地址+端口号,其中172.20.20.1是 ip,而15605 是端口号
第四列:箭头 >, 表示数据流向
第五列:接收方的ip地址+端口号,其中 172.20.20.2 是 ip,而5920 是端口号
第六列:冒号
第七列:数据包内容,包括Flags 标识符,seq 号,ack 号,win 窗口,数据长度 length,其中 [P.] 表示 PUSH 标志位为 1


# 不指定任何参数
监听第一块网卡上经过的数据包。主机上可能有不止一块网卡,所以经常需要指定网卡。

# 监听特定网卡
tcpdump -i en0

# 监听特定主机
例子:监听本机跟主机182.254.38.55之间往来的通信包。
备注:出、入的包都会被监听。
tcpdump host 182.254.38.55

# 特定来源、目标地址的通信
特定来源
tcpdump src host hostname/ip

# 特定目标地址
tcpdump dst host hostname/ip

# 如果不指定src跟dst,那么来源 或者目标 是hostname的通信都会被监听
tcpdump host hostname/ip 


# 过滤网段
若你的ip范围是一个网段,可以直接这样指定
$ tcpdump net 192.168.10.0/24

# 根据源网段进行过滤
$ tcpdump src net 192.168

# 根据目标网段进行过滤
$ tcpdump dst net 192.168


# 特定端口
tcpdump port 3000
端口同样可以再细分为源端口,目标端口

# 根据源端口进行过滤
$ tcpdump src port 8088

# 根据目标端口进行过滤
$ tcpdump dst port 8088

如果你想要同时指定两个端口你可以这样写
$ tcpdump port 80 or port 8088

$ tcpdump port 80 or 8088

如果你的想抓取的不再是一两个端口,而是一个范围,一个一个指定就非常麻烦了,此时你可以这样指定一个端口段。

$ tcpdump portrange 8000-8080
$ tcpdump src portrange 8000-8080
$ tcpdump dst portrange 8000-8080

对于一些常见协议的默认端口,我们还可以直接使用协议名,而不用具体的端口号
比如 http == 80,https == 443 等
$ tcpdump tcp port http


# 基于协议进行过滤:proto
常见的网络协议有:tcp, udp, icmp, http, ip,ipv6 等

若你只想查看 icmp 的包,可以直接这样写
$ tcpdump icmp

protocol 可选值:ip, ip6, arp, rarp, atalk, aarp, decnet, sca, lat, mopdl, moprc, iso, stp, ipx, or netbeui


# 来源主机+端口+TCP
监听来自主机123.207.116.169在端口22上的TCP数据包

tcpdump tcp port 22 and src host 123.207.116.169

# 监听特定主机之间的通信
tcpdump ip host 210.27.48.1 and 210.27.48.2
210.27.48.1除了和210.27.48.2之外的主机之间的通信

tcpdump ip host 210.27.48.1 and ! 210.27.48.2

# 稍微详细点的例子
tcpdump tcp -i eth1 -t -s 0 -c 100 and dst port ! 22 and src net 192.168.1.0/24 -w ./target.cap
(1)tcp: ip icmp arp rarp 和 tcp、udp、icmp这些选项等都要放到第一个参数的位置,用来过滤数据报的类型
(2)-i eth1 : 只抓经过接口eth1的包
(3)-t : 不显示时间戳
(4)-s 0 : 抓取数据包时默认抓取长度为68字节。加上-S 0 后可以抓到完整的数据包
(5)-c 100 : 只抓取100个数据包
(6)dst port ! 22 : 不抓取目标端口是22的数据包
(7)src net 192.168.1.0/24 : 数据包的源网络地址为192.168.1.0/24
(8)-w ./target.cap : 保存成cap文件,方便用ethereal(即wireshark)分析

# 抓http包

# 限制抓包的数量
如下,抓到1000个包后,自动退出

tcpdump -c 1000

# 保存到本地
备注:tcpdump默认会将输出写到缓冲区,只有缓冲区内容达到一定的大小,或者tcpdump退出时,才会将输出写到本地磁盘,使用 -w 参数后接一个以 .pcap 后缀命令的文件名,就可以将 tcpdump 抓到的数据保存到文件中。

$ tcpdump icmp -w icmp.pcap

tcpdump -n -vvv -c 1000 -w /tmp/tcpdump_save.pcap

# 也可以加上-U强制立即写到本地磁盘(一般不建议,性能相对较差)

# 实战例子
先看下面一个比较常见的部署方式,在服务器上部署了nodejs server,监听3000端口。nginx反向代理监听80端口,并将请求转发给nodejs server(127.0.0.1:3000)。

浏览器 -> nginx反向代理 -> nodejs server

问题:假设用户(183.14.132.117)访问浏览器,发现请求没有返回,该怎么排查呢?

步骤一:查看请求是否到达nodejs server -> 可通过日志查看。

步骤二:查看nginx是否将请求转发给nodejs server。

tcpdump port 8383 
这时你会发现没有任何输出,即使nodejs server已经收到了请求。因为nginx转发到的地址是127.0.0.1,用的不是默认的interface,此时需要显示指定interface

tcpdump port 8383 -i lo
备注:配置nginx,让nginx带上请求侧的host,不然nodejs server无法获取 src host,也就是说,下面的监听是无效的,因为此时对于nodejs server来说,src host 都是 127.0.0.1

tcpdump port 8383 -i lo and src host 183.14.132.117
步骤三:查看请求是否达到服务器

tcpdump -n tcp port 8383 -i lo and src host 183.14.132.117

3. 读取抓包文件内容

# 从文件中读取包数据
使用 -w 是写入数据到文件,而使用 -r 是从文件中读取数据。

# 读取后,我们照样可以使用上述的过滤器语法进行过滤分析。
$ tcpdump icmp -r all.pcap

# 过滤指定网卡的数据包
-i:指定要过滤的网卡接口,如果要查看所有网卡,可以 -i any
# 过滤特定流向的数据包
-Q: 选择是入方向还是出方向的数据包,可选项有:in, out, inout,也可以使用 --direction=[direction] 这种写法
# 其他常用的一些参数
-A:以ASCII码方式显示每一个数据包(不显示链路层头部信息). 在抓取包含网页数据的数据包时, 可方便查看数据

-l : 基于行的输出,便于你保存查看,或者交给其它工具分析

-q : 简洁地打印输出。即打印很少的协议相关信息, 从而输出行都比较简短.

-c : 捕获 count 个包 tcpdump 就退出

-s : tcpdump 默认只会截取前 96 字节的内容,要想截取所有的报文内容,可以使用 -s number, number 就是你要截取的报文字节数,如果是 0 的话,表示截取报文全部内容。

-S : 使用绝对序列号,而不是相对序列号

-C:file-size,tcpdump 在把原始数据包直接保存到文件中之前, 检查此文件大小是否超过file-size. 如果超过了, 将关闭此文件,另创一个文件继续用于原始数据包的记录. 新创建的文件名与-w 选项指定的文件名一致, 但文件名后多了一个数字.该数字会从1开始随着新创建文件的增多而增加. file-size的单位是百万字节(nt: 这里指1,000,000个字节,并非1,048,576个字节, 后者是以1024字节为1k, 1024k字节为1M计算所得, 即1M=102410241,048,576)

-F:使用file 文件作为过滤条件表达式的输入, 此时命令行上的输入将被忽略.

# 对输出内容进行控制的参数
-D : 显示所有可用网络接口的列表
-e : 每行的打印输出中将包括数据包的数据链路层头部信息
-E : 揭秘IPSEC数据
-L :列出指定网络接口所支持的数据链路层的类型后退出
-Z:后接用户名,在抓包时会受到权限的限制。如果以root用户启动tcpdump,tcpdump将会有超级用户权限。
-d:打印出易读的包匹配码
-dd:以C语言的形式打印出包匹配码.
-ddd:以十进制数的形式打印出包匹配码

#  过滤规则组合
and:所有的条件都需要满足,也可以表示为 &&
or:只要有一个条件满足就可以,也可以表示为 ||
not:取反,也可以使用 

举个例子,我想需要抓一个来自10.5.2.3,发往任意主机的3389端口的包

$ tcpdump src 10.5.2.3 and dst port 3389

当你在使用多个过滤器进行组合时,有可能需要用到括号,而括号在 shell 中是特殊符号,因为你需要使用引号将其包含。例子如下:

$ tcpdump 'src 10.0.2.4 and (dst port 3389 or 22)'

而在单个过滤器里,常常会判断一条件是否成立,这时候,就要使用下面两个符号

=:判断二者相等
==:判断二者相等
!=:判断二者不相等
当你使用这两个符号时,tcpdump 还提供了一些关键字的接口来方便我们进行判断,比如

if:表示网卡接口名、
proc:表示进程名
pid:表示进程 id
svc:表示 service class
dir:表示方向,in 和 out
eproc:表示 effective process name
epid:表示 effective process ID
比如我现在要过滤来自进程名为 nc 发出的流经 en0 网卡的数据包,或者不流经 en0 的入方向数据包,可以这样子写

$ tcpdump "( if=en0 and proc =nc ) || (if != en0 and dir=in)"

httpd

1. 创建vhost.conf

<VirtualHost *:80>
DocumentRoot "/var/www/htmlc/test1/"
ServerName www.test1.com
<Directory "/var/www/htmlc/test1/">
Options FollowSymLinks ExecCGI
AllowOverride All
Order allow,deny
Allow from all
Require all granted
</Directory>
</VirtualHost>

2. 将文件移动到conf.d

3. 根据配置文件创建目录和文件

NTP

1. 基础命令

# 安装
yum -y install ntp ntpdate

# 关闭chronyd
systemctl disable chronyd

# 开启
systemctl start ntpd 

# 开放防火墙端口
firewall-cmd --zone=public --add-port=123/udp --permanent 
firewall-cmd --reload


# 使用中国NTP Server手动同步时间
ntpdate cn.pool.ntp.org

2. 配置服务端

vim /etc/ntp.conf

# 新增

restrict 172.22.10.6 nomodify notrap nopeer noquery //当前节点IP地址

# 授权172.22.10.0网段上所有机器可以从这台机器上查询和时间同步

restrict 172.22.10.0 mask 255.255.255.0 nomodify notrap //集群所在网段、掩码、权限

# 新增本地ntp服务器172.22.10.6,注释掉原有的server 0-n

server 127.127.1.0

fudge 127.127.1.0 stratum 10

interface ignore  wildcard

interface listen  172.22.10.6

interface listen  127.0.0.1

3. 配置客户端

1. 简单版

# 直接添加一行
server 4.centos.pool.ntp.org iburst

2. 详细版(不熟)

1)修改配置文件
vim  /etc/ntp.conf

# 增加
restrict 172.22.10.92 nomodify notrap nopeer noquery //当前节点IP地址
restrict 172.22.10.0 mask 255.255.255.0 nomodify notrap //集群所在网段的网段(Gateway),子网掩码(Genmask)

server 172.22.10.6 iburst //NTP服务器IP地址,可以注释掉别的server或者在需要配置的ntp服务器后添加perfer--优先,提高优先级,如:server 172.22.10.6 perfer iburst

fudge 172.22.10.6 stratum 10 //NTP服务器层级设置


2)预先同步一次时间(先关闭ntpd服务)

# ntpd进程进行同步时,只能同步较小的时间差,为防止时间差别太大,提前使用ntpdate进行一次时间同步

ntpdate 172.22.10.6

用户与组

1. 用户操作

一、用户操作

- 1、查看用户
id 用户名
cut -d : -f 1 /etc/passwd                               # 输出所有用户名
cat /etc/passwd | grep -v /sbin/nologin | cut -d : -f 1 # 输出可登陆的用户名
cat /ect/passwd                                         # 输出用户信息

/etc/passwd文件每一行代表一个用户,格式如下:
username:password:UserID:Group ID:comment:home directory:shell
  分别代表用户名、密码、用户ID(整数)、组ID(整数)、用户说明、用户登陆的主目录、
  用户登陆后执行命令。值得注意的是密码现在不存这个文件了,改成 /etc/shadow 文件。

- 2、添加用户

复制代码
useradd -h                           # useradd命令帮助
useradd username                     # 添加一个用户username
useradd username -g groupname                      # 添加一个用户并加入group组中,组不存在会报错
useradd username -g groupname -s /bin/false        # 创建不登陆的用户
useradd username -g groupname -s /sbin/nologin     # 创建不登陆的用户

useradd mysql -g mysql -s /bin/false -r            # 创建系统用户,且不用登陆,系统用户是不会创建用户目录的

- 3、设置用户密码
passwd username # 设置用户密码

- 4、修改用户

usermod -h                                           # usermod命令帮助
usermod username -l username2                        # 修改用户username登陆名为username2
usermod username -l username2 -d /home/username2 -m  # 修改用户名、home目录
usermod username -g groupname                        # 修改用户组

# 小技巧:将系统用户改为普通用户
usermod username -s /bin/bash               # 修改Shell

mkdir /home/username                        # 创建用户目录,和/etc/passwd中的保持一致
cp /etc/skel/.bashrc /home/username/        # 环境变量文件,否则登陆时显示 -bash-4.2$
cp /etc/skel/.bash_profile /home/username/  #环境变量文件,否则登陆时显示 -bash-4.2$

- 5、删除用户
userdel -h            # userdel命令帮助
userdel username      # 删除用户,家目录和邮箱目录会被保留,再次创建该用户时会报错
userdel -r username   # 删除用户,家目录和邮箱目录同步删除
如果忘记使用-r参数,手工删除/home和/var/spool/mail对应的目录即可。
rm -rf /home/xxx                    # xxx代表用户名
rm -rf /var/spool/mail/xxx

- 6、其它
last           # 查看用户登陆记录

2. 用户密码操作

可以使用chage命令来手动修改账户的相关属性:
格式:chage [选项] 账户名
  
[选项]
-m:密码可更改的最小天数。为零时代表任何时候都可以更改密码。
-M:密码保持有效的最大天数。
-w:账户密码到期前,提前收到警告信息的天数。
-E:帐号到期的日期。过了这天,此帐号将不可用。
-d:上一次更改的日期。
-i:停滞时期。如果一个密码已过期这些天,那么此帐号将不可用。
-l:例出当前的设置。由非特权账户来确定他们的密码或帐号何时过期。


passwd 命令用于修改用户密码,过期时间,认证信息等。

普通用户只能使用 passwd 命令修改自身的系统密码,而 root 管理员则有权限修改其他所有人的密码。

参数	作用
-l 	锁定用户,禁止登陆。
-u	解除锁定,允许登陆。
--stdin 允许通过标准输入修改用户密码,如 echo "NewPassWord" | passwd --stdin Username
-d  	删除密码,允许用户空密码登陆
-e  	强制用户在下次登陆时修改密码
-S	显示用户的密码是否被锁定,以及密码所采用的加密算法名称

# 修改用户密码策略(对root无效)
vim /etc/login.defs
 
 #修改如下参数
 PASS_MAX_DAYS 90#设置登录密码有效期90天
 PASS_MIN_DAYS 1  #登录密码最短修改时间,增加可以防止非法用户短期更改多次
 PASS_MIN_LEN 8  #登录密码最小长度8位
 PASS_WARN_AGE 7 #登录密码过期提前7天提示修改
 FAIL_DELAY 10 #登录错误时等待时间10秒
 FAILLOG_ENAB yes #登录错误记录到日志
 SYSLOG_SU_ENAB yes #当限定超级用户管理日志时使用
 SYSLOG_SG_ENAB yes #当限定超级用户组管理日志时使用
 MD5_CRYPT_ENAB yes #当使用md5为密码的加密方法时使用

3. 用户权限(visudo)

vim /etc/sudoers 或 visudo

# 允许用户可在任何地方运行任何命令

user ALL=(ALL) ALL  #这里省略了是否需要密码验证

 

# 允许用户组wheel可以以root的身份,在任何机器上免密码的运行所有命令

%wheel ALL=(ALL) NOPASSWD: ALL 

 

# 允许普通用户hong可以以root的身份,在任何机器上免密码的运行所有命令

hong ALL=NOPASSWD: ALL  

 

1"字段2"表示允许登录的主机, ALL表示所有; 如果该字段不为ALL,表示授权用户只能在某些机器上登录本服务器来执行sudo命令. 比如:

jack mycomputer=/usr/sbin/reboot,/usr/sbin/shutdown

 

2)字段3,字段4是可以省略的,"字段3"如果省略, 相当于(root:root),表示可以通过sudo提权到root; 如果为(ALL)或者(ALL:ALL), 表示能够提权到(任意用户:任意用户组)。

表示: 普通用户jack在主机(或主机组)mycomputer上, 可以通过sudo执行reboot和shutdown两个命令。"字段3""字段4"省略


3"字段5"是使用逗号分开一系列命令,这些命令就是授权给用户的操作; ALL表示允许所有操作。


# 授权单个或多个命令

linuxprobe ALL=(ALL) /usr/sbin/useradd, /bin/rm

# 授权单个或多个命令目录

linuxprobe ALL=(ALL) /usr/sbin/*, /usr/bin/*

# 授权单个或多个命令目录, 并排除某个特殊命令

linuxprobe ALL=(ALL) /usr/sbin/*, /usr/bin/*, !/usr/sbin/visudo

# 执行 sudo 时, 不用输用户密码, 直接执行命令

linuxprobe ALL=(ALL) NOPASSWD: /usr/sbin/useradd, /bin/rm

4. 用户组基础操作

- 1、查看用户组
cut -d : -f 1 /etc/group # 列出用户组名
cat /etc/group           # 输出用户组文件内存

- 2、添加用户组
groupadd -g 1001   # 指定gid
groupadd -g 1001 test # 添加test用户组

- 3、修改用户组
groupmod test -n mytest # 将test用户组改名为mytest

- 4、删除用户组
groupdel test # 删除test用户组,组不存在会报错

5. 实操

# 查看当前用户UID,查看当前用户所在的组
id

# 查看当前系统中的所有用户
cat /etc/passwd

# 查看当前系统中所有的组
cat /etc/group

# 创建组manager
groupadd manager
# 创建用户nova,并且该用户的附加组为manager
useradd -G manager nova
# 创建用户john,并且该用户不能以交互式方式登录系统
useradd -s /sbin/nologin john
# 创建用户lany,并且该用户的主要组为root组,且是manager和wheel组内成员
useradd -g root lany
usermod -G manager lanny
usermod -aG wheel lany
# 创建用户alex,为其添加注释“Hello World!”
useradd -c "hello" alex
# 创建用户tom,并且指定用户的UID为1234
useradd -u 1234 tom
# 以上所有用户的密码均为P@ssW9rD
echo P@ssW9rD | passwd --stdin nova


# 创建用户组ansible,并将该组内所有成员提权成root相同的权限,允许用户在不输入密码的前提下执行命令
groupadd ansible
vim /etc/sudoers 或 visudo
%ansible       ALL=(ALL)       NOPASSWD: ALL

# 将nova设置为与root相同的权限
vim /etc/sudoers 或 visudo
复制root那一行

# 为alex用户仅添加创建、修改、删除用户的权限
vim /etc/sudoers 
alex   ALL=     NOPASSWD: /usr/sbin/useradd,/usr/sbin/userdel,/usr/sbin/usermod

# 禁止user1账号做周期性计划任务。
echo “user1” > /etc/cron.deny

# oper1账号的密码必须90天更换一次
chage -M 90 oper1

# 要求oper1账号在首次登陆系统时强制更新密码为centos
Chage -d 0 oper1

# oper1账号的密码在2022年1月1日过期
chage -E '2022-01-01' oper1

# oper1账号的密码在30天后过期
date -d "+30day" +%F
chage -E '显示日期' oper1

# 强制用户下次登陆时修改密码,并且设置密码最低有效期0和最高有限期90,提前15天发警报提示
chage -d 0 -m 0 -M 90 -W 15 root

# 要求每当oper1用户登陆系统时,显示本月的日历。
Su - oper1
Vim .bashrc
添加cal

文件与目录权限

1. 权限查看、修改

ls -lh # 显示权限 
ls -ld # 查看目录详情
chmod ugo+rwx directory1 #设置目录的所有人(u)、群组(g)以及其他人(o)以读(r,4 )、写(w,2)和执行(x,1)的权限 
chmod go-rwx directory1  #删除群组(g)与其他人(o)对目录的读写执行权限

chown user1 file1 #改变一个文件的所有人属性 
chown -R user1 directory1 #改变一个目录的所有人属性并同时改变改目录下所有文件的属性 
chown user1:group1 file1 #改变一个文件的所有人和群组属性

chgrp -R group1 file1 #改变文件的群组


# 文件类型,使用ll命令查看
第1位:文件类型(d 目录,- 普通文件,l 链接文件)

# 创建软硬链接
ln /mub1/m2.c /usr/liu/a2.c   #硬
ln -s /usr/mengqc/mub1 /usr/liu/abc   #软

# 特殊权限

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-khsa4gR6-1675241162746)(./%E7%89%B9%E6%AE%8A%E6%9D%83%E9%99%90.png)]

2. setfacl

设置文件访问控制列表
# 用户harry能够读取和写入/var/tmp/fstab文件
[root@servera ~]# setfacl -m u:harry:rw- /var/tmp/fstab
# 用户natasha无法读取或写入/var/tmp/fstab文件
[root@servera ~]# setfacl -m u:natasha:--- /var/tmp/fstab
# 查看
[root@servera ~]# getfacl /var/tmp/fstab

3. 实操

# 查看/root/下所有文件的权限
ls -al /root/

# 查看/mnt/(目录本身)的属性
ls -ld /mnt/

# 创建/data/目录,并设置权限为所有人均可读写执行
mkdir /data/
chmod 777 /data

# 在/data/下创建文件file,将文件拥有人修改为student,且权限为所有人可读可写不可执行                                                                                
touch file
chown student file
chmod 666 file

# 将/etc/passwd文件拷贝到/data/pass,设置文件权限为拥有人可读可写,拥有组只读,其他人不具备任何权限
cp /etc/passwd /data/pass/
chmod 640 passwd

# 创建/data/test/目录,修改文件拥有组为wheel,且组内成员对该目录可读可写可执行,其他权限不变
chown :wheel /data/test
ls -ld /data/test/
chmod g+rwx /data/test/

进程管理

1.查看进程

ps aux		# 查看进程及占用CPU及内存
# 查看CPU占用前十的进程
ps aux|head -n1;ps aux|grep -v PID|sort -nr -k3|head -n10
# 查看内存占用前十的进程
ps aux|head -n1;ps aux|grep -v PID|sort -nr -k4|head -n10

# 查找进程相关线程cpu使用情况
ps -eLo pid,ppid,tid.pcpu | grep 进程号

ps -l 		# 观察与当前终端机相关的进程
ps -lA 		# 观察系统所有的进程数据(显示内容项同 ps -l 的项一样,只不过是系统所有进程)
ps axjf		# 连同部分进程树状态

pidof # 查看某个进程的PID


# 列出正在运行的服务
systemctl
systemctl | more
systemctl | grep httpd
systemctl list-units --type service
systemctl list-units --type mount

# 列出所有服务
systemctl list-unit-files





# 使用top命令动态查看进程信息
top

行	字段	         含义
1	top	        程序名
1	15:52:31	当前时间
1	up 2 days	正常运行时间(uptime),从机器最后一次启动开始计算的时间总数,这个例子中,系统已经运行了2天
1	2 users	        有两个用户已登录
1	load average	负载均值指的是等待运行的进程数,即共享CPU资源的处于可运行状态的进程数。第一个代表前60s的均值,第二个代表前5min的均值,第三个代表前15min的均值。该值小于1.0表示该机器不忙
2	Tasks	        统计进程数及各个进程的状态信息
3	5.9 us	5.9%的CPU时间被用户进程占用,这里指的是处于内核外的进程
3	1.3 sy	1.3%的CPU时间被系统进程(内核进程)占用
3	0.0 ni	0.0%的CPU时间被友好进程(nice)(低优先级进程)占用
3	91.4 id	91.4%的CPU时间是空闲的
3	0.1 wa	0.0%的CPU时间来等待I/O操作
4	Mem	显示物理RAM(随机存取内存)的使用情况
5	Swap	显示交换空间(虚拟内存)的使用情况

2. 进程状态

状态	含义
R	运行状态。进程正在运行或者准备运行
S	睡眠状态。进程不在运行,而是在等待某事件发生,如键盘输入或者受到网络报表
D	不可中断的睡眠状态。进程在等待I/O操作,如硬盘驱动
T	暂停状态。进程在等待I/O操作,如硬盘驱动
Z	无效或者“僵尸”进程。子进程被终止,但是还没有被其父进程彻底释放掉
<	高优先级进程。进程可以被赋予更多的重要性,分配更多的CPU时间。进程的这一特性称为优先级(niceness)。高优先级的进程被说成较不友好,是因为它将消耗更多的CPU时间,这样留给其它进程CPU时间就会变少。
N	低优先级进程。低优先级进程(友好进程,a nice process)只有在其它更高优先级的进程使用完处理器后才能获得使用处理器的时间.

3. 进程控制

# 通过使用信号  
kill  信号   pid
信号1 重新加载配置文件
信号9 强制终止
信号15 默认值。终结
信号19 暂停一个进程
信号18 恢复暂停的进程

日志管理

1. LogSystem

CentOS 7/8 使用systemd-journald来做日志中心库,使用rsyslog来做日志持久化,使用logrotate来做日志文件轮转。

2. rsyslog服务

`rsyslog` 服务根据优先级排列日志信息,将它们写入到 `/var/log`目录中永久保存

# 配置文件
/etc/rsyslog.conf


mail.info  /var/log/mail.log   #表示将mail相关的,级别为info及info以上级别的信息记录到/var/log/mail.log文件中 

auth.=info  @10.1.1.1          #表示将auth相关的,级别为info的信息记录到10.1.1.1主机上去,前提是10.1.1.1要能接收其主机发来的日志信息

user.!=error                   #表示记录user相关的,不包括error级别的信息

user.!error                   #表示user.error相反

*.info                         #表示记录所有的日志信息的info级别

mail.*                         #表示记录所有mail相关的所有级别的信息

*.*                            #表示记录所有的日志信息的所有的日志级别

cron.info;mail.info            #多个日志来源可以用“ ; ”隔开

cron,mail.info                 #与cron.info;mail.info        是一个意思

mail.*;mail.!=info             #表示记录mail相关的所有级别的信息,但是不包括info级别的信息

磁盘监控

df(磁盘使用情况)
参数
-a	显示所有文件系统信息,包括系统特有的 /proc、/sysfs 等文件系统;
-m	以 MB 为单位显示容量;
-k	以 KB 为单位显示容量,默认以 KB 为单位;
-h	使用人们习惯的 KB、MB 或 GB 等单位自行显示容量;
-T	显示该分区的文件系统名称;
-i	不用硬盘容量显示,而是以含有 inode 的数量来显示。

使用
方式1

[root@kuaihe-soa-001 /dev]#df
Filesystem     1K-blocks     Used Available Use% Mounted on
/dev/vda1      412716208 68222492 323522308  18% /
tmpfs           16439616        0  16439616   0% /dev/shm
 [root@kuaihe-soa-001 /dev]#df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/vda1       394G   66G  309G  18% /
tmpfs            16G     0   16G   0% /dev/shm
[root@kuaihe-soa-001 /dev]#
注:tmpts是内存空间,重启后会丢失


Filesystem:表示该文件系统位于哪个分区,因此该列显示的是设备名称;
1K-blocks:此列表示文件系统的总大小,默认以 KB 为单位;
Used:表示用掉的硬盘空间大小;
Available:表示剩余的硬盘空间大小;
Use%:硬盘空间使用率。如果使用率高达 90% 以上,就需要额外注意,因为容量不足,会严重影响系统的正常运行;
Mounted on:文件系统的挂载点,也就是硬盘挂载的目录位置。

方式2


[root@kuaihe-soa-001 /dev]#cd /
[root@kuaihe-soa-001 /]#ls
bin  boot  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  selinux  srv  sys  tmp  usr  var
[root@kuaihe-soa-001 /]#df -h /home
Filesystem      Size  Used Avail Use% Mounted on
/dev/vda1       394G   66G  309G  18% /

这里在 df 命令后添加了目录名,在这种情况下,df 命令会自动分析该目录所在的分区,并将所在分区的有关信息显示出来。由此,我们就可以知道,该目录下还可以使用多少容量。

方式3


[root@kuaihe-soa-001 /]#df -aT
Filesystem     Type        1K-blocks     Used Available Use% Mounted on
/dev/vda1      ext4        412716208 68238212 323506588  18% /
proc           proc                0        0         0    - /proc
sysfs          sysfs               0        0         0    - /sys
devpts         devpts              0        0         0    - /dev/pts
tmpfs          tmpfs        16439616        0  16439616   0% /dev/shm
none           binfmt_misc         0        0         0    - /proc/sys/fs/binfmt_misc

使用 -a 选项,会将很多特殊的文件系统显示出来,这些文件系统包含的大多是系统数据,存在于内存中,不会占用硬盘空间,因此你会看到,它们所占据的硬盘总容量为 0

分区

1. 基于硬盘空余空间创建分区(fdisk)

# 查看硬盘
lsblk

# 查看机器所挂硬盘个数及分区情况
fdisk -l

# 使用新建盘创建分区
fdisk /dev/sdb

# 根据提示选择
d delete a partition 注:这是删除一个分区的动作;
l list known partition types 注:l是列出分区类型,以供我们设置相应分区的类型;
m print this menu 注:m 是列出帮助信息;
n add a new partition 注:添加一个分区;
o create a new empty DOS partition table
p print the partition table 注:p列出分区表;
q quit without saving changes 注:不保存退出;
s create a new empty Sun disklabel
t change a partition's system id 注:t 改变分区类型;
u change display/entry units
v verify the partition table
w write table to disk and exit 注:把分区表写入硬盘并退出;
x extra functionality (experts only) 注:扩展应用,专家功能

n p +5G w  //根据提示选择

2. 基于文件创建分区(dd)

# 用dd创建一个100M大小的空文件
dd if=/dev/zero of=/tmp/file bs=1024 count=100000

# 用ext4将这个文件格式化
mkfs.ext4 /tmp/file

# mount挂载
mkdir /mnt/newdisk
mount -o loop /tmp/file /mnt/newdisk

# 用df -h查看是否多了一个100M的分区
df -h

# 开机自动挂载 可以加入到/etc/fstab中
vim /etc/fstab
加入 /tmp/file     /mnt/newdisk           ext3    defaults        1 2

3. 创建SWAP分区

# 查看内存
free -m
#查看swap信息,包括文件和分区的详细信息
swapon -s 

#添加交换空间有两种选择:添加一个交换分区或添加一个交换文件

一、增加swap交换文件

1、使用dd命令创建一个swap交换文件

dd if=/dev/zero of=/home/swap bs=1024 count=1024000

这样就建立一个/home/swap的分区文件,大小为1G。

2、制作为swap格式文件:

mkswap /home/swap

3、再用swapon命令把这个文件分区挂载swap分区

/sbin/swapon /home/swap

我们用free -m命令看一下,发现已经有交换分区了


4、为防止重启后swap分区变成0,要修改/etc/fstab文件

vi /etc/fstab

在文件末尾(最后一行)加上

/home/swap swap swap default 0 0



二、删除swap交换文件

1、先停止swap分区

/sbin/swapoff /home/swap

2、删除swap分区文件

rm -rf /home/swap

3、删除自动挂载配置命令

vi /etc/fstab

这行删除

/home/swap swap swap default 0 0
这样就能把手动增加的交换文件删除了。

注意:
1、增加删除swap的操作只能使用root用户来操作。
2、装系统时分配的swap分区貌似删除不了。
3、swap分区一般为内存的2倍,但最大不超过2G


三、使用分区来做SWAP(虚拟内存).
1 使用fdisk来创建交换分区(假设 /dev/sdb2 是创建的交换分区)

fdisk /dev/sdb

2 使用 mkswap 命令来设置交换分区:

mkswap /dev/sdb2

3 启用交换分区:

swapon /dev/sdb2

4 写入/etc/fstab,以便在引导时启用:

/dev/sdb2 swap swap defaults 0 0

四、删除交换分区

1、先停止swap分区

/sbin/swapoff /dev/sdb2

2、删除自动挂载配置命令

vi /etc/fstab

这行删除

/dev/sdb2 swap swap defaults 0 0

卷操作

1. 命令

# 1.pv命令

    pvcreate:创建PV
	pvcreate  device
	pvdisplay:查看命令
	pvs:查看
	pvscan:扫描物理卷
	pvremove 移除物理卷
	pvmove:将pv中的数据挪移到其他pv中

# 2.vg命令

    vgcreate
		vgcreate vgname  /dev/sd....(divce)
			-s: 用来指定PE大小
		
	vgextend:扩容
	vgreduce:删除
	vgremove:删除卷组
	vgs:查看
	vgdisplay:查看命令
	vgrename

# 3.lv命令:

      lvcreate:
		-n:指定逻辑卷名称
		-L:指定逻辑卷大小   #绝对容量  +# 增量
		-l:指定逻辑卷大小  指定使用PE个数
		-s:创建快照
		-p:设置属性  r
		lvextend
		lvreduce
	lvrename
	lvs
	lvdisplay
	lvremove
	lvconvert:拍照
	
	lv缩减:
	1、卸载逻辑卷
		2、强制检测磁盘剩余空间
		3、使用resize2fs缩减文件系统
		4、再使用lvreduce命令缩减逻辑卷
		5、再挂载使用
		文件系统大小需要和逻辑卷大小一致
		
删除逻辑卷
		1、卸载逻辑卷
		2、lvremove删除逻辑卷,删除之前一定要删除掉/etc/fstab中记录的挂载信息
		3、vgremove删除卷组
		4、pvremove删除物理卷

2. 创建逻辑卷

 # 查看分区
 lsblk 查看硬盘
 # 创建物理卷
 pvcreate /dev/sdb1 /dev/sdb2
 # 查看物理卷
 pvs 
 pvdisplay

# 创建卷组
 vgcreate myvg /dev/sdb[1-2] 
# 创建卷组,指定pe
 vgcreate -s 16m myvg /dev/sdb[1-2] 
# 查看卷组
 vgs、vgdisplay  
# 删除卷组
 vgremove myvg 
#  添加分区
 vgextend myvg /dev/sdb3 

# 逻辑卷
 lvcreate -L 5G -n mylv myvg //创建逻辑卷,直接指定大小
 lvcreate -l 60 -n mylv myvg  //创建辑卷,指定PE个数
 lvs lvscan 查看逻辑卷

# /dev/myvg/mylv等同于/dev/mapper/myvg-mylv
 mkfs.ext4 /dev/myvg/mylv 创建文件系统

# 挂载逻辑卷
mount /dev/myvg/mylv /opt 
# 持久挂载到/data目录下,并要求挂载时禁止程序自动运行(该挂载点内不允许运行程序或脚本)。
mount -o noexec /dev/sdb1 /data
echo "/dev/sdb1 /data ext4 noexec 0 0" >> /etc/fstab

# 删除逻辑卷
lvremove /dev/myvg/mylv

# 持久化挂载
 df -h  # 查看
 
 vim /etc/fstab # 编辑文件,持久化
 
 填写
 /dev/myvg/mylv  /opt    defaults        0  0
 
 mount -a //刷新
 
 # 扩容逻辑卷
 lvextend -L +1G /dev/myvg/mylv  
 # 扩容文件系统
 resize2fs /dev/myvg/mylv  # (ext4格式)
 xfs_growfs /dev/myvg/mylv  # (xfs格式)

NFS

1. 配置本机挂载本机nfs

# 安装
yum install -y nfs-utils
systemctl start nfs-server
systemctl enable nfs-server

# 修改配置文件
vim /etc/exports
/share   *(rw,sync,no_root_squash)

# 重启服务
systemctl restart nfs-server

# 创建共享文件目录,修改权限
mkdir /share
chmod -R 777 /share
cd /share
touch test.txt

# 客户端创建挂载点,并挂载
mkdir /mnt/share
mount 192.168.3.93:/share /mnt/share
# 重启服务
systemctl restart nfs-server

# 持久化
vim /etc/fstab
127.0.0.1:/share  /mnt/share         nfs     defaults,_netdev        0 0
mount -a

2. 配置文件

# /etc/exports文件内容格式:

<输出目录> [客户端1 选项(访问权限,用户映射,其他)] [客户端2 选项(访问权限,用户映射,其他)]
a. 输出目录:

输出目录是指NFS系统中需要共享给客户机使用的目录;

b. 客户端:

客户端是指网络中可以访问这个NFS输出目录的计算机

客户端常用的指定方式

指定ip地址的主机:192.168.0.200
指定子网中的所有主机:192.168.0.0/24 192.168.0.0/255.255.255.0
指定域名的主机:david.bsmart.cn
指定域中的所有主机:*.bsmart.cn
所有主机:*
c. 选项:

选项用来设置输出目录的访问权限、用户映射等。

NFS主要有3类选项:

访问权限选项

设置输出目录只读:ro
设置输出目录读写:rw
用户映射选项

all_squash:将远程访问的所有普通用户及所属组都映射为匿名用户或用户组(nfsnobody);
no_all_squash:与all_squash取反(默认设置);
root_squash:将root用户及所属组都映射为匿名用户或用户组(默认设置);
no_root_squash:与rootsquash取反;
anonuid=xxx:将远程访问的所有用户都映射为匿名用户,并指定该用户为本地用户(UID=xxx);
anongid=xxx:将远程访问的所有用户组都映射为匿名用户组账户,并指定该匿名用户组账户为本地用户组账户(GID=xxx);
其它选项

secure:限制客户端只能从小于1024的tcp/ip端口连接nfs服务器(默认设置);
insecure:允许客户端从大于1024的tcp/ip端口连接服务器;
sync:将数据同步写入内存缓冲区与磁盘中,效率低,但可以保证数据的一致性;
async:将数据先保存在内存缓冲区中,必要时才写入磁盘;
wdelay:检查是否有相关的写操作,如果有则将这些写操作一起执行,这样可以提高效率(默认设置);
no_wdelay:若有写操作则立即执行,应与sync配合使用;
subtree:若输出目录是一个子目录,则nfs服务器将检查其父目录的权限(默认设置);
no_subtree:即使输出目录是一个子目录,nfs服务器也不检查其父目录的权限,这样可以提高效率;

shell

1. 基础

# shell的执行方式:
- 路径方式 :必须赋予权限
- source  立即执行,不需要权限
- bash 执行

新建一个文件,扩展名为sh(sh代表shell),输入一些代码:

#!/bin/bash
echo "Hello World !"#!” 是一个约定的标记,它告诉系统这个脚本需要什么解释器来执行,即使用哪一种Shell。

运行Shell脚本有两种方法。

1.作为可执行程序,将上面的代码保存为test.sh,并 cd 到相应目录:

chmod +x ./test.sh  #使脚本具有执行权限
./test.sh #执行脚本
注意,一定要写成./test.sh,而不是test.sh。

2.作为解释器参数,这种运行方式是,直接运行解释器,其参数就是shell脚本的文件名,如:

/bin/sh test.sh
/bin/php test.php
这种方式运行的脚本,不需要在第一行指定解释器信息,写了也没用。

下面的脚本使用 read 命令从 stdin 获取输入并赋值给 PERSON变量,最后在 stdout 上输出:

#!/bin/bash
 
echo "What is your name?"
read PERSON
echo "Hello, $PERSON"
运行脚本:

chmod +x ./test.sh
$./test.sh

# 配置只使用名称运行
export PATH=/opt/sahre:$PATH    #在PATH中添加目录/opt/share
export PATH=$PATH:/opt/share


export设置环境变量是暂时的,只在本次登录中有效,可修改如下文件来使命令长久有效。

1. 修改profile文件
#vi /etc/profile

在里面加入:

export PATH="$PATH:/opt/share"

这个在我们的机器上是大家共用的,建议不修改这个,只修改自己根路径下的。

2. 修改本id根路径下的.bashrc或.bash_profile或$HOME/.profile文件:
# vi /home/zhaodw/.bash_profile

在里面加入:

export PATH="$PATH:/opt/share"

source /home/zhaodw/.bash_profile
注意:
1、执行脚本时是在一个子shell环境运行的,脚本执行完后该子shell自动退出;
2、一个shell中的系统环境变量才会被复制到子shell中(用export定义的变量);
3、一个shell中的系统环境变量只对该shell或者它的子shell有效,该shell结束时变量消失(并不能返回到父shell中)。
4、不用export定义的变量只对该shell有效,对子shell也是无效的。

2. test语句

执行条件表达式

# 执行条件表达式并显示返回值。
[root@pc root]$ test ! "abc" == 123; echo $?
0

# 等价形式,注意:方括号 [ 后面的空格以及方括号 ] 前面的空格。

[root@pc root]$ [ ! "abc" == 123 ]; echo $?
0
# 支持正则的测试 [[      ]] 
[root@pc root]$ [[ ! "abc" == 123 ]]; echo $?
0

3. shell 语法

算符描述示例
文件比较运算符
-e filename如果 filename 存在,则为真[ -e /var/log/syslog ]
-d filename如果 filename 为目录,则为真[ -d /tmp/mydir ]
-f filename如果 filename 为常规文件,则为真[ -f /usr/bin/grep ]
-L filename如果 filename 为符号链接,则为真[ -L /usr/bin/grep ]
-r filename如果 filename 可读,则为真[ -r /var/log/syslog ]
-w filename如果 filename 可写,则为真[ -w /var/mytmp.txt ]
-x filename如果 filename 可执行,则为真[ -L /usr/bin/grep ]
filename1 -nt filename2如果 filename1 比 filename2 新,则为真[ /tmp/install/etc/services -nt /etc/services ]
filename1 -ot filename2如果 filename1 比 filename2 旧,则为真[ /boot/bzImage -ot arch/i386/boot/bzImage ]
字符串比较运算符 (请注意引号的使用,这是防止空格扰乱代码的好方法)
-z string如果 string 长度为零,则为真[ -z “$myvar” ]
-n string如果 string 长度非零,则为真[ -n “$myvar” ]
string1 = string2如果 string1 与 string2 相同,则为真[ “$myvar” = “one two three” ]
string1 != string2如果 string1 与 string2 不同,则为真[ “$myvar” != “one two three” ]
算术比较运算符
num1 -eq num2等于[ 3 -eq $mynum ]
num1 -ne num2不等于[ 3 -ne $mynum ]
num1 -lt num2小于[ 3 -lt $mynum ]
num1 -le num2小于或等于[ 3 -le $mynum ]
num1 -gt num2大于[ 3 -gt $mynum ]
num1 -ge num2大于或等于[ 3 -ge $mynum ]
#!/bin/bash

touch hello.txt
# 变量类型默认都是字符串类型,无法直接进行数值运算
echo "脚本主题: data本身就是复数" >> hello.txt

echo "========================= 特殊变量 $n $# $* $@ ========================="
echo "$HOME"
echo "$SHELL"
echo "$USER"
# $1 获取第一个参数,$2 获取第二个参数
echo "第一个爱妃是 $1, 可谓是倾国倾城"
# $# 获取入参个数
echo "此次入宫了 $# 个妃子"
# $* 代表所有参数,看作整体
echo "妃子名单*: $*"
# $@ 代表所有参数,区分对待
# shellcheck disable=SC2145
echo "妃子名单@: $@"
# $? 上一次命令的执行状态。0: 正确执行; 非0 : 执行发生错误(具体是哪个数,由命令自己决定)
echo " 上一次命令执行状态: $? "

echo "========================= 定义变量(随用随注销) ========================="
echo "A=1, 等号两边不能有空格"
echo "变量名可以由字母、数字和下划线组成,但是不能以数字开头"
echo "变量默认都是以字符串类型,无法直接进行数值运算"
echo "变量的值如果有空格,需要使用双引号或单引号括起来"
Z=1
echo "$A的值是: $Z"

echo "========================= 运算符 ========================="
echo "一共有三种方式,推荐使用$((运算符形式))"
echo "  1. $((8 + 8 * 8))"
# shellcheck disable=SC2007
echo "  2. $[8 + 8 * 8]"
# expr
echo "  3. expr 8 + 8 * 8"
echo "注意: 和声明变量不同,expr运算符间要有空格, 乘号还要转义 /*, 而且还不能运算两个以上的数字"

echo "========================= if条件判断 ========================="
echo "基本语法 [ condition ] (注意 condition 前后要有空格)"
echo "注意: condition可以是字符串: 条件非空即为true, [ wyf ] 返回true, [] 返回false"
echo "      也可以是条件表达式"
echo "注意: 在命令行中可以查询$?, 为0,代表是true, 但是在sh脚本中不管是执行了true和false分支,都是0"

echo "========================= (1) 字符串比较 ========================="
echo "= 字符串比较"
# shellcheck disable=SC2034
str="hello"
if [ "$str" ]; then
  echo "true: 字符串{$str}不为空"
else
  echo "false: 字符串{$str}为空"
fi

echo "========================= (2) 两个整数之间的比较 ==================="
echo "-lt 小于(less than)              -le 小于等于(less equal)"
echo "-eq 等于(equal)                  -ne 不等于(not equal) "
echo "-gt 大于(greater than)           -ge 大于等于(greater equal)"
# shellcheck disable=SC2050
if [ 23 -ge 22 ]; then
  echo "true: 23 >= 22"
else
  echo "false: 23 < 22"
fi

echo "========================= (3) 按照文件权限进行判断 ==================="
echo "-r 有读的权限(read)"
echo "-w 有写的权限(write)"
echo "-x 有执行的权限(execute)"

echo "========================= (4) 按照文件类型进行判断 ==================="
echo "-e 文件存在(exist)"
echo "-f 文件存在并且是一个常规的文件(file)"
echo "-d 文件存在并且是一个目录(directory)"

if [ -d hello.sh ]; then
  echo "true: hello.sh 是directory"
else
  echo "false: hello.sh 不是directory"
fi

echo "========================= 流程控制(重点) ==================="

echo "========================= (1) if判断 ==================="
echo "基本语法: if 后要有空格和fi闭环"
echo "if [ condition ]; then"
echo "   true分支 "
echo "fi"

echo "======  elif 和 else ======"
echo "
      if [ condition ]; then
          commands;
      elif [ condition ]; then
          commands;
      else
         commands;
      fi"

echo "========================== (2) case语句 ========================"

# shellcheck disable=SC2162
# read -p "please input a number to case statement:" num #打印信息提示用户输入,输入信息赋值给num变量
num=3
case "$num" in
1)
    echo "The num you input is 1"
    ;;
[2-5])
    echo "The num you input is 2-5"
    ;;
[6-9])
    echo "The num you input is 6-9"
    ;;
*)
    echo "please input number[1-9] int"
esac

echo "========================== (3) for循环 ========================"
sum=0
for ((i = 1; i <= 100; i++))
do
  sum=$((sum + i))
done
echo "1~100的累加和: $sum"

echo "遍历输入参数: "
for p in "$@"
do
  echo "爱妃: $p"
done

sum2=0
k=1
while [ $k -le 50 ]
do
  sum2=$((sum2 + k))
  k=$((k + 1))
done
echo "1~50的累加和: $sum2"

#echo "========================== (3) read读取控制台输入 ========================"
#read -r -p "请输入你喜欢的演员, -r可以正常读取反斜杠: " girlName
#echo "$girlName 是你的女朋友"
#read -r -t 3 -p "请在三秒内输入另一个女明星: " other
#
#if [ "$other" ]; then
#  echo "$other 也是你的女朋友"
#else
#  echo "我就知道你很专一"
#fi

echo "========================== 系统函数 ========================"
echo "========================== (1) basename ========================"
# 基本语法: basename NAME [SUFFIX]
# 删除前导目录, 打印名称
# 如果指定,还可以删除后缀
# $(cmd) 指定输出
fileNameWithSuffix=$(basename include/stdio.h)
echo "$fileNameWithSuffix"  # stdio.h
fileName=$(basename include/stdio.h .h)
echo "$fileName" # stdio

echo "========================== (2) dirname ========================"
# Usage: dirname [OPTION] NAME...
# 输出 Name的所在最后一个斜杠之前的内容(NAME所在目录部分,且删除最后一个斜杠)
# 如果Name不包含斜杆,则输入 '.' ,代表当前目录
dir1=$(dirname /usr/bin/)
dir2=$(dirname /AuI18N/2052/usr/bin/a.txt)
dir3=$(dirname stdio.h)
echo "dir1: $dir1"
echo "dir2: $dir2"
echo "dir3: $dir3"


echo "========================== 自定义函数 ========================"
echo "标准写法: "
function name() {

    echo "== name() =="
    return 0
    # [return value], value取值范围是0-255
    # 表示函数的返回值,可写可不写
}
name
# 函数返回值只能通过$?系统变量获得,可以显示加。如果不加,讲以最后一条命令运行结果做回返回值
echo "func result : $?"

function twoSum() {
  s=0
  s=$(($1+$2))
  echo "twoSum result : $s"
}

# 调用 Shell 函数时可以给它传递参数,也可以不传递
# 如果不传递参数,直接给出函数名字即可:name
# 如果传递参数,那么多个参数之间以空格分隔:name param1 param2 param3
twoSum 6 6

echo "========================== sed ========================"
echo "Usage: sed [选项] 'command' fileName"
echo " -n, --quiet, --silent 只打印匹配行"
echo "也可以用数字开头,代表对指定行操作"
echo " 常用命令: s替换 d删除 p打印 q退出 i行前 a行后"
echo "-e 和 ; 都可以实现多条cmd"
#sed "s/u/UC/g" abc.txt  # u ==> UC, g代表整行都替换
#echo "=="
#sed "s/u/UC/" abc.txt
# sed "s/a//g" abc.txt   # 把所有的a都删掉了
# sed "s/#.*//g" abc.txt   # -i 会对源文件进行修改
# sed "s/\s*#.*//g" abc.txt   # \s*代表0或多个空格
# sed "s/\s*#.*//g; /^$/d" abc.txt # /^$/d删除空行
# sed "/a/q" abc.txt # 遇到第一个a就退出
# sed -n "/a/p" abc.txt # 打印匹配到a的行
# sed "3q" abc.txt # 打印到第三行就退出
# sed "3p" abc.txt # 到第三行就打印
#sed "/^wo/a cao" abc.txt # a 在匹配行后加一行
#sed "/^wo/i ai~" abc.txt  # i 在匹配行前加一行
#cmd1="2a mei nv22"
#sed "$cmd1" abc.txt
#sed "3s/a/TT/g" abc.txt # 只给第三行的a换成了TT
#sed "/lai/d" abc.txt
#sed "4d;s/wo/ni/g" abc.txt  # ; 号实现多条命令,删除第四行,且替换字符
#sed -e "4d" -e "s/wo/ni/g" abc.txt  # ; 号实现多条命令,删除第四行,且替换字符

echo "============================== awk ============================="
echo "常用函数:
tolower():字符转为小写。
length():返回字符串长度。
substr():返回子字符串。
rand():随机数。
"
echo "一个强大的文本分析工具,把文件逐行读入,以空格为默认分隔符将每行切片,切开的部分再进行分析处理"
echo "awk [选项参数] 'pattern1{action1} pattern2{action2}...'" fileName
echo "pattern : 表示awk在数据中查找的内容"
echo "action  : 在找到所匹配内容时所执行的一系列命令"
echo "常用选项参数 -F 指定分隔符"
echo "常用选项参数 -v 定义变量, awk的变量是与世隔绝的,里面取不到外面的,外面的也取不到里面的"
awk -F ":" '/^root/ {print $7}' demo.txt
awk -F ":" '/^root/ {print $1 ", " $7}' demo.txt
awk -F ":" '/^root/ {printf("第一列内容是%s, 第7列内容是: %s  ! \n", $1, $7)}' demo.txt
# BEGIN 和 END
awk -F ":" 'BEGIN{print "=== lu ben wei niu bi~ ==="}
            /^root/ {printf("第一列内容是%s, 第7列内容是: %s  ! \n", $1, $7)}
            END{print "=== bi xv di ! ==="}' demo.txt

awk -F ":" 'BEGIN{print "=== lu ben wei niu bi~ ==="}
            {printf("第一列内容是%s, 第7列内容是: %s  ! \n", $1, $7)}
            END{print "=== bi xv di ! ==="}' demo.txt
awk -F ":" -v i=1 '{print $3 + i}' demo.txt # 定义变量,给第三列加1
# awk 内置变量
awk -F ":" '{printf("文件名: %s, 行号: %s, 该行一共 %s 列, 第一列: %s \n", FILENAME, NR, NF, $1)}' demo.txt
# 打印空行的行号
awk '/^$/ {printf("空行行号: %s \n", NR)}' demo.txt

echo "================== wc ================="
echo "Usage: wc [OPTION]... [FILE]..."
echo "wc 会把文件名称打印出来,可以用awk去除"
total_lines=$(wc -l demo.txt | awk -F " " '{print $1}')
total_bytes=$(wc -c demo.txt | awk -F " " '{print $1}')
echo "demo.txt ==>> 总行数: $total_lines, 总字节数: $total_bytes"

echo "================ sort =================="
echo "Usage: sort [OPTION]... [FILE]..."
echo "
-n, 按照数值排序
-r, 反序
-b, 忽略前导空格
-t, 指定排序时所用的栏位分隔字符
-k, 指定排序的列
"
echo "按照日排序(第三列)"
sort -t "-" -k 3 -n sort.txt
sort -t "-" -k 3 -n -r sort.txt

4. 实操

1. 基础

# 利用for循环建立user1~~user5总共五个账号,并且密码均为redhat
# 提示man passwd命令中以标准输入方式给予账号密码。
vim user.sh
#!/bin/bash
for i in {1..5}
do
        useradd user$i
        echo redhat | passwd --stdin user$i
done
sh user.sh

# 访问网页
#!/bin/bash
url=http://127.0.0.1
code=$(curl -s -I -m 2 -o /dev/null $url -w %{http_code})
if [ "$code" -eq 200 ]; then
        echo "page is ok"
else
        echo "404"
fi

# 输入输出
#!/bin/bash

echo "输入用户名: "  
#读取从键盘的输入  
read username
id $username &> /dev/null
if [ $? -eq 0 ] ; then
        echo "user exists"
else
        useradd ${username}
fi

# case
#!/bin/bash

case $1 in
        a|A)
                echo a;;
        b|B)
                echo b;;
        *)
                echo none;;
esac

# 测试ping
#!/bin/bash

for i in {1..20}
do
        ping -c 5192.168.70.$i &> /dev/null
        if [ $? -eq 0 ];then
                echo "192.168.70.$i is up"
        else
                echo "192.168.70.$i is down"
        fi
done


# 九九乘法表
#!/bin/bash

for((i=1;i<=9;i++))
do
        for((j=1;j<=i;j++))
        do
                echo -n "${j}x${i}=$[i*j] "
        done
        echo 
done


# 控制台给函数传参
#!/bin/bash
#test()
{
        echo "$1 and $2"
}
#test 1 2

2. 常见问题

#!/bin/bash
# 计算demo.txt第三列总和
third_sum=$(awk -F ":" -v sum=0 '{sum+=$3} END{print sum}' demo.txt)
echo "第三列的和是: $third_sum"
unset third_sum

# 判断一个文件是否存在
if [ -f sort.txt ]; then
    echo "sort.txt 文件存在"
else
    echo "sort.txt 文件不存在"
fi

# 在当前目录查找包含字符 shen 的文件名称
# uniq 去重
# uniq 在后面显示行重复次数
grep -r shen | awk -F ":" '{print $1}' | uniq -c

# 输出 0 ~ 500 之间7的倍数
#for ((i = 0; i <= 500; i++))
#do
#  if [ $((i % 7)) -eq 0 ]; then
#    echo "$i"
#  fi
#done
#unset "$i"
#exit 0

#for i in {0..500}
#do
#  if [ $((i % 7)) -eq 0 ]; then
#    echo "$i"
#  fi
#done
#unset "$i"
#exit 0

# 生成 0 ~ 500的数字, 步长为7
# seq 0 7 500

# 写一个 bash脚本以统计一个文本文件 nowcoder.txt中字母数小于8的单词。
#
#
#
#示例:
#假设 nowcoder.txt 内容如下:
#how they are implemented and applied in computer
#
#你的脚本应当输出:
#how
#they
#are
#and
#applied
#in
awk '{
  for (i=1; i <= NF; i++) {
      if (length($i) < 8){
          print $i
      }
  }
}' n.txt

# 打印出空行,或者只有空格和制表符的行
awk 'NF == 0 {print NR}' n.txt

# 统计每个单词出现的次数
echo "===!!@@====="
awk '{
    for (i=1; i <= NF; i++) {
        print $i
    }
}' now.txt | sort | uniq -c | awk '{printf("%s %s\n", $2, $1)}' | sort -k 2 -n > res.txt

echo "====="
awk '{
 for (i = 1; i <= NF; ++i)
     mp[$i]++;
}
END {
 for (k in mp)
     printf("%s %d\n", k, mp[k]);
}' now.txt | sort -k 1 -n


awk '{print $2}' nowcoder.txt |
sort -n |
uniq -c |
awk '$1 > 1 {print $0}'


echo "
假设每行列数相同,并且每个字段由空格分隔

示例:
假设 nowcoder.txt 内容如下:
job salary
c++ 13
java 14
php 12

你的脚本应当输出(以词频升序排列):
job c++ java php
salary 13 14 12
"
cols=$(sed "1q" nowcoder.txt | awk '{print NF}')
for ((i = 1; i <= cols; i++)); do
    awk -v k="$i" '{printf("%s ", $k)}' nowcoder.txt
    echo
done

echo "
写一个 bash脚本以统计一个文本文件 nowcoder.txt中每一行出现的1,2,3,4,5数字个数
并且要计算一下整个文档中一共出现了几个1,2,3,4,5数字数字总数。

示例:
假设 nowcoder.txt 内容如下:
a12b8
10ccc
2521abc
9asf
你的脚本应当输出:
line1 number: 2
line2 number: 1
line3 number: 4
line4 number: 0
sum is 7
"
awk -F "" '
BEGIN{sum = 0}
{
    count = 0;
    for (i = 0; i < NF; i++) {
        if ($i == 1 || $i == 2 || $i == 3 || $i == 4 || $i == 5) {
            count++;
        }
    }
    sum += count;
    printf("line%s number:%d\n", NR, count);
}
END{printf("sum is %d\n", sum)}
' nowcoder.txt


echo "
写一个bash脚本以实现一个需求,求输入的一个的数组的平均值

第1行为输入的数组长度N
第2~N行为数组的元素,如以下为:
数组长度为4,数组元素为1 2 9 8
示例:
4
1
2
9
8

那么平均值为:5.000(保留小数点后面3位)
你的脚本获取以上输入应当输出:
5.000
"
awk 'BEGIN{sum = 0; len = 0}
{
    if (NR == 1) {
        len = $1;
    } else {
        sum += $1;
    }
}
END{printf("%0.3f\n", sum / len)}'


# xargs
应用场景1: 批量更改当前目录下的文件名
ls ./ | xargs -I GG echo "mv GG prefix_GG"
ls ./ | xargs -I GG mv GG prefix_GG

也可以这样批量更改该文件下的文件名
for i in ./*; do
  name=$(basename "$i")
  echo "mv $name sup_$name"
done

3. 获取硬件信息

#!/bin/bash

#CPU型号
cpu_model=`cat /proc/cpuinfo | grep "model name" | awk -F ':' '{print $2}' | sort | uniq`
echo "$cpu_model"

#CPU架构
cpu_architecture=`uname -m`
echo "$cpu_architecture"

#物理CPU个数
cpu_phy_num=`cat /proc/cpuinfo | grep "physical id" | sort | uniq | wc -l`
echo "$cpu_phy_num"

#CPU核数
cpu_core_num=`cat /proc/cpuinfo | grep "cpu cores" | uniq | awk -F ': ' '{print $2}'`
echo "$cpu_core_num"

#逻辑CPU个数
cpu_proc_num=`cat /proc/cpuinfo | grep "processor" | uniq | wc -l`
echo "$cpu_proc_num"

##CPU主频
cpu_main_freq=`cat /proc/cpuinfo | grep "model name" | awk -F '@' 'NR==1 {print $2}'`
echo "$cpu_main_freq"

##L1d缓存
cpu_l1d_cache=`lscpu | grep -i 'L1d 缓存\|L1d cache' | awk -F ':|:' '{print $2}'`
echo "$cpu_l1d_cache"

##L1i缓存
cpu_l1i_cache=`lscpu | grep -i 'L1i 缓存\|L1i cache' | awk -F ':|:' '{print $2}'`
echo "$cpu_l1i_cache"

##L2缓存
cpu_l2_cache=`lscpu | grep -i 'L2 缓存\|L2 cache' | awk -F ':|:' '{print $2}'`
echo "$cpu_l2_cache"

##L3缓存
cpu_l3_cache=`lscpu | grep -i 'L3 缓存\|L3 cache' | awk -F ':|:' '{print $2}'`
echo "$cpu_l3_cache"

#操作系统名称
system_name=`head -n 1 /etc/issue | awk '{print $1,$2}'`
echo "$system_name"

#操作系统位数
systembit=`getconf LONG_BIT`
echo "$systembit"

#操作系统内核版本
system_kernel=`uname -r`
echo "$system_kernel"


#物理内存容量
meminfo=`sudo dmidecode | grep "^[[:space:]]*Size.*MB$" | uniq -c | sed 's/ \t*Size: /\*/g' | sed 's/^ *//g'`
echo "$meminfo"

#单位转换函数
function convert_unit()
{
	result=$1
	if [ $result -ge  1048576 ]
	then
		value=1048576 #1024*1024	
		result_gb=$(awk 'BEGIN{printf"%.2f\n",'$result' / '$value'}') #将KB转换成GB,并保留2位小数
		echo $result_gb"GB"
	elif [ $result -ge  1024 ]
	then
		value=1024 	
		result_mb=$(awk 'BEGIN{printf"%.2f\n",'$result' / '$value'}') #将KB转换成MB,并保留2位小数
		echo $result_mb"MB"
	else
		echo $result"KB"
	fi
}

#单位:KB
MemTotal=$(cat /proc/meminfo | awk '/^MemTotal/{print $2}') #内存总量
MemFree=$(cat /proc/meminfo | awk '/^MemFree/{print $2}')   #空闲内存
MemUsed=$(expr $MemTotal - $MemFree)  #已用内存

##计算内存占用率
Mem_Rate=$(awk 'BEGIN{printf"%.2f\n",'$MemUsed' / '$MemTotal' *100}') #保留小数点后2位

MemShared=$(cat /proc/meminfo | awk '/^Shmem/{print $2}') #共享内存
Buffers=$(cat /proc/meminfo | awk '/^Buffers/{print $2}') #文件缓冲区
Cached=$(cat /proc/meminfo | awk '/^Cached/{print $2}') #用于高速缓冲存储器

SwapTotal=$(cat /proc/meminfo | awk '/^SwapTotal/{print $2}') #交换区总量
SwapFree=$(cat /proc/meminfo | awk '/^SwapFree/{print $2}') #空闲交换区
Mapped=$(cat /proc/meminfo | awk '/^Mapped/{print $2}') #已映射

##虚拟内存
VmallocUsed=$(cat /proc/meminfo | awk '/^VmallocUsed/{print $2}') #已使用的虚拟内存

echo "$(convert_unit $MemTotal)"
echo "$(convert_unit $MemFree)"
echo "$(convert_unit $MemUsed)"
echo "$Mem_Rate%"
echo "$(convert_unit $MemShared)"
echo "$(convert_unit $Buffers)"
echo "$(convert_unit $Cached)"
echo "$(convert_unit $SwapTotal)"
echo "$(convert_unit $SwapFree)"
echo "$(convert_unit $Mapped)"
echo "$(convert_unit $VmallocUsed)"


#磁盘型号
disk_model=`fdisk -l | grep "Disk model" | awk -F : '{print $2}' | sed 's/^ //'`
echo "$disk_model"

usesum=0
totalsum=0
disknum=`df -hlT |wc -l `
for((n=2;n<=$disknum;n++))
do
	use=$(df -k |awk NR==$n'{print int($3)}')
	pertotal=$(df -k |awk NR==$n'{print int($2)}')
	usesum=$[$usesum+$use]		#计算已使用的总量
	totalsum=$[$totalsum+$pertotal]	#计算总量
done
freesum=$[$totalsum-$usesum]
diskutil=$(awk 'BEGIN{printf"%.2f\n",'$usesum' / '$totalsum'*100}')
freeutil=$(awk 'BEGIN{printf"%.2f\n",100 - '$diskutil'}')

#磁盘总量
if [ $totalsum -ge 0 -a $totalsum -lt 1024 ];then
echo "$totalsum K"

elif [ $totalsum -gt 1024 -a  $totalsum -lt 1048576 ];then
	totalsum=$(awk 'BEGIN{printf"%.2f\n",'$totalsum' / 1024}')
echo "$totalsum M"

elif [ $totalsum -gt 1048576 ];then
	totalsum=$(awk 'BEGIN{printf"%.2f\n",'$totalsum' / 1048576}')
echo "$totalsum G"

fi

#磁盘已使用总量
if [ $usesum -ge 0 -a $usesum -lt 1024 ];then
echo "$usesum K"

elif [ $usesum -gt 1024 -a  $usesum -lt 1048576 ];then
	usesum=$(awk 'BEGIN{printf"%.2f\n",'$usesum' / 1024}')
echo "$usesum M"

elif [ $usesum -gt 1048576 ];then
	usesum=$(awk 'BEGIN{printf"%.2f\n",'$usesum' / 1048576}')
echo "$usesum G"

fi

#磁盘未使用总量
if [ $freesum -ge 0 -a $freesum -lt 1024 ];then
echo "$freesum K"

elif [ $freesum -gt 1024 -a  $freesum -lt 1048576 ];then
	freesum=$(awk 'BEGIN{printf"%.2f\n",'$freesum' / 1024}')
echo "$freesum M"

elif [ $freesum -gt 1048576 ];then
	freesum=$(awk 'BEGIN{printf"%.2f\n",'$freesum' / 1048576}')
echo "$freesum G"
fi

#磁盘占用率
echo "$diskutil%"

#磁盘空闲率
echo "$freeutil%"


#显卡型号
graphicscardmodel=`lspci | grep -i 'VGA' | sed '2d' | cut -f3 -d ":" | sed 's/([^>]*)//g'`
echo "$graphicscardmodel"

#显卡生产商
graphicscardmanufacturer=`lspci | grep -i 'VGA'| sed '2d'| awk '{ print $5,$6 }'`
echo "$graphicscardmanufacturer"



#主板厂商
boardmanufacturer=`sudo dmidecode | grep -A 10 "Base Board Information" |grep "Manufacturer" | awk -F ':' '{print $2}'`
echo "$boardmanufacturer"

#主板名称
boardname=`sudo dmidecode | grep -A 10 "Base Board Information" |grep "Product Name" | awk -F ':' '{print $2}'`
echo "$boardname"

#BIOS厂商
biosvendor=`sudo dmidecode | grep -A 28 "BIOS Information" | grep 'Vendor' | awk -F ':' '{print $2}'`
echo "$biosvendor"

#BIOS版本
biosversion=`sudo dmidecode | grep -A 28 "BIOS Information" | grep 'Version' | awk -F ':' '{print $2}'`
echo "$biosversion"

#BIOS发行日期
biosrelease=`sudo dmidecode | grep -A 28 "BIOS Information" | grep 'Release' | awk -F ':' '{print $2}'`
echo "$biosrelease"

#网卡信息
netcardinfo=`lspci | grep -i eth | head -n +1 | awk -F : '{print $3}' | sed 's/^ //'`
echo "$netcardinfo"

4. 获取硬件使用率

#!/bin/bash
# 获取要监控的本地服务器IP地址
IP=`ifconfig | grep inet | grep -vE 'inet6|127.0.0.1' | awk '{print $2}'`
echo "IP地址:"$IP
 
# 获取cpu总核数
cpu_num=`grep -c "model name" /proc/cpuinfo`
echo "cpu总核数:"$cpu_num
 
# 1、获取CPU利用率
################################################
#us 用户空间占用CPU百分比
#sy 内核空间占用CPU百分比
#ni 用户进程空间内改变过优先级的进程占用CPU百分比
#id 空闲CPU百分比
#wa 等待输入输出的CPU时间百分比
#hi 硬件中断
#si 软件中断
#################################################
# 获取用户空间占用CPU百分比
cpu_user=`top -b -n 1 | grep Cpu | awk '{print $2}' | cut -f 1 -d "%"`
echo "用户空间占用CPU百分比:"$cpu_user
 
# 获取内核空间占用CPU百分比
cpu_system=`top -b -n 1 | grep Cpu | awk '{print $4}' | cut -f 1 -d "%"`
echo "内核空间占用CPU百分比:"$cpu_system
 
# 获取空闲CPU百分比
cpu_idle=`top -b -n 1 | grep Cpu | awk '{print $8}' | cut -f 1 -d "%"`
echo "空闲CPU百分比:"$cpu_idle
 
# 获取等待输入输出占CPU百分比
cpu_iowait=`top -b -n 1 | grep Cpu | awk '{print $10}' | cut -f 1 -d "%"`
echo "等待输入输出占CPU百分比:"$cpu_iowait
 
#2、获取CPU上下文切换和中断次数
# 获取CPU中断次数
cpu_interrupt=`vmstat -n 1 1 | sed -n 3p | awk '{print $11}'`
echo "CPU中断次数:"$cpu_interrupt
 
# 获取CPU上下文切换次数
cpu_context_switch=`vmstat -n 1 1 | sed -n 3p | awk '{print $12}'`
echo "CPU上下文切换次数:"$cpu_context_switch
 
#3、获取CPU负载信息
# 获取CPU15分钟前到现在的负载平均值
cpu_load_15min=`uptime | awk '{print $11}' | cut -f 1 -d ','`
echo "CPU 15分钟前到现在的负载平均值:"$cpu_load_15min
 
# 获取CPU5分钟前到现在的负载平均值
cpu_load_5min=`uptime | awk '{print $10}' | cut -f 1 -d ','`
echo "CPU 5分钟前到现在的负载平均值:"$cpu_load_5min
 
# 获取CPU1分钟前到现在的负载平均值
cpu_load_1min=`uptime | awk '{print $9}' | cut -f 1 -d ','`
echo "CPU 1分钟前到现在的负载平均值:"$cpu_load_1min
 
# 获取任务队列(就绪状态等待的进程数)
cpu_task_length=`vmstat -n 1 1 | sed -n 3p | awk '{print $1}'`
echo "CPU任务队列长度:"$cpu_task_length
 
#4、获取内存信息
# 获取物理内存总量
mem_total=`free | grep Mem | awk '{print $2}'`
echo "物理内存总量:"$mem_total
 
# 获取操作系统已使用内存总量
mem_sys_used=`free | grep Mem | awk '{print $3}'`
echo "已使用内存总量(操作系统):"$mem_sys_used
 
# 获取操作系统未使用内存总量
mem_sys_free=`free | grep Mem | awk '{print $4}'`
echo "剩余内存总量(操作系统):"$mem_sys_free
 
# 获取应用程序已使用的内存总量
mem_user_used=`free | sed -n 3p | awk '{print $3}'`
echo "已使用内存总量(应用程序):"$mem_user_used
 
# 获取应用程序未使用内存总量
mem_user_free=`free | sed -n 3p | awk '{print $4}'`
echo "剩余内存总量(应用程序):"$mem_user_free
 
 
# 获取交换分区总大小
mem_swap_total=`free | grep Swap | awk '{print $2}'`
echo "交换分区总大小:"$mem_swap_total
 
# 获取已使用交换分区大小
mem_swap_used=`free | grep Swap | awk '{print $3}'`
echo "已使用交换分区大小:"$mem_swap_used
 
# 获取剩余交换分区大小
mem_swap_free=`free | grep Swap | awk '{print $4}'`
echo "剩余交换分区大小:"$mem_swap_free
 

#5、获取磁盘I/O统计信息
echo "指定设备(/dev/sda)的统计信息"
# 每秒向设备发起的读请求次数
disk_sda_rs=`iostat -kx | grep sda| awk '{print $4}'`
echo "每秒向设备发起的读请求次数:"$disk_sda_rs
 
# 每秒向设备发起的写请求次数
disk_sda_ws=`iostat -kx | grep sda| awk '{print $5}'`
echo "每秒向设备发起的写请求次数:"$disk_sda_ws
 
# 向设备发起的I/O请求队列长度平均值
disk_sda_avgqu_sz=`iostat -kx | grep sda| awk '{print $9}'`
echo "向设备发起的I/O请求队列长度平均值"$disk_sda_avgqu_sz
 
# 每次向设备发起的I/O请求平均时间
disk_sda_await=`iostat -kx | grep sda| awk '{print $10}'`
echo "每次向设备发起的I/O请求平均时间:"$disk_sda_await
 
# 向设备发起的I/O服务时间均值
disk_sda_svctm=`iostat -kx | grep sda| awk '{print $11}'`
echo "向设备发起的I/O服务时间均值:"$disk_sda_svctm
 
# 向设备发起I/O请求的CPU时间百分占比
disk_sda_util=`iostat -kx | grep sda| awk '{print $12}'`
echo "向设备发起I/O请求的CPU时间百分占比:"$disk_sda_util

5. 密码比对

#!/bin/bash
COUNT=0
PASSWD=12345

while [ $COUNT -lt 3 ]
do
        read -p "input passwd:" password
        if [ "$password" = "$PASSWD" ];then
                echo "right"
                exit
        else
                echo "wrong"
                let COUNT++
        fi
done
echo "too many wrong!"

6. 磁盘监控

df -hl 查看磁盘剩余空间
 
df -h 查看每个根路径的分区大小
 
du -sh [目录名] 返回该目录的大小
 
du -sm [文件夹] 返回该文件夹总M数
 
du -h [目录名] 查看指定文件夹下的所有文件大小(包含子文件夹)

查看硬盘的分区 #sudo fdisk -l

查看IDE硬盘信息 #sudo hdparm -i /dev/hda

查看STAT硬盘信息 #sudo hdparm -I /dev/sda 或 #sudo apt-get install blktool #sudo blktool /dev/sda id

查看硬盘剩余空间 #df -h #df -H

查看目录占用空间 #du -hs 目录名

使用命令查看指定目录空间情况,例如查看opt目录

du -h --max-depth=1 /opt


#!/bin/bash

echo "磁盘当前实时读写速率:"
# 每秒向设备发起的读请求次数
disk_sda_rs=`iostat -kx | grep sda| awk '{print $4}'`
echo "每秒向设备发起的读请求次数:"$disk_sda_rs

# 每秒向设备发起的写请求次数
disk_sda_ws=`iostat -kx | grep sda| awk '{print $5}'`
echo "每秒向设备发起的写请求次数:"$disk_sda_ws



max_filesys_use=`df -h | sort -nr -k5 | head -n1`
echo "最大文件系统使用率:"
echo $max_filesys_use

echo "磁盘使用情况:"
df -h | grep "/dev/sda"
disk_use=`df -h | grep "/dev/sda" | awk '{print $5}' | cut -d '%' -f 1`

echo "磁盘使用率: $disk_use%"

echo "inode监控:"
df -i

变量

1. 分类

- 环境变量:系统设置的,通过使用env显示所有变量
/etc/environment​​文件​​ 
设置整个系统的环境信息,​​在系统启动时被读取​​,与登录用户无关。​
/etc/profile​​文件​​
为系统的每个用户设置环境信息,​​任何用户每次登录时执行该文件​。

- 本地变量: 变量名不能是数字,而且区分大小写。子进程不能读取父进程定义的变量。
 可以通过使用export命令,把本地变量,转成为环境变量

- 位置变量: 数字开头的变量$1 
$$ 打印进程号pid
$? 保存上一次命令的退出值,0-255,0表示没有错误,非0表示有错误
$@($*)   打印所有参数
$# 打印参数个数
$! 打印后台进程的pid

- 只读变量readonly

2. 数学计算

(( ))	 //用于整数运算,效率很高,推荐使用。
let	   //用于整数运算,和 (()) 类似。
$[]	   //用于整数运算,不如 (()) 灵活。
expr	 //可用于整数运算,也可以处理字符串。比较麻烦,需要注意各种细节,不推荐使用。
bc	   //Linux下的一个计算器程序,可以处理整数和小数。Shell 本身只支持整数运算,想计算小数就得使用 bc 这个外部的计算器。
declare -i	//将变量定义为整数,然后再进行数学运算时就不会被当做字符串了。功能有限,仅支持最基本的数学运算(加减乘除和取余),不支持逻辑运算、自增自减等,所以在实际开发中很少使用。

ftp

1. 安装、启动

# 查看是否已经安装了vsftpd
# 如果没有返回任何结果,表示没有安装;如果返回文件包名,这表示已经安装了该服务;
[root@centos7 ~]# rpm -qa|grep vsftpd
vsftpd-3.0.2-29.el7_9.x86_64               # 代表已安装
[root@centos7 ~]# vsftpd -version
vsftpd: version 3.0.2                      # 代表已安装
[root@centos7 ~]# rpm -e vsftpd            # 卸载vsftpd
# 再次检查
[root@centos7 ~]# rpm -qa|grep vsftpd
[root@centos7 ~]# vsftpd -version
bash: vsftpd: 未找到命令...

# 安装ftp服务器
# 如果已经安装,再次执行yum就会把软件包升级到最新版本
[root@centos7 ~]# yum install -y vsftpd

# 安装ftp客户端
[root@centos7 ~]# yum install -y ftp lftp

# 设置为开机自动启动服务
[root@centos7 ~]# systemctl enable vsftpd.service 

# 启动vsftpd服务
# ftp服务器的服务名是vsftpd,相关的操作如下:
[root@centos7 ~]# systemctl start  vsftpd.service      # 启动服务
systemctl stop  vsftpd.service        # 停止服务
systemctl restart vsftpd.service      # 重启服务
systemctl status vsftpd.service       # 查看服务状态
systemctl enable vsftpd.service       # 设置开机自启动vsftpd服务
systemctl disable vsftpd.service      # 禁用开机自启动vsftpd服务

# 连接ftp
ftp 192.168.202.132

2. ftp配置文件

# 核心配置文件
vim /etc/vsftpd/vsftpd.conf

# 黑名单文件,此文件中的用户不允许访问FTP服务器
/etc/vsftpd/ftpusers

# 白名单文件,此文件中的用户允许访问FTP服务器
/etc/vsftpd/user_list


#----匿名用户设置----
anonymous_enable=NO #禁止匿名用户登录
# 开放上传权限
Anon_upload_enable=yes
# 可创建目录的同时可以在此目录中上传文件
Anon_mkdir_write_enable=yes   

#----本地用户设置----
local_enable=YES #允许本地用户登录ftp服务器
write_enable=YES #允许用户想服务器执行写入操作
local_umask=022 #设置服务器上本地用户创建文件的权限掩码

#----欢迎语设置----
dirmessage_enable=YES #启用目录提示消息

#----日志文件设置----
xferlog_enable=YES #启用日志文件功能,记录于/var/log/xferlog
xferlog_std_format=YES #启用标准的日志格式

#----FTP工作方式与端口设置----
connect_from_port_20=YES #主动模式下,是否启用默认的20端口进行数据传输

#----与连接相关的设置----
listen=NO            #vsftpd不是以独立的服务运行,要受到xinetd服务的管控,功能上会受到限制
listen_ipv6=YES

#----控制用户是否允许切换到上级目录----
chroot_list_enable=YES         #开启限制用户在主目录的功能
chroot_list_file=/etc/vsftpd/chroot_list #在chroot_list文件中加入你要限制的用户名,一行一个用户

#----虚拟用户设置----
pam_service_name=vsftpd      #虚拟用户使用PAM认证方式

#----控制用户访问(通过vsftpd.user_list和ftpusers文件来实现)----
userlist_enable=YES #是否启用userlist_file文件
userlist_file=/etc/vsftpd/user_list #允许user_list文件中加入的用户访问ftp服务器

#----控制主机访问----
tcp_wrappers=YES #vsftpd服务器检查/etc/hosts.allow和/etc/hosts.deny中的设置,来决定请求连接的主机,是否允许访问该FTP服务器

#----其它设置----
allow_writeable_chroot=YES #去除用户主目录的写权限

3. 用户管理

# ftpusers不受任何配制项的影响,它总是有效,它是一个黑名单
该文件存放的是一个禁止访问FTP的用户列表


# userlist_enable和userlist_deny
当且仅当userlist_enable=YES时:userlist_deny项的配置才有效,user_list文件才会被使用;当其为NO时,无论userlist_deny项为何值都是无效的,本地全体用户(除去ftpusers中的用户)都可以登入FTP
当userlist_enable=YES时,userlist_deny=YES时:user_list是一个黑名单,即:所有出现在名单中的用户都会被拒绝登入;
当userlist_enable=YES时,userlist_deny=NO时:user_list是一个白名单,即:只有出现在名单中的用户才会被准许登入(user_list之外的用户都被拒绝登入);另外需要特别提醒的是:使用白名单后,匿名用户将无法登入!除非显式在user_list中加入一行:anonymous



# 添加用户到 user_list,只有添加到 user_list 的用户才有权访问 ftp 服务器
vi /etc/vsftpd/user_list

# If userlist_deny=YES (default), never allow users in this file, and
# do not even prompt for a password.
# Note that the default vsftpd pam config also checks /etc/vsftpd/ftpusers
# for users that are denied.
edi
test


# 限制主目录
chroot_local_user #是否将所有用户限制在主目录,YES为启用 NO禁用.(该项默认值是NO,即在安装vsftpd后不做配置的话,ftp用户是可以向上切换到要目录之外的)

chroot_list_enable #是否启动限制用户的名单 YES为启用  NO禁用(包括注释掉也为禁用)

chroot_list_file=/etc/vsftpd/chroot_list #是否限制在主目录下的用户名单,至于是限制名单还是排除名单,这取决于chroot_local_user的值,我们可以这样记忆: chroot_local_user总是一个全局性的设定,其为YES时,全部用户被锁定于主目录,其为NO时,全部用户不被锁定于主目录。那么我们势必需要在全局设定下能做出一些“微调”,即,我们总是需要一种“例外机制",所以当chroot_list_enable=YES时,表示我们“需要例外”。而”例外“的含义总是有一个上下文的,即,当”全部用户被锁定于主目录“时(即chroot_local_user=YES),"例外"就是:不被锁定的用户是哪些;当"全部用户不被锁定于主目录"时(即chroot_local_user=NO),"例外"“就是:要被锁定的用户是哪些。这样解释和记忆两者之间的关系就很清晰了!

RAID

1. 配置raid0

yum install -y mdadm 安装mdadm
mdadm -C -v /dev/md0 -l 0 -n 2 /dev/sdb /dev/sdc 创建raid0
cat /proc/mdstat 查看raid
mdadm -Ds 查看raid详细信息

mdadm -Ds>/etc/mdadm.conf 生成配置文件

mkfs.xfs /dev/md0 创建文件系统
# 在格式化时,可以指定-E选项下的stride参数指定条带是块大小的多少倍,有在一定程度上提高软RAID性能,如块默认大小为4k,而条带大小默认为64k,则stride为16,这样就避免了RAID每次存取数据时都去计算条带大小,如:
mkfs.ext4  -E stride=16 -b 4096 /dev/md0


mkdir /raid0/
mount /dev/md0 /raid0/ 挂载

df -Th /raid0/

blkid /dev/md0 
echo "、dev/md0 /raid0 xfs defaults 0 0" > /etc/fstab 
mount -a //刷新一下
# 开机自动挂载

以下为删除raid0
umount /raid0/
mdadm -S /dev/md0 # 停止阵列
rm -rf /etc/mdadm.conf
rm -rf /raid0/
mdadm --zero-superblock /dev/sdb
mdadm --zero-superblock /dev/sdc
vi /etc/fstab 

2. 配置raid5

 mdadm -Cv /dev/md5 -l5 -n3 /dev/sdb /dev/sdc /dev/sdd --spare-devices=1 /dev/sde 
 # 创建raid5

 mdadm -D /dev/md5 查看硬盘信息
 mdadm /dev/md5 -f /dev/sdb1 热移除故障盘
 mkfs.xfs /dev/md5 格式化
 mount /dev/md5 /mnt/ 挂载

docker

1. 常用命令

# 运行centos镜像
docker run -it --name centos centos:last /bin/bash 

 
# 服务
# 查看Docker版本信息
docker version

# 查看docker简要信息
docker -v

# 启动Docker
systemctl start docker

# 关闭docker
systemctl stop docker

# 设置开机启动
systemctl daemon-reload # 重新加载配置文件
systemctl enable docker

# 重启docker服务
service docker restart

# 关闭docker服务
service docker stop


# 镜像
# 镜像仓库
Docker Hub 等镜像仓库上有大量的高质量的镜像可以用,可以从仓库获取镜像。

# 检索镜像
docker search 关键字

# 拉取镜像
docker pull [选项] [Docker Registry 地址[:端口号]/]仓库名[:标签]

# 镜像管理
# 列出镜像
docker image ls
docker images
复制
删除镜像
# 删除指定镜像
docker rmi <镜像Id>
复制
导出镜像
# 将镜像保存为归档文件
docker save

# 导入镜像
docker load

# Dockerfile构建镜像
Dockerfile 是一个文本格式的配 文件,用户可以使用 Dockerfile 来快速创建自定义的镜像。

Dockerfile 由一行行行命令语句组成,并且支持以#开头的注释行.

# Dockerfile常见指令

 FROM:指定基础镜像
 
 RUN:执行命令
 
 COPY:复制文件
 
 ADD:更高级的复制文件
 
 CMD:容器启动命令
 
 ENV:设置环境变量
 
 EXPOSE:暴露端口
 
其它的指令还有ENTRYPOINT、ARG、VOLUME、WORKDIR、USER、HEALTHCHECK、ONBUILD、LABEL等等。

# 以下是一个Dockerfile实例:

FROM java:8
MAINTAINER "jinshw"<jinshw@qq.com>
ADD mapcharts-0.0.1-SNAPSHOT.jar mapcharts.jar
EXPOSE 8080
CMD java -jar mapcharts.jar

# 镜像构建
docker build 名称 .

# 镜像运行

# 新建并启动
docker run [镜像名/镜像ID]
# 启动已终止容器
docker start [容器ID]

# 查看容器
# 列出本机运行的容器
$ docker ps 
# 列出本机所有的容器(包括停止和运行)
$ docker ps -a

# 停止容器
# 停止运行的容器
docker stop [容器ID]
# 杀死容器进程
docker  kill [容器ID] 

# 重启容器
docker restart [容器ID] 

# 删除容器
docker  rm [容器ID]

# 进入容器
进入容器有两种方式:

# 如果从这个 stdin 中 exit,会导致容器的停止
docker attach [容器ID]
# 交互式进入容器
docker exec [容器ID]

进入容器通常使用第二种方式,docker exec后面跟的常见参数如下:

- d, --detach 在容器中后台执行命令;
 - i, --interactive=true I false :打开标准输入接受用户输入命令

# 导出和导入
导出容器
#导出一个已经创建的容器到一个文件
docker export [容器ID]

导入容器
# 导出的容器快照文件可以再导入为镜像
docker import [路径]

其它
查看日志
# 导出的容器快照文件可以再导入为镜像
docker logs [容器ID]

这个命令有以下常用参数
 -f : 跟踪日志输出

--since :显示某个开始时间的所有日志

-t : 显示时间戳

--tail :仅列出最新N条容器日志

复制文件
# 从主机复制到容器
docker cp host_path containerID:container_path 
# 从容器复制到主机
docker cp containerID:container_path host_path

2. docker run

# 命令说明:
-p 8082:80: 将容器的 80 端口映射到主机的 8082 端口。
--name runoob-nginx-test-web:将容器命名为 runoob-nginx-test-web。
-v /nginx/www:/usr/share/nginx/html:将我们自己创建的 www 目录挂载到容器的 /usr/share/nginx/html
-d, --detach=false, 指定容器运行于前台还是后台,默认为false
-i, --interactive=false, 打开STDIN,用于控制台交互
-t, --tty=false, 分配tty设备,该可以支持终端登录,默认为false
-u, --user="", 指定容器的用户
-a, --attach=[], 登录容器(必须是以docker run -d启动的容器)
-w, --workdir="", 指定容器的工作目录
-c, --cpu-shares=0, 设置容器CPU权重,在CPU共享场景使用
-e, --env=[], 指定环境变量,容器中可以使用该环境变量
-m, --memory="", 指定容器的内存上限
-P, --publish-all=false, 指定容器暴露的端口
-p, --publish=[], 指定容器暴露的端口
-h, --hostname="", 指定容器的主机名
-v, --volume=[], 给容器挂载存储卷,挂载到容器的某个目录
--volumes-from=[], 给容器挂载其他容器上的卷,挂载到容器的某个目录
--cap-add=[], 添加权限,权限清单详见:http://linux.die.net/man/7/capabilities
--cap-drop=[], 删除权限,权限清单详见:http://linux.die.net/man/7/capabilities
--cidfile="", 运行容器后,在指定文件中写入容器PID值,一种典型的监控系统用法
--cpuset="", 设置容器可以使用哪些CPU,此参数可以用来容器独占CPU
--device=[], 添加主机设备给容器,相当于设备直通
--dns=[], 指定容器的dns服务器
--dns-search=[], 指定容器的dns搜索域名,写入到容器的/etc/resolv.conf文件
--entrypoint="", 覆盖image的入口点
--env-file=[], 指定环境变量文件,文件格式为每行一个环境变量
--expose=[], 指定容器暴露的端口,即修改镜像的暴露端口
--link=[], 指定容器间的关联,使用其他容器的IP、env等信息
--lxc-conf=[], 指定容器的配置文件,只有在指定--exec-driver=lxc时使用
--name="", 指定容器名字,后续可以通过名字进行容器管理,links特性需要使用名字
--net="bridge", 容器网络设置:
bridge 使用docker daemon指定的网桥
host //容器使用主机的网络
container:NAME_or_ID >//使用其他容器的网路,共享IP和PORT等网络资源
none 容器使用自己的网络(类似--net=bridge),但是不进行配置
--privileged=false, 指定容器是否为特权容器,特权容器拥有所有的capabilities
--restart="no", 指定容器停止后的重启策略:
no:容器退出时不重启
on-failure:容器故障退出(返回值非零)时重启
always:容器退出时总是重启
--rm=false, 指定容器停止后自动删除容器(不支持以docker run -d启动的容器)
--sig-proxy=true, 设置由代理接受并处理信号,但是SIGCHLD、SIGSTOP和SIGKILL不能被代理


# 运行httpd
docker run -it -d -p 80:80  --name datahttpd -v /opt/share/www/html:/usr/local/apache2/htdocs/ httpd

# 运行Nginx
$ docker run -d -p 8082:80 --name runoob-nginx-test-web 
-v /nginx/www:/usr/share/nginx/html 
-v /nginx/conf/nginx.conf:/etc/nginx/nginx.conf 
-v /nginx/logs:/var/log/nginx nginx

3. 创建docker镜像

 mkdir dockerfile
 cd dockerfile
 vim Dockerfile
 FROM centos   
 RUN mkdir -p /opt/aaa
 docker build -t centosaaa .

4. 上传本地镜像

 docker load -i httpd.tar

5. 创建私有仓库

1. 服务端

 docker pull registry
 docker run -d -v /home/docker/registry:/var/lib/registry -p 5000:5000 
 --restart=always --privileged=true --name registry registry:last 基于私有仓库镜像运行容器
 http://192.168.235.128:5000/v2/   或 curl 192.168.235.128:5000/v2/_catalog 查看运行

 # 修改配置文件
 vim /etc/docker/daemon.json 
 {"insecure-registries":["192.168.235.128:5000"]}
 systemctl daemon-reload
 systemctl restart docker重启

docker images 查看镜像
docker tag httpd 192.168.248.128:5000/httpd:v1.0 修改标签
docker push 192.168.235.128:5000/httpd:v1.0 上传
curl 192.168.235.128:5000/v2/httpd/tags/list 查看

2. 客户端

 # 修改配置文件
 vim /etc/docker/daemon.json
 {"insecure-registries":["192.168.235.128:5000"]} 
 systemctl daemon-reload
 systemctl restart docker 重启

 docker pull 192.168.235.128:5000/httpd:v1.0 拉取镜像
 docker tag busybox 192.168.235.128:5000/busybox111:v1.0
 docker push 192.168.235.128:5000/busybox111:v1.0 上传镜像
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值