Linux基础

一,文件管理

文件管理基础

1.linux系统的单目录结构

  • 文件的时间
ls -l 文件名 仅看的是文件的修改时间
Linux文件有
三种时间,用stat查看 
例如:stat anaconda-ks.cfg
 
访问时间:atime,查看内容,用cat检测
修改时间:mtime,修改内容
改变时间:ctime,修改内容,修改权限等属性,凡是有改动都会变
  • 文件的扩展名
Linux文件是没有扩展名!!!
 
// 方法一:
ls -l 文件名    //看第一个字符
-   普通文件(文本文件,二进制,压缩文件,电影,图片。。。),例如:/bin/ls
d   目录文件(蓝色),例如/home/
b   设备文件(块设备)存储设备硬盘,U盘,例如:/dev/sda
c   设备文件(字符设备)打印机,例如:终端/dev/tty1
s   套接字文件,例如:/run/rpcbind.sock 
p   管道文件,例如:/run/systemd/initctl/fifo
l   链接文件(淡蓝色),例如:/bin
 
ps:通过颜色判断文件的类型是错误的!!!
 
// 方法二:
[root@xxx ~]# file /etc/grub.conf

2.根/ 目录结构及作用

  • 1.命令相关目录

    bin -> usr/bin # 普通用户使用的命令如ls、date
    sbin -> usr/sbin # 管理员使用的命令
    
  • 2.启动目录

    boot # 存放的启动相关的文件,例如kernel,grub(引导装载程序)
    
  • 3、系统文件目录

    usr # 系统文件,相当于C:\Windows
     lib -> usr/lib # 库文件Glibc
     lib64 -> usr/lib64 # 库文件Glib
    
  • 4、用户家目录

  • home # 普通用户家目录
    root # root用户的HOME
    
  • 5、配置文件目录

    etc # 配置文件,很重要,系统级服务配置文件都在这里
    /etc/sysconfig/network-script/ifcfg-*,网络配置文件
    /etc/hostname,系统主机名配置文件
    /etc/resolv.conf,dns客户端配置文件
    /etc/hosts,本地域名解析配置文件
    /etc/fstab    系统挂载目录 开机自启动挂载列表
    /etc/passwd  系统用户文件
    
  • 6、设备目录文件

    dev # 设备文件,/dev/sda /dev/sr0
    /dev/cdrom 和/dev/sr0,系统光盘镜像设备
    /dev/null,黑洞设备,只进不出。类似于垃圾回收站
    /dev/random,生成随机数的设备
    /dev/zero,能源源不断地产生数据,类似于取款机,随时随地取钱
    /dev/pts/0,虚拟的Bash Shell终端,提供给远程用户使用 0代表第一个终端 1代表第2个终端
    以此类推
    /dev/stderr,错误输出    
    /dev/stdin,标准输入
    /dev/stdout,标准输出
    
  • 7、虚拟文件系统

    虚拟文件系统:类似于小汽车的仪表板,能够看到汽车是否有故障,或者是否缺油了。
    proc # 虚拟的文件系统,反映出来的是内核,进程信息或实时状态 
    反映系统当前进程的实时状态
    /proc/meminfo:内存信息
    /proc/cpuinfo:cpu信息
    
    
  • 可变的目录与临时目录

    var  #存放的是一些变化文件,比如数据库,日志,邮件.... 
    
    /tmp,系统临时目录(类似于公共厕所),系统会定时删除该目录下长时间没有访问的文件。
    /var,存放一些变化文件,如下
                        mysql:          /var/lib/mysql
                        vsftpd:         /var/ftp
                        mail:           /var/spool/mail
                        cron:           /var/spool/cron
                        log:            /var/log 系统日志文件存放目录
                                        /var/log/messages系统日志
                                        /var/log/secure系统登录日志
                        /var/tmp        临时文件(主要是程序产生的临时文件)
     
    
  • 9、设备(主要指存储设备)挂载目录

     media # 移动设备默认的挂载点
     mnt # 手工挂载设备的挂载点
     opt # 早期第三方厂商的软件存放的目录.
     tmp # 临时存放文件,类似于回收站,超过十天自动删除
    
  • 10、其他的一些重要目录

    drwx------.  2 root root 16384 Jul 11  2019 lost+found # 孤儿文件
    这个目录是使用标准的ext2/ext3档案系统格式才会产生的一个目录,目的在于当档案系统发生错误时, 将一些遗失的片段放置到这个目录下。这个目录通常会在分割槽的最顶层存在, 例如你加装一颗硬盘于/disk中,那在这个系统下就会自动产生一个这样的目录『/disk/lost+found
    lost+found这个目录一般情况下是空的,当系统非法关机后,如果你丢失了一些文件,在这里能找回来用来存放fsck过程中部分修复的文件的
    lost+found:几乎每个被格式化过的Linux分区都会有,意外后找回的文件一般在这里面。
    这个目录是储存发生意外后丢失的文件的。只有root用户才能打开
     
    application
    run #  存放程序运行后所产生的pid文件
    srv # 物理设备产生的一些文件
    sys # 硬件设备的驱动程序信息
    

3.文件管理

3.1文件管理:基本命令
ls -l
#浏览目录
ls        # 默认浏览当目录
ls -l 目录 # 浏览目录下的子目录子文件名的详细信息
ls -al 目录 # 浏览的结果中包含隐藏文件
ls -dl 目录 # 查看目录
 
[root@localhost ~]# ll a.txt 
-rw-r--r--. 1 root root 0 12月 15 14:02 a.txt
 
# 各部分解析如下
-rw-r--r--. 权限,后面的点代表是否在selinux开启的情况下(enforcing或者permissive都属于开启)创建的文件
 
1               硬链接个数
root            属主
root            属组
0               文件大小,单位字节
12月 15 14:02   文件修改时间
a.txt           文件名字
 
# 权限的第一个为代表文件类型
格式         说明
-            普通文件(文本,    二进制,    压缩包,    图片,    日志等)    
d            目录文件
b            设备文件(块设备)存储设备硬盘    /dev/sda1,    /dev/sda2
c            设备文件(字符设备)打印机,终端    /dev/tty1,    /dev/zero
s            套接字文件,    进程间通信(socket)
p            管道文件
l            链接文件
 
注意: Linux文件扩展名不代表任何含义, 仅仅是为了运维人员便于识别
tree

#查看目录树:需要先安装tree命令,执行yum install tree -y
tree -a 目录    # 显示所有文件,包括隐藏文件
tree -d 目录    # 只显示子目录
tree -L 1 目录  # -L 遍历目录的最大层数,-L后应该是大于0的正整数
tree -F 目录    # -F 在条目后加上文件类型的指示符号,例如会在显示出的目录后面加上左斜杠/
 
[root@localhost ~]# tree /a  
/a
├── b
│   ├── 1.txt
│   ├── 2.txt
│   └── 3.txt
├── bb
│   ├── a.txt
│   ├── b.txt
│   └── c.txt
└── bbbb
 
了解一下tree命令其他选项
-a 显示所有文件和目录。
-A 使用ASNI绘图字符显示树状图而非以ASCII字符组合。
-C 在文件和目录清单加上色彩,便于区分各种类型。
-d 显示目录名称而非内容。
-D 列出文件或目录的更改时间。
-f 在每个文件或目录之前,显示完整的相对路径名称。
-F 在执行文件,目录,Socket,符号连接,管道名称名称,各自加上"*","/","=","@","|"号。
-g 列出文件或目录的所属群组名称,没有对应的名称时,则显示群组识别码。
-i 不以阶梯状列出文件或目录名称。
-I 不显示符合范本样式的文件或目录名称。
-l 如遇到性质为符号连接的目录,直接列出该连接所指向的原始目录。
-n 不在文件和目录清单加上色彩。
-N 直接列出文件和目录名称,包括控制字符。
-p 列出权限标示。
-P 只显示符合范本样式的文件或目录名称。
-q 用"?"号取代控制字符,列出文件和目录名称。
-s 列出文件或目录大小。
-t 用文件和目录的更改时间排序。
-u 列出文件或目录的拥有者名称,没有对应的名称时,则显示用户识别码。
-x 将范围局限在现行的文件系统中,若指定目录下的某些子目录,其存放于另一个文件系统上,则将该子目录予以排除在寻找范围外。
 
mkdir
#1、=============创建文件:touch  
touch file1.txt             //无则创建,有则修改时间
touch /home/file10.txt
touch file{1..20}
touch Ego{n,N}.txt     //等价touch Egon.txt EgoN.txt
touch -t 2011111111 2018.rmvb 
修改文件时间 语法:
-t STAMP


 
#2、=============创建目录:mkdir  
mkdir dir1
mkdir /home/dir2 /home/dir3
mkdir /home/{dir4,dir5}

mkdir -v /home/{dir6,dir7}   -v显示创建信息
    mkdir: 已创建目录 “/home/dir6”
    mkdir: 已创建目录 “/home/dir7”
mkdir -p /home/dir8/111/222     //包括其父母的创建
cp
#1、=============复制:cp   
语法:cp 源 目标
 
cp -v install.log  /home/dir1
cp -v install.log  /home/dir1/aaa.txt

cp -r /etc /home/dir1 
cp -r /etc/* /home/dir1
	-r 拷贝文件夹时候用
	 
cp -rv /etc /tmp
\cp -rv /etc /tmp
 
扩展用法:
cp -rfv /etc/hosts{,.old}
cp -rvf /etc/sysconfig/network-scripts/ifcfg-eth0{,.old}
 
关于-f参数的一个实验
[root@aliyum ~]# echo "1111" > /opt/a.txt
[root@aliyum ~]# echo "2222" > /t2/a.txt
[root@aliyum ~]# 
[root@aliyum ~]# chmod o=wx /t2
[root@aliyum ~]# chmod o=- /t2/a.txt 
[root@aliyum ~]# 
[root@aliyum ~]# ll -d /t2
drwxr-x-wx 2 root root 4096 Oct 20 00:07 /t2
[root@aliyum ~]# ll /t2/a.txt 
-rw-r----- 1 root root 5 Oct 20 00:07 /t2/a.txt
[root@aliyum ~]# 
[root@aliyum ~]# su - xxx
Last login: Tue Oct 20 00:05:43 CST 2020 on pts/2
[xxx@aliyum ~]$ cp /opt/a.txt /t2/a.txt  # 失败
cp: cannot create regular file ‘/t2/a.txt’: Permission denied
[xxx@aliyum ~]$ \cp /opt/a.txt /t2/a.txt  # 失败
cp: cannot create regular file ‘/t2/a.txt’: Permission denied
[xxx@aliyum ~]$ 
[xxx@aliyum ~]$ 
[xxx@aliyum ~]$ cp -f /opt/a.txt /t2/a.txt  # 成功
[xxx@aliyum ~]$ exit
logout
[root@aliyum ~]# cat /t2/a.txt 
1111
[root@aliyum ~]# 
 
========================================================
小知识:root用户使用cp (默认有一个别名 alias cp='cp -i') -i   显示提示信息(是否覆盖)
1. /bin/cp -rf /etc /tmp
2. # unalias cp                
    # cp -rf /etc /tmp  
3. # \cp -rf /etc /tmp
4.-f 参数是强制复制,比如你在A文件夹里面有个文件名叫B,然后你把C文件夹里面的另一个文件名叫B的复制到A里面,这个时候会照成冲突,然后会提示你要不要继续复制.加上-f 就不会提示你了.
 
你输入-f 还是会提示你的原因是
-------------------------------------------------------------
有的系统在安装的时候,cp - i 的 alias 就是 cp
也就是说你在执行cp的时候,其实是执行的cp -i 
取消掉cp的alias就好了 
==========================================
解决办法
unalias cp 
========================================================

rsync
  • 可以用来清空目录或文件
    1. 建立一个空目录
        mkdir -p /del_blank
    2. 确立需要清空的目标目录
        /del_data
    3. 使用rsync同步删除(注意目录后面的“/”),整体效率会快一个数量级的样子。
        rsync --delete-before -a -H -v --progress --stats /del_blank/  /del_data/
    选项说明:
    –delete-before 接收者在传输之前进行删除操作
    –progress 在传输时显示传输过程
    -a 归档模式,表示以递归方式传输文件,并保持所有文件属性
    -H 保持硬连接的文件
    -v 详细输出模式
    -stats 给出某些文件的传输状态 
 
    一般我们不需要显示进度,使用以下命令即可
        rsync --delete-before -a -H /del_blank/ /del_data/
  这样我们要删除的 del_data目录就会被清空了
  • 使用rsync将源服务器文件夹同步复制到远程服务器
rsync -avz --progress --append  --delete  /backupnew/ rsync@116.62.71.214::book

参数说明:

​ - a 归档模式,保留文件的所有权限、时间戳和所有元数据。

​ -v 详细模式,显示同步过程中的详细信息。

​ -z 压缩模式,使用gzip压缩数据,减小传输数据量。

-P:显示传输过程中的进度百分比。

​ --progress 显示同步过程中的进度。

​ --append 追加新增加的文件到目标文件中,而不是覆盖掉已有的文件。

​ --delete 删除目标文件夹中与源文件夹中不一致的所用东西。

  • 利用rsync+inotify实现文件实时同步

老生常谈:rsync+inotify数据量百万级文件,大小将近1t的做实时同步_rsync 大文件_木一番的博客-CSDN博客

首先要先下载rsync+inotify

rsync默认读取的配置文件是/etc/rsyncd.conf

1.在服务端的操作

创建密码账户文件:

echo "trs:123456" >> /etc/rsync.pwd
# 一定要修改权限为600
chmod 600 /etc/rsync.pwd

修改配置文件,无非就是ip,用户,密码,同步过来文件存放的路径等等

vim /etc/rsyncd.conf

uid = root       
gid = root
use chroot = no
max connections = 0            #0表示没有限制
pid file = /var/run/rsyncd.pid
lock file = /var/run/rsyncd.lock
log file = /var/log/rsyncd.log
# exclude = lost+found/
# transfer logging = yes
timeout = 600                                           
# ignore nonreadable = yes
# dont compress   = *.gz *.tgz *.zip *.z *.Z *.rpm *.deb *.bz2
 
[test01]                                               
path = /TRS/HyCloud/data/                     
read only = false                                     
ignore errors                                                  
auth users = trs                                        
secrets file = /etc/rsync.pwd                     

设置开机启动

systemctl enable rsyncd

开启rsync

systemctl start rsyncd

2.在客户端的操作

  • 安装inotify
tar -zxvf inotify-tools-3.13.tar.gz 
 
cd inotify-tools-3.13
 
./configure --prefix=/usr/local/inotify       (注意前面是:   ./)
 
make
 
make install
  • 创建密码文件(简单点就行,不超过8位数,看其他人都是这么讲,原因未知,无所谓了)
    直接运行下面的命令即可,创建rsync.pwd,并保存123456。这里文件名和随意取,不要跟系统中存在的文件名发生冲突就行。
echo "123456" >> /etc/rsync.pwd
  • 修改监控的文件数量
    查看系统默认参数值
sysctl -a | grep max_queued_events
结果是:fs.inotify.max_queued_events = 16384
sysctl -a | grep max_user_watches
结果是:fs.inotify.max_user_watches = 8192
sysctl -a | grep max_user_instances
结果是:fs.inotify.max_user_instances = 128
  • 修改参数:
sysctl -w fs.inotify.max_queued_events="99999999"
sysctl -w fs.inotify.max_user_watches="99999999"
sysctl -w fs.inotify.max_user_instances="65535"
  • vi /etc/sysctl.conf #添加以下代码
fs.inotify.max_queued_events=99999999
fs.inotify.max_user_watches=99999999
fs.inotify.max_user_instances=65535

:wq! #保存退出
参数说明:

max_queued_events #inotify队列最大长度,如果值太小,会出现"** Event Queue Overflow **"错误,导致监控文件不准确
max_user_watches #要同步的文件包含多少目录,可以用:find /data -type d | wc -l 统计,必须保证max_user_watches值大于统计结果(这里/data为同步文件目录)
max_user_instances #每个用户创建inotify实例最大值
  • 修改密码文件权限
chmod 600 /etc/rsync.pwd
  • 创建脚本文件rsync.sh

rsync.sh作用:客户端的data文件发生crud等等操作,就同步到服务端服务器上

#!/bin/bash
src=/TRS/HyCloud/data                             # 需要同步的源路径
log_file=/var/log/rsync_client.log               #日志
des=test01                                                #126服务器上配置文件里的模块名
rsync_passwd_file=/etc/rsync.pwd           # rsync验证的密码文件
ip1=59.212.25.124                                   # 目标服务器1
#ip2=192.168.0.19                                   # 目标服务器2
user=trs                                                    # rsync --daemon定义的验证用户名
cd ${src}                                                   
    /usr/local/bin/inotifywait -mrq --format  '%Xe %w%f' -e modify,create,delete,attrib,close_write,move ./ | while read file
    do
        INO_EVENT=$(echo $file | awk '{print $1}')      # 把inotify输出切割 把事件类型部分赋值给INO_EVENT
        INO_FILE=$(echo $file | awk '{print $2}')       # 把inotify输出切割 把文件路径部分赋值给INO_FILE
        echo "-------------------------------$(date)------------------------------------"
        echo $file
        #增加、修改、写入完成、移动进事件
        #增、改放在同一个判断,因为他们都肯定是针对文件的操作,即使是新建目录,要同步的也只是一个空目录,不会影响速度。
        if [[ $INO_EVENT =~ 'CREATE' ]] || [[ $INO_EVENT =~ 'MODIFY' ]] || [[ $INO_EVENT =~ 'CLOSE_WRITE' ]] || [[ $INO_EVENT =~ 'MOVED_TO' ]]         # 判断事件类型
        then
            echo 'CREATE or MODIFY or CLOSE_WRITE or MOVED_TO'
            rsync -avzcR --password-file=${rsync_passwd_file} $(dirname ${INO_FILE}) ${user}@${ip1}::${des}
    # INO_FILE变量代表路径哦  -c校验文件内容
            # && rsync -avzcR --password-file=${rsync_passwd_file} $(dirname ${INO_FILE}) ${user}@${ip2}::${des}
    #仔细看 上面的rsync同步命令 源是用了$(dirname ${INO_FILE})变量 即每次只针对性的同步发生改变的文件的目录(只同步目标文件的方法在生产环境的某些极端
    #环境下会漏文件 现在可以在不漏文件下也有不错的速度 做到平衡)
    #然后用-R参数把源的目录结构递归到目标后面 保证目录结构一致性
fi
        #删除、移动出事件
        if [[ $INO_EVENT =~ 'DELETE' ]] || [[ $INO_EVENT =~ 'MOVED_FROM' ]]
        then
            echo 'DELETE or MOVED_FROM'
            rsync -avzR --delete --password-file=${rsync_passwd_file} $(dirname ${INO_FILE}) ${user}@${ip1}::${des} 
            # && rsync -avzR --delete --password-file=${rsync_passwd_file} $(dirname ${INO_FILE}) ${user}@${ip2}::${des}
    #看rsync命令 如果直接同步已删除的路径${INO_FILE}会报no such or directory错误 所以这里同步的源是被删文件或目录的上一级路径
    #并加上--delete来删除目标上有而源中没有的文件,这里不能做到指定文件删除,如果删除的路径越靠近根,则同步的目录月多,同步删除的操作就越花时间。
    #这里有更好方法的同学,欢迎交流。
        fi
        #修改属性事件 指 touch chgrp chmod chown等操作
        if [[ $INO_EVENT =~ 'ATTRIB' ]]
        then
            echo 'ATTRIB'
            if [ ! -d "$INO_FILE" ]
    # 如果修改属性的是目录 则不同步,因为同步目录会发生递归扫描,等此目录下的文件发生同步时,rsync会顺带更新此目录。
            then
                rsync -avzcR --password-file=${rsync_passwd_file} $(dirname ${INO_FILE}) ${user}@${ip1}::${des}         
                # && rsync -avzcR --password-file=${rsync_passwd_file} $(dirname ${INO_FILE}) ${user}@${ip2}::${des}
            fi
        fi
    done
  • 修改脚本权限:
 chmod +x /root/rsync.sh
  • 为了适配脚本,加入一个软连接
 ln -s /usr/local/inotify/bin/inotifywait /usr/local/bin/
  • 后台执行
 nohup sh /root/rsync.sh &

移动与删除

#1、=============复制:mv   
mv 源 目标
# mv file2 /home/dir3   将file2移动到/home/dir3里
# mv file4 file5                将file4重命名为file5,当前位置里的移动就是重命名
 
#2、=============复制:rm
示例:删除/home/dir1       
# cd /home
# rm -rf dir1       
-r 递归
-f force强制
-v 详细过程
find

按照文件名去找

# find /etc -name "ifcfg-eth0"
# find /etc -iname "ifcfg-eth0"     # -i忽略大小写
# find /etc -iname "ifcfg-eth*"


按照文件大小去找:

[root@localhost ~]# find /etc -size +3M                 # 大于3M
[root@localhost ~]# find /etc -size 3M
[root@localhost ~]# find /etc -size -3M
[root@localhost ~]# find /etc -size +3M -ls             # -ls找到的处理动作

指定目录深度去找

-maxdepth levels
[root@localhost ~]# find / -maxdepth 5 -a  -name "ifcfg-eth0"  # -a并且,-o或者,不加-a,默认就是-a
[root@localhost ~]#find  /  -maxdepth 1  -type  f  -size +10m  (搜索本目录下最深层级为1的目录下文件大小大于10m的文件)

按时间去找(ctime,atime,mtime)

[root@localhost ~]# find /etc -mtime +3                 # 修改时间超过3天(也就是3天内未修改)
[root@localhost ~]# find /etc -mtime 3                  # 修改时间等于3天
[root@localhost ~]# find /etc -mtime -3                 # 修改时间3天以内(也就是3天内有修改)

按文件属主属组找

[root@localhost ~]# find /home -user egon               # 属主是egon的文件
[root@localhost ~]# find /home -group it                # 属组是it组的文件
[root@localhost ~]# find /home -user egon -group it
[root@localhost ~]# find /home -user egon -a -group it  # 同上意思一样
[root@localhost ~]# find /home -user egon -o -group it
[root@localhost ~]# find /home -nouser  # 用户还存在,在/etc/passwd中删除了记录
[root@localhost ~]# find /home -nogroup  # 用户还存在,在/etc/group中删除了记录
[root@localhost ~]# find /home -nouser -o -nogroup 

按文件类型找

[root@localhost ~]# find /dev -type f                       # f普通
[root@localhost ~]# find /dev -type d                       # d目录
[root@localhost ~]# find /dev -type l                       # l链接
[root@localhost ~]# find /dev -type b                       # b块设备
[root@localhost ~]# find /dev -type c                       # c字符设备
[root@localhost ~]# find /dev -type s                       # s套接字
[root@localhost ~]# find /dev -type p                       # p管道文件
[root@localhost ~]#find  /  -type  f  -name “.txt”  (-type  f表示查询所有以txt结尾的普通文件)
[root@localhost ~]#find  /  -type  d  -name “.txt”  (-type  d表示查询所有以txt结尾的文件夹)
[root@localhost ~]#find  /  -type  d  -name “.txt”  -delete  (-delete 表示删除动作)

根据inode号查找:inum n

[root@localhost ~]# find / -inum 1811

按文件权限去找

[root@localhost ~]# find . -perm 644 -ls
[root@localhost ~]# find . -perm -644 -ls
[root@localhost ~]# find . -perm -600 -ls
[root@localhost ~]# find /sbin -perm -4000 -ls      # 包含set uid
[root@localhost ~]# find /sbin -perm -2000 -ls      # 包含set gid
[root@localhost ~]# find /sbin -perm -1000 -ls      # 包含sticky

找到后处理的动作

-print
-ls
-delete
-exec
-ok
[root@localhost ~]# find /etc -name "ifcfg*" -print  # 必须加引号
[root@localhost ~]# find /etc -name "ifcfg*" -ls
[root@localhost ~]# find /etc -name "ifcfg*" -exec cp -rvf {} /tmp \;  # 非交互
[root@localhost ~]# find /etc -name "ifcfg*" -ok cp -rvf {} /tmp \;  # 交互
 
[root@localhost ~]# find /etc -name "ifcfg*" -exec rm -rf {} \;
[root@localhost ~]# find /etc -name "ifcfg*" -delete  # 同上

find结合xargs

[root@localhost ~]# find . -name "egon*.txt" |xargs  rm -rf
 
[root@localhost ~]# find /etc -name "ifcfg-eth0" |xargs -I {} cp -rf {} /var/tmp
[root@localhost ~]# find /test -name "ifcfg-ens33" |xargs -I {} mv {} /ttt
[root@localhost ~]# find /ttt/ -name "ifcfg*" |xargs -I {} chmod 666 {}
xargs(通用的,适用于所有不支持管道的命令):
    xargs命令:可以移动材料到文件夹时使用
    #find  .  -name  ”*.txt”  -type f  | xargs  -i  mv {}  abc/  (找出当前目录下所有的以.txt结尾的普通文件,移动到abc文件夹下)
    #find  ./abc  -name”*.txt” -type f  | xargs  -I  bb  mv  bb  ./  (找出当前目录下abc目录下所有的以.txt结尾的普通文件,移动到当前文件夹下)
    

find结合exec(-exec和-delete是find独有的)

[root@localhost ~]#find  /tmp  -type  f  -exec  rm -rf  {} \;   (找出/tmp下的所有普通文本文件并强制删除,-exec代表着后面执行xshell命令,也可以换成-ok,注意后面有分号)
wget
wget -O 本地路径 远程包链接地址  # 将远程包下载到本地,-O指定下载到哪里,可以生路-O 本地路径
wget https://www.cnblogs.com/xiaowenyiyi/p/16871271.html
# ps:如果wget下载提示无法建立SSL连接,则加上选项--no-check-certificate
wget --no-check-certificate -O 本地路径 远程包链接地址 
curl
#curl命令是一个利用URL规则在命令行下工作的文件传输工具。它支持文件的上传和下载,所以是综合传输工具,但按传统,习惯称curl为下载工具。作为一款强力工具,curl支持包括HTTP、HTTPS、[ftp]等众多协议,还支持POST、cookies、认证、从指定偏移处下载部分文件、用户代理字符串、限速、文件大小、进度条等特征。做网页处理流程和数据检索自动化,curl可以祝一臂之力。
 
[root@localhost ~]# curl -o 123.png https://www.xxx.com/img/hello.png
 
# ps: 如果遇到下载提示无法简历SSL链接,使用-k选项或者--insecure
curl -k -o 123.png https://www.xxx.com/img/hello.png
**sort **

Linux sort 命令用于将文本文件内容加以排序。

sort 可针对文本文件的内容,以行为单位来排序。

-n 依照数值的大小排序。
-r 以相反的顺序来排序。
-k 以某列进行排序。
-t 指定分隔符,默认以空格为分隔符
-g 按照通常数值排序,支持科学计数法

eg:sort -t ":" -n -k2  1.txt   (-t 指定: 为分隔符,-n 数值大小 ,-k 以第二列)
	结果:
        b : 2
        a : 3
        c : 56
uniq
-c  在每列旁边显示该行重复出现的次数
-d  只显示重复的行
-u  只显示不重复的行
cut
   #cut  -c  4-7  text.txt
          -c  以字符为单位
          -d  以自定义分隔符,默认以tab为分隔符
          -f  与-d一起使用,指定哪个区域
    例子:
    一个文件(text)内容为:ABC:22:33:44:55
                         bf:11:22:fs:66
    当在终端输入#cut  -d  “:”  -f  1-3  text
    则会得到  ABC:22:33  的数据
             bf:11:22
tr
用法:tr  '原内容' '替换内容'   
-d  删除字符
 
tr:
    #echo “aaaa bbbb” | tr ‘[a-z]’ ‘[A-Z]’  输出为AAAABBBB替换的作用
    #echo”aa00aa bb88bb” | tr  -d  ‘a-z’  输出为0088  删除字符的作用
    #tr  ‘a’  ‘A’  <  aa.txt  替换aa.txt文件中a字符为A字符
    #echo”aaa00bb” | tr -s  ‘ab’  输出为a0b 把aaa变为a,bb变为b
wc
-c 统计文件的Bytes数
-l 统计行数
-w 统计文件中单词的个数,默人以空白字符作为分隔符

tar
参数:z:gzip算法
	 x:解压
	 c:压缩
	 v:显示过程
	 f:要放在最后一个,对应紧跟在f后面的文件
tar解压:
	#tar -zxvf  文件名.tar.gz    -----解压文件
	#tar -zxvf  文件名.tar.gz   -C  /opt/mydev/  -----C指定路径解压
tar压缩:	
	#tar -zcvf  文件名.tar.gz  需要压缩的文件路径   -----压缩文件
tar查看:
	#tar -ztvf  文件名.tar.gz  ----查看压缩包里有哪些内容  
unzip解压:
	#unzip  文件名.zip   ----解压(.zip)
	#unzip  test.zip  -d /opt/mydev/
zip压缩:	
	#zip  文件名.zip  1.txt 2.txt  ---压缩(.zip)
	#zip   文件名.zip  -r  1dir 2dir 3dir 1.txt    ---(-r 参数可以压缩文件夹)
Vim

安装vim

yum install vim*

vimdiff  文件1  文件2	  同时编辑两个文件(可以根据提示看出两个文件的不同,ctrl+ww 可以
vim  -o  文件1  文件2     同时编辑两个文件



Ctrl + f    向下翻一页
Ctrl + b  	向上翻一页
Ctrl + d 		向下翻半页
Ctrl + u 		向上翻半页
n      下一个
:$      最后一行
?关键字   从下往上找

**************命令模式**************************
#命令模式下dG     删除光标后的所有行内容
#命令模式下dd     删除光标的一行
#gg     跳到首行
#shift+G   跳到尾行
#H    跳到屏幕的首行
#L    跳到屏幕的最后一行  
#crtl +v   可视化模式,可以用来删除首行的注释

复制一行:
        把光标移动到该行的任意位置,按下yy
        把光标移动到目标行的任意位置,按下p
         
    复制3行:
        把光标移动到该行的任意位置,按下3yy
        把光标移动到目标行的任意位置,按下p
把yy换成dd就变成了剪切操作


可视块模式:#crtl +v 
        批量去注释
            前提:注释的行需要整齐排列
              
            1、在命令模式,按ctrl+v
            2、上下键选中#号
            3、按下d
              
        批量加注释
            前提:注释的行需要整齐排列
              
            1、先将光标移动到首行的开头位置
            2、在命令模式,按ctrl+v
            3、上下键选中第一列
            4、shift+i,然后输入#
            5、连续按两下ESC

*****************扩展模式-末行模式*************************

:10  进入第十行
:%  s/123/456/gi 适用于所有行把123替换为456 (%表示所有行,之后带个空格,g的作用是替换这一行所有符合的内容,i表示不区分大小写)
:1,5 s/123/456/g   适用于1到5行把123替换为456
:1,$  s/123/456/g   适用于1到最后一行把123替换为456
:set nu  显示行号
:1,5 w  /home/aaa   将1到5行的数据输入到一个文件里面,截取日志的时候可以用
:r /etc/passwd    从另外一个文件读内容到当前位置
:set ic   忽略大小写

image-20221101150736749

image-20221101151049466

文件管理高级-三剑客

通配符

常见通配符

image-20221024100308947

eg:1.找出根目录下最大文件深度是3,且所有以l开头的文件,且以小写字母结尾,中间出现任意一个字符的文本文件。
	第一种写法#find  /  -maxdepth 3  -type f  -name “l?[a-z]”
	第二种写法#find  /  -maxdepth 3  -type f  -name “l?[[:lower:]]”
eg:找出/emp下以任意一位数字开头,且以非数字结尾的文件
	#find /tmp  -type f  -name “[0-9][!0-9]”
eg:找出/emp下以非字母开头,后面跟着一个字母以及其他任意长度的字符的文件
	#find /tmp  -type f  -name “ [^a-zA-Z][a-zA-Z]* ”
eg:移动/tmp/下,所有以非字母开头的文件,复制到/tmp/aa/目录下
	# mv  /tmp/[!a-zA-Z]*  /tmp/aa/ 

grep,sed,awk

Linux三剑客(grep,sed,awk)
基本正则表达式BRE集合
image-20221024100549533

扩展正则表达式ERE集合
扩展正则表达式必须用grep -E才能生效

image-20221024100727775

grep
参数用法
-v参数表示结果取反
-o表示只显示匹配的内容,别的内容隐藏
-n显示行号
-i忽略大小写
-E支持高级正则
-c不返回结果,返回匹配的行数
-w强制匹配单词,不进行模糊匹配
# 用法
grep 选项 '正则' 文件路径
 
# 选项
-n, --line-number           在过滤出的每一行前面加上它在文件中的相对行号
-i, --ignore-case           忽略大小写
-l, --files-with-matches    如果匹配成功,则只将文件名打印出来,失败则不打印
                            通常-rl一起用,grep -rl 'root' /etc 
-R, -r, --recursive         递归
-v    取反
# 示例
[root@localhost ~]# grep -rl 'root' /etc     打印/etc下包含“root”内容的文件名   
 


Eg:找出所有以abc结尾的行                   找出所有不以abc结尾的行
grep  -n  “abc$”  text.txt                 grep  -n  “abc$”  text.txt  -v 

Eg:找出非空行信息
grep  -n  “.”  text.txt

Eg:找出包含nginx单词的内容,不进行模糊匹配
grep  -w   text.txt

Eg:找出包含good和glad的内容
grep  -E  “g(oo|la)d”  text.txt

Eg:找出包含root的行的总数、
grep -c root /etc/passwd

Sed

语法:sed 选项(-n -i) “规则( a d i p )” 文件

参数用法
aappend,对文本进行追加,在指定行后面添加一行/多行文本
dDelete,删除匹配行
iInsert,表示插入文本,在指定行前添加一行/多行文本
pPrint,打印匹配行的内容,通常与p和-n一起用
S/正则/替换内容/gi匹配正则内容,然后替换内容。结局g代表全局匹配,i为不区分大小写
sed  选项(-n -i)  “规则( a d i p )”   文件
		选项:
            -n 取消默认输出
            -i 把输出到屏幕中的内容(规则处理的结果+默认输出的结果)
 行号定位:
           sed '1p' a.txt 打印第一行
           sed '1,3p' a.txt
           sed '3p;5p' a.txt
                            Eg:在第二行下面追加一行
                                    #Sed  ‘2a 我是第三行’  test.txt
                                在每一行后面追加换行符
                                    #Sed ‘a -----------’ test.txt
                                在第三行后面插入123
                                    #sed ‘3i 123’ test.txt
                                打印第三行第五行
                                    #sed ‘3p;5p’ test.txt
							Eg:删除第5行之后的内容
									#sed  ‘5,$d’  test.txt
									
正则定位:
 		Eg:查询以aa开头的行,替换其中的b为c(/^aa/为正则定位,不写的话就是全局查找)
			#sed  '/^aa/s/b/c/g' test.txt     
        
        Eg:查询包含liunx的行
            #sed  “/linux/p”  test.txt  -n
        Eg:删除包含liunx的行
            #sed  “/linux/d”  test.txt  (现在只是内存中删除了包含Linux的行,源文件还是会有)
            #sed  “/linux/d”  test.txt  -i (现在就没有了)
	
        Eg:把m替换成n
                #Sed  ‘s/m/n/g’ test.txt
            把m替换成n并且把111111换成222222
                #Sed  -e  “s/m/n/g”  -e  ‘s/111111/222222/g’  test.txt

awk

主要擅长处理有规律的文本,主要用于做一些格式化处理

内置参数用法
$n指定分隔符后,选择第n列
$0完整的输入记录
FS字段分隔符,默认是空格
NF分割后,当前一共有多少个字段(列数)
NR当前记录数,行数
-F指定分隔符
-v定义或修改一个ask内部的变量
-f从脚本文件中读取awk命令

 awk 选项 '规则' 文件路径
     
    选项:
    -F: 指定分隔符 
     
    规则:定位+命令
     
        定位:
            行号定位:
                awk -F: 'NR == 3{print $1,$3}' /etc/passwd
                awk -F: 'NR >= 3 && NR <=5{print $1,$3}' /etc/passwd
                awk -F: 'NR <= 3 || NR >=8{print $1,$3}' test.txt 
                awk -F: 'NR == 3 || NR ==5 || NR==7{print $1,$3}' test.txt 
 
            正则定位
                awk -F: '//{print $1,$2}' 文件路径
             
            没有定位代表定位所有行
 
        命令:
            {print $n}


Eg:awk  ‘{print  $1} ’  test.txt   打印第一列数据。默认分隔符为空格
	awk  ‘NR==5{print} ’  test.txt   打印第五行的内容
	awk  ‘{print  NR , $0}’  test.txt  等同于cat  -n
	awk  -F ‘:’  ‘{print  ![img](https://g.yuque.com/gr/latex?1%2C)(NF-1),$NF}’  test.txt 以:为分隔符,打印出第一列倒数第二列和最后一列
	

对于awk而言,变量分为内置变量与自定义变量

内置变量解释
FS通过awk -v 修改内置变量FS ( awk -v FS=’指定的分隔符 ’
简写 awk -F ‘指定的分隔符’) 起到了自定义分隔符的作用
OFS语法: awk -v OFS=’自定义填充分隔开的内容之间的内容 ’
例子:awk -v OFS=’------’ -v FS=’:’ ‘{print $1,$2}’ test.txt
RSawk -v RS=’:’ {print $0} test.txt 会让系统认为遇到:就会换行,默认的RS是\n,现在相当于改为了:
ORSawk -v ORS=’--------’ {print $0} test.txt 他就相当于把\t给换成了------- 也叫输出时自定义换行符,遇到换行就改成自定义的-------
NF列号
NR行号
FNR打印多个文本时,会分别显示行号
FILENAME当前文件名字
ARGC命令行参数的个数
ARGV数组,保存的是命令行所给定的各参数

awk的模式

关系运算符解释示例
<小于X<y
<=小于等于x<=y
==等于x==y
!=不等于x!=y
>=大于等于x>=y
>大于x>y
~匹配正则X~/正则/y
!~不匹配正则X!~/正则/y
EG:找出以mm开头的行,并打印第一列
#awk -F’:’ ‘/^mm/{print $1}’  test.txt

二,用户管理-权限管理

1)用户管理命令

useradd(用户控制)
	#useradd添加用户
		选项:-g指定用户组,如果不写-g则会创建同名组并自动加入
		选项:-d指定用户的HOME路径,不指定,HOME目录默认在/home/用户名
	#userdel(删除用户)
    	选项:-r 删除用户的HOME目录,不使用的话HOME目录保留
    #id 用户名  (查看用户信息)
    #usermod  (修改用户所属组)
    	选项:-aG 用户组 用户名 (把用户名加入到用户组里)
    	选项:-l 新名字 旧名字 (修改用户名)
    #usermod  -aG 	用户组 用户名     # 将某个用户加入到某个组
    # gpasswd -a user07 it    # 将某个用户加入到某个组
    # gpasswd -M user02,user03,user04 it   # 将多个用户加入到it组

1.查看用户

[root@localhost ~]# id user1
uid=1002(user1) gid=1003(user1) 组=1003(user1)
 
[root@localhost ~]# who  # 查看所有登录的用户信息
[root@localhost ~]# whoami  # 查看当前登录的用户名

2.删除用户

[root@localhost ~]# userdel user1 # 删除用户user1,但不删除用户家目录和mail
 
[root@localhost ~]# userdel -r user1  # 要想删彻底,加-r选项

3.添加用户

#怎样在Linux系统中添加一个新的用户账户
1) 掌握useradd命令的功能:新增一个用户。
2) 了解useradd命令的常用选项:
3) –u:指定用户的UID
4) –g:指定用户所属的主群
   –G:指定用户所属的附加群
5) –d:指定用户的家目录
6) –c:指定用户的备注信息
7) –s:指定用户所用的shell
8) -e:修改过期时间
9) -M: 不创建家目录
10) -r: 创建系统账户,uid处于系统用户范围内,默认就没有家目录
 
#灵活应用useradd命令的举例:
a) 例如:在系统中新增一个fox(狐狸)用户的命令:useradd fox
b) 例如:在系统中新增一个用户user01,属组为police以及uid为600的命令:
useradd –u 600 –g police user01
 
# 其他练习
[root@root ~]# useradd user01       
[root@root ~]# useradd user02 -u 503                # 创建用户usr02,指定uid
[root@root ~]# useradd user03 -d /aaa               # 创建用户user03 指定家目录
[root@root ~]# useradd user04 -M                    # 创建用户user04,不创建家目录
[root@root ~]# useradd user05 -s /sbin/nologin      # 创建用户并指定shell
[root@root ~]# useradd user06 -g hr                 # 创建用户,指定主组
[root@root ~]# useradd user07 -G sale               # 创建用户,指定附加组
[root@root ~]# useradd user08 -e 2014-04-01         # 指定过期时间
[root@root ~]# useradd user10 -u 4000 -s /sbin/nologin
 
[root@aliyum ~]# useradd xxx -M -s /sbin/nologin  # 创建普通用户,但是没有家目录,不能登录系统
[root@aliyum ~]# useradd -r yyy -s /sbin/nologin  # yyy属于系统用户,uid处于系统用户uid范围内

4.修改用户

#usermod  (修改用户所属组)
    	选项:-aG 用户组 用户名 (把用户名加入到用户组里)
    	选项:-l 新名字 旧名字 (修改用户名)

-u         #指定要修改用户的UID
 
-g         #指定要修改用户基本组
 
-a        #将用户添加到补充组。仅与-G选项一起使用
 
-G        #指定要修改用户附加组,使用逗号隔开多个附加组, 覆盖原有的附加组
 
-d         #指定要修改用户家目录
 
-c         #指定要修改用户注释信息
 
-s         #指定要修改用户的bash shell
 
[root@root ~]# usermod -e 2013-02-11 user1000  # 修改过期时间
[root@root ~]# usermod -g group1 jj # 修改主组
[root@root ~]# usermod -a -G group2 jj # 修改附加组,-a添加,不加-a代表覆盖
 
其他选项
-m        #将用户主目录的内容移动到新位置。如果当前主目录不存在,则不会创建新的主目录
 
-l         #指定要修改用户的登陆名
 
-L         #指定要锁定的用户
 
-U         #指定要解锁的用户

5.修改用户密码

passwd  # 默认给当前用户设定密码
passwd 用户名  # root用户可以给自己以及所有其他用户设定密码,普通用户只能设定自己的密码
echo "密码" | passwd --stdin 用户名  # 非交互式
 
# 补充:可以利用系统内置变量生成随机字符串来充当密码
[root@aliyum ~]# echo $RANDOM|md5sum|cut -c 1-10
70ba11a74b
[root@aliyum ~]# 

2)组管理

组管理命令

groupadd
 
groupmod
 
groupdel 
 
gpasswd  # 设置组密码
 
newgrp  # 切换主组*(临时获取组的权限,下次推出后将失效)

1.创建组

[root@aliyum ~]# groupadd gg1  #创建基本组, 不指定gid
[root@aliyum ~]# tail -1 /etc/group
gg1:x:2005:
[root@aliyum ~]# groupadd -g 5555 gg2  #创建基本组, 指定gid为5555
[root@aliyum ~]# tail -1 /etc/group
gg2:x:5555:
[root@aliyum ~]# groupadd -r gg3  # 创建系统组,gid从201-999
[root@aliyum ~]# tail -1 /etc/group
gg3:x:991:

2.修改组

[root@aliyum ~]# groupmod -g 1111 gg3    #修改主组
[root@aliyum ~]# tail -1 /etc/group
gg3:x:1111:
[root@aliyum ~]# groupmod -n new_gg3 gg3  # -n 修改组名称
[root@aliyum ~]# tail -1 /etc/group
new_gg3:x:1111:

3.删除组

如果一个组是一个用户的主组,那么该组不能被删除,删掉用户会默认一起删掉他的主组
 
[root@aliyum ~]# useradd egon1
[root@aliyum ~]# groupadd devops
[root@aliyum ~]# usermod -G devops egon1
[root@aliyum ~]# id egon1
uid=2004(egon1) gid=2004(egon1) groups=2004(egon1),5556(devops)
[root@aliyum ~]# 
[root@aliyum ~]# 
[root@aliyum ~]# groupdel devops  # 附加组可以删除
[root@aliyum ~]# id egon1  # 查看用户,发现他的附加组没有了
uid=2004(egon1) gid=2004(egon1) groups=2004(egon1)
[root@aliyum ~]# groupdel egon1  # 无法删除组egon1,因为组egon1属于egon1用户的主组
groupdel: cannot remove the primary group of user 'egon1'
[root@aliyum ~]# 

4.组成员管理

注意:gpasswd将用户添加到组或从组中删除,只针对已存在的用户
[root@root ~]# gpasswd -a user07 it                 # 将某个用户加入到某个组
[root@root ~]# gpasswd -M user02,user03,user04 it   # 将多个用户加入到it组
[root@root ~]# gpasswd -A lhf it # 指定lhf为组it的组长,除了root用户外lhf用户也可以采用第一条命令往it组里添加成员
[root@root ~]# grep 'it' /etc/group                   # 查看it组中的成员
it:x:505:user02,user03,user04
[root@root ~]# gpasswd -d user07 it                 # 删除用户usr07从it组

可以设置密码,让一些非组成员用户通过“newgrp 组” 的方式临时切换到组内并输入密码的方式获取组的特性

[root@localhost ~]# groupadd group1
[root@localhost ~]# gpasswd group1
正在修改 group1 组的密码
新密码:
请重新输入新密码:
[root@localhost ~]# touch /tmp/a.txt
[root@localhost ~]# ll /tmp/a.txt 
-rw-r--r-- 1 root root 0 8月  10 21:01 /tmp/a.txt
[root@localhost ~]# chown .group1 /tmp/a.txt 
[root@localhost ~]# !ll
ll /tmp/a.txt 
-rw-r--r-- 1 root group1 0 8月  10 21:01 /tmp/a.txt
[root@localhost ~]# chmod g+w /tmp/a.txt 
[root@localhost ~]# gpasswd group1
 
[root@localhost ~]# su - egon
上一次登录:一 8月 10 21:01:46 CST 2020pts/0 上
[egon@localhost ~]$ echo 123 >> /tmp/a.txt  # 此时没有权限
-bash: /tmp/a.txt: 权限不够
[egon@localhost ~]$ newgrp group1  # 临时切换到组group1下,拥有其权限
密码:
[egon@localhost ~]$ echo 123 >> /tmp/a.txt 
[egon@localhost ~]$ cat /tmp/a.txt 
123

三,文件权限-权限管理

1)文件基本权限

1.基本权限介绍

  • 文件的权限针对三类对象进行定义

owner 属主,缩写u

group 属组,缩写g

other 其他,缩写o

  • 每个文件针对每类访问者定义了三种主要权限

r:Read 读

w:Write 写

x:eXecute 执行

  • 设置权限:修改属组,属主
[root@aliyun ~]# chown 主.组 file1           # 改属主、属组
[root@aliyun ~]# chown 主        file1       # 只改属主
[root@aliyun ~]# chown        .组   file1       # 只改属组
 
[root@aliyun ~]# chown -R /test  # 递归修改
  • 修改u g o 权限
# 加减法
chmod u+x,g-w,o+r a.txt
# 赋值
chmod a=rwx a.txt
chmod a=- a.txt
chmod ug=rw,o=r file1
 
# 数字
chmod 644 file1
 
chmod -R 777 xxx/
  • 对于文件和目录来说,r,w,x有着不同的作用和含义:

  • 针对文件:

 r:读取文件内容
 
 w:修改文件内容
 
 x:执行权限对除二进制程序以外的文件没什么意义
  • 针对目录:目录本质可看做是存放文件列表、节点号等内容的文件:
 r:查看目录下的文件列表
 
 w:删除,移动和创建目录下的文件
 
 x:可以cd进入目录,能查看目录中文件的详细属性,能访问目录下文件内容(基础权限)

2)特殊权限

详解:[](Linux 特殊权限 SUID,SGID,SBIT - linhaifeng - 博客园 (cnblogs.com))

suid 4

sgid 2

sticky 1

2.1 SUID

在 Linux 中,所有账号的密码记录在 /etc/shadow 这个文件中,并且只有 root 可以读写入这个文件:

[root@aliyun ~]# ll /etc/shadow
---------- 1 root root 1109 Aug 11 16:11 /etc/shadow

如果另一个普通账号 tester 需要修改自己的密码,就要访问 /etc/shadow 这个文件。但是明明只有 root 才能访问 /etc/shadow 这个文件,这究竟是如何做到的呢?事实上,tester 用户是可以修改 /etc/shadow 这个文件内的密码的,就是通过 SUID 的功能。

[root@aliyun ~]# ll `which passwd`
-rwsr-xr-x 1 root root 27856 Aug  9  2019 /bin/passwd

可以看到 passwd命令是带有s权限的

下面我们来看 tester 用户是如何利用 SUID 权限完成密码修改的:

  1. tester 用户对于 /usr/bin/passwd 这个程序具有执行权限,因此可以执行 passwd 程序
  2. passwd 程序的所有者为 root
  3. tester 用户执行 passwd 程序的过程中会暂时获得 root 权限
  4. 因此 tester 用户在执行 passwd 程序的过程中可以修改 /etc/shadow 文件

例子:

[root@localhost ~]# ll `which cat`
-rwxr-xr-x. 1 root root 54160 10月 31 2018 /usr/bin/cat
[root@localhost ~]# chmod 4755 `which cat`  # 或者 chmod u+s `which cat`
[root@localhost ~]# ll `which cat`
-rwsr-xr-x. 1 root root 54160 10月 31 2018 /usr/bin/cat
 
[root@localhost ~]# su - egon
[egon@localhost ~]$ cat /etc/shadow  # 可以看到内容
2.0 SGID

作用:sgid权限一般应用在目录上,当一个目录拥有sgid权限时,任何用户在该目录下创建的文件的属组都会继承该目录的属组。

sgid权限也使用s表示,增加权限g+s,移除权限g-s;
sgid权限也可以使用数字形式表示,0表示去除sgid权限,2表示添加sgid权限,而且是在原权限的数字表达形式开头加0或2,如:0755移除sgid权限,2755添加sgid权限。

[root@localhost ~]# mkdir /test
[root@localhost ~]# chmod g+s /test/  # 等同于chmod 2755 /test/
[root@localhost ~]# ll -dl /test/
drwxr-sr-x 2 root root 6 8月  11 17:06 /test/
[root@localhost ~]# 
[root@localhost ~]# chown .egon /test/  # 后期任何人在该目录下创建的文件or目录的属组都是egon
3.0 sticky

作用:sticky权限一般针对目录来设置,作用是只允该目录下的文件的创建者删除自己的创建的文件,不允许其他人删除文件。(root用户除外,因为root用户是超级管理员),而且sticky权限只能设置在other位置上。

sticky权限使用t表示,增加权限o+t,移除权限o-t;
sticky权限也可以使用数字形式表示,0表示去除权限,1表示添加权限,而且是在原权限的数字表达形式开头加0或1,如下:如:0755移除sticky权限,1755添加sticky权限

[root@localhost ~]# ls -dl /tmp/
drwxrwxrwt. 13 root root 4096 8月  11 17:09 /tmp/
[root@localhost ~]# chmod o+t /test/   # 或者 chmod 1755 /test
4.0 umask(权限掩码)

临时设置

[root@localhost ~]# umask 000       //设置umask权限

永久设置

[root@localhost tmp]# vim /etc/profile  # 或者/etc/bashrc内容一样
......
if [ $UID -gt 199 ] && [ "`id -gn`" = "`id -un`" ]; then
   umask 002    //表示uid大于等于199的默认umask值,表示普通用户
else
   umask 022    //表示uid小于199的默认umask值,表示root
fi

3)高级权限

ACL

作用:实现更加灵活的权限管理,打破了三类用户的权限管理

  • 添加权限:
        修改属主的权限
            setfacl -m u::权限 a.txt
 
        修改属组的权限
            setfacl -m g::权限 a.txt
 
        修改其他人的权限
            setfacl -m o::权限 a.txt
 
        修改具体某一个用户的权限
            setfacl -m u:用户名:权限 a.txt
 
        修改具体某一个组的权限
            setfacl -m g:组名:权限 a.txt  # 组必须存在
 
        # 也可以给目录设置,都一样     
  • 查看删除权限
# 查看
getfacl /opt/a.txt
 
# 删除
setfacl -x g:group1 /opt/a.txt  # 删除组hr的权限
setfacl -x u:wang file      删除wang账户对指定file文件的ACL权限
setfacl -x g:g1 file   删除g1组对指定file文件的ACL权限

setfacl -b /opt/a.txt  #删除所有acl权限

ACL权限下的mask

设置用户对指定文件所能拥有的最大权限(限高作用)

setfacl -m mask::r file             使指定文件file所拥有的最大权限位读r

setfacl -x mask::r file               取消指定文件file的最大权限限制mask

setfacl -b f1                      取消f1文件所有的ACL权限

ACL生效顺序:所有者、自定义用户、自定义组、其他人

4)ssh配置免密登录

有机器A[192.168.1.1],B[192.168.1.2]。现想A通过ssh免密码登录到B

第一步,在A机下生成公钥/私钥对:

ssh-keygen -t rsa  -C "添加标识"   #默认也是rsa模式加密,

直接三次回车,它将在~/下生成.ssh目录,.ssh下有id_rsa和id_rsa.pub

第二步,把A机下的id_rsa.pub复制到B机下:

完成后还需要将id_rsa.pub内容追加到B机的.ssh/authorized_keys文件里

scp ~/.ssh/id_rsa.pub root@192.168.1.2:~/id_rsa.pub 

第三步、B机把从A机复制的id_rsa.pub添加到.ssh/authorzied_keys文件里:

cat id_rsa.pub >> .ssh/authorized_keys

第四步,权限很重要,authorized_keys的权限只能是600!!!

chmod 600 .ssh/authorized_keys

第五步、验证A机无密码登录B机。

ssh root@192.168.1.2

四,软件包安装

1)rpm

rpm包格式:

# 例1
mysql-connector-odbc-5.2.5-8.el7.x86_64.rpm
 
软件包名:mysql-connector-odbc
版本号Version:5.2.5
发布版本Release:8.el7
平台:el7.x86_64
后缀:.rpm
 
# 例2
abrt-python-doc-2.1.11-57.el7.centos.noarch.rpm
 
abrt-python-doc     #软件包的名称
 
2.1.11              #软件的版本 
 
57                  #软件编译之后的发布的次数 
 
el7                 #适合的操作系统的版本 
 
noarch              #适用于不同版本的CPU  
 
.rpm                #后缀名 

rpm命令

#1、安装:rpm -ivh <RPM包名全称>
 
#2、卸载:rpm -e <RPM包名>
 
#3、升级:rpm -Uvh <RPM包名>
 
#4、查询:
rpm -qa                      #查询系统中安装的所有RPM软件包
 
rpm -qa | grep php         #检索系统中已经安装有关php的软件包
 
rpm -q <RPM包名>            #查询指定软件包是否已安装
                             [root@egon ~]# rpm -q zip
                             zip-3.0-11.el7.x86_64
 
rpm -qi <RPM包名>           #查询系统中已安装包的描述信息
 
rpm -ql <RPM包名>           #查询系统中已安装包里所包含的文件
 
rpm -qc <RPM包名>             #查询指定软件包的所有配置文件
                              [root@egon ~]# rpm -qc mariadb
                               /etc/my.cnf.d/client.cnf
 
rpm -qd <RPM包名>              # 查询某个包安装的帮助文档
                              [root@localhost ~]# rpm -qd zlib  
 
rpm -qf 文件路径             #查询系统中指定文件所属的软件包
                             [root@egon ~]# rpm -qf /usr/sbin/ifconfig 
                              net-tools-2.0-0.25.20131004git.el7.x86_64
 
-p                            # 在上述选项的基础上加选项-p,就可以查看尚未安装的rpm包信息
[root@localhost ~]# rpm -e dos2unix  # 先卸载一下,证明本地rpm数据库中没有该包信息
 
[root@localhost ~]# rpm -qip /opt/Packages/dos2unix-6.0.3-7.el7.x86_64.rpm
[root@localhost ~]# rpm -qlp /opt/Packages/dos2unix-6.0.3-7.el7.x86_64.rpm
[root@localhost ~]# rpm -qcp /opt/Packages/dos2unix-6.0.3-7.el7.x86_64.rpm
[root@localhost ~]# rpm -qdp /opt/Packages/dos2unix-6.0.3-7.el7.x86_64.rpm
 
额外选项
--nomd5     # 不检验软件包的签名
--nodeps    # 忽略依赖性安装软件,安装后软件有可能无法使用,最好是解决依赖性后再安装
             [root@localhost ~]# rpm -e dos2unix  --nodeps  # 忽略依赖关系
 
--force     # 强制安装软件包,只有安装和升级可以强制执行

2)yum命令

常用选项说明:
#仓库        
            yum repolist                     # 查询可用仓库
            yum repolist all                 #查看包括已启用或禁用的所有仓库状态
 
            # 关闭与启用仓库:本质:都是在修改repo文件中的enable的值 0 不启用 1 启用
            yum-config-manager --disable epel        #关闭仓库epel
            yum-config-manager --enable epel         #启用仓库epel
 
#查看        
            yum list                        #列出可用仓库中所有的软件包
            yum list | less
            yum grouplist                   #列出可用仓库中的软件组
 
            yum provides /usr/sbin/ifconfig   #查询命令所属的软件包,可以不加路径,只写命令名字
                                              #与rpm -qf的区别在于yum provides后可以只跟命名名
 
#安装        yum install httpd httpd-tools  #加上-y选项可以变成非交互
            yum groupinstall "开发工具" -y   #安装软件组,一个软件组中包含了多个软件包
            yum groups install "开发工具" -y   #同上
 
#卸载        yum remove httpd httpd-tools http*  #卸载软件包
            yum groupremove "开发工具" -y.       #卸载软件组
            yum groups remove "开发工具" -y      #同上
 
#重装        yum reinstall httpd             #不小心删除了配置文件的时,可以reinstall一下
 
#更新        yum check-update                 #检查可以更新的软件包
 
            yum update -y                    #更新所有软件包,包括内核,通常只在刚装完系统时执行
 
            yum update httpd -y              #更新某个软件包
 
#缓存              
            yum makecache                    #制作元数据缓存
            yum clean all                    #清理元数据缓存
            vim /etc/yum.conf                #默认软件包下载安装后会自动删除
                                             #设置keepcache=1 即开启了软件包缓存
                                             #缓存目录为配置文件中指定的cachedir
 
#历史记录
           yum history                       # 查看执行过的yum命令历史记录
           yum history info ID号             # 查看具体某一条yum命令的详细信息
           yum history undo ID号             # 撤销执行过的历史命令
 
# 关于安装需要注意:
无论yum安装的软件来自何方,yum时刻以自己仓库中的repodata存储的依赖关系为准,如果有多个仓库,就依次检索
#1、yum直接安装公网的rpm包, 会自动查找当前系统上已有的仓库解决依赖关系
yum install https://mirrors.aliyun.com/centos/7.6.1810/os/x86_64/Packages/samba-4.8.3-4.el7.x86_64.rpm
 
#2、Yum直接安装本地的rpm包,会自动查找当前系统上已有的仓库解决依赖关系
yum localinstall -y /mnt/Packages/httpd-2.4.6-88.el7.centos.x86_64.rpm

五,进程管理

1)进程介绍

程序:存放代码的文件》》静态

进程(加工车间概念):程序的运行进程》》动态

线程(生产线概念):进程内代码的执行过程,线程才是cpu上的执行单位,一个进程内至少有一个线程

同一个程序可能对应的多个进程

父进程:程序与运行时产生的第一个进程

子进程:由父进程衍生fork()出来的进程

注意:如果父进程终止,子进程也会随之被终止

并发:多个进程看起来是同时运行的(操作系统运用多道技术,为多个进程申请内存资源并实现物理上的隔离,再通过调度cpu去来回切换完成工作)

并行:多个任务是真正的同时运行(只有多核才能实现并行)

任务的三种运行状态:运行态,就绪态,阻塞态

提交任务的两种方式:同步(快递员那着包裹等着你签收)

​ 异步(快递员通知你一声就放下快递走了)

进程-进程之进程状态(R,S,D,T,Z,X)

#1、进程概念:
1)正在执行的程序
2)正在计算机上执行的程序实例
3)能分配处理器并由处理器执行的实体
进程的两个基本元素是程序代码和代码相关联的数据集。进程是一种动态描述,但并不代表所有的进程都在运行。这就可以引入‘进程状态’。
进程在内存中因策会略或调度需求,
会处于各种状态:
 
#2、Linux下的进程状态:
 
static const char * const task_state_array[] = {
"R (running)", /* 0 */
"S (sleeping)", /* 1 */
"D (disk sleep)", /* 2 */
"T (stopped)", /* 4 */
"t (tracing stop)", /* 8 */
"X (dead)", /* 16 */
"Z (zombie)", /* 32 */
};
 
# R- -可执行状态(运行状态)
只有在运行状态的进程才有可能在CPU上运行,注意是可能,并不意味着进程一定在运行中。同一时刻可能有多个进程处在可执行状态,这些进程的PCB(进程控制块)被放入对应CPU的可执行队列中。然后进程调度器从各个可执行队列中分别选择一个进程在CPU上运行。
另外如果计算机只有一个处理器,那么一次最多只有一个进程处于这种状态。
 
linux的两种睡眠状态S与D是一个重点知识,此处先赞做了解,后续我们将详细介绍
# S- -可中断睡眠状态(sleeping)
进程等待某个资源处于sleep状态,此时可以通过发送信号将这个进程唤醒。例如发送kill 信号。
 
# D- -不可中断睡眠(disk sleep)
进程在内核中某些不能被信号打断,例如对某些硬件设备进行操作时刻(等待磁盘Io,等待网络io等等)。进程处于D状态一般情况下很短暂,不应该被top或者ps看到。如果进程在top和ps看到长期处于D状态,那么可能进程在等待IO时出现了问题导致进程一直等待不到IO资源 此时如果要处理掉这个D进程,那么只能重启整个系统才会恢复。因为此时整个进程无法被kill 掉。
 
# T- -暂停状态
给进程发送一个SIGSTOP信号,进程就会响应信号进入T状态,除非该进程正处在D状态。
再通过发送SIGCONT信号让进程继续运行。
kill -SIGSTOP
kill -SIGCONT
 
# Z- -僵死状态
僵死状态是一个比较特殊的状态。进程在退出的过程中,处于TASK_DEAD状态。
在这个退出过程中,进程占有的所有资源将被回收,除了task_struct结构(以及少数资源)以外。于是进程就只剩下task_struct这么个空壳,故称为僵尸。
X- -死亡状态或退出状态(dead)
死亡状态是内核运⾏ kernel/exit.c ⾥的 do_exit() 函数返回的状态。这个状态只是⼀个返回状态,你不会在任务列表⾥看到这个状态

进程状态之间的切换

进程在运行中不断的改变运行状态;
1)就绪状态
当进程已分配到除CPU以外的所有必要的资源,只要获得处理机便可立即执行,这时的进程状态称为就绪状态。
2)执行(Running)状态
当进程已获得处理机,其程序正在处理机上执行,此时的进程状态称为执行状态
3) 阻塞(Blocked)状态
正在执行的进程,由于等待某个事件发生而无法执行时,便放弃处理机而处于阻塞状态。引起进程阻塞的事件可有多种,例如,等待I/O完成、申请缓冲区不能满足、等待信件(信号)等。
 
就绪–>执行
处在就绪状态的进程,当调度器为其分配了处理机后,就变成了执行状态。
 
执行–>就绪
执行状态的进程在其执行过程中,时间片跑完了不得不让出处理机,于是从执行变成就绪状态。
 
执行–>阻塞
正在执行的进程等待某种事件而无法继续执行时,便从执行状态变成阻塞状态。
 
阻塞–>就绪
处在阻塞状态的进程,如果等待的时间发生,则从阻塞状态转变成就绪状态。

----------->很重要的一段话<--------------

1.运行着的进程分为两种:一种是真的拿到cpu资源真的在运行,另外一种是在运行队列里,随时可以运行,处于R状态的进程泛指这两种状态。

2.睡眠时指,进程需要等待某种资源而进入状态,要等的资源可能是一个信号量,或者是磁盘的io,这个状态的进程会被放入到外wait queue队列里。睡眠着的进程具体还包括两个子进程:一个是可以被打断的,我们用ps查看到的进程,显示为S stat 。还有一个是不可以被打断的,用ps去查看是D stat。

3.除了上面进程在活着的时候的两个状态,进程在调用do_exit()退出的时候,会有两个状态:

​ (1)一个是:EXIT_DEAD,也就是进程在真正退出时那一瞬间的状态。

​ (2)另一个是:EXIT_ZOMBIE状态,这是进程在EXIT_DEAD前的一个状态,僵尸进程。

2)查看进程

ps命令

ps -aux 是常用组合,查看显示进程用户,pid,占用cpu百分比,占用内存百分比,状态,执行的命令等

-a         #显示一个终端的所有进程
 
-u        #选择有效的用户id或者是用户名
 
-x         #显示没有控制终端的进程,同时显示各个命令的具体路径。

查看带有父进程的命令:ps -ef

查看进程树:pstree + pid (yum下载psmisc)

查看root用户开启了那些进程:pgrep -lu root

查看结果显示

USER:    运行进程的用户
 
PID:    进程ID
 
%CPU:    CPU占用率
 
%MEM:    内存占用率
 
VSZ:    占用虚拟内存,单位:kb(killobytes)
         VSZ是指已分配的线性空间大小,这个大小通常并不等于程序实际用到的内存大小,产生这个的可能性很多 
         比如内存映射,共享的动态库,或者向系统申请了更多的堆,都会扩展线性空间大小。
 
RSS:    占用实际内存,单位:kb(killobytes)
        RSZ是Resident Set Size,常驻内存大小,即进程实际占用的物理内存大小
 
TTY:    进程运行的终端
 
STAT:   进程状态     man ps (/STATE)            
      R     运行
      S     可中断睡眠 Sleep,即在睡眠的过程中可以接收信号唤醒=》执行的IO操作可以得到硬件设备的响应
      D     不可中断睡眠,即在睡眠的过程中不可以接收信号唤醒=》执行的IO操作得不到硬件设备的响应
      T     停止的进程 
      Z     僵尸进程
      X     死掉的进程(几乎看不见,因为死了就立即回收了)
 
      <  标注了<小于号代表优先级较高的进程
      N     N代表优先级较低的进程
 
      s     包含子进程
 
      +     +表示是前台的进程组
 
      l     小写字母l,代表以线程的方式运行,即多线程
      |     管道符号代表多进程
 
START:    进程的启动时间
TIME:    进程占用CPU的总时间
 
COMMAND: 进程文件,进程名
          带[]号的代表内核态进程
          不带[]号的代表用户态进程

ps按内存排序:

# ps aux --sort -rss | head   #按照虚拟内存使用量进行排序

使用以下 ps 命令格式可在输出中仅展示有关内存消耗过程的特定信息。
# ps -eo pid,ppid,%mem,%cpu,cmd --sort=-%mem | head

如果你只想查看命令名称而不是命令的绝对路径,请使用下面的 ps 命令格式。
# ps -eo pid,ppid,%mem,%cpu,comm --sort=-%mem | head

lsof命令

列出某个程序所打开的文件信息:

lsof -c mysql

列出某个用户打开的文件信息

lsof  -u username

查看谁正在使用某个文件

lsof   /filepath/file

通过某个进程号显示该进程打开的文件

lsof -p 111      #列出多个进程号就是111,222,333

列出所有tcp 网络连接信息

lsof  -i tcp

列出所有udp网络连接信息

lsof  -i udp

列出谁在使用某个端口

lsof -i :3306

特定的tcp端口和udp端口

lsof -i udp:55
lsof -i tcp:3306

top按内存排序:

你应该正确地 了解 top 命令输出 以解决系统中的性能问题。
# top -c -b -o +%MEM | head -n 20 | tail -15   #按照虚拟内存使用量进行排序

如果你只想查看命令名称而不是命令的绝对路径,请使用下面的 top 命令格式。
# top -b -o +%MEM | head -n 20 | tail -15

linux进程有两种睡眠状态、

################## 1、S (TASK_INTERRUPTIBLE)(可中断睡眠,在ps命令中显示“S”)##################
处于这个状态的进程因为等待某某事件的发生(比如等待socket连接、等待信号量),而被挂起。这些进程的task_struct结构被放入对应事件的等待队列中。当这些事件发生时(由外部中断触发、或由其他进程触发),对应的等待队列中的一个或多个进程将被唤醒。
 
例如:处在这种睡眠状态的进程是可以通过给它发送signal来唤醒的,比如发HUP信号给nginx的master进程可以让nginx重新加载配置文件而不需要重新启动nginx进程;
 
通过ps命令我们会看到,一般情况下,进程列表中的绝大多数进程都处于TASK_INTERRUPTIBLE状态(除非机器的负载很高)。毕竟CPU就这么一两个,进程动辄几十上百个,如果不是绝大多数进程都在睡眠,CPU又怎么响应得过来。
 
 
 
##################### 2、D (TASK_UNINTERRUPTIBLE)(不可中断睡眠,在ps命令中显示“D”)##################
与TASK_INTERRUPTIBLE状态类似,进程处于睡眠状态,但是此刻进程是不可中断的。不可中断,指的并不是CPU不响应外部硬件的中断,而是指进程不响应异步信号。
 
绝大多数情况下,进程处在睡眠状态时,总是应该能够响应异步信号的。否则你将惊奇的发现,kill -9竟然杀不死一个正在睡眠的进程了!于是我们也很好理解,为什么ps命令看到的进程几乎不会出现TASK_UNINTERRUPTIBLE状态,而总是TASK_INTERRUPTIBLE状态。
 
而TASK_UNINTERRUPTIBLE状态存在的意义就在于,内核的某些处理流程是不能被打断的。如果响应异步信号,程序的执行流程中就会被插入一段用于处理异步信号的流程(这个插入的流程可能只存在于内核态,也可能延伸到用户态),于是原有的流程就被中断了。
 
在进程对某些硬件进行操作时(比如进程调用read系统调用对某个设备文件进行读操作,而read系统调用最终执行到对应设备驱动的代码,并与对应的物理设备进行交互),可能需要使用TASK_UNINTERRUPTIBLE状态对进程进行保护,以避免进程与设备交互的过程被打断,造成设备陷入不可控的状态。这种情况下的TASK_UNINTERRUPTIBLE状态总是非常短暂的,通过ps命令基本上不可能捕捉到。
 
不可中断状态的进程则是正处于内核态关键流程中的进程,并且这些流程是不可打断的,比如最常见的是等待硬件设备的I/O响应,也就是我们在ps命令中看到的D状态(Uninterruptible Sleep,也称为Disk Sleep)的进程。
 
比如,当一个进程向磁盘读写数据时,为了保证数据的一致性,在得到磁盘回复前,它是不能被其他进程或者中断打断的,这个时候的进程就处于不可中断状态。如果此时的进程被打断了,就容易出现磁盘数据与进程数据不一致的问题。
 
!!!!!!!!!!!!!!!!!!!!所以,不可中断状态实际上是系统对进程和硬件设备的一种保护机制!!!!!!!!!!。
!!!!!!!!!!!!!!!!!!!!所以,不可中断状态实际上是系统对进程和硬件设备的一种保护机制!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!所以,不可中断状态实际上是系统对进程和硬件设备的一种保护机制!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!所以,不可中断状态实际上是系统对进程和硬件设备的一种保护机制!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!所以,不可中断状态实际上是系统对进程和硬件设备的一种保护机制!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!所以,不可中断状态实际上是系统对进程和硬件设备的一种保护机制!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!所以,不可中断状态实际上是系统对进程和硬件设备的一种保护机制!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!所以,不可中断状态实际上是系统对进程和硬件设备的一种保护机制!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!所以,不可中断状态实际上是系统对进程和硬件设备的一种保护机制!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!所以,不可中断状态实际上是系统对进程和硬件设备的一种保护机制!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!所以,不可中断状态实际上是系统对进程和硬件设备的一种保护机制!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!所以,不可中断状态实际上是系统对进程和硬件设备的一种保护机制!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!所以,不可中断状态实际上是系统对进程和硬件设备的一种保护机制!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!所以,不可中断状态实际上是系统对进程和硬件设备的一种保护机制!!!!!!!!!!
 
linux系统中也存在容易捕捉的TASK_UNINTERRUPTIBLE状态。执行vfork系统调用后,父进程将进TASK_UNINTERRUPTIBLE状态,直到子进程调用exit或exec 通过下面的代码就能得到处于TASK_UNINTERRUPTIBLE状态的进程:
 
[root@localhost ~]# cat test.c 
void main() {  
if (!vfork()) sleep(100);  
} 
 
[root@localhost ~]# gcc -o test  test.c
 
[root@localhost ~]# ./test 
 
[root@localhost ~]# ps -aux | grep test
root      19454  0.0  0.0   4212   352 pts/6    D+   10:02   0:00 ./test
root      19455  0.0  0.0   4212   352 pts/6    S+   10:02   0:00 ./test
 
# 进程为什么会被置于uninterruptible sleep状态呢?
进程为什么会被置于D状态呢?处于uninterruptible sleep状态的进程通常是在等待IO,比如磁盘IO,网络IO,其他外设IO,如果进程正在等待的IO在较长的时间内都没有响应,那么就很会不幸地被ps看到了,同时也就意味着很有可能有IO出了问题,可能是外设本身出了故障,也可能是比如NFS挂载的远程文件系统已经不可访问了。
 
正是因为得不到IO的响应,进程才进入了uninterruptible sleep状态,所以要想使进程从uninterruptible sleep状态恢复,就得使进程等待的IO恢复,比如如果是因为从远程挂载的NFS卷不可访问导致进程进入uninterruptible sleep状态的,那么可以通过恢复该NFS卷的连接来使进程的IO请求得到满足。
 
# 强调
D与Z状态的进程都无法用kill -9杀死
 
# D状态,往往是由于 I/O 资源得不到满足,而引发等待
在内核源码 fs/proc/array.c 里,其文字定义为“ "D (disk sleep)", /* 2 */ ”(由此可知 D 原是Disk的打头字母),对应着 include/linux/sched.h 里的“ #define TASK_UNINTERRUPTIBLE 2 ”。举个例子,当 NFS 服务端关闭之时,若未事先 umount 相关目录,在 NFS 客户端执行 df 就会挂住整个登录会话,按 Ctrl+C 、Ctrl+Z 都无济于事。断开连接再登录,执行 ps axf 则看到刚才的 df 进程状态位已变成了 D ,kill -9 无法杀灭。正确的处理方式,是马上恢复 NFS 服务端,再度提供服务,刚才挂起的 df 进程发现了其苦苦等待的资源,便完成任务,自动消亡。若 NFS 服务端无法恢复服务,在 reboot 之前也应将 /etc/mtab 里的相关 NFS mount 项删除,以免 reboot 过程例行调用 netfs stop 时再次发生等待资源,导致系统重启过程挂起。
 
Nginx举例一则,只是举个例子大概看看就行
第二客户端机器我们将运行另一个副本的wrk,但是这个脚本我们使用50的并发连接来请求相同的文件。因为这个文件被经常访问的,它将保持在内存中。在正常情况下,NGINX很快的处理这些请求,但是工作线程如果被其他的请求阻塞性能将会下降。所以我们暂且叫它“加载恒定负载”。
 
性能将由服务器上ifstat监测的吞吐率(throughput)和从第二台客户端获取的wrk结果来度量。
 
现在,没有线程池的第一次运行不会给我们带来非常令人兴奋的结果
top - 10:40:47 up 11 days,  1:32,  1 user,  load average: 49.61, 45.77 62.89
Tasks: 375 total,  2 running, 373 sleeping,  0 stopped,  0 zombie
%Cpu(s):  0.0 us,  0.3 sy,  0.0 ni, 67.7 id, 31.9 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem:  49453440 total, 49149308 used,   304132 free,    98780 buffers
KiB Swap: 10474236 total,    20124 used, 10454112 free, 46903412 cached Mem
 
  PID USER     PR  NI    VIRT    RES     SHR S  %CPU %MEM    TIME+ COMMAND
 4639 vbart    20   0   47180  28152     496 D   0.7  0.1  0:00.17 nginx
 4632 vbart    20   0   47180  28196     536 D   0.3  0.1  0:00.11 nginx
 4633 vbart    20   0   47180  28324     540 D   0.3  0.1  0:00.11 nginx
 4635 vbart    20   0   47180  28136     480 D   0.3  0.1  0:00.12 nginx
 4636 vbart    20   0   47180  28208     536 D   0.3  0.1  0:00.14 nginx
 4637 vbart    20   0   47180  28208     536 D   0.3  0.1  0:00.10 nginx
 4638 vbart    20   0   47180  28204     536 D   0.3  0.1  0:00.12 nginx
 4640 vbart    20   0   47180  28324     540 D   0.3  0.1  0:00.13 nginx
 4641 vbart    20   0   47180  28324     540 D   0.3  0.1  0:00.13 nginx
 4642 vbart    20   0   47180  28208     536 D   0.3  0.1  0:00.11 nginx
 4643 vbart    20   0   47180  28276     536 D   0.3  0.1  0:00.29 nginx
 4644 vbart    20   0   47180  28204     536 D   0.3  0.1  0:00.11 nginx
 4645 vbart    20   0   47180  28204     536 D   0.3  0.1  0:00.17 nginx
 4646 vbart    20   0   47180  28204     536 D   0.3  0.1  0:00.12 nginx
 4647 vbart    20   0   47180  28208     532 D   0.3  0.1  0:00.17 nginx
 4631 vbart    20   0   47180    756     252 S   0.0  0.1  0:00.00 nginx
 4634 vbart    20   0   47180  28208     536 D   0.0  0.1  0:00.11 nginx<
 4648 vbart    20   0   25232   1956    1160 R   0.0  0.0  0:00.08 top
25921 vbart    20   0  121956   2232    1056 S   0.0  0.0  0:01.97 sshd
25923 vbart    20   0   40304   4160    2208 S   0.0  0.0  0:00.53 zsh
在这种情况下,吞吐率受限于磁盘子系统,而CPU在大部分时间里是空转状态的。从wrk获得的结果来看也非常低:
Running 1m test @ http://192.0.2.1:8000/1/1/1
  12 threads and 50 connections
  Thread Stats   Avg    Stdev     Max  +/- Stdev
    Latency     7.42s  5.31s   24.41s   74.73%
    Req/Sec     0.15    0.36     1.00    84.62%
  488 requests in 1.01m, 2.01GB read
Requests/sec:      8.08
Transfer/sec:     34.07MB
请记住,文件是从内存送达的!第一个客户端的200个连接创建的随机负载,使服务器端的全部的工作进程忙于从磁盘读取文件,因此产生了过大的延迟,并且无法在合适的时间内处理我们的请求。

top命令

基本语法:
[root@localhost ~]# top
[root@localhost ~]# top -d 1  # 1秒刷新一次
[root@localhost ~]# top -d 1 -p 进程的pid
[root@localhost ~]# top -d 1 -p `pgrep nginx | head -1`
[root@localhost ~]# top -d 1 -p `pgrep sshd | head -1`,33  # 查看sshd以及pid为33的进程
[root@localhost ~]# top -d 1 -u nginx  # 查看指定用户进程
[root@localhost ~]# top -b -n 2 > top.txt  # 将2次top信息写入到文件
显示信息的解释:
第一部分:系统整体统计信息
up左边的代表当前的时间
up右边代表运行了多长时间
load average: 0.86, 0.56, 0.78    CPU 1分钟,5分钟,15分钟平均负载
 
平均负载解释如下:
'''
===========>什么是平均负载?
平均负载是指,单位时间内,系统处于可运行状态和不可中断状态的平均进程数,也就是平均活跃进程数
 
===========>平均负载多少合理? 
假设现在在4,2,1核的CPU上,如果平均负载为2时,意味着什么呢?
------------------------------------------------
核心数      平均负载        含义
4             2         有一半(50%)的CPU是空闲状态
2             2         CPU刚好完全被占用
1             2         至少一半的进程是抢不到CPU
-------------------------------------------------
 
===========>平均负载的三个数值我们该关注哪一个?
三个值相当于三个样本,我们应该统筹地看
1、如果1分钟,5分钟,15分钟的负载数值相差不大,代表系统的负载很'稳定'
2、如果1分钟的值,远小于15分钟的值,那么证明系统的平均负载逐渐降低,即我们的系统刚刚经历过大风浪,但目前已逐渐趋于平均。至于15分钟区间内,系统负载上升的原因,还需要我们认真查明
3、如果15分钟的值,远小于1分钟的值,那么证明系统的平均负载逐渐升高,有可能是临时的也有可能持续上升,需要观察
4、一旦1分钟的平均负载接近或超过了CPU的个数,就意味着,系统正在发生过载的问题,这时候就得分析问题了, 并且要想办法优化。
 
==========>平均负载实验:4个CPU跑满
[root@egon ~]# cat /proc/cpuinfo  | grep processor
processor   : 0
processor   : 1
processor   : 2
processor   : 3
打开窗口1:执行top命令,然后按1,观察四个核的id几乎为100%,然后在窗口2执行命令观察负载情况
[root@egon ~]# top
[root@egon ~]# 按1
 
打开窗口2:依次执行下述命令,然后在窗口来观察变化
[root@egon ~]# while true;do ((1+1));done &
[root@egon ~]# while true;do ((1+1));done &
[root@egon ~]# while true;do ((1+1));done &
[root@egon ~]# while true;do ((1+1));done &
 
用ps aux | grep bash会看到一系列R的bash进程,然后一个个杀掉,观察cpu的负载逐步恢复平静
 
思考:如果把测试命令换成下述命令,一直连续执行n次,cpu负载都不会很高,为什么??
[root@egon ~]# while true;do ((1+1));sleep 0.1;done &  
[root@egon ~]# while true;do ((1+1));sleep 0.1;done &  
[root@egon ~]# while true;do ((1+1));sleep 0.1;done &  
。。。执行好多次
 
补充1:也可以使用stress工具来取代上述的while命令
stress是Linux系统压力测试工具,可用作异常进程模拟平均负载升高的场景,需要安装yum install stress -y
[root@egon ~]# stress --cpu 4 --timeout 3000  # 3000代表持续执行3000秒
 
补充2:安装yum install sysstat -y会得到下述两个命令
mpstat 是多核CPU性能分析工具,用来实时检查每个CPU的性能指标,以及所有CPU的平均指标。
[root@egon ~]# mpstat -P ALL 3  # 3s输出一组所有指标
 
pidstat 是一个常用的进程性能分析工具,用来实时查看进程的CPU,内存,IO,以及上下文切换等性能指标。
[root@egon ~]# pidstat -u 1 5  # 1秒一次,总共输出5次
'''
第三行显示信息解释
us User,用户态进程占用cpu时间的百分比,不包括低优先级进程的用户态时间(nice值1-19)
sys System,内核态进程占用cpu时间的百分比
ni Nice,nice值1-19的进程用户态占cpu时间的百分比
id Idle,系统空闲cpu的百分比
wa Iowait,系统等待I/O的cpu时间占比,该时间不计入进程的CPU时间
hi Hardware irq,处理硬件中断所占用CPU的时间,该时间同样不计入进程的CPU时间
si Softtirq,处理软件中断的时间,该时间不计入进程的CPU时间
st Steal,表示同一宿主机上的其他虚拟机抢走的CPU时间
 
linux中断:https://www.cnblogs.com/linhaifeng/articles/13916102.html

3)shell管理进程

关于HUP信号:

在 Unix 的早期版本中,每个终端都会通过 modem(理解为终端) 和系统通讯。
当用户 logout 时,modem 就会挂断(hang up)电话。 
同理,当 modem 断开连接时,就会给终端发送 hangup 信号来通知其关闭所有子进程。 

综上,用户注销(logout)或者网络断开或者关闭终端(关闭终端,不是单纯的exit)时,终端都会收到来自linux hup 信号,然后会关闭所有子进程

要想我们的进程一直在后台运行,有几种方式:

​ nohup命令

​ setsid命令

​ 在子shell中提交任务

​ screen

3.1 nohup

nohup的用途就是让提交的命令忽略hangup信号,该命令通常与&符号一起使用

nohup 的使用是十分方便的,只需在要处理的命令前加上 nohup 即可,但是 nohup 命令会从终端解除进程的关联,进程会丢掉STDOUT,STDERR的链接。标准输出和标准错误缺省会被重定向到 nohup.out 文件中。一般我们可在结尾加上"&"来将命令同时放入后台运行,也可用">filename 2>&1"来更改缺省的重定向文件名。

语法:
#nohup  ping www.baidu.com  &>/dev/null  &
#nohup  ping www.baidu.com   &   下面这种方式会把日志输入到当前文件夹下的nohup.out文件里

#可以使用jobs -l 查看有那些挂载到后台运行的进程
#kill %1  可以终止相应进程

3.2 setsid

setsid会把进程的父id改为1,让运行的程序归init程序管理

# 1、在终端2中执行命令
[root@egon ~]# setsid ping www.baidu.com  # 也可以在后面加&符号
 
# 2、关闭终端2
 
# 3、在终端1中查看
[root@egon ~]# ps -ef |grep [p]ing
root     102335      1  0 17:53 ?        00:00:00 ping www.baidu.com

3.3 在子shell中提交任务

# 1、在终端2中执行命令
[root@egon ~]# (ping www.baidu.com &)  # 提交的作业并不在作业列表中
 
# 2、关闭终端2
 
# 3、在终端1中查看
[root@egon ~]# ps -ef |grep [p]ing
root     102361      1  0 17:55 ?        00:00:00 ping www.baidu.com
 
可以看到新提交的进程的父 ID(PPID)为1(init 进程的 PID),并不是当前终端的进程 ID。因此并不属于当前终端的子进程,从而也就不会受到当前终端的Linux HUP信号的影响了。

3.4 screen 会话分离

安装:

#yum -y install screen

如何启动一个 screen 会话:

#screen 
#screen -S name

从 screen 会话中分离:

#要从当前的 screen 会话中分离,你可以按下 Ctrl- a+d

重新连接到 screen 会话:

#screen -r
##screen -r -S name #名字的方式连接

如果你有多个 screen 会话,你可以用 ls 参数列出它们。

#screen -ls

中止 screen 会话:

#你可以按下 Ctrl+d,或者在命令行中使用 exit 命令。
#exit

多个用户进入同一个窗口:可以实现共享屏幕的感觉

screen -x  -S  窗口名字

3.5 扩展知识

jobs

查看“当前终端”后台运行的进程
#jobs
#[1]+  运行中               ping www.baidu.com &>>/tmp/acces.log &

bg

bg命令:启动“当前终端”后台运行的进程 (类似于给进程直接发18信号,但这个仅限于当前终端起的进程   kill -18)
#bg %1

fg

fg命令:将“当前终端”后台运行的进程调到前台来运行 
#fg %1

4) 僵尸进程 ,孤儿进程

僵尸:

#1、什么是僵尸进程
操作系统负责管理进程
我们的应用程序若想开启子进程,都是在向操作系统发送系统调用
当一个子进程开启起来以后,它的运行与父进程是异步的,彼此互不影响,谁先死都不一定
 
linux操作系统的设计规定:父进程应该具备随时获取子进程状态的能力
如果子进程先于父进程运行完毕,此时若linux操作系统立刻把该子进程的所有资源全部释放掉,那么父进程来查看子进程状态时,会突然发现自己刚刚生了一个儿子,但是儿子没了!!!
这就违背了linux操作系统的设计规定
所以,linux系统出于好心,若子进程先于父进程运行完毕/死掉,那么linux系统在清理子进程的时候,会将子进程占用的重型资源都释放掉(比如占用的内存空间、cpu资源、打开的文件等),但是会保留一部分子进程的关键状态信息,比如进程号the process ID,退出状态the termination status of the process,运行时间the amount of CPU time taken by the process等,此时子进程就相当于死了但是没死干净,因而得名"僵尸进程",其实僵尸进程是linux操作系统出于好心,为父进程准备的一些子进程的状态数据,专门供父进程查阅,也就是说"僵尸进程"是linux系统的一种数据结构,所有的子进程结束后都会进入僵尸进程的状态
 
# 2、那么问题来了,僵尸进程残存的那些数据不需要回收吗???
当然需要回收了,但是僵尸进程毕竟是linux系统出于好心,为父进程准备的数据,至于回收操作,应该是父进程觉得自己无需查看僵尸进程的数据了,父进程觉得留着僵尸进程的数据也没啥用了,然后由父进程发起一个系统调用wait / waitpid来通知linux操作系统说:哥们,谢谢你为我保存着这些僵尸的子进程状态,我现在用不上他了,你可以把他们回收掉了。然后操作系统再清理掉僵尸进程的残余状态,你看,两者配合的非常默契,但是,怕就怕在。。。
 
# 3、分三种情况讨论
1、linux系统自带的一些优秀的开源软件,这些软件在开启子进程时,父进程内部都会及时调用wait/waitpid来通知操作系统回收僵尸进程,所以,我们通常看不到优秀的开源软件堆积僵尸进程,因为很及时就回收了,与linux系统配合的很默契
 
2、一些水平良好的程序员开发的应用程序,这些程序员技术功底深厚,知道父进程要对子进程负责,会在父进程内考虑调用wait/waitpid来通知操作系统回收僵尸进程,但是发起系统调用wait/waitpid的时间可能慢了些,于是我们可以在linux系统中通过命令查看到僵尸进程状态
[root@egon ~]# ps aux | grep [Z]+
 
3、一些垃圾程序员,技术非常垃圾,只知道开子进程,父进程也不结束,就在那傻不拉几地一直开子进程,也压根不知道啥叫僵尸进程,至于wait/waitpid的系统调用更是没听说过,这个时候,就真的垃圾了,操作系统中会堆积很多僵尸进程,此时我们的计算机会进入一个奇怪的现象,就是内存充足、硬盘充足、cpu空闲,但是,启动新的软件就是无法启动起来,为啥,因为操作系统负责管理进程,每启动一个进程就会分配一个pid号,而pid号是有限的,正常情况下pid也用不完,但怕就怕堆积一堆僵尸进程,他吃不了多少内存,但能吃一堆pid
 
# 4、如果清理僵尸进程
针对情况3,只有一种解决方案,就是杀死父进程,那么僵尸的子进程会被linux系统中pid为1的顶级进程(init或systemd)接管,顶级进程会定期发起系统调用wait/waitpid来通知操作系统清理僵尸
 
针对情况2,可以发送信号给父进程,通知它快点发起系统调用wait/waitpid来清理僵尸的儿子
kill -CHLD 父进程PID
 
# 5、结语
僵尸进程是linux系统出于好心设计的一种数据结构,一个子进程死掉后,相当于操作系统出于好心帮它的爸爸保存它的遗体,之说以会在某种场景下有害,是因为它的爸爸不靠谱,儿子死了,也不及时收尸(发起系统调用让操作系统收尸)
 
说白了,僵尸进程本身无害,有害的是那些水平不足的程序员,他们总是喜欢写bug,好吧,如果你想看看垃圾程序员是如何写bug来堆积僵尸进程的,你可以看一下这篇博客https://www.cnblogs.com/linhaifeng/articles/13567273.html

孤儿:

父进程先死掉,而它的一个或多个子进程还在运行,那么那些子进程将成为孤儿进程。孤儿进程将被进程号为1的顶级进程(init或systemd)所收养,并由顶级进程对它们完成状态收集工作。
进程就好像是一个民政局,专门负责处理孤儿进程的善后工作。每当出现一个孤儿进程的时候,内核就把孤儿进程的父进程设置为顶级进程,而顶级进程会循环地wait()它的已经退出的子进程。这样,当一个孤儿进程凄凉地结束了其生命周期的时候,顶级进程就会代表党和政府出面处理它的一切善后工作。因此孤儿进程并不会有什么危害。
 

5)排查java内存问题工具:

jmap

概述

jmap -heap 是一个Java 命令行工具,用于获取Java 进程的堆内存信息。它会输出 Java 进程的整体堆内存使用情况,包括 heap 总大小、已使用大小、空闲大小等。同时还会输出堆内存中各种对象所占用的空间大小以及数量,如类、字符数组、字符串等。

在使用 jmap -heap 命令时,需要注意以下几点:

  1. jmap -heap 命令会暂停 Java 进程的执行并进行内存快照,可能会对应用程序的性能产生一定的影响。
  2. jmap -heap 命令只能用于 HotSpot 虚拟机,不适用于其他虚拟机实现。
  3. jmap -heap 命令可能会产生较大的输出,建议将输出重定向到文件中以便后续分析。

参数:

  • -dump:导出 Java 堆内存中的内容到文件中。
  • -file:指定导出文件的文件名,如果不指定则默认为 java_pid[进程 ID].hprof。
  • -F:强制执行指令,即使 JVM 正在退出或者已经退出。
  • -histo:打印 Java 堆内存中各个对象类型的实例数目和大小。
  • -J:传递参数给 JVM,例如“-J-Xms512m”。
常用命令
  1. 查看 24126 进程的堆内存使用情况

jmap -heap 24126

# 查看 24126 进程的堆内存使用情况
jmap -heap 24126


jmap -heap 24126


# 表示 jmap 正在尝试连接并附加到一个进程ID为 24126 的Java进程
Attaching to process ID 24126, please wait...
# 表示 jmap 已经成功附加到了该进程并成功连接了调试器
Debugger attached successfully.
# 表示该 Java 进程正在运行 Server 模式的编译器
Server compiler detected.
# 表示该 Java 程序的版本号为 25.121-b13
JVM version is 25.121-b13

# 表示 Java 进程正在使用线程本地对象分配的方式
using thread-local object allocation.
# 表示 Java 进程正在使用 4 个线程来进行并行垃圾回收
Parallel GC with 4 thread(s)

# 堆内存配置信息
Heap Configuration:
   MinHeapFreeRatio         = 0                       # 表示在堆内存达到最大值之前,堆内存中不允许有任何自由空间
   MaxHeapFreeRatio         = 100                     # 表示在堆内存达到最大值之后,堆内存中允许全部是自由空间
   MaxHeapSize              = 5368709120 (5120.0MB)   # 表示堆内存的最大容量为 5GB
   NewSize                  = 2684354560 (2560.0MB)   # 表示新生代(Young Generation)的初始容量为 2.5GB
   MaxNewSize               = 2684354560 (2560.0MB)   # 表示新生代的最大容量为 2.5GB
   OldSize                  = 2684354560 (2560.0MB)   # 表示老年代(Old Generation)的初始容量为 2.5GB
   NewRatio                 = 1                       # 表示新生代与老年代内存大小的比例为 1:1
   SurvivorRatio            = 8                       # 表示 Eden 区域与 Survivor 区域之间内存大小的比例为 8:1
   MetaspaceSize            = 21807104 (20.796875MB)  # 表示元数据区域的大小为 20.8MB
   CompressedClassSpaceSize = 1073741824 (1024.0MB)   # 表示压缩类空间的大小为 1GB
   MaxMetaspaceSize         = 17592186044415 MB       # 表示元数据区域的最大容量为 16 EB(exabytes)
   G1HeapRegionSize         = 0 (0.0MB)               # 表示 G1 垃圾回收器使用的内存段的大小为 0

# 堆内存的使用情况
Heap Usage:
PS Young Generation                                   # 表示使用了 Parallel Scavenge(PS)年轻代内存的信息
Eden Space:                                           # 表示 Eden 区域的使用情况
   capacity = 1009254400 (962.5MB)                    # 表示 Eden 区域的最大容量为 962.5MB
   used     = 474955488 (452.9528503417969MB)         # 表示 Eden 区域已使用的内存大小为 452.95MB
   free     = 534298912 (509.5471496582031MB)         # 表示 Eden 区域尚未使用的内存大小为 509.55MB
   47.06003639914773% used
From Space:                                           # 表示 Survivor 0 区域的使用情况
   capacity = 834142208 (795.5MB)                     # 表示 Survivor 0 区域的最大容量为 795.5MB
   used     = 326834600 (311.69376373291016MB)        # 表示 Survivor 0 区域已使用的内存大小为 311.69MB
   free     = 507307608 (483.80623626708984MB)        # 表示 Survivor 0 区域尚未使用的内存大小为 483.81MB
   39.182119891000646% used
To Space:                                             # 表示 Survivor 1 区域的使用情况
   capacity = 793247744 (756.5MB)                     # 表示 Survivor 1 区域的最大容量为 756.5MB
   used     = 0 (0.0MB)                               # 表示 Survivor 1 区域尚未使用任何内存
   free     = 793247744 (756.5MB)                     # 表示 Survivor 1 区域尚未使用的内存大小为 756.5MB
   0.0% used
PS Old Generation                                     # 表示使用了 Parallel Scavenge(PS)老年代内存的信息
   capacity = 2684354560 (2560.0MB)                   # 表示老年代的最大容量为 2.5GB
   used     = 1371482032 (1307.9471893310547MB)       # 表示老年代已使用的内存大小为 1307.95MB
   free     = 1312872528 (1252.0528106689453MB)       # 表示老年代尚未使用的内存大小为 1252.05MB
   51.091687083244324% used                           # 表示老年代已使用内存占总内存的比例为 51.09%

53559 interned Strings occupying 6180024 bytes.

  1. 输出为dump文件

​ 执行这个命令,JVM 会将整个 heap 的信息 dump 到一个文件,heap 如果比较大的话会导致这个过程比较耗时,并且执行的过程中为了保证 dump 的信息是可靠的会暂停应用。

jmap -dump:live,format=b,file=a.log 1213 # live是只打印活着的

jmap -dump:format=b,file=a.log 1213

  1. 查看对象数最多的对象,并按降序排序输出

jmap -histo |sort -k 2 -g -r|less

  1. 查看占用内存最多的对象,并按降序排序输出

jmap -histo |sort -k 3 -g -r|less

jstat

jstat命令可以查看堆内存各部分的使用量,以及加载类的数量

1.编译统计

jstat -compiler 19570

结果解析:

Compiled:编译数量。
Failed:失败数量
Invalid:不可用数量
Time:时间
FailedType:失败类型
FailedMethod:失败的方法

2.垃圾回收统计

jstat -gc 19570 1000 #1000表示一秒钟打印一次

image-20230925135522237

结果解析

S0C:第一个幸存区的大小
S1C:第二个幸存区的大小
S0U:第一个幸存区的使用大小
S1U:第二个幸存区的使用大小
EC:伊甸园区的大小
EU:伊甸园区的使用大小
OC:老年代大小
OU:老年代使用大小
MC:方法区大小
MU:方法区使用大小
CCSC:压缩类空间大小
CCSU:压缩类空间使用大小
YGC:年轻代垃圾回收次数
YGCT:年轻代垃圾回收消耗时间
FGC:老年代垃圾回收次数
FGCT:老年代垃圾回收消耗时间
GCT:垃圾回收消耗总时间

jstack

jstack分析cpu过高问题

  • top
  • top -H -p pid
  • 在top种shift + h #找到占用cpu最高的线程
  • printf %x 线程id # 转换为16进制
  • jstack pid |grep 16进制数
  • jstcak -l pid >/tmp/log.txt
  • 分析堆栈信息

六,存储管理

目前常见的磁盘分区格式有两种,MBR分区和GPT分区

MBR 分区,MBR 的意思是 "主引导记录"。MBR 最大支持 2TB 容量,在容量方面存在着极大的瓶颈。
GPT 分区,GPT 意为 GUID 分区表,它支持的磁盘容量比 MBR 大得多。这是一个正逐渐取代 MBR 的新标准,它是由 UEFI 辅住而形成的,将来 UEFI 用于取代老旧的 BIOS,而 GPT 则取代老旧的 MBR。

磁盘分区工具

MBR 分区,MBR 的意思是 "主引导记录"。MBR 最大支持 2TB 容量,在容量方面存在着极大的瓶颈。
GPT 分区,GPT 意为 GUID 分区表,它支持的磁盘容量比 MBR 大得多。这是一个正逐渐取代 MBR 的新标准,它是由 UEFI 辅住而形成的,将来 UEFI 用于取代老旧的 BIOS,而 GPT 则取代老旧的 MBR。

1) MBR分区

[root@egon ~]# lsblk /dev/sda
NAME   MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
sda      8:0    0   10G  0 disk 
├─sda1   8:1    0  500M  0 part /boot
├─sda2   8:2    0    1G  0 part [SWAP]
└─sda3   8:3    0  8.5G  0 part /
[root@egon ~]# 
[root@egon ~]# lsblk /dev/sdb
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sdb    8:16   0  20G  0 disk 
[root@egon ~]# lsblk /dev/sdc
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sdc    8:32   0  20G  0 disk 

fdisk工具

适用于磁盘小于2T的磁盘,

语法:

​ #fdisk /dev/sdb

命令选项:

n  #新建分区
p  #打印分区
d  # 删除一个已有的分区,保存退出后需要执行partprobe命令刷新一下分区表
w  #保存

查看磁盘分区情况:

fdisk -l  或者 lsblk -f

2) GPT分区

适用于磁盘大于2T的

# 需要安装命令
[root@egon ~]# yum install gdisk -y    ##########安装##########
 
[root@egon ~]# gdisk /dev/sdc           ########语法#########
......
Command (? for help): m      ######m为帮助信息##########
b    back up GPT data to a file                            #将GPT数据备份到文件中
 
c    change a partition's name                            #更改分区的名称
 
d    delete a partition                                    #删除分区
 
i    show detailed information on a partition            #显示分区的详细信息
 
l    list known partition types                            #列出已知的分区类型
 
n    add a new partition                                    #添加一个新的分区
 
o    create a new empty GUID partition table (GPT)        #创建一个新的空GUID分区表(GPT)
p    print the partition table                            #打印分区表
 
q    quit without saving changes                            #没有保存更改就退出
 
r    recovery and transformation options (experts only)    #恢复和转换选项(仅限专家使用)
s    sort partitions                                        #年代分类分区
 
t    change a partition's type code                        #不要更改分区的类型代码
 
v    verify disk                                            #验证磁盘
 
w    write table to disk and exit                        #将表写入磁盘并退出
 
x    extra functionality (experts only)                    #额外功能(仅限专家使用)
?    print this menu                                        #打印菜单



#######常用选项#####
n  #新建分区
p  #打印分区
d  # 删除一个已有的分区,保存退出后需要执行partprobe命令刷新一下分区表
w  #保存

例子:

Command (? for help): n  # 新建
Partition number (1-128, default 1):  # 直接回车,默认分区号为1
First sector (34-5242879966, default = 2048) or {+-}size{KMGTP}: #直接回车,使用默认的起始位置
Last sector (2048-5242879966, default = 5242879966) or {+-}size{KMGTP}: +1G # 设定1G的空间
Current type is 'Linux filesystem'
Hex code or GUID (L to show codes, Enter = 8300): L  # 列出所有文件系统
......会看到一系列文件系统信息,默认的8300编号代表Linux filesystem,用它就好
Hex code or GUID (L to show codes, Enter = 8300):  # 直接回车用默认8300就好
Changed type of partition to 'Linux filesystem'
 
Command (? for help): p  # 打印查看
......
Number  Start (sector)    End (sector)  Size       Code  Name
   1            2048         2099199   1024.0 MiB  8300  Linux filesystem
 
Command (? for help): w  # 保存
Final checks complete. About to write GPT data. THIS WILL OVERWRITE EXISTING
PARTITIONS!!
 
Do you want to proceed? (Y/N): y  # 输入y保存
OK; writing new GUID partition table (GPT) to /dev/sdc.
The operation has completed successfully.

3) 格式化制作文件系统

磁盘必须格式化制作文件系统,然后才能挂载使用

针对一块硬盘/dev/sdb可以直接格式化,然后挂载

[root@egon ~]# mkfs.xfs /dev/sdb # /dev/sdb整体就是一个分区

也可以在进行MBR或者GPT分区完成之后,针对其中的某一块分区进行格式化

[root@egon ~]# mkfs.xfs /dev/sdb1

ps

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

挂载和卸载

[root@egon ~]# mount /dev/sdb1 /opt/
 
卸载
umount /dev/sdb1 # 或者umount /opt
 
强制卸载
umount -l /dev/sdb1 # 或者umount -l /opt

4) xfs文件系统备份

命令安装

[root@localhost ~]# yum install -y  xfsdump   
#####安装包xfsdump-3.1.7-1.el7.x86_64####

xfsdump的备份级别,默认为0(全量备份)

0                       完全备份
 
1    <=   level <= 9    增量备份:
 
# ps:增量备份是和第一次的备份(level 0)进行比较,仅备份有差异的文件(level 1)

xfsdump常用参数

-L:xfsdump会记录每次备份的session Label,这里可以填写针对此文件系统的简易说明;
-M:xfsdump可以记录存储Media Label,这里可以填写此媒体的简易说明。
-l:是L的小写,就是指定level,有0~9共10个等级,默认为0,即完整备份。
-f:后面接产生的文件和destination file 。例如/dev/st0设备文件名或其他一般文件文件名
-I:大写的“i”,从/var/lib/xfsdump/inventory 列出目前备份的信息状态。

xfsdump的限制

1.必须用root权限
2.只能备份已挂载的文件系统
3.只能备份XFS文件系统
4.只能用xfsrestore解释
5.透过文件系统的UUID来分辨备份档,因此不能备份相同UUID的文件系统

xfsdump备份与xfsrestore恢复

# 1、数据备份
# 1.1 先做全量备份,切记“备份的源路径”末尾不要加左斜杠/
xfsdump -l 0 -L sdb3_bak -M sdb3_bak -f 全量备份的成果路径1 备份的源路径 
 
# 1.2 再做增量备份
xfsdump -l 1 -L sdb3_bak -M sdb3_bak -f 增量备份的成果路径2 备份的源路径 
xfsdump -l 1 -L sdb3_bak -M sdb3_bak -f 增量备份的成果路径3 备份的源路径 
xfsdump -l 1 -L sdb3_bak -M sdb3_bak -f 增量备份的成果路径4 备份的源路径 
 
# 2、数据恢复
# 2.1、先恢复全量备份
xfsrestore -f 全量备份的成果路径1 数据恢复的路径
# 2.2、再依次恢复增量
xfsrestore -f 增量备份的成果路径2 数据恢复的路径
xfsrestore -f 增量备份的成果路径2 数据恢复的路径
xfsrestore -f 增量备份的成果路径2 数据恢复的路径

示例

备份:

# 1、准备一个分区并制作好xfs文件系统,挂载好后给它加一点初始数据
[root@localhost ~]# df
文件系统         1K-块    已用    可用 已用% 挂载点
。。。。。。
/dev/sdb3      1038336   76836  961500    8% /opt
[root@localhost ~]# cp -r /etc/ /opt/
[root@localhost ~]# echo 111 > /opt/1.txt
[root@localhost ~]# ls /opt/
1.txt  etc
[root@localhost ~]# 
 
# 2、先做全量备份
[root@localhost ~]# xfsdump -l 0 -L sdb3_bak -M sdb3_bak -f /all.bak /opt
 
# 3、往/opt下新增文件2.txt,然后作增量备份
[root@localhost ~]# echo 222 > /opt/2.txt
[root@localhost ~]# xfsdump -l 1 -L sdb3_bak -M sdb3_bak -f /add.bak1 /opt
 
# 4、往/opt下新增文件3.txt,然后作增量备份
[root@localhost ~]# echo 333 > /opt/3.txt
[root@localhost ~]# xfsdump -l 1 -L sdb3_bak -M sdb3_bak -f /add.bak2 /opt
 
# 5、查看一下备份文件大小
[root@localhost ~]# du -sh /opt/
41M /opt/
 
[root@localhost ~]# ll -h /all.bak   # 全量备份大小
-rw-r--r--. 1 root root 37M 11月  4 18:44 /all.bak
[root@localhost ~]# ll -h /add.bak1  # 增量备份大小
-rw-r--r--. 1 root root 22K 11月  4 18:45 /add.bak1
[root@localhost ~]# ll -h /add.bak2  # 增量备份大小
-rw-r--r--. 1 root root 23K 11月  4 18:46 /add.bak2

恢复

[root@localhost ~]# rm -rf /opt/*
[root@localhost ~]# xfsrestore -f /all.bak /opt/  # 先恢复全量
......
[root@localhost ~]# ls /opt/
1.txt  etc
[root@localhost ~]# xfsrestore -f /add.bak1 /opt/  # 再恢复增量1
[root@localhost ~]# ls /opt/
1.txt  2.txt  etc
[root@localhost ~]# xfsrestore -f /add.bak2 /opt/  # 再恢复增量2
[root@localhost ~]# ls /opt/
1.txt  2.txt  3.txt  etc

5) LVM

5.1什么是lvm

LVM(Logical Volume Manager),即逻辑卷管理,是Linux环境下对磁盘分区进行管理的一种机制,LVM是建立在硬盘和分区之上的一个逻辑层,来提高磁盘分区管理的灵活性。通过LVM系统管理员可以轻松管理磁盘分区,如:将若干个磁盘分区连接为一个整块的卷组(volume group),形成一个存储池。管理员可以在卷组上随意创建逻辑卷组(logical volumes),并进一步在逻辑卷组上创建文件系统。管理员通过LVM可以方便的调整存储卷组的大小,并且可以对磁盘存储按照组的方式进行命名、管理和分配。当系统添加了新的磁盘,通过LVM管理员就不必将磁盘的文件移动到新的磁盘上以充分利用新的存储空间,而是直接扩展文件系统跨越磁盘即可。

image-20230406091506179

LVM概念

物理卷(PV):(physical volume),把常规的磁盘设备通过pvcreate命令对其进行初始化,形成了物理卷。其实就是硬盘或分区。(面粉)
 
卷组(VG):(volume group),把多个物理卷组成一个逻辑的整体,这样卷组的大小就是多个硬盘之和。或者理解就是由一个或多个PV组成的整体。(面团)
 
逻辑卷(LV):(logical volume),从卷组中划分需要的空间大小出来。用户仅需对其格式化然后即可挂载使用。从VG中切割出的空间用于创建文件系统。(切成馒头)
 
基本单元(PE):(physical extend),分配的逻辑大小的最小单元,默认为4MB的基本块。(假设分配100MB逻辑空间,则需要创建25个PE)

LVM的优缺点

# 优点:
# 1、可以在系统运行的状态下动态的扩展文件系统的大小。
# 2、文件系统可以跨多个磁盘,因此文件系统大小不会受物理磁盘的限制。
# 3、可以增加新的磁盘到LVM的存储池中。
# 4、可以以镜像的方式冗余重要的数据到多个物理磁盘。
# 5、可以方便的导出整个卷组到另外一台机器。
 
# 缺点:
# 1、因为加入了额外的操作,存取性能受到影响。
# 2、当卷组中的一个磁盘损坏时,整个卷组都会受到影响。
解释:LVM如果有一个磁盘损坏,整个lvm都坏了,lvm只有动态扩展作用,
方案:底层用RAID + 上层LVM = 既有冗余又有动态扩展
 
# 2、在从卷组中移除一个磁盘的时候必须使用reducevg命令(该命令要求root权限,并且不允许在快照卷组中使用)

5.2 LVM的基础使用:

下载安装包

yum install -y lvm2

1.制作pv,可以对分区做也可以对整块盘做

关键词 pvcreatepvs

# 制作
[root@egon ~]# pvcreate /dev/sdb1  # 对分区做
[root@egon ~]# pvcreate /dev/sdb2  # 对分区做
[root@egon ~]# pvcreate /dev/sdb3  # 对分区做
[root@egon ~]# pvcreate /dev/sdc   # 对整块盘做
 
# 查看
[root@egon ~]# pvs
  PV         VG Fmt  Attr PSize  PFree 
  /dev/sdb1     lvm2 ---   1.00g  1.00g
  /dev/sdb2     lvm2 ---   1.00g  1.00g
  /dev/sdb3     lvm2 ---   1.00g  1.00g
  /dev/sdc      lvm2 ---  20.00g 20.00g
[root@egon ~]# pvscan 
  PV /dev/sdb1                      lvm2 [1.00 GiB]
  PV /dev/sdc                       lvm2 [20.00 GiB]
  PV /dev/sdb2                      lvm2 [1.00 GiB]
  PV /dev/sdb3                      lvm2 [1.00 GiB]
  Total: 4 [23.00 GiB] / in use: 0 [0   ] / in no VG: 4 [23.00 GiB]

2.制作VG,将PV加入VG中

关键词 vgcreatevgs

# 制作一个vg1:
[root@egon ~]# vgcreate vg1 /dev/sdb1 /dev/sdc  # 包含/dev/sdb1与/dev/sdc两个pv
  Volume group "vg1" successfully created
[root@egon ~]# vgs
  VG  #PV #LV #SN Attr   VSize  VFree 
  vg1   2   0   0 wz--n- 20.99g 20.99g
 
# 也可以再制作一个vg2:
[root@egon ~]# vgcreate vg2 /dev/sdb2 /dev/sdb3  # 包含/dev/sdb2与/dev/sdb3两个pv
  Volume group "vg2" successfully created
[root@egon ~]# vgs
  VG  #PV #LV #SN Attr   VSize  VFree 
  vg1   2   0   0 wz--n- 20.99g 20.99g
  vg2   2   0   0 wz--n-  1.99g  1.99g

3.创建逻辑卷LV

关键词 lvcreate -L 100M -n lv1_name vg1

选项
    -L    #逻辑卷大小
    -n    #逻辑卷名字
 
# 从vg1中分出来逻辑卷lv1_from_vg1、lv2_from_vg1
[root@egon ~]# lvcreate -L 100M -n lv1_from_vg1 vg1
[root@egon ~]# lvcreate -L 200M -n lv2_from_vg1 vg1
 
# 从vg2中分出来一个建逻辑卷lv1_from_vg2、lv1_from_vg2
[root@egon ~]# lvcreate -L 300M -n lv1_from_vg2 vg2
[root@egon ~]# lvcreate -L 400M -n lv2_from_vg2 vg2
 
# 查看
[root@egon ~]# lvs
  LV           VG  Attr       LSize   Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert
  lv1_from_vg1 vg1 -wi-a----- 100.00m                                                    
  lv2_from_vg1 vg1 -wi-a----- 200.00m                                                    
  lv1_from_vg2 vg2 -wi-a----- 300.00m                                                    
  lv2_from_vg2 vg2 -wi-a----- 400.00m   
 
# 把vg的100%空间都给lv
lvcreate -l 100%VG -n lv的名字 vg的名字

4.格式化文件系统并实现挂载使用

关键词 mkfs.xfs /dev/vg1/lv1_from_vg1

[root@egon ~]# mkfs.xfs /dev/vg1/lv1_from_vg1 
[root@egon ~]# mkfs.xfs /dev/vg1/lv2_from_vg1 
 
[root@egon ~]# mkfs.xfs /dev/vg2/lv1_from_vg2 
[root@egon ~]# mkfs.xfs /dev/vg2/lv2_from_vg2 
 
[root@egon ~]# mount /dev/vg1/lv1_from_vg1 /test1/
[root@egon ~]# mount /dev/vg1/lv2_from_vg1 /test2/
[root@egon ~]# 
[root@egon ~]# mount /dev/vg2/lv1_from_vg2 /test3/
[root@egon ~]# mount /dev/vg2/lv2_from_vg2 /test4/
 
# 查看
[root@egon ~]# df
文件系统                       1K-块    已用    可用 已用% 挂载点
...
/dev/mapper/vg1-lv1_from_vg1   98980    5344   93636    6% /test1
/dev/mapper/vg1-lv2_from_vg1  201380   10464  190916    6% /test2
/dev/mapper/vg2-lv1_from_vg2  303780   15584  288196    6% /test3
/dev/mapper/vg2-lv2_from_vg2  406180   20704  385476    6% /test4
[root@egon ~]# 

小实验:


***********新磁盘进行挂载**************
pvcreate /dev/sdb   创建pv
vgcreate gaocongvg1   /dev/sdb     创建卷组  ------(vgs , vgdisplay查看卷组信息
 											     (vgextend gaocongvg1   /dev/sdd扩充卷组,添加物理卷)									                		                 (vgreduce gaocongvg1   /dev/sdd 这个是把新物理卷从卷组中删除,)
					                             (删除卷组vgchange -a n  /dev/gaocongvg1)
lvcreate -n lv1 -L 200M  gaocongvg1    创建逻辑卷lv1---------(lvs , lvdisplay查看卷组信息)
mkfs.xfs /dev/gaocongvg1/lv1         通过mkfs.xfs 对新⽣成的逻辑卷lv1格式化,然后挂载使⽤
mkdir  guazai    创建挂载点
mount   /dev/gaocongvg1/lv1    guazai   挂载使用(umount    /dev/gaocongvg1/lv1取消挂载)
  
总体流程-->创建pv(pvcreate)-->创建卷组( vgcreate)-->创建逻辑卷(lvcreate)-->mkfs.xfs (格式化)-->挂载mount 

5.3在线动态扩容

关键词 lvextend

lvextend -L  [+]MGT  /dev/VG_NAME/VL_NAME
# 注意:-L 100M 与 -L +100M不是一个意思,或者代表在原有的基础上扩容

示例:

# 1、新增一块盘或者一个分区
fdisk /dev/sdb ......
partprobe
ls /dev/sdb4
 
# 2、新增一个pv
[root@egon ~]# pvcreate /dev/sdb4
 
# 3、把新增的pv扩到vg2里
[root@egon ~]# vgextend vg2 /dev/sdb4
[root@egon ~]# vgs  # 可以看到vg2扩容了
 
# 4、接下来对lv1_from_vg2扩容
[root@egon ~]# lvextend -L +1000M /dev/vg2/lv1_from_vg2 
[root@egon ~]# xfs_growfs /dev/vg2/lv1_from_vg2  # 扩展逻辑卷后需要更新fs文件系统

5.4在线动态缩容与删除

正式环境一般不进行缩容,在自己测试下可以玩一玩

缩容关键词 lvreduce

lvreduce -L [-]MGT /dev/VG_NAME/LV_NAME 缩减逻辑卷

删除关键词 lvremove ,vgremove,pvremove

# 删除lv之前需要先卸载挂载点
[root@egon ~]# umount /test3
[root@egon ~]# lvremove /dev/vg2/lv1_from_vg2 
 
# 删vg
[root@egon ~]# vgremove vg2
 
# 删pv:只能删掉那些不属于任何vg的pv
[root@egon ~]# pvremove /dev/sdb2
[root@egon ~]# pvremove /dev/sdb3

小实验

pvcreate /dev/sdb    创建pv        (/dev/sdb为新磁盘)  
vgextend gaocongvg1   /dev/sdb扩充卷组,添加物理卷  (vgreduce gaocongvg1  /dev/sdd 这个是把新物理卷从卷组中删除,删除卷组vgchange -a n  /dev/gaocongvg1)
lvextend  -n lv1 -L 200M    /dev/gaocongvg1/需要扩容的逻辑卷名字      --- -----(lvs , lvdisplay查看卷组信息)
xfs_growfs    /dev/gaocongvg1/需要扩容的逻辑卷名字   (lvextend  之后可以发现挂载点的大小依然没变,可以使用xfs_growfs让系统发现lv的大小的变化)

还有一个快照功能,感觉没啥用

七,网络管理

1)基本网络配置

修改网卡名字
#修改网卡配置文件名称
[root@egon ~]# cd /etc/sysconfig/network-scripts/
[root@egon ~]# mv ifcfg-ens33 ifcfg-eth0
 
#修改网卡配置文件设备名称
[root@egon ~]# sed -i "s#ens33#eth0#g" ifcfg-eth0
 
##GRUB添加kernel参数
[root@egon ~]# vim /etc/sysconfig/grub
GRUB_CMDLINE_LINUX="rhgb quiet 'net.ifnames=0 biosdevname=0'"
 
#加载到引导分区
[root@egon ~]# grub2-mkconfig -o /boot/grub2/grub.cfg
 
#重启系统生效
[root@egon ~]# reboot
查看网卡信息
# 查看当前系统所连接的所有网卡
[root@egon ~]# lspci |grep -i eth
 
# 确认网线已经连接好,以eth0 为例
[root@egon ~]# mii-tool eth0
eth0:negotiated 1000baseT-FD flow-control,link ok # link ok网卡能够被识别,并且接了有效的网线
 
[root@egon ~]# mii-tool eth1
SIOCGMIIPHY on 'eth1' failed: Invalid argument
网卡虽然能够被识别(网卡已经被驱动了,但不能用:网卡配置错误,网线没接等)
网卡配置文件
# 打开网卡配置文件,完成静态ip配置,修改完毕后重启网络服务即可:systemctl restart network
DEVICE=eth0         <-- 网卡名字
BOOTPROTO=static       <---- dhcp 动态获取IP
                          <---- none 根据其他选项决定动态还是静态
                          <---- static肯定是手工指定IP
NM_CONTROLLED=no          <---如果NetworkManager服务启用,该网卡配置文件也不受该服务管理
ONBOOT=yes          <---- 网络服务启动的时候,yes代表激活状态 , no 代表禁用
TYPE=Ethernet
IPADDR=10.1.1.11        <-- IP 地址
NETMASK=255.255.255.0     <-- 子网掩码
GATEWAY=10.1.1.1          <-- 默认网关
DNS1=10.1.1.1             <-- DNS1 服务器
DNS2=8.8.8.8              <-- DNS2 服务器
HWADDR=14:da:e9:eb:a9:61  <---MAC地址
USERCTL=no           <---是否允许普通用户启动或者停止该网卡
IPV6INIT=no          <---是否在该网卡上启动IPV6的功能
PEERDNS=yes          <---是否允许网卡在启动时向DHCP服务器查询DNS信息,
                          # 设置为yes时,此文件设置的DNS将覆盖/etc/resolv.conf,
                          # 若开启了DHCP,则默认为yes,所以dhcp的dns也会覆盖/etc/resolv.conf
ifconfig命令
1、ifconfig -a 查看所有网卡信息(包括未激活的网卡)
2、ifconfig eth0 查看单个网卡信息
3、ifconfig eth0 192.168.1.122 netmask 255.255.255.0 临时设定IP和掩码(重启服务或者系统都失效)
4、ifconfig eth0 192.168.1.122/24 
 
5、ifconfig eth0:1 192.168.0.2 netmask 255.255.255.0 配置子接口
# 删除:下述两种方式都可以
ifconfig eth0:0 down
ifconfig eth0:1 del 192.168.0.2  # 删除,不必加掩码
 

ifconfig命令解释

[root@egon ~]# ifconfig ens33
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
         # 从flags可知该接口已启用,支持广播、组播,MTU:1500(最大传输单元):1500字节
         # 其他了解知识:
         // UP:表示“接口已启用”。
         // BROADCAST :表示“主机支持广播”。
         // RUNNING:表示“接口在工作中”。
         // MULTICAST:表示“主机支持多播”。
         // 可以了解一下繁杂模式:https://www.cnblogs.com/linhaifeng/articles/13949611.html
 
        inet 192.168.12.42  netmask 255.255.255.0  broadcast 192.168.12.255
        # IPv4地址           子网掩码               广播地址
 
        inet6 fe80::499e:c2c1:f5ed:3900  prefixlen 64  scopeid 0x20<link>
        # IPv6地址                        掩码长度       作用域,link表示仅该接口有效
 
        ether 00:0c:29:86:f8:59  txqueuelen 1000  (Ethernet)
        #网卡接口的MAC地址         传输队列长度       接口类型为Ethernet
 
        RX packets 5708  bytes 1061424 (1.0 MiB)
        # 表示开机后此接口累积接收的报文个数,总字节数
 
        RX errors 0  dropped 833  overruns 0  frame 0
        # 表示开机后此接口累积接收报文错误数,丢弃数,溢出数(由于速度过快而丢失的数据包数),冲突的帧数
 
        TX packets 102  bytes 16768 (16.3 KiB)
        # 表示开机后此接口累积发送的报文个数,总字节数
 
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
        # 表示开机后此接口累积发送报文错误数,丢弃数,溢出数(由于速度过快而丢失的数据包数),
        # carrier 载荷数(发生carrier错误而丢失的数据包数)
        # collisions 冲突数
ethool解决网卡丢包严重问题
# 1、储备知识1: linux软硬件中断
中断是系统用来影响硬件设备请求的一种机制,它会打断进程的正常调度和执行,然后调用内核中的终端处理程序来影响设备的请求。
中断是一个异步的事件处理机制,可以提高操作系统处理并发的能力。
详见博客:https://www.cnblogs.com/linhaifeng/articles/13916102.html
 
# 2、储备知识2:全双工与半双工,目前网卡一般都应该采用全双工模式
全双工传输英文写法是:Full-Duplex Transmissions
是指交换机在发送数据的同时也能够接收数据,两者同步进行,这好像我们平时打电话一样,说话的同时也能够听到对方的声音。目前的交换机都支持全双工。
 
全双工的好处在于迟延小、冲突少、速度快。
与之对应的是【半双工】这个概念:就是指一个时间段内只有一个动作发生,举个简单例子,一天窄窄的马路,同时只能有一辆车通过,当目前有两量车对开,这种情况下就只能一辆先过,等到头儿后另一辆再开,这个例子就形象的说明了半双工的原理。早期的对讲机、以及早期集线器等设备都是实行半双工的产品。随着技术的不断进步,半双工会逐渐退出历史舞台。
// 了解更多全双工与半双工:https://www.cnblogs.com/linhaifeng/articles/13949762.html
 
# 3、储备知识3:CRC   
CRC即循环冗余校验码(Cyclic Redundancy Check):是数据通信领域中最常用的一种查错校验码,其特征是信息字段和校验字段的长度可以任意选定。循环冗余检查(CRC)是一种数据传输检错功能,对数据进行多项式计算,并将得到的结果附在帧的后面,接收设备也执行类似的算法,以保证数据传输的正确性和完整性
// 了解更多:https://www.cnblogs.com/linhaifeng/articles/13949806.html
 
# 4、储备知识4:网卡工作原理
网卡发包:
    1、ip包+14个字节的mac头变成数据帧frame
    2、frame拷贝到网卡芯片内部的缓冲区,由网卡处理
    3、网卡芯片为frame添加头部同步信息和CRC校验,此时才是真正可以发送的packet,然后发送该packet
网卡收包:
    1、网络包packet到达网卡,网卡先检查包packet的CRC校验,保证其完整性和正确性,然后去掉它的头得到frame
    2、网卡将frame拷贝到网卡内部的FIFO缓冲区
    3、网卡驱动程序产生硬件中断,把frame从网卡拷贝到内存中,接下来就交给内核处理
 
网卡丢包!!!
    内核通常需要快速的拷贝网络数据包到系统内存!!!
    因为网卡上接收网络数据包的缓存大小固定,而且相比系统内存也要小得多。
    所以上述拷贝动作一旦被延迟,必然造成网卡FIFO缓存溢出 - 进入的数据包占满了网卡的缓存,后续的包只能被丢弃,这也应该就是ifconfig里的overrun的来源。
 
// 网卡工作原理:
https://www.cnblogs.com/linhaifeng/articles/13949943.html

丢包问题解决

# 丢包排查
网卡工作在数据链路层,数据量链路层,会做一些校验,封装成帧。我们可以查看校验是否出错,确定传输是否存在问题。然后从软件层面,是否因为缓冲区太小丢包。
 
# 1 先查看硬件情况
一台机器经常收到丢包的报警,先看看最底层的有没有问题:
# 1.1 查看工作模式是否正常
[root@egon ~]# ethtool ens33 | egrep 'Speed|Duplex'
    Speed: 1000Mb/s
    Duplex: Full
 
# 1.2 查看CRC校验是否正常     
[root@egon ~]# ethtool -S ens33 | grep crc # crc错误值大通常是因为服务器外部的网络环境有问题导致的
     rx_crc_errors: 0
 
-----------Speed,Duplex,CRC 之类的都没问题,基本可以排除物理层面的干扰----------
 
# 2 通过 ifconfig 可以看到 overruns 是否一直增大,如果查看结果是一直增大
for i in `seq 1 100`; do ifconfig ens33 | grep RX | grep overruns; sleep 1; done
 
# 3 调整网卡缓冲区
[root@egon ~]# ethtool -g ens33
Ring parameters for ens33:
Pre-set maximums:  # 最大可以设置的值
RX:     4096
RX Mini:    0
RX Jumbo:   0
TX:     4096
Current hardware settings:  # 当前设置的值
RX:     256
RX Mini:    0
RX Jumbo:   0
TX:     256
[root@egon ~]# ethtool -G ens33 rx 2048  # 调大
[root@egon ~]# ethtool -G ens33 tx 2048  # 调大
[root@egon ~]# 
[root@egon ~]# ethtool -g ens33
Ring parameters for ens33:
Pre-set maximums:
RX:     4096
RX Mini:    0
RX Jumbo:   0
TX:     4096
Current hardware settings:
RX:     2048
RX Mini:    0
RX Jumbo:   0
TX:     2048
 
[root@egon ~]#
ping命令
ping 目标IP地址  # ctrl+c结束 测试是否两台主机网络是否通
ping -c 次数 目标IP地址
 
# 在自己的机器上执行,则禁用别人ping自己
[root@egon ~]# echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_all 
NetworkManager服务
NetworkManager作用:是redhat6自带的检测网络、自动连接网络的图形化工具。NetworkManager 服务会干扰网络配置,如:DNS经常会被刷掉,所以通常关闭
[root@egon ~]# systemctl stop NetworkManager
[root@egon ~]# systemctl disable NetworkManager
dns配置文件
1)/etc/resolv.conf DNS解析文件,
[root@egon ~]# cat /etc/resolv.conf  # 设置DNS指向,最多3个
nameserver 8.8.8.8  # 对应网卡配置文件中的配置项DNS1
nameserver 192.168.12.1  # 对应网卡配置文件中的配置项DNS2
 
2)/etc/hosts 本地名称解析文件,优先于DNS
 
ps:dns检索优先级
浏览器DNS缓存->本地系统DNS缓存->本地计算机HOSTS文件->ISP DNS缓存->递归or迭代搜索
永久设置主机名
[root@egon ~]# hostnamectl set-hostname egon.xxx.com
[root@egon ~]# hostname
egon.xxx.com
[root@egon ~]# 
[root@egon ~]# cat /etc/hostname 
egon.xxx.com

2)路由route

2.1 交换与路由

交换:指同网络访问,两台机器连接在同一个交换机上,配置同网段的不通ip就可以就直接通讯

路由:指跨网络访问的路径选择

2.2linux处理数据包的过程

收到外界发来的请求后,从它的网卡流入后需要对它进行路由决策,根据其目标决定是流入本机的用户空间还是在内核空间直接转发给其他主机

# 1、如果是流入本机用户空间的数据,
则数据会从内核空间进入用户空间(被应用程序接收并处理);
此时如果本机用户空间的应用程序不需要产生新的数据包对外发送,那便不再涉及到从某个网卡流出数据;
但是如果本机用户空间的应用程序需要产生新的数据包对外发送,那便需要从某个网卡流出数据,但在流出之前,也需要做路由决策:根据目标决定从哪个网卡流出。
 
# 2、如果不是流入本机用户空间的数据,仅仅只是要经由本机把数据包转发给其他主机
则必然涉及到从某个网卡流出,此时数据包必须从流入网卡完整地转发给流出网卡,这要求Linux主机能够完成这样的转发。但Linux主机默认未开启ip_forward功能,这使得数据包无法转发而被丢弃。
 
ps:Linux主机和路由器不同,路由器本身就是为了转发数据包,所以路由器内部默认就能在不同网卡间转发数据包,而Linux主机默认则不能转发。若要开启linux主机的转发功能,有很多方式,如下所示

临时开启Linux主机的路由转发功能,重启网络服务则失效

# 方式1:
echo 1 > /proc/sys/net/ipv4/ip_forward
 
# 方式2:
sysctl -w net.ipv4.ip_forward=1

若要永久生效,则应该写入配置文件

# 在CentOS 6中:
将/etc/sysctl.conf文件中的"net.ipv4.ip_forward"值改为1即可
 
#在CentOS 7中:
systemd管理了太多的功能,sysctl的配置文件也分化为多个,包括/etc/sysctl.conf、/etc/sysctl.d/*.conf和/usr/lib/sysctl.d/*.conf,并且这些文件中默认都没有net.ipv4.ip_forward项。当然,直接将此项写入到这些配置文件中也都是可以的,建议写在/etc/sysctl.d/*.conf中,这是systemd提供自定义内核修改项的目录。例如:
 
echo "net.ipv4.ip_forward=1" > /etc/sysctl.d/ip_forward.conf

可以使用以下几种方式查看是否开启了转发功能

[root@egon ~]# sysctl net.ipv4.ip_forward
[root@egon ~]# cat /proc/sys/net/ipv4/ip_forward
[root@egon ~]# sysctl -a | grep ip_forward

!!!注意:只有当本机被别人当作网关并且本机开启了路由转发功能时,别人发来的请求包,本机才会帮忙转发,很重要

2.3 网关/路由

Linux上分为3种路由:

主机路由:掩码32位,精确某一台主机

所以主机路由是直接指明到某台具体的主机怎么走,主机路由也就是所谓的静态路由

网络路由:掩码小于32位,精确某一网段

所以网络路由指明到某类网络怎么走

默认路由

不走主机路由的和网络路由的、全部都走默认路由。操作系统上设置的默认路由一般也称为网关。

路由是区分优先级的:

大前提:
主机范围越小、越精确、优先级越高,而缩小主机范围的恰恰就是子网掩码,掩码越长范围越小、越精确、优先级越高
 
优先级区分:
# 1、在Linux中,路由条目的优先级确定方式是先匹配掩码位长度,掩码越长的优先级高
也就是说,掩码位长的路由条目优先级一定比掩码位短的优先级高,所以主机路由的优先级最高,然后是直连网络(即同网段)的路由(也算是网络路由)次之,再是网络路由,最后才是默认路由即网关。
 
# 2、若路由条目的掩码长度相同,则比较节点之间的管理距离(比如metric),管理距离短的生效。

例子

[root@egon ~]# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         192.168.100.2   0.0.0.0         UG    100    0        0 eth0
172.16.10.0     0.0.0.0         255.255.255.0   U     100    0        0 eth1
192.168.0.0     192.168.100.70  255.255.0.0     UG    0      0        0 eth0
192.168.100.0   0.0.0.0         255.255.255.0   U     100    0        0 eth0
192.168.100.78  0.0.0.0         255.255.255.255 UH    0      0        0 eth0

本机ping 192.168.6.6

# 先检索掩码长的路由条件,即按照如下顺序
255.255.255.255 > 255.255.255.0 > 255.255.0.0 > 0.0.0.0 
 
于是先对应192.168.100.78发现无法匹配,然后比对192.168.100.0,发现也无法匹配,接着再匹配192.168.0.0这条网络路由条目,发现能匹配,所以选择该路由条目,从eth0发出数据包

2.4 route 命令

说明
Destination目标网段或者主机
Gateway网关地址,”*” 表示目标是本主机所属的网络,不需要路由
Genmask网络掩码
Flags标记。一些可能的标记如下:
U — 路由是活动的
H — 目标是一个主机
G — 路由指向网关
R — 恢复动态路由产生的表项
D — 由路由的后台程序动态地安装
M — 由路由的后台程序修改
! — 拒绝路由
Metric路由距离,到达指定网络所需的中转数(linux 内核中没有使用)
Ref路由项引用次数(linux 内核中没有使用)
Use此路由项被路由软件查找的次数
Iface该路由表项对应的输出接口

管理路由表

route [add/del] [-host/-net/default] [address[/mask]] [netmask] [gw] [dev]
 
选项说明:
add/del:增加或删除路由条目
-net:增加或删除的是一条网络路由
-host:增加或删除的是一条主机路由
default:增加或删除的是一条默认路由
netmask:明确使用netmask关键字指定掩码,要可以不使用该选项直接在地址上使用cidr格式的掩码,即IP/MASK。
gw:指定下一跳的地址。要求下一跳地址必须是能到达的,且一般是和本网段直连的接口。
dev:强制将路由条目关联到指定的接口上。一般内核会自动判断路由条目应该关联到哪个网络接口。
 
# route命令添加的多少临时生效

添加和删除默认路由

[root@egon ~]# route add default gw 192.168.100.10
[root@egon ~]# route del default
[root@egon ~]# route del default gw 192.168.100.10   # 若有多条默认路由,则再加上gw即可唯一删除指定条目

添加和删除网络路由

[root@egon ~]# route add -net 172.16.10.0/24 gw 192.168.100.70
[root@egon ~]# route add -net 172.16.10.0 netmask 255.255.255.0 gw 192.168.100.70
删除
[root@egon ~]# route del -net 172.16.10.0/24 gw 192.168.100.70
[root@egon ~]# route del -net 172.16.10.0 netmask 255.255.255.0 gw 192.168.100.70
[root@egon ~]# route del -net 172.16.10.0/24 dev eth0

添加和删除主机路由

[root@egon ~]# route add -host 172.16.10.55 gw 192.168.10.20
[root@egon ~]# route del -host 172.16.100.55

八,Linux系统优化

yum源配置

# 一:先在测试环境,配置好yum源
默认国外的yum源(软件仓库)比较慢,所以换成国内的。
# 1.1、备份
[root@egon ~]# mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup
 
# 1.2、下载新的CentOS-Base.repo 到/etc/yum.repos.d/
[root@egon ~]# curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
 
# 1.3.添加epel源
[root@egon ~]# curl -o /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
 
# 二:然后执行yum update -y,以及安装常用软件包,然后执行部署,将部署过程中安装的包缓存本地
[root@egon ~]# yum update -y  # 刚装完系统后就立即执行,日后就不要轻易更新了
[root@egon ~]# yum -y install tree nmap sysstat lrzsz  telnet bash-completion bash-completion-extras vim  lsof  net-tools rsync ntpdate nfs-utils
 
# 三:将所有主机上的软件包汇总到一起,做成一个自己的yum源用来后期使用

规范主机名

hostnamectl set-hostname 主机名  # 主机名能够反映出主机的作用即可

关闭SElinux

 SELinux(Security-Enhanced Linux)是美国国家安全局(NSA)对于强制访问控制的实现,这个功能让系统管理员又爱又恨,这里我们还是把它给关闭了吧,至于安全问题,后面通过其他手段来解决,这也是大多数生产环境的做法,如果非要开启也是可以的。
 
#临时关闭
[root@egon ~]# setenforce  0
 
#永久关闭,修改完配置后重启主机
[root@egon ~]# sed 's#SELINUX=enforcing#SELINUX=disabled#g' /etc/selinux/config
 
#检查结果
[root@egon ~]# grep "disabled" /etc/selinux/config

关闭防火墙

关闭防火墙的目的是为了让初学者学习更方便,将来在学了Firewalld技术后可再统一开启。 在企业环境中,一般只有配置外网IP的linux服务器才需要开启防火墙,但即使是有外网IP,对于高并发高流量的业务服务器仍是不能开的,因为会有较大性能损失,导致网站访问很慢,这种情况下只能在前端加更好的硬件防火墙了。
 
# 临时关闭
[root@egon ~]# systemctl  stop firewalld
 
# 设置开机不启动
[root@egon ~]# systemctl  disable  firewalld

配置ntp,同步时间

#给定时任务加上注释
[root@egon ~]# echo '#Timing synchronization time' >>/var/spool/cron/root
 
#定时任务
[root@egon ~]# echo '0 */1 * * * /usr/sbin/ntpdate ntp1.aliyun.com &>/dev/null' >>/var/spool/cron/root
 
#检查结果
[root@egon ~]# crontab -l

内核优化

ulimit

临时设置用户级所能打开的最大进程数: -u选项

ulimit -u 3

永久设置控制用户开启的最大进程数:

/etc/security/limits.conf

# max user processes   (-u)
* soft nproc 65565
* hard nproc 65565
root soft nproc 65565
root hard nproc 65565

临时设置用户级所能分配的文件描述符数量: -n选项

ulimit -n 12

永久设置用户级所能分配的文件描述符数量:

/etc/security/limits.conf

# open files  (-n)
* soft nofile 65536
* hard nofile 65536
root soft nofile 65536
root hard nofile 65536

服务器优化脚本

#!/bin/bash
echo "----关闭selinux----"
sed -i '/^SELINUX=.*/c SELINUX=disabled' /etc/selinux/config
sed -i 's/^SELINUXTYPE=.*/SELINUXTYPE=disabled/g' /etc/selinux/config
grep --color=auto '^SELINUX' /etc/selinux/config
setenforce 0

sleep 1
echo "----关闭防火墙----"
systemctl stop firewalld
systemctl disable firewalld
systemctl stop iptables
systemctl disable iptables

sleep 1
echo "----关闭network管理系统----"
systemctl stop NetworkManager
systemctl disable NetworkManager

sleep 1
#echo "----配置DNS----"
#sed -i '1i\nameserver 223.5.5.5' /etc/resolv.conf
#sed -i '2i\nameserver 1.2.4.8' /etc/resolv.conf

sleep 1
echo "----安装依赖插件----"
yum -y install epel-release wget
mkdir -p /etc/yum.repos.d/bak
mv /etc/yum.repos.d/* /etc/yum.repos.d/bak
wget http://mirrors.aliyun.com/repo/Centos-7.repo -P /etc/yum.repos.d/
wget http://mirrors.aliyun.com/repo/epel-7.repo -P /etc/yum.repos.d/
yum -y install wget vim ntp unzip zip net-snmp* telnet sysstat gcc gcc-c++ make openssl* perl ncurses* nethogs lsof lrzsz libselinux-python bash-completion net-tools setuptool system-config-network-tui ntsysv expat-devel psmisc nmap fping traceroute python2-pip readline-devel cpp cmake bison libaio-devel ncurses-devel perl-DBD-MySQL perl-Time-HiRes openssh-clients libaio zlib-devel libssl.so.6 numactl jemalloc compat-readline5-devel

sleep 1
echo "----修改时区----"
timedatectl set-timezone Asia/Shanghai
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

#sleep 1
#echo "----禁止使用Ctrl+Alt+Del重启----"
#mv /usr/lib/systemd/system/ctrl-alt-del.target /usr/lib/systemd/system/ctrl-alt-del.target.bak
#init q

sleep 1
echo "----修改字符编码----"
echo 'LANG="en_US.UTF-8"
SUPPORTED="zh_CN.GB18030:zh_CN:zh:en_US.UTF-8:en_US:en"
SYSFONT="latarcyrheb-sun16"' > /etc/locale.conf

#sleep 1
#echo "----内网服务器,配置同步时间----"
#systemctl stop ntpd
#systemctl disable ntpd

sleep 1
echo "----可上外网服务器,配置同步时间----"
ntpdate ntp1.aliyun.com
echo '*/5 * * * * /usr/sbin/ntpdate ntp1.aliyun.com > /dev/null 2>&1' >> /var/spool/cron/root



echo "----优化tcp连接数----"
sleep 1
echo "----用户可用的最大进程数量----"
cat >> /etc/security/limits.conf << EOF
* soft nproc 65536
* hard nproc 65536
* soft nofile 65536
* hard nofile 65536
EOF

sleep 1
echo "----Linux最大进程数最大进程数量----"
cat >> /etc/security/limits.d/20-nproc.conf << EOF
* soft nproc unlimited
* hard nproc unlimited
EOF


#这里使用的是64位的系统,所以目录是lib64,请先确认此文件是否存在,不然会导致密码登陆报moudule is unknow
#cat >> /etc/pam.d/login << EOF
#session required /lib64/security/pam_limits.so
#session required pam_limits.so
#EOF

sleep 1
echo "----Linux系统所有进程共计可以打开的文件数量----"
cat >> /etc/sysctl.conf << EOF
fs.file-max = 65535
EOF

sleep 1
echo "----用户登录系统后打开文件数量----"
cat >> /etc/profile << EOF
ulimit -HSn 65535
EOF

#sleep 1
#echo "----配置密码策略----"
#source /etc/profile

#sleep 1
#echo "----设置密码长度不低于8位----"
#authconfig --passminlen=8 --update

#sleep 1
#echo "----设置密码中连续字符最大数目3个----"
#authconfig --passmaxclassrepeat=3 --update

#sleep 1
#echo "----密码需包含小写,大写,数字,特殊字符----"
#authconfig --enablereqlower --update
#authconfig --enablerequpper --update
#authconfig --enablereqdigit --update
#authconfig --enablereqother --update

#sleep 1
#echo "----检查配置成功----"
#cat /etc/security/pwquality.conf

sleep 1
echo "----配置ssh禁用反向解析----"
echo 'UseDNS=no' >> /etc/ssh/sshd_config

#sleep 1
#echo "----配置ssh-server侦听端口----"
#echo 'Port 22' >> /etc/ssh/sshd_config

#sleep 1
#echo "----不允许通过密码ssh远程登录----"
#echo 'PermitRootLogin no' >> /etc/ssh/sshd_config
#systemctl restart sshd

#sleep 1
#echo "----设置ssh,20分钟登录无操作自动退出,服务器每120秒心跳包测试客户端,三次不成功断开----"
#echo 'export TMOUT=1200' >> /etc/profile
#source /etc/profile
#echo 'ClientAliveInterval 120
#ClientAliveCountMax 3' >> /etc/ssh/sshd_config
#systemctl restart sshd

sleep 1
echo "----设置用户登录记录----"
echo '#!/bin/bash
loginFile="/var/log/sshd/sshlogin.log"
user=$USER
ip=${SSH_CLIENT%% *}
#if [ "$user" != "root" ] || [ "$ip" != "192.168.31.88" ]
 #then
echo "LoginUser:"$user"--IP:"$ip"--LoginTime:"`date "+%Y-%m-%d %H:%M:%S"` >> "$loginFile";
#fi' >> /etc/ssh/sshrc
mkdir /var/log/sshd
touch /var/log/sshd/sshlogin.log
chmod -R 777 /var/log/sshd
chmod +x /etc/ssh/sshrc

sleep 1
#echo "----查看历史操作记录,并加时间戳----"
echo 'export HISTTIMEFORMAT="%F %T `whoami` "' >> /etc/profile
source /etc/profile

#sleep 1
#echo "----系统启动配置文件赋权----"
chmod +x /etc/rc.d/rc.local

sleep 1
#echo "----cloudinit配置调整----"
#sed -ri '/disable_root/{s#\S$#0#}' /etc/cloud/cloud.cfg
#sed -ri '/ssh_pwauth/{s#\S$#1#}' /etc/cloud/cloud.cfg
#sed -ri '/package-update/s@^@#@' /etc/cloud/cloud.cfg
#sed -ri '/update_etc_hosts/s@^@#@' /etc/cloud/cloud.cfg
#sed -ri '/yum-add-repo/s@^@#@' /etc/cloud/cloud.cfg

#设置sysctl
echo "----设置sysctl----"
SYSCONF="
#Add
net.ipv4.tcp_max_syn_backlog = 65536
net.core.netdev_max_backlog = 32768
net.core.somaxconn = 32768
net.core.wmem_default = 8388608
net.core.rmem_default = 8388608
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_timestamps = 0
net.ipv4.tcp_synack_retries = 2
net.ipv4.tcp_syn_retries = 2
net.ipv4.tcp_tw_recycle = 1
#net.ipv4.tcp_tw_len = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_mem = 94500000 915000000 927000000
net.ipv4.tcp_max_orphans = 3276800
net.ipv4.tcp_fin_timeout = 120
net.ipv4.tcp_keepalive_time = 120
net.ipv4.ip_local_port_range = 1024 65535 
net.nf_conntrack_max = 16404388
net.netfilter.nf_conntrack_tcp_timeout_established = 10800 "


#####*******一键安装docker和docker-compose并配置阿里云镜像源*****###
echo "一键安装docker和docker-compose并配置阿里云镜像源"
yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-engine


echo -e " =========== 1.删除已经存在的 docker ================\n\n"

echo -e "step 1: 安装必要的一些系统工具"
sudo yum install -y yum-utils device-mapper-persistent-data lvm2

echo -e "\n\nStep 2: 添加软件源信息,国内 Repository 更加稳定"
sudo yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

version=sudo cat /etc/redhat-release|sed -r 's/.* ([0-9]+)\..*/\1/'

if $version=7; then
        echo  -e "\n\nStep 3: 更新 Centos version is : $version; run yum makecache fast"
        sudo yum makecache fast
elif $version=8; then
        echo -e "\n\nStep 3: 更新Centos version is : $version; run yum makecache fast"
        sudo dnf makecache
fi

echo -e "=========== 2.配置国内镜像加速 ================\n\n"
# 1.创建一个目录
sudo mkdir -p /etc/docker
# 2.编写配置文件
sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["http://hub-mirror.c.163.com",
    "https://docker.mirrors.ustc.edu.cn",
    "https://reg-mirror.qiniu.com",
    "http://f1361db2.m.daocloud.io"
  ]
}
EOF
sudo systemctl daemon-reload

echo -e "=========== 3.完成配置 docker Repository ================\n\n"

# 安装docker和docker-compose,默认安装的是lastest版本
sudo yum install docker-ce \
                 docker-ce-cli \
                 containerd.io \
                 docker-buildx-plugin \
                 docker-compose-plugin -y


echo -e "=========== 4.成功安装完 docker ================\n\n"

sudo systemctl enable docker
sudo systemctl start docker

ln -s /usr/libexec/docker/cli-plugins/docker-compose /usr/bin/docker-compose

e

终端个性化设置

欢迎页面

vi /etc/motd

/**
 * ┌───┐   ┌───┬───┬───┬───┐ ┌───┬───┬───┬───┐ ┌───┬───┬───┬───┐ ┌───┬───┬───┐
 * │Esc│   │ F1│ F2│ F3│ F4│ │ F5│ F6│ F7│ F8│ │ F9│F10│F11│F12│ │P/S│S L│P/B│  ┌┐    ┌┐    ┌┐
 * └───┘   └───┴───┴───┴───┘ └───┴───┴───┴───┘ └───┴───┴───┴───┘ └───┴───┴───┘  └┘    └┘    └┘
 * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐ ┌───┬───┬───┐ ┌───┬───┬───┬───┐
 * │~ `│! 1│@ 2│# 3│$ 4│% 5│^ 6│& 7│* 8│( 9│) 0│_ -│+ =│ BacSp │ │Ins│Hom│PUp│ │N L│ / │ * │ - │
 * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤ ├───┼───┼───┤ ├───┼───┼───┼───┤
 * │ Tab │ Q │ W │ E │ R │ T │ Y │ U │ I │ O │ P │{ [│} ]│ | \ │ │Del│End│PDn│ │ 7 │ 8 │ 9 │   │
 * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴─────┤ └───┴───┴───┘ ├───┼───┼───┤ + │
 * │ Caps │ A │ S │ D │ F │ G │ H │ J │ K │ L │: ;│" '│ Enter  │               │ 4 │ 5 │ 6 │   │
 * ├──────┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴────────┤     ┌───┐     ├───┼───┼───┼───┤
 * │ Shift  │ Z │ X │ C │ V │ B │ N │ M │< ,│> .│? /│  Shift   │     │ ↑ │     │ 1 │ 2 │ 3 │   │
 * ├─────┬──┴─┬─┴──┬┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤ ┌───┼───┼───┐ ├───┴───┼───┤ E││
 * │ Ctrl│    │Alt │         Space         │ Alt│    │    │Ctrl│ │ ← │ ↓ │ → │ │   0   │ . │←─┘│
 * └─────┴────┴────┴───────────────────────┴────┴────┴────┴────┘ └───┴───┴───┘ └───────┴───┴───┘
 */

终端颜色

vi /etc/profile

PS1='\[\e[1;35m\]\u@\h:\[\e[0m\]\[\e[1;33m\]\w\[\e[1;35m\]\[\e[0m\]\[\e[1;34m\]\$ \[\e[0m\]'

参考连接

/etc/cloud/cloud.cfg

#设置sysctl
echo “----设置sysctl----”
SYSCONF="
#Add
net.ipv4.tcp_max_syn_backlog = 65536
net.core.netdev_max_backlog = 32768
net.core.somaxconn = 32768
net.core.wmem_default = 8388608
net.core.rmem_default = 8388608
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_timestamps = 0
net.ipv4.tcp_synack_retries = 2
net.ipv4.tcp_syn_retries = 2
net.ipv4.tcp_tw_recycle = 1
#net.ipv4.tcp_tw_len = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_mem = 94500000 915000000 927000000
net.ipv4.tcp_max_orphans = 3276800
net.ipv4.tcp_fin_timeout = 120
net.ipv4.tcp_keepalive_time = 120
net.ipv4.ip_local_port_range = 1024 65535
net.nf_conntrack_max = 16404388
net.netfilter.nf_conntrack_tcp_timeout_established = 10800 "

#####**一键安装docker和docker-compose并配置阿里云镜像源###
echo “一键安装docker和docker-compose并配置阿里云镜像源”
yum remove docker
docker-client
docker-client-latest
docker-common
docker-latest
docker-latest-logrotate
docker-logrotate
docker-engine

echo -e " =========== 1.删除已经存在的 docker ================\n\n"

echo -e “step 1: 安装必要的一些系统工具”
sudo yum install -y yum-utils device-mapper-persistent-data lvm2

echo -e “\n\nStep 2: 添加软件源信息,国内 Repository 更加稳定”
sudo yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

version=sudo cat /etc/redhat-release|sed -r ‘s/.* ([0-9]+)…*/\1/’

if $version=7; then
echo -e “\n\nStep 3: 更新 Centos version is : $version; run yum makecache fast”
sudo yum makecache fast
elif $version=8; then
echo -e “\n\nStep 3: 更新Centos version is : $version; run yum makecache fast”
sudo dnf makecache
fi

echo -e “=========== 2.配置国内镜像加速 ================\n\n”

1.创建一个目录

sudo mkdir -p /etc/docker

2.编写配置文件

sudo tee /etc/docker/daemon.json <<-‘EOF’
{
“registry-mirrors”: [“http://hub-mirror.c.163.com”,
“https://docker.mirrors.ustc.edu.cn”,
“https://reg-mirror.qiniu.com”,
“http://f1361db2.m.daocloud.io”
]
}
EOF
sudo systemctl daemon-reload

echo -e “=========== 3.完成配置 docker Repository ================\n\n”

安装docker和docker-compose,默认安装的是lastest版本

sudo yum install docker-ce
docker-ce-cli
containerd.io
docker-buildx-plugin
docker-compose-plugin -y

echo -e “=========== 4.成功安装完 docker ================\n\n”

sudo systemctl enable docker
sudo systemctl start docker

ln -s /usr/libexec/docker/cli-plugins/docker-compose /usr/bin/docker-compose

e










## 终端个性化设置

### 欢迎页面

vi   /etc/motd

/**

  • ┌───┐ ┌───┬───┬───┬───┐ ┌───┬───┬───┬───┐ ┌───┬───┬───┬───┐ ┌───┬───┬───┐
  • │Esc│ │ F1│ F2│ F3│ F4│ │ F5│ F6│ F7│ F8│ │ F9│F10│F11│F12│ │P/S│S L│P/B│ ┌┐ ┌┐ ┌┐
  • └───┘ └───┴───┴───┴───┘ └───┴───┴───┴───┘ └───┴───┴───┴───┘ └───┴───┴───┘ └┘ └┘ └┘
  • ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐ ┌───┬───┬───┐ ┌───┬───┬───┬───┐
  • │~ `│! 1│@ 2│# 3│$ 4│% 5│^ 6│& 7│* 8│( 9│) 0│_ -│+ =│ BacSp │ │Ins│Hom│PUp│ │N L│ / │ * │ - │
  • ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤ ├───┼───┼───┤ ├───┼───┼───┼───┤
  • │ Tab │ Q │ W │ E │ R │ T │ Y │ U │ I │ O │ P │{ [│} ]│ | \ │ │Del│End│PDn│ │ 7 │ 8 │ 9 │ │
  • ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴─────┤ └───┴───┴───┘ ├───┼───┼───┤ + │
  • │ Caps │ A │ S │ D │ F │ G │ H │ J │ K │ L │: ;│" '│ Enter │ │ 4 │ 5 │ 6 │ │
  • ├──────┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴────────┤ ┌───┐ ├───┼───┼───┼───┤
  • │ Shift │ Z │ X │ C │ V │ B │ N │ M │< ,│> .│? /│ Shift │ │ ↑ │ │ 1 │ 2 │ 3 │ │
  • ├─────┬──┴─┬─┴──┬┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤ ┌───┼───┼───┐ ├───┴───┼───┤ E││
  • │ Ctrl│ │Alt │ Space │ Alt│ │ │Ctrl│ │ ← │ ↓ │ → │ │ 0 │ . │←─┘│
  • └─────┴────┴────┴───────────────────────┴────┴────┴────┴────┘ └───┴───┴───┘ └───────┴───┴───┘
    */

### 终端颜色

vi /etc/profile

PS1=‘[\e[1;35m]\u@\h:[\e[0m][\e[1;33m]\w[\e[1;35m][\e[0m][\e[1;34m]$ [\e[0m]’










# 参考连接

[](https://egonlin.com/?p=184)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值