2024-08-15-Thu-T-Linux

一、基础篇

1.1 Linux入门

linux 官网: www.kernel.org

网站扫描: https://sitereport.netcraft.com

  • Linux和Unix关系
    • Uninx
      • BSD
        • FreeBSD
      • Sun Solaris
      • IBM AIX
      • AT&T System V
      • Minix
        • GUN/Linux内核
          • Ubuntu
          • RedHat
            • centOS
            • RedhatOS
          • SUSE
          • Fedora

1.2 vm和Linux安装

使用相应工具安装linux虚拟机, 本文使用multipass安装虚拟机
安装multipass brew install multipass

虚拟机网络连接模式介绍

  • 桥接模式: 虚拟机会获得一个与主机网络相同网段的IP地址,与主机、同网段的其他设备以及外网设备进行通信. 桥接模式将虚拟机直接连接到物理网络,虚拟机像是主机网络中的一台真实设备, 适合需要与外网和局域网中的其他设备自由通信的虚拟机,常用于企业网络、开发测试等。可能会引起ip冲突.
  • NAT模式: 虚拟机被分配一个虚拟的私有IP地址,外部网络无法直接访问该虚拟机。虚拟机通过主机的NAT转发来访问外网,主机充当网关角色。虚拟机只能通过主机访问外网,不能直接访问局域网中的其他设备。不会引起ip冲突
  • 仅主机模式:仅主机模式为虚拟机和主机之间创建一个完全隔离的网络环境,虚拟机不能直接访问外网。虚拟机和主机通过一个专用的虚拟网络接口互相通信,但不会与外部网络相连。不能访问外网,也不能与局域网中的其他设备通信。

虽然虚拟机与局域网中的其他设备隔离,但虚拟机与主机之间仍然可以直接通信。通常,Multipass 会为主机和虚拟机建立一个虚拟网络接口,用于相互访问。
通过这个接口,主机可以使用虚拟机的内部 IP 地址直接访问虚拟机的服务。这个功能设计为方便主机与虚拟机之间的数据交换,尤其是在不需要外部网络访问的开发和测试场景中。

1.3 Linux目录结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
├── bin -> usr/bin
├── bin.usr-is-merged
├── boot
├── dev
├── etc
├── home
├── lib -> usr/lib
├── lib.usr-is-merged
├── lost+found
├── media
├── mnt
├── opt
├── proc
├── root
├── run
├── sbin -> usr/sbin
├── sbin.usr-is-merged
├── snap
├── srv
├── sys
├── tmp
├── usr
└── var
  • /bin (/usr/bin, /usr/local/bin): Binary的缩写, 用于存放经常使用的命令
  • /sbin (/usr/sbin, /usr/local/sbin): Super User Binary, 系统管理员使用的系统管理命令
  • /home: 存放普通用户的目录
  • /root: 管理员用户主目录
  • /lib: 系统开机所需要的最基本的动态连接共享库
  • /lost+found: 这个目录一般情况是空的, 当系统非法关机后, 这里会存放一些文件
  • /etc: 所有的系统管理所需要的配置文件和子目录
  • /usr: 用户的很多应用程序文件都放在这个目录下, 类似于windows program files
  • /boot: 存放用于启动Linux的一些核心文件, 包括连接文件和镜像文件
  • /proc: 虚拟的目录, 系统内存的映射, 访问这个目录可以获取系统信息
  • /srv: service缩写, 存放一些服务启动后需要提取的数据
  • /sys: 这是linux2.6内核的一个变化, 该目录下安装了2.6内核新出现的一个文件系统sysfs
  • /tmp: 用于存放临时文件
  • /dev: device, 所有的硬件用文件的形式存储到此处
  • /media: Linux会自动识别一些设备, 如U盘, 光驱, 当识别到这些设备后, 会将其挂载在此目录下
  • /mnt: 挂载其他文件系统使用
  • /opt: 给主机额外安装软件所摆放的目录,
  • /usr/local: 给主机额外安装软件的安装目录, 一般是通过通过编译源码的方式安装的程序
  • /var: 用于存放日志等不断扩充的内容, 或者经常被修改的内容都存放在此目录下
  • /selinux: security enhanced linux, selinux是一种安全子系统, 它能控制程序, 有三种模式, 可以自行设置.

二、实际操作篇

2.1 远程登录

编辑虚拟机ssh配置文件/etc/ssh/sshd_config
修改或添加: PermitRootLogin yes
这样虚拟机可以通过ssh服务进行账号密码的登录
ssh -p22 root@192.168.64.19

同时可以进行文件传输
scp root@node2:/home/ubuntu/cni-plugins-linux-amd64-v1.3.0.tgz ./ : 此命令将远程主机node2上的文件下载到当前目录下

2.2 vim和vi

Linux系统会内置vi编辑器
vim是vi的增强版本, 可以主动根据字体颜色辨别语法正确性. 代码补全, 编译以及错误跳转等方便编程等功能特别丰富
命令行输入vimtutor进入vim tutor, 可以学习一些基本操作
vim手册(同:help user-manual)

vi和vim的三种模式
其实官方文档里没有按照此分类

  1. 默认模式
    以vim打开一个文档就进入了默认模式. 在这个模式中, 可以使用上下左右键和删除键来移动光标. 同时可以通过一些字母键来编辑文本内容
  2. 插入模式
    按下: i, I, o, O, a, A, r, R等任何一个字符进入编辑模式, 通常使用i. (airo)
    i:从当前光标之前插入
    I: 从行首插入
    A: 从行尾追加
    a: 从当前光标之后追加
    r: 替换当前光标所在的单个字符, 替换后自动结束
    R: 替换当前光标所在字符, 替换后移动到下一个字符继续替换
  3. 命令行模式
    在此模式下, 可以根据相关指令, 完成读取, 存盘, 替换, 退出vim, 显示行号等操作.

三种模式的关系:

alt text

2.2.1 快捷键使用

编辑模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# 1. 拷贝与粘贴
# 拷贝当前行
yy
# 拷贝当前行向下的5行(从当前行为1开始计算, 1,2,3,4,5)
5yy
# 粘贴
p # 从下一行的行首开始粘贴复制或剪贴的内容

# 2.删除
# 删除当前行
dd
# 删除当前行向下的5行(从当前行为1开始计算, 1,2,3,4,5)
5dd
# 删除某个字母
dw

# 删除光标下的某个字符
x

# 撤销上一步操作
u

# 3. 查找
# 在文件中查找某个单词, 例如: "test"
/test # 输入回车后查找, 查找下一个输入n

# 4. 设置
# 设置文件行号
set nu # 开启行号
set nonu # 关闭行号

# 5. 其他操作
# 移动到首行 good game
gg

# 移动到末行
G

# 移动到当前行的行首
0

# 移动到当前行的行尾
$





2.3 开机、重启和用户登录、注销

2.3.1 关机、重启和注销

shutdown -h now: 立即关机, halt
shutdown == shutdown -h 1: 一分钟后关机
shutdown -r now: 立即重启
halt: 关机, 不会等待设备关闭, 与shutdown -h now效果相同
reboot: 重启
sync: 将内存的数据同步到磁盘

Note: 不管是重启还是关机, 首先要运行sync命令, 将内存数据写到磁盘,否则数据可能丢失
目前shutdown/reboot/halt 等命令均已经在关机前运行了sync, 但是还是有可能丢失数据, 因此还是建议在关机前运行sync

2.3.2 用户登录、注销

su -l root: 切换到root用户, -l参数表示登录
su - root: 切换到root用户, 不登录
logout: 退出当前用户, 在运行级别5下, 但是在运行级别3下, 退出不会关机

2.3.3 用户管理

1. 添加用户
useradd 用户名: 创建用户, 默认密码为空, 默认家目录为/home/用户名
useradd -g 组名 用户名: 为用户指定组
useradd -d /home/用户名 用户名: 为用户指定家目录

passwd 用户名: 修改用户密码

2. 修改用户

usermod -g 组名 用户名: 修改用户组
usermod -aG sudo 用户名: 将用户添加到sudo用户组

3. 删除用户
userdel 用户名: 删除用户, 会保留家目录
userdel -r 用户名: 删除用户, -r参数表示删除用户家目录
一般情况, 建议保留家目录, 以免数据丢失

4. 查询用户信息
id 用户名: 查看用户信息
who: 查看当前登录用户
w: 查看当前登录用户, 显示时间
last: 查看系统登录日志
whoami: 查看当前用户名
who am i: 查看当前用户名, 显示ip地址, 登录时间

2.3.4 组管理

5. 组管理
groupadd 组名: 创建组
groupmod -n 新组名 老组名: 修改组名
groupdel 组名: 删除组

添加用户时, 如果没有指定组, 则默认生成一个组, 该组名称与用户名相同

6. 用户和组相关的文件
/etc/passwd: 用户信息 (用户名:密码:UID:GID:注释:主目录:shell)

/etc/group: 组信息 (组名:密码:GID:用户列表)

/etc/shadow: 用户密码信息 (登录名:加密口令:最后一次密码修改日期:最小时间间隔:最大时间间隔:警告时间:不活动时间:失效日期:标志)

2.4 实用指令

shel的理解:
alt text

2.4.1 运行级别

基本介绍

  • 0: 系统停机状态,系统默认运行级别不能设为0,否则不能正常启动。
  • 1: 单用户工作状态,root权限,用于系统维护,禁止远程登陆。
  • 2: 多用户状态(没有NFS)。NFS Network File System,即网络文件系统,用于挂载远程文件系统。
  • 3: 完全的多用户状态(有NFS),登陆后进入控制台命令行模式。
  • 4: 系统未使用,保留。
  • 5: X11控制台,登陆后进入图形GUI模式。
  • 6: 系统正常关闭并重启,默认运行级别不能设为6,否则不能正常启动。

systemctl get-default: 获取当前默认运行级别。

通过init切换运行级别。
应用实例: init [0123456]

开启设定
对于centOS7以前: /etc/inittab
ubuntu: /usr/lib/systemd/system

1
2
multi-user.target: analogous to runlevel 3   # 多用户等价于运行级别3
graphical.target: analogous to runlevel 5 # 图形化界面等价于运行级别5

设置默认的运行级别: systemctl set-default graphical.target

2.4.2 帮助指令

man [命令或配置文件]: 查看帮助
help [命令]: 查看shell内置命令的帮助信息
top: 查看系统进程使用情况
history: 查看命令历史, history 10: 查看最近10条命令, !100: 执行历史记录中第100条命令
df -h: 查看磁盘使用情况
free -m: 查看内存使用情况

2.4.3 文件/文件夹操作

mkdir [选项] 目录名: 创建目录, -p创建多级目录
rmdir [选项] 目录名: 删除空目录
touch [选项] 文件名: 创建文件
rm [选项] 文件名: 删除文件, -r递归删除
cp [选项] 源文件 目标文件: 复制文件
mv [选项] 源文件 目标文件: 移动文件, -u移动文件并更新软连接
ln [选项] 源文件 软连接名: 创建软连接, -s创建软连接
cat [选项] 文件名: 显示文件内容, -n显示行数
head [选项] 文件名: 显示文件前几行, -n指定显示前n行, 不加参数则显示前10行
tail [选项] 文件名: 显示文件后几行, -n指定显示后n行, 不加参数则显示后10行, -f实时显示文件内容
more [选项] 文件名: 分页显示文件内容,
less [选项] 文件名: 分页显示文件内容, /搜索, n下一行, N上一行, q退出

2.4.4 时间日期类

date +%Y-%m-%d_%H:%M:%S: 2024-11-07_03:08:38

2.4.5 搜索查找类

find [选项] 路径名: 在指定路径下查找文件, -name按文件名查找, -user按用户查找, -type按文件类型查找, -mtime按修改时间查找, -size按文件大小查找(+代表大于, -代表小于, 不写代表等于. k, M, G), -exec执行命令, -delete删除文件

locate 文件名: 定位文件路径, 第一次执行之前需要执行updatedb命令

grep [选项] 关键字 文件名: 在文件中查找关键字, -i不区分大小写, -n显示行号和匹配行, -v反向查找, -r递归查找, -l只显示文件名

2.4.6 压缩和解压

gzip [选项] 文件名: 压缩文件, 只能压缩为*.gz文件 -d解压文件, -k保留文件名, -f强制解压, -c压缩文件到标准输出
gunzip [选项] 文件名: 解压文件

zip [选项] 文件名 压缩的内容: 压缩文件, 可以压缩为*.zip文件, -r递归压缩, -d解压文件, -k保留文件名, -f强制解压, -c压缩文件到标准输出
unzip [选项] 文件名: 解压文件, -d指定解压路径

tar [选项] xxx.tar.gz 打包的内容: 压缩文件, 可以压缩为*.tar.gz文件, -z打包同时压缩, -v显示详细信息, -f指定压缩后的文件名, -c产生.tar打包文件, -x解压.tar文件

2.5 组管理和权限管理

在linux中, 每个用户必须属于一个组, 不能独立于组之外.
对于每一个文件, 有:

  • 所有者
  • 所在组
  • 其他组

chown [选项] 新所有者:新组 新文件: 修改文件所有者和所在组, -R递归修改
groupadd [选项] 新组名: 创建新组
groupmod [选项] 老组名 新组名: 修改组名
chgrp [选项] 新组 新文件: 修改文件所在组, -R递归修改

usermod -g 新组 用户名: 修改用户所在组
usermod -d 新目录 用户名: 修改用户主目录, -m将用户主目录移动到新目录(usermod -d /home/tom -m newtomgroup)

权限介绍

1
2
3
ls -l # 显示的内容如下:  
drwxr-x--- 6 ubuntu ubuntu 4096 Nov 7 02:52 ubuntu
0123456789 10 11 12 13(byte) 14(modify time) 15

0-9位说明:

  • 第0位: 文件类型

    • d: 目录
    • -: 普通文件
    • l: 符号链接
    • c: 字符设备文件
    • b: 块设备文件, 比如硬盘
  • 第1-3位: 文件所有者权限

  • 第4-6位: 文件所在组权限

  • 第7-9位: 其他用户权限

    • r == 4: 读权限
    • w == 2: 写权限
    • x == 1: 执行权限

第10位说明:

  • 如果是目录: 子目录数
  • 如果是文件: 硬链接数

chmod详解

  1. 第一种类型操作
    1
    2
    3
    4
    5
    # 通过+ - =变更权限
    chmod g+w file # 没有指定u,g,o,a则默认添加给所有者权限, 添加给其他组除写权限之外的指定权限
    chmod g+wrx file # 添加给所在组rwx权限
    chmod o-wrx file # 删除其他组rwx权限
    chmod o=x file #给其他组执行权限
  • u: 所有者
  • g: 所在组
  • o: 其他用户
  • a: 所有者、所在组、其他用户
  1. 第二种类型操作
1
2
3
4
5
6
# 通过4, 2, 1 变更权限
chmod 777 file # 添加rwx权限给所有用户
chmod 755 file # 添加rwx权限给所在组和执行权限给其他用户
chmod 751 file # 添加rwx权限给所在组和rw权限给其他用户
chmod 640 file # 添加rw权限给所在组,添加x权限给其他用户

  • 4: 读权限
  • 2: 写权限
  • 1: 执行权限

2.6 定时任务调度

2.6.1 crontab定时任务

crontab [选项] :

  • -e: 编辑crontab文件
  • -l: 查询crontab任务
  • -r: 删除当前用户crontab文件
1
2
3
4
5
6
7
* * * * * /bin/bash /root/script.sh # 每分钟执行一次
*/1 * * * * /bin/bash /root/script.sh # 每隔1分钟执行一次
0 8 * * * /bin/bash /root/script.sh # 每天早上8点执行一次
0 8 * * 1 /bin/bash /root/script.sh # 每周一早上8点执行一次
0 8 1 * * /bin/bash /root/script.sh # 每月1号早上8点执行一次
0 8 1 1,6,12,18 * /bin/bash /root/script.sh # 每月1号、6号、12号、18号早上8点执行一次

  • *: 任意值
  • -: 值范围, 如: 1-5 表示1到5
  • /: 步长
  • ,: 列举多个值, 如: 1,3,5

其他操作

1
2
service crond restart # 重启定时服务

2.6.2 at定时任务

at命令是一次性定时任务,需要指定时间,在指定的时间执行命令,命令执行完毕,该定时任务自动结束。
默认情况是1分钟后执行

at [选项] 时间: 在指定时间执行命令, 输入CRL+D结束输入

at选项:

  • -f <文件名> : 从指定文件读取任务
  • -m: 任务完成后发送邮件通知
  • -q <队列名>: 指定队列名,默认为cron
  • -t <时间戳>: 指定时间戳,格式为%s,如1577836800,表示2020年1月1日0点0分0秒
  • -I: 列出at队列, 等同于atq
  • -d <任务ID>: 删除指定任务, 等同于atrm
  • -v: 显示任务将被执行的时间
  • -l: 列出所有任务
  • -c <任务ID>: 打印任务的内容到标准输出(命令行)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 实例
# 指定时间
at 10:00 2024-08-15
at> echo "hello world" >> /tmp/test.txt
at> date >> /tmp/test.txt

# 相对时间
at now + 5 minutes
at now + 7 hours
at now + 1 days
at now + 1 weeks
at now + 1 months
at now + 1 years

2.7 磁盘分区、挂载

Linux无论有几个分区, 分给哪一个目录使用, 它归根结底就只有一个根目录, 一个独立的且唯一的文件结构. Linux中每个分区都是用来组成整个文件系统的一部分.
Linux采用了一种叫“载入”的处理方法, 它的整个文件系统中包含了一整套的文件和目录, 且将一个分区和一个目录关联起来, 这样, 就可以认为, 这个分区是属于这个目录的.
示意图:
alt text

2.7.1 磁盘分区及挂载

lsblklsblk -f: 查看磁盘分区情况
fdisk /dev/sda: 分区磁盘

  • m: 查看命令列表
  • l: 查看磁盘分区情况, 同 p
  • n: 新增分区
  • d: 删除分区
  • w: 写入分区

分区完成后, 需要格式化磁盘分区, 格式化磁盘分区, 可以使用mkfs命令:
mkfs -t ext4 /dev/sda1: 格式化磁盘分区, ext4是文件系统类型
挂载磁盘分区(临时, 重启后会丢失):
mount /dev/sda1 /mnt/data: 将磁盘分区挂载到/mnt/data目录下
卸载磁盘分区:
umount /dev/sda1: 卸载磁盘分区

挂载磁盘分区(永久):
vim /etc/fstab: 编辑挂载文件, 将磁盘分区挂载到/mnt/data目录下

1
2
/dev/sda1    /mnt/data      ext4    defaults        0 0
# 设备 挂载点 文件系统 选项 dump(0表示不备份,1表示备份) fsck(0表示不检查硬盘, 1检查其他目录, 2检查根目录)

修改/etc/fstab文件后, 需要重启系统,或使用mount -a能生效:

2.7.2 磁盘情况查询

df -h: 查看磁盘使用情况
du [选项] [文件或目录]: 显示该目录及该目下目录或文件磁盘占用情况
--h: 显示时带计量单位, 如: 1K, 1M, 1G
--s: 仅显示该目录大小
---max-depth: 限制显示目录深度, 默认不限制
--c: 列出明细同时, 显示汇总(total)值
--a: 显示所有文件, 包括隐藏文件

2.7.3 磁盘实用指令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 1. 统计/opt文件夹下“文件”的个数
ls -l /opt | grep "^-" | wc -l

# 2. 统计/opt文件夹下“目录”的个数
ls -l /opt | grep "^d" | wc -l

# 3. 统计/opt文件夹及子目录下“文件”的个数
ls -lR /opt | grep "^-" | wc -l

# 4. 以树状结构显示目录结构
tree /opt -L 2 # 显示深度为2



2.8 网络配置

alt text

  • IP获取方式
    • DHCP 动态获取IP地址
    • 静态配置IP地址

2.8.1 静态配置IP地址

直接修改配置文件来指定IP, 并可以连接到外网(推荐)

1
2
3
4
5
6
7
8
9
10
11
12
13
# CentOS 的ens33网卡配置为例
vim /etc/sysconfig/network-scripts/ifcfg-ens33
# 修改内容如下
DEVICE=eth0 # 接口名(设备, 网卡)
HWADDR=00:50:56:00:00:00 # 网卡MAC地址
TYPE= Ethernet # 网络类型
UUID= 01b0f841-c5c3-4a23-a6f2-035a83b0acb7 # 网卡唯一标识
NOBOOT=no # 系统启动时, 网络接口是否有效
BOOTPROTO= static # IP的配置方法, none(引导时不使用协议)|dhcp(动态分配)|bootp(bootp协议)|static(静态手动分配)
IPADDR= 192.168.1.100 # IP地址
GATEWAY= 192.168.1.1 # 网关IP地址
DNS1= 114.114.114.114 # DNS服务器IP地址

2.8.2 设置主机名和hosts映射

为了方便记忆, 可以给Linux系统设置主机名, 也可以根据需要修改主机名
hostname: 查看当前主机名
修改文件/etc/hostname文件, 修改主机名. 修改后重启生效
设置主机名和hosts映射: vim /etc/hosts

2.8.3 主机名解析分析

实例: 用户在浏览器输入了www.baidu.com
alt text

2.9 进程管理

在linux中, 每个执行的程序都称为一个进程, 每一个进程都分配一个ID号(PID, 进程号)
每一个进程都可能以两种方式存在:

  • 前台: 用户目前屏幕上可以进行操作的进程
  • 后台: 实际在运行中, 但是屏幕无法看到

一般系统的服务都是以后台进程的方式存在, 而且都会常驻载系统中, 直到关机才结束

2.9.1 查看与终止进程

  • 显示系统执行的程序
    • ps: 显示当前正在运行的进程
      • ps -a: 显示所有进程, 包括前台和后台进程
      • ps -u: 以用户身份显示
      • ps -x: 显示后台进程运行的参数
      • ps -ef: 以全格式显示当前所有进程, -e显示所有进程, -f全格式
  • 终止进程
    • kill [选项] 进程号: 终止进程
      • kill -9 进程号: 强制终止进程, 强制终止进程, 即使该进程正在运行中, 也可以强制终止
    • killall 进程名称: 终止进程名称为进程名称的进程

最佳实践:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 1. 踢掉某个非法登录用户
ps -aux | grep "sshd" # 通过查询sshd运行服务, 找到tom登录的进程号
kill 11421 # 强制终止11421进程, 从而让踢掉tom登录

# 2. 终止远程登录服务sshd, 在适当的时候再重启sshd服务
kill sshd服务对应的进程号
systemctl start sshd

# 3. 终止多个gedit
killall gedit


# 4. 强制杀死一个终端(命令行)
ps -aux | grep "bash"
kill -9 10487 # 不使用-9参数, 无法终止终端命令行

查看进程树
pstree [选项]: 可以更直观的来看进程信息

  • -p: 显示进程的PID
  • -u: 显示进程的用户名

2.9.2 服务(service)管理

service本质就是进程, 但是是运行在后台的, 通常都会监听某个端口, 等待其他进程的请求, 比如(mysql, sshd, 防火墙等). 因此我们又称为守护进程,

service管理指令:

  • service|systemctl [选项] 服务名 [start|stop|restart|reload|status]: 管理服务

2.9.3 服务管理

Linux系统有7种运行级别, 常用的是3和5

  • 0: 系统停机状态,系统默认运行级别不能设为0,否则不能正常启动。
  • 1: 单用户工作状态,root权限,用于系统维护,禁止远程登陆。
  • 2: 多用户状态(没有NFS)。NFS Network File System,即网络文件系统,用于挂载远程文件系统。
  • 3: 完全的多用户状态(有NFS),登陆后进入控制台命令行模式。
  • 4: 系统未使用,保留。
  • 5: X11控制台,登陆后进入图形GUI模式。
  • 6: 系统正常关闭并重启,默认运行级别不能设为6,否则不能正常启动。

开机流程说明:

1
开机--> BIOS --> /boot --> systemd进程 --> 运行级别 --> 运行级别对应的服务

chkconfig
通过chkconfig可以给服务各个级别设置自启动/关闭
chkconfig指令管理的服务在/etc/etc/init.d查看
基本语法:

  • chkconfig --list #显示服务在各个运行级别的自启动状态
  • chkconfig --level 5 service_name [on|off]
  • 演示:(对network服务进行操作) chkkonfig --level 3 network on

systemctl
基本语法: systemctl [start|stop|restart|reload|status] service_name
systemctl管理的指令在/usr/lib/systemd/system查看

  • systemctl设置服务自启动状态
    • systemctl list-unit-files | grep service_name: 查看服务开机自启动状态
    • systemctl enable service_name: 设置开机自启动
    • systemctl disable service_name: 设置开机不启动
    • systemctl is-enabled service_name: 查看服务是否开机启动

案例: 查看当前防火墙的状态, 关闭防火墙和重启防火墙

1
2
3
4
5
6
ls -l /usr/lib/systemd/system/firewalld.service # 查看防火墙服务文件
systemctl list-unit-files | grep firewalld
systemctl status firewalld
systemctl stop firewalld
telnet 127.0.0.1 22 # 测试是否关闭

防火墙firwall指令

  • firewall-cmd --permanenet --add-port=端口号/协议: 打开端口
  • firewall-cmd --permanent --remove-port=端口号/协议: 关闭端口
  • firewall-cmd --reload: 重新加载, 才能生效
  • firewall-cmd --query-port=端口号/协议: 查看端口是否开放
  • firewall-cmd --list-ports: 查看已开放的端口
  • firewall-cmd --list-all: 查看防火墙状态
  • netstat -antp: 查看端口是否开放

动态监控进程top
top与ps类似, 它们都用来显示正在执行的进程, Top与ps最大的不同之处, 在于top在执行一段时间可以更新正在运行的进程.
基本语法: top [选项]

  • -i: 不显示任何限制或者僵死的进程
  • -d 秒速: 刷新间隔, 可以设置成0.1秒, 但是刷新间隔过短, 会导致top的cpu占用率非常高, 默认为3秒
  • -p 进程号: 查看某个进程的详细信息

交互操作:

  • q: 退出top
  • d: 修改刷新间隔
  • k: 杀死进程
  • u: 按用户筛选
  • P: 按CPU使用率排序, 默认
  • M: 按内存使用率排序
  • N: 按进程号排序

监控网络状态netstat
基本语法: netstat [选项]

  • -an: 按一定顺序排列输出
  • -p: 显示进程号和进程名

2.10 RPM和APT

RPM 用于互联网下载包的打包及安装工具, 它包含在某些Linux发行版中, 比如CentOS, Fedora等。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# 查询已安装的软件包
rpm -q [包名] # 查看是否已安装指定的软件包

# 查询安装的所有软件包
rpm -qa # 列出系统中所有已安装的软件包

# 查询软件包的信息
rpm -qi [包名] # 查看某个已安装包的详细信息

# 查询软件包文件列表
rpm -ql [包名] # 显示某个已安装包包含的文件

# 查询文件属于哪个软件包
rpm -qf [文件路径] # 通过文件路径查询它所属的软件包

# 安装软件包
rpm -ivh [包文件名] # 安装指定的 .rpm 包文件 (-i安装, -v显示详细信息, -h显示进度条)

# 升级软件包
rpm -Uvh [包文件名] # 升级或安装软件包 (-U升级或安装)

# 仅升级已安装的软件包
rpm -Fvh [包文件名] # 仅升级已安装的软件包(如包未安装则不操作)

# 卸载软件包
rpm -e [包名] # 卸载已安装的包(需指定包名而非文件名)

# 验证软件包完整性
rpm -V [包名] # 验证指定包中的文件是否已被更改

# 检查安装包文件的依赖关系
rpm -qpR [包文件名] # 检查安装某个 .rpm 包文件时可能存在的依赖关系

# 检查已安装包的依赖
rpm -qR [包名] # 检查已安装的包的依赖关系

# 显示包文件的说明信息(不安装)
rpm -qip [包文件名] # 查看指定 .rpm 包文件的描述信息

# 显示包文件包含的文件列表(不安装)
rpm -qlp [包文件名] # 查看指定 .rpm 包文件中包含的文件列表

APT

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# 更新源
vim /etc/apt/sources.list

# 更新软件包列表
sudo apt update # 从软件源获取最新的包信息,但不安装更新

# 升级所有已安装的软件包
sudo apt upgrade # 安装所有已安装包的最新版本(不会移除包)

# 升级所有已安装的软件包,并允许移除旧包
sudo apt full-upgrade # 在需要时移除冲突的旧包,以完成系统的全面升级

# 安装软件包
sudo apt install [包名] # 安装指定软件包,如果已安装则不重复安装

# 安装特定版本的软件包
sudo apt install [包名]=[版本号] # 安装指定版本的软件包

# 卸载软件包(保留配置文件)
sudo apt remove [包名] # 卸载指定软件包,但保留配置文件

# 完全卸载软件包(包含配置文件)
sudo apt purge [包名] # 完全卸载指定软件包及其配置文件

# 自动移除不再需要的依赖包
sudo apt autoremove # 移除安装时自动添加、但现在已不再需要的依赖包

# 搜索软件包
apt search [关键词] # 在包列表中搜索与关键词匹配的包

# 显示软件包的信息
apt show [包名] # 显示指定包的详细信息(包括描述、依赖等)

# 查看软件包是否已安装
dpkg -l | grep [包名] # 使用 dpkg 列出并过滤出指定包的信息

# 列出软件包的依赖关系
apt depends [包名] # 列出指定包的依赖关系

# 列出包的反向依赖(哪些包依赖此包)
apt rdepends [包名] # 列出指定包的反向依赖关系

# 清理下载的包缓存
sudo apt clean # 清空 /var/cache/apt/archives 中的已下载包文件

# 清除已删除软件包的缓存文件
sudo apt autoclean # 清除不再需要的包缓存文件(已删除包的缓存)

# 检查系统中是否有未满足的依赖
sudo apt check # 检查系统中是否存在依赖问题

2.11 Shell编程

Shell是一个命令行解释器, 它为用户提供了一个向Linux内核发送请求以便运行程序的界面系统级程序, 用户可以用shell来启动、挂起、停止甚至是编写一些程序

2.11.1 执行方式

  1. 脚本的格式要求:
    • 脚本以#/bin/bash开头
    • 脚本需要有可执行权限
  2. 脚本常用执行方式:
    • 直接执行脚本:sh 脚本文件名
    • 脚本文件执行:./脚本文件名 (需要添加执行权限 +x)

案例:

1
2
#!/bin/bash # 声明解释器, 一般默认是bash, 所以有时候没有添加这一行也会执行后续内容
echo "Hello World!"

2.11.2 Shell中的变量

  1. 普通变量:
    • set 显示当前shell中所有的变量
    • 系统变量
      • $HOSTNAME
      • $USER
      • $PATH
      • $HOME
      • 定义环境变量: export VAR_NAME=VALUE
    • 自定义变量
      • 变量定义规则: 可以由字母数字下划线组成, 但是不能以数字开头; 等号两边不能有空格; 变量名一般大写
      • 定义变量: 变量名=值
      • 引用变量:$变量名
      • 删除变量:unset 变量名
      • 声明静态变量:readonly 变量名 (静态变量不能被unset, 也不能被修改)
    • 将命令返回值赋值给变量: 使用用反引号或者是括号
1
2
3
4
5
6
A=`date`
echo "$A"

C=(date)
echo "$C"

  1. Shell脚本多行注释:

    1
    2
    3
    4
    :<<! 内容 
    内容
    !

  2. 位置参数变量
    当执行一个shell脚本时, 如果希望获取命令行的参数信息, 可以使用位置参数变量.
    比如: ./myshell.sh 100 200

  • 基本语法:
    • $n: n为数字, 0代表命令本身(不含参数), 1-9代表第一到第九个参数, 参数超过十个(包含10), 使用大括号, 例如${12}
    • $*: 代表命令行中所有的参数, 把所有参数看成一个整体
    • $@: 代表命令行中所有的参数, 把每个参数看成单独个体
    • $#: 代表命令行中参数的个数
  1. 预定义变量
    shell设计者事先已经定义好的变量, 可以直接在shell中使用.
  • $$: 当前进程的进程号
  • $!: 后台运行的最后一个进程的进程号
  • $?: 最后一次执行命令的返回状态, 如果变量为0, 则说明上一个命令执行成功

2.11.3 Shell中的运算符

基本语法:

  1. $((运算式)), $[运算式], expr 运算式
  2. expr运算符之间需要有空格, 加、减、乘、除、取余用+, -, \*, /, %表示

2.11.4 条件判断

基本语法:

  1. [ condition ]: 非空返回true, 可以使用$?验证, 0为true, 1为false(注意: condition前后需要有空格)

if判读:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# 基本语法
if [ condition ]; then
Do some things
fi


#或者
if [ condition ]
then
Do some things
fi



#或者
if [ condition ]
then
Do some things
elif [ condition ]
then
Do other things
else
then
Don't do it
fi

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# 数值比较
-eq:等于
if [ "$a" -eq "$b" ]; then
echo "a equals b"
fi

-ne:不等于
if [ "$a" -ne "$b" ]; then
echo "a is not equal to b"
fi

-lt:小于
if [ "$a" -lt "$b" ]; then
echo "a is less than b"
fi

-le:小于或等于
if [ "$a" -le "$b" ]; then
echo "a is less than or equal to b"
fi

-gt:大于
if [ "$a" -gt "$b" ]; then
echo "a is greater than b"
fi

-ge:大于或等于
if [ "$a" -ge "$b" ]; then
echo "a is greater than or equal to b"
fi

# 字符串比较
=:字符串相等
if [ "$str1" = "$str2" ]; then
echo "Strings are equal"
fi

!=:字符串不相等
if [ "$str1" != "$str2" ]; then
echo "Strings are not equal"
fi

-z:字符串为空
if [ -z "$str1" ]; then
echo "str1 is empty"
fi

-n:字符串不为空
if [ -n "$str2" ]; then
echo "str2 is not empty"
fi

# 文件判断
-e:文件存在
if [ -e "$file" ]; then
echo "File exists"
fi

-f:文件存在且为普通文件
if [ -f "$file" ]; then
echo "File is a regular file"
fi

-d:文件存在且为目录
if [ -d "$file" ]; then
echo "It is a directory"
fi

-r:文件存在且可读
if [ -r "$file" ]; then
echo "File is readable"
fi

-w:文件存在且可写
if [ -w "$file" ]; then
echo "File is writable"
fi

-x:文件存在且可执行
if [ -x "$file" ]; then
echo "File is executable"
fi

-s:文件存在且大小大于 0
if [ -s "$file" ]; then
echo "File size is greater than 0"
fi

# 逻辑运算
-a:逻辑与(AND)
if [ -r "$file" -a -w "$file" ]; then
echo "File is readable and writable"
fi

-o:逻辑或(OR)
if [ -r "$file" -o -w "$file" ]; then
echo "File is readable or writable"
fi

!:逻辑非(NOT)
if [ ! -x "$file" ]; then
echo "File is not executable"
fi

# 组合条件
&&:条件1和条件2都为真
if [ "$a" -lt "$b" ] && [ "$str1" != "$str2" ]; then
echo "a is less than b and str1 is not equal to str2"
fi

# 使用双中括号(更适合字符串和正则匹配)
[[ ... ]]:字符串和正则表达式匹配
if [[ "$str1" =~ ^h.*o$ ]]; then
echo "str1 matches the regex pattern"
fi

# 示例:检查变量是否为空
-z:字符串为空
if [ -z "$var" ]; then
echo "var is empty"
fi

# 示例:检查文件是否存在且可执行
-x:文件存在且可执行
if [ -x "$file" ]; then
echo "File is executable"
fi

# 示例:两个条件都为真
&&:条件1和条件2都为真
if [ "$a" -eq 5 ] && [ "$b" -eq 10 ]; then
echo "Both conditions are true"
fi

2.11.5 case语句

1
2
3
4
5
6
7
8
9
10
11
12
13
# 基本语法
case $变量名 in
"var1")
Do the thing of var1
;;
"var2")
Do the thing of var2
''
"var3")
Do the thing of var3
*)
Do the things that are not the case var1, var2, var3
esac

2.11.6 循环控制

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# for 循环基本语法分
# 基本语法 1
for var in var1 var2 var3
do
Do some repeate things
done
#例如
for i in $@
do
echo $i
done

# 基本语法 2
for (( start_var;condition;var_change))
do
Do sone repeate things
done
#例如
for ((i=0;i<9;i++))
do
echo $i
done



# while 循环
# 基本语法
while [ condition ] # 注意空格
do
Do some things repeately
done


2.11.7 读取控制台输入

基本语法: read [选项] [参数]

  • 选项:
    • -p: 指定读取值时的提示符
    • -t: 指定读取值时的等待时间(秒)
  • 参数: 指定读取值的变量名
1
2
3
4
5
6
7
# 案例
read -p "请输入A:" A
echo "A = $A"

read -p "请输入B:" -t 3 B # 3秒之内输入B的值, 否则自动执行下一行
echo "B = $B"

2.11.8 函数

shell中的函数包括系统函数和自定义函数

  1. 系统函数
  • basename
    基本语法: basename [pathname] [suffix]
    功能: 返回完整路径最后/的部分(不包括/), 常用于获取文件名
    suffix为后缀, 如果指定suffix, basename会将pathname中的suffix去掉
    例子: basename /home/ubuntu/t.txt .txt, 结果是t

  • dirname
    基本语法: dirname pathname
    功能: 返回完整路径的目录(即除去pathname中最后的/及之后的部分)
    例子: dirname /home/ubuntu/t.txt 结果是: /home/ubuntu

  1. 自定义函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# 基本语法

# 定义
[ function ] funcname()
{
Action;
[return int];
}

# 调用
funcname [value]

# 例子1:

func1(){
echo "$1"
echo "$2"
}

func1 23 43
# 输出为:
23 43

# 例子2:
function func2(){
echo $A
echo $B
}
read -p "请输入一个字符: " A # AAA
read -p "请输入一个字符: " B # BBB
func2 $A $B
# 输出为:
AAA
BBB

2.11.9 综合案例

每天凌晨2:30备份数据库testDatabse到/data/backup/db
开始备份和备份结束都能给出相应的提示信息
备份后的文件要求以备份时间为文件名, 并打包为.tar.gz的形式
在备份的同时, 检查是否有10天前的备份数据库文件, 有就将其删除

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

#!/bin/bash

# 设置备份路径和数据库名称
BACKUP_DIR="/data/backup/db"
DB_NAME="testDatabase"
TIMESTAMP=$(date +"%Y%m%d%H%M")
BACKUP_FILE="${BACKUP_DIR}/${DB_NAME}_${TIMESTAMP}.tar.gz"

# 创建备份目录(如果不存在)
mkdir -p "$BACKUP_DIR"

# 开始备份
echo "开始备份数据库 ${DB_NAME} 到 ${BACKUP_FILE}"
mysqldump -u root -pYOUR_PASSWORD $DB_NAME | gzip > "$BACKUP_FILE"

# 检查备份是否成功
if [ $? -eq 0 ]; then
echo "数据库备份成功: ${BACKUP_FILE}"
else
echo "数据库备份失败"
exit 1
fi

# 删除 10 天前的备份文件
find "$BACKUP_DIR" -name "${DB_NAME}_*.tar.gz" -type f -mtime +10 -exec rm -f {} \;

echo "旧备份文件清理完成"

# 保存为/usr/sbin/mysql_db_backup.sh
1
2
30 02 * * * sh /usr/sbin/mysql_db_backup.sh

三、高级篇

3.1 日志管理

日志文件是重要的系统信息文件, 其中记录了许多重要的系统事件, 包括用户的登录信息, 系统的启动信息, 系统的安全信息, 邮件相关信息, 各种服务相关信息
日志对于安全来说很重要, 它记录了系统每天发生的各种事件, 通过日志来检查错误发生的原因, 或者受到攻击时攻击者留下的痕迹.
日志是用来记录重大事件的工具.
/var/log目录就是系统日志文件的保存位置 (variable)
rsyslogd是用于记录日志的后台程序, 对应的配置文件是/etc/rsyslog.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/var/log/boot.log            # 系统启动日志
/var/log/cron # cron 作业调度器日志
/var/log/cpus # CPU 使用情况日志



/var/log/syslog # 系统日志(记录系统的常规操作信息和错误)
/var/log/messages # 系统消息日志,包含大多数常规系统事件
/var/log/auth.log # 用户认证相关日志(登录、sudo等)
/var/log/dmesg # 内核启动信息日志

/var/log/mail.log # 邮件系统日志
/var/log/apache2/ # Apache Web 服务器日志(可能位于该目录或 /var/log/httpd/)
/var/log/nginx/ # Nginx Web 服务器日志
/var/log/mysql/ # MySQL 数据库日志
/var/log/postgresql/ # PostgreSQL 数据库日志
/var/log/daemon.log # 系统守护进程的日志
/var/log/kern.log # 内核日志
/var/log/user.log # 用户相关的日志(用户登录/注销等)
/var/log/lpr.log # 打印服务日志
/var/log/ufw.log # 防火墙日志(Ubuntu的ufw)
/var/log/debug # 调试日志(开发调试使用)
/var/log/apt/history.log # APT 包管理历史日志
/var/log/apt/term.log # APT 包管理终端输出日志

3.1.1 rsyslogd配置文件

ps -aux | grep rsyslog | grep -v grep 查看rsyslogd进程是否启动, 只有启动了日志才能正常记录
systemctl list-unit-files | grep rsyslog 查看rsyslogd是否是自启动状态

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# 配置文件 : /etc/rsyslog.con
# 编辑文件时的格式为:
*.* 存放日志文件
# 修改配置文件后重启日志服务生效
systemctl restart rsyslog
# 其中第一个*代表日志类型,第二个*代表日志级别
# 日志类型分为:
auth ##pam产生的日志
authpriv ##ssh、ftp等登录信息的验证信息
corn ##时间任务相关
kern ##内核
lpr ##打印
mail ##邮件
mark(syslog)-rsyslog ##服务内部的信息,时间标识
news ##新闻组
user ##用户程序产生的相关信息
uucp ##unix to nuix copy主机之间相关的通信
local 1-7 ##自定义的日志设备

# 日志级别为:
# 从上到下,级别从低到高,记录信息越来越少
debug ##有调试信息的,日志通信最多
info ##一般信息日志,最常用
notice ##最具有重要性的普通条件的信息
warning ##警告级别
err ##错误级别,阻止某个功能或者模块不能正常工作的信息
crit ##严重级别,阻止整个系统或者整个软件不能正常工作的信息
alert ##需要立刻修改的信息
emerg ##内核崩溃等重要信息
none ##什么都不记录

日志的格式包含以下4列

  • 事件产生的时间
  • 产生事件的服务器的主机名
  • 产生事件的服务名或程序名
  • 事件的具体信息
    例如:
    1
    2
    3
    4
    2024-11-13T07:20:59.433134+00:00 LinuxLearn rsyslogd: [origin software="rsyslogd" swVersion="8.2312.0" x-pid="823762" x-info="https://www.rsyslog.com"] start
    2024-11-13T07:21:01.985136+00:00 LinuxLearn CRON[823844]: pam_unix(cron:session): session opened for user root(uid=0) by root(uid=0)
    2024-11-13T07:21:01.985662+00:00 LinuxLearn CRON[823845]: (root) CMD (date > mydate.txt)
    2024-11-13T07:21:01.987758+00:00 LinuxLearn CRON[823844]: pam_unix(cron:session): session closed for user root

3.1.2 日志轮替

日志轮替就是把旧的日志文件移动并改名, 同时建立新的空日志文件, 当旧的日志文件超出保存范围之后, 就会被自动删除

  1. Linux使用logrotate进行日志轮替管理,要想改变日志轮替文件名字,通过 /etc/logrotate.conf 配文件中“dateext”等参数
  2. 如果配置文件中有“dateext”参数,那么日志会用日期来作为日志文件的后缀,例如“secure-20201010” 。这样日志文件名不会重叠,也就不需要日志文件的改名,只需要指定保存日志个数,删除多余的日志文件即可
  3. 如果配置文件中没有“dateext参数,日志文件就需要进行改名了。当第一次进行日志轮替时,当前的“secure“日志会自动改名为“secure.1”. 然后新创建“secure”日志, 用来保存新的日志.
  4. 当第二次进行日志轮替时, “secure.1”会自动改名为“secure.2”, 当前的“secure”日志会自动改名为“secure.1”, 然后也会新建“secure”日志, 用来保存新的日志. 依次类推.如果超过日志的默认保存个数, 系统会自动删除目前存在的最旧的日志.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# /etc/logrotate.conf 
# 全局配置
weekly # 每周对日志文件进行一次轮替
rotate 5 # 保留5个日志文件

create # 日志轮替后创建新的空日志文件

dateext # 使用日期作为日志文件后缀

# 单独配置 (优先级更高)

/var/log/btmp{
missingok # 如果日志不存在, 忽略该日志的警告信息
monthly
create 0600 root utmp # 建立新的日志文件, 权限是0664 (0普通文件, 664(wr-wr-r--)), 所有者为root, 组织属于utmp
rotate 1
}

配置参数说明

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# 全局配置参数:
# -----------------------
daily # 每天轮替日志
weekly # 每周轮替日志
monthly # 每月轮替日志
yearly # 每年轮替日志
rotate <num> # 保留最近的 <num> 个轮替文件
compress # 启用压缩(默认使用 gzip)
delaycompress # 延迟压缩,直到下次轮替
notifempty # 如果日志文件为空,则不轮替
missingok # 如果日志文件丢失,不报错
create <mode> <owner> <group> # 创建新日志文件时设置权限(mode)、所有者(owner)和组(group)
sharedscripts # 脚本共享,轮替多个文件时只运行一次脚本
postrotate # 轮替后执行的脚本(结束脚本)
endscript # 结束脚本标记
prerotate # 轮替前执行的脚本(开始脚本)
# -----------------------

# 针对特定日志文件配置的参数:
# -----------------------
size <size> # 当日志文件达到指定大小时进行轮替(例如:size 100M)
ifempty # 即使日志文件为空,也进行轮替
dateext # 使用日期扩展名进行轮替(例如:logfile.1 -> logfile-20231111.1)
dateformat <format> # 自定义日期扩展名的格式(默认为:%Y%m%d)
su <user> <group> # 使用指定的用户和组运行 logrotate 进程
# -----------------------

# 其他常见选项:
# -----------------------
compresscmd <cmd> # 自定义压缩命令,默认是 gzip
uncompresscmd <cmd> # 自定义解压命令,默认是 gunzip
compressext <ext> # 自定义压缩文件扩展名,默认为 .gz
createonerr # 如果日志文件创建失败,则立即退出
olddir <dir> # 将旧日志文件移动到指定目录(例如:/var/log/old)
nomail # 禁止发送邮件
mail <email> # 如果轮替失败,发送邮件给指定用户
# -----------------------

# 示例:
# -----------------------
/var/log/nginx/*.log {
daily
rotate 7
compress
delaycompress
missingok
notifempty
create 0640 www-data www-data
postrotate
systemctl reload nginx
endscript
}

# 针对 MySQL 日志轮替示例:
/var/log/mysql/*.log {
weekly
rotate 5
compress
missingok
notifempty
create 0644 mysql mysql
sharedscripts
postrotate
/usr/bin/mysqladmin flush-logs
endscript
}

3.1.3 查看内存日志

journalctl可以查看内存日志

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
 journalctl                        # 查看所有日志
journalctl -b # 查看当前启动的日志
journalctl -b -1 # 查看上次启动的日志
journalctl -xe # 查看错误日志,显示详细的错误信息
journalctl -f # 实时查看日志(类似于 `tail -f`)
journalctl -u <service_name> # 查看特定服务的日志(例如:journalctl -u nginx)
journalctl --since "2024-11-01" # 查看从某个日期之后的日志
journalctl --until "2024-11-02" # 查看到某个日期的日志
journalctl --since "2 hours ago" # 查看最近 2 小时的日志
journalctl -p err # 查看日志级别为 error 及以上的日志
journalctl -n 50 # 查看最近 50 行日志
journalctl -o short # 以简洁的格式输出日志
journalctl -o json # 以 JSON 格式输出日志
journalctl -r # 反向查看日志(最新的日志显示在最前面)
journalctl --no-pager # 禁止分页输出,所有日志一次性输出
journalctl -k # 只显示内核日志
journalctl -t <unit_name> # 按系统单元名称过滤日志(例如:journalctl -t nginx)
journalctl -u <service_name> -f # 实时查看指定服务的日志
journalctl _PID=1 _COMM=sshd # 按进程 ID 和进程名过滤日志(例如:journalctl _PID=1 _COMM=sshd)

1
2
3
4
5
6
7
8
9
10
11
12

dmesg | grep -i memory # 查看内核启动日志中的内存信息
free -h # 查看系统内存使用情况(以人类可读的格式)
vmstat # 查看虚拟内存、进程、CPU等的统计信息
top # 实时查看系统资源使用情况(包括内存)
htop # 类似于 top,但提供更友好的交互界面(需要安装)
cat /proc/meminfo # 查看详细的内存信息(包括总内存、可用内存、缓存等)
cat /proc/slabinfo # 查看内核内存分配器的状态
watch -n 1 free -h # 每秒更新一次,实时监控内存使用情况
ps aux --sort=-%mem # 查看按内存占用排序的进程列表
sar -r 1 3 # 使用 sar 命令查看内存使用情况,1 代表间隔 1 秒,3 表示查看 3 次

3.2 定制自己的linux

通过裁剪现有的Linux系统, 创建属于自己的Linux系统
首先了解Linux系统的启动流程
alt text

3.3 Linux内核源码和内核升级

Linux官网并没有直接托管 Linux 0.01 的源代码,因为 Linux 内核的官方网站主要托管的是最新的稳定版本。
建议从官网的Linux Git 存储库阅读Linux源码

1
2
3
4
5
git clone git://git.kernel.org/pub/scm/linux/kernel/git/nico/archive.git
cd linux
git checkout v0.01

# 本人保存在了 /Users/fei/myspace/learnspace/Linux/archive 目录下
1
2
3
4
5
6
7
8
9
10
11
total 8
-rw-r--r-- 1 fei staff 2.1K Nov 13 17:31 Makefile # Makefile是编译内核的核心文件,定义了如何构建内核、模块和其他相关文件
drwxr-xr-x 4 fei staff 128B Nov 13 17:31 boot # boot目录包含与内核启动相关的文件,如引导加载程序、启动映像等
drwxr-xr-x 21 fei staff 672B Nov 13 17:31 fs # fs目录包含与文件系统相关的代码,实现了多种文件系统的支持
drwxr-xr-x 18 fei staff 576B Nov 13 17:31 include # include目录包含内核源代码中使用的头文件,定义了内核接口、结构等
drwxr-xr-x 3 fei staff 96B Nov 13 17:31 init # init目录包含内核初始化代码,负责初始化系统并启动第一个用户空间进程
drwxr-xr-x 20 fei staff 640B Nov 13 17:31 kernel # kernel目录包含内核的核心功能代码,如调度、进程管理、系统调用等
drwxr-xr-x 14 fei staff 448B Nov 13 17:31 lib # lib目录包含内核需要的库文件,提供一些共享函数或基础功能
drwxr-xr-x 5 fei staff 160B Nov 13 17:31 mm # mm目录包含内存管理代码,包括虚拟内存、内存分配等
drwxr-xr-x 3 fei staff 96B Nov 13 17:31 tools # tools目录包含开发、调试和测试工具,这些工具通常用于内核开发和维护

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
uname -a  # 查看当前内核版本
yum info kernel -q # 检测内核版本, 显示可以升级的版本
yum list kernel -q

# 1. 更新本地包索引
sudo apt update # 更新APT包管理器的本地包索引

# 2. 检查可用的内核版本
apt search linux-image # 搜索可用的Linux内核映像,查看可用的内核版本

# 3. 安装新的内核版本
sudo apt install linux-image-<version> # 安装新版本的内核(例如:linux-image-5.4.0-80-generic)
# 请将 <version> 替换为你需要安装的内核版本

# 4. 安装相应的内核头文件(可选,但对于编译内核模块很重要)
sudo apt install linux-headers-<version> # 安装对应版本的内核头文件

# 5. 更新GRUB引导加载器
sudo update-grub # 更新GRUB配置文件,确保新安装的内核版本出现在启动菜单中

# 6. 重启系统
sudo reboot # 重启系统,选择新内核启动

# 7. 检查当前内核版本
uname -r # 查看当前运行的内核版本,确保已成功切换到新内核


3.4 Linux备份与恢复

实体机无法做快照, 如果系统发生崩溃或者数据损坏, 后果严重, 需要重新做系统, 还会造成数据丢失, 所以我们可以使用备份和恢复技术
Linux备份和恢复的两种方式:

  1. 把需要的备份的文件达成tar包, 下次需要恢复的时候, 再解压覆盖即可
  2. 使用dump和restore命令

备份操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# 1. 使用 tar 命令进行备份(打包并压缩文件夹)
tar -czvf /path/to/backup/backup_name.tar.gz /path/to/directory # 打包并压缩指定目录
# 解释:
# -c:创建新的归档文件
# -z:使用 gzip 压缩
# -v:显示处理文件的详细信息
# -f:指定归档文件的名称(必须放在选项后面)

# 2. 使用 rsync 命令进行增量备份
rsync -av --delete /path/to/source/ /path/to/backup/ # 将源目录备份到目标目录
# 解释:
# -a:归档模式,保留文件的权限、时间戳等信息
# -v:显示详细信息
# --delete:删除目标目录中源目录中已删除的文件

# 3. 使用 dd 命令进行磁盘备份
dd if=/dev/sda of=/path/to/backup/disk_backup.img bs=64K # 将磁盘/dev/sda的内容备份到指定文件
# 解释:
# if:输入文件或设备
# of:输出文件或设备
# bs:设置块大小(64KB)

# 4. 使用 dump 和 restore 进行文件系统备份
# 备份文件系统
dump -0u -f /path/to/backup/filesystem.dump /dev/sda1 # 备份文件系统到 dump 文件
# 恢复文件系统
restore -r -f /path/to/backup/filesystem.dump # 从 dump 文件恢复文件系统

恢复操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 1. 使用 tar 命令恢复备份
tar -xzvf /path/to/backup/backup_name.tar.gz -C /path/to/restore # 从 tar.gz 文件恢复目录到指定位置
# 解释:
# -x:提取归档文件
# -z:解压 gzip 文件
# -v:显示详细过程
# -f:指定归档文件
# -C:指定恢复的目标目录

# 2. 使用 rsync 恢复增量备份
rsync -av /path/to/backup/ /path/to/restore/ # 将备份的文件恢复到目标目录
# 解释:
# -a:归档模式,保持文件属性
# -v:显示详细信息

# 3. 使用 dd 命令恢复磁盘备份
dd if=/path/to/backup/disk_backup.img of=/dev/sda bs=64K # 将备份的磁盘镜像恢复到目标磁盘
# 解释:
# if:输入文件(备份的磁盘镜像)
# of:输出文件或设备(目标磁盘)
# bs:设置块大小(64KB)

# 4. 使用 restore 恢复文件系统
restore -r -f /path/to/backup/filesystem.dump # 从 dump 文件恢复整个文件系统

dump和restore详解

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 1. 使用 dump 命令进行文件系统备份
dump -0u -f /path/to/backup/filesystem.dump /dev/sda1 # 备份文件系统
# 解释:
# dump:创建文件系统备份
# -0:备份级别(0 表示完全备份,1-9 表示增量备份)
# -u:更新文件系统的备份状态(备份完成后会在文件系统的超级块中标记备份已完成)
# -f:指定备份的目标文件
# /dev/sda1:指定需要备份的文件系统设备(例如,根文件系统或其他挂载的分区)

# 备份级别:
# - 级别 0:完全备份,备份所有文件。
# - 级别 1 到 9:增量备份,仅备份上次备份之后修改或新增的文件。

# 2. 使用 restore 命令恢复文件系统
restore -r -f /path/to/backup/filesystem.dump # 从 dump 文件恢复文件系统
# 解释:
# restore:恢复 dump 备份文件
# -r:恢复整个文件系统
# -f:指定需要恢复的备份文件(dump 文件)
# 使用 restore 命令时,通常需要在恢复过程中指定一个目标目录来还原文件系统内容。

# 恢复的方式:
# - 恢复整个文件系统:使用 -r 选项,直接从 dump 文件恢复。
# - 恢复部分文件:使用 -i 选项进入交互式模式,选择恢复特定文件。

3.5 Linux可视化管理webmin和bt运维工具

bt下载: wget -O install.sh http://download.bt.cn/install/install_6.0.sh && bash install.sh

3.6 Linux入侵检测、权限划分、系统优化

3.7 Linux面试题

  1. 分析t.log日志, 将各个ip地址截获, 并统计出现次数, 并按照从大大小排序
1
2
3
4
5
6
7
8
9
# t.txt
http://192.168.200.10/index1.html
http://192.168.200.10/index2.html
http://192.168.200.20/index1.html
http://192.168.200.30/index1.html
http://192.168.200.40/index1.html
http://192.168.200.30/order.html
http://192.168.200.10/order.html

1
2
3
# 获取ip
cat t.txt | cut -d "/" -f 3 | sort | uniq -c | sort -nr # 对内容进行分割, 按照/划分, 取第三段. 并进行排序, 统计后再进行从大到小排序,

  1. 统计连接到服务器的各个ip情况, 并按照连接数从大到小排序
1
2
3
# 查看网络情况, 筛选出已连接的, 并按空格拆分, 取出第4位, 再去掉端口
netstat -an | grep ESTABLISHED | awk -F " " '{print $4}' | awk -F ":" '{print $1}'

  1. 如忘记了mysql5.7数据库的ROOT用户的密码,如何找回?

  2. 写出指令:统计ip访问情况,要求分析nginx访问日志(access.log),找出访问页面数量在前十位的ip

  3. 使用tcpdump监听本机,将来自ip 192.168.200.1,tcp端口为22的数据,保存输出到tcpdump.log,用做将来数据分析

  4. 常用的Nginx模块,用来做什么

1. 常用命令

1.1 系统操作

  • 查看系统信息:uname -a
  • 查看系统版本:cat /etc/issue
  • 查看系统发行版:cat /etc/os-releaselsb_release -a
  • 查看系统内核版本:uname -r

1.2 文件操作

1.2.1 sed命令

菜鸟教程

Linux sed 命令是利用脚本来处理文本文件。

sed 可依照脚本的指令来处理、编辑文本文件。

Sed 主要用来自动编辑一个或多个文件、简化对文件的反复操作、编写转换程序等。

语法:

  • sed [options] [script] [input]
  • sed [-hnV][-e<script>][-f<script文件>][文本文件]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

# 1. 参数说明
-h或--help 显示帮助。
-n或--quiet或--silent 仅显示script处理后的结果。
-V或--version 显示版本信息。

-e<script>或--expression=<script> 以选项中指定的**script**来处理输入的文本文件。
-f<script文件>或--file=<script文件> 以选项中指定的**script文件**来处理输入的文本文件。

# 2. 动作说明
a :新增, a 的后面可以接字串,而这些字串会在新的一行出现(目前的下一行)~
c :取代, c 的后面可以接字串,这些字串可以取代 n1,n2 之间的行!
d :删除,因为是删除啊,所以 d 后面通常不接任何东东;
i :插入, i 的后面可以接字串,而这些字串会在新的一行出现(目前的上一行);
p :打印,亦即将某个选择的数据印出。通常 p 会与参数 sed -n 一起运行~
s :取代,可以直接进行取代的工作哩!通常这个 s 的动作可以搭配正则表达式!例如 1,20s/old/new/g 就是啦!

# 3. 实例
我们先创建一个 testfile 文件,内容如下:
cat testfile #查看testfile 中的内容
HELLO LINUX!
Linux is a free unix-type opterating system.
This is a linux testfile!
Linux test
Google
Taobao
Runoob
Tesetfile
Wiki

1.2.2 find

find [路径] [匹配条件] [动作]

vim 操作

新建/编辑 .vimrc 文件

1
2
3
syntax on
set nu


2024-08-15-Thu-T-Linux
http://example.com/2024/08/15/2024-08-15-Thu-T-Linux/
Author
Fei
Posted on
August 15, 2024
Licensed under