1.使用while read line和/etc/passwd,计算用户id总和。
#!/bin/bash
# 初始化总和变量
total=0
# 逐行读取/etc/passwd文件
while IFS=: read -r username password uid gid gecos home shell; do
# 累加UID到总和
((total += uid))
done < /etc/passwd
# 输出结果
echo "所有用户ID的总和是: $total"
2.总结索引数组和关联数组,字符串处理,高级变量使用及示例。
一、索引数组(Indexed Arrays)
索引数组使用整数作为下标,从 0 开始。
基本操作
# 1. 声明数组
declare -a fruits # 显式声明(可选)
fruits=("apple" "banana" "cherry")
# 2. 单独赋值
fruits[0]="apple"
fruits[1]="banana"
fruits[2]="cherry"
# 3. 访问元素
echo ${fruits[0]} # 输出: apple
echo ${fruits[@]} # 输出所有元素
echo ${#fruits[@]} # 输出元素个数
echo ${!fruits[@]} # 输出所有索引
# 4. 修改元素
fruits[1]="grape" # 将第二个元素改为grape
# 5. 删除元素
unset fruits[2] # 删除第三个元素
示例:遍历数组
for fruit in "${fruits[@]}"; do
echo "I like $fruit"
done
二、关联数组(Associative Arrays)
关联数组使用字符串作为键(需要 Bash 4.0+)。
基本操作
# 1. 声明数组
declare -A person # 必须显式声明
# 2. 赋值
person["name"]="John"
person["age"]=30
person["city"]="New York"
# 3. 访问元素
echo ${person["name"]} # 输出: John
echo ${person[@]} # 输出所有值
echo ${!person[@]} # 输出所有键
echo ${#person[@]} # 输出键值对数量
# 4. 删除元素
unset person["age"] # 删除age键值对
示例:遍历关联数组
for key in "${!person[@]}"; do
echo "$key: ${person[$key]}"
done
三、字符串处理
Bash 提供了多种字符串操作方法。
- 字符串长度
str="Hello World"
echo ${#str} # 输出: 11
- 子串提取
echo ${str:0:5} # 从索引0开始,取5个字符 → Hello
echo ${str:6} # 从索引6开始到末尾 → World
- 子串替换
echo ${str/World/Universe} # 替换第一个匹配 → Hello Universe
echo ${str//o/O} # 替换所有匹配 → HellO WOrld
- 删除前缀 / 后缀
filename="document.pdf"
echo ${filename%.pdf} # 删除最短后缀 → document
echo ${filename#*.} # 删除最短前缀 → pdf
- 大小写转换(Bash 4.0+)
echo ${str^^} # 全部大写 → HELLO WORLD
echo ${str,,} # 全部小写 → hello world
四、高级变量使用
- 变量间接引用
通过变量的值作为另一个变量的名称。
var1="hello"
var2="var1"
echo ${!var2} # 相当于 ${var1} → hello
- 参数扩展
# 默认值
name=${USER:-"Guest"} # 如果USER未定义,使用"Guest"
# 使用默认值并赋值
name=${USER:="Guest"} # 如果USER未定义,赋值为"Guest"
# 错误提示
echo ${unknown:?"Error: variable not set"} # 未定义时抛出错误
- 命令替换
date=$(date) # 获取当前日期时间
files=$(ls) # 获取文件列表
echo "Today is $date"
- 算术扩展
a=5
b=3
echo $((a + b)) # 输出: 8
echo $((a * b)) # 输出: 15
((a++)) # 自增
echo $a # 输出: 6
五、综合示例
示例 1:统计文件类型
#!/bin/bash
declare -A file_types
for file in *; do
ext=${file##*.} # 获取文件扩展名
((file_types[$ext]++)) # 对应类型计数+1
done
# 输出统计结果
for type in "${!file_types[@]}"; do
echo "$type: ${file_types[$type]} files"
done
示例 2:批量重命名文件
#!/bin/bash
for file in *.jpg; do
new_name="${file%.*}_new.jpg" # 生成新文件名
mv "$file" "$new_name" # 重命名文件
echo "Renamed $file to $new_name"
done
3.编写shell脚本,求10个随机数的最大值与最小值。
#!/bin/bash
# 初始化最大值和最小值
max=0
min=101 # 初始化为大于可能随机数的数
# 生成10个随机数并找出最大值和最小值
for ((i=1; i<=10; i++)); do
# 生成1到100之间的随机数
num=$((RANDOM % 100 + 1))
echo "生成的随机数 $i: $num"
# 更新最大值
if [[ $num -gt $max ]]; then
max=$num
fi
# 更新最小值
if [[ $num -lt $min ]]; then
min=$num
fi
done
# 输出结果
echo "------------------------"
echo "最大值: $max"
echo "最小值: $min"
4.使用递归调用,完成阶乘算法实现。
#!/bin/bash
# 递归计算阶乘的函数
factorial() {
local n=$1
# 基本情况:0! = 1
if [[ $n -eq 0 ]]; then
echo 1
return
fi
# 递归情况:n! = n * (n-1)!
local result=$(factorial $((n - 1)))
echo $((n * result))
}
# 主程序
if [[ $# -ne 1 ]]; then
echo "用法: $0 <非负整数>"
exit 1
fi
number=$1
# 检查输入是否为非负整数
if ! [[ $number =~ ^[0-9]+$ ]]; then
echo "错误: 请输入一个非负整数。"
exit 1
fi
# 计算阶乘并输出结果
result=$(factorial "$number")
echo "$number 的阶乘是: $result"
5.通过shell编程完成,30鸡和兔的头,80鸡和兔的脚,分别有几只鸡,几只兔?
#!/bin/bash
# 定义总头数和总脚数
heads=30
legs=80
# 计算兔子数量: (总脚数 - 2*总头数)/2
rabbits=$(( (legs - 2 * heads) / 2 ))
# 计算鸡的数量: 总头数 - 兔子数量
chickens=$(( heads - rabbits ))
# 验证计算结果是否合理
if [[ $rabbits -lt 0 || $chickens -lt 0 || $((2 * chickens + 4 * rabbits)) -ne $legs ]]; then
echo "无解: 给定的头和脚数量无法组成合理的鸡兔数量。"
else
echo "鸡的数量: $chickens"
echo "兔的数量: $rabbits"
fi
6.结合编程的for循环,条件测试,条件组合,完成批量创建100个用户,
#!/bin/bash
# 遍历1到100的数字
for i in $(seq 1 100); do
username="user$i" # 用户名格式:user1, user2, ..., user100
# 检查用户是否存在
if id "$username" &>/dev/null; then
echo "用户 '$username' 已存在"
else
# 创建用户并添加说明
useradd "$username" &>/dev/null && echo "已添加用户 '$username'"
fi
done
7.结合进程管理命令,说明进程各种状态。
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1234 0.5 0.1 123456 10240 ? R 10:00 0:01 top
# R (Running):进程正在运行或准备运行
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
user 5678 0.0 0.2 234567 20480 ? S 10:01 0:00 bash
# S (Sleeping):进程处于可中断睡眠状态,等待事件发生
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 9012 0.0 0.0 0 0 ? D 10:02 0:05 [jbd2/sda1-8]
# D (Disk Sleep):进程处于不可中断睡眠状态,通常在进行磁盘I/O
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
user 12345 0.0 0.0 0 0 ? Z 10:03 0:00 [defunct]
# Z (Zombie):僵尸进程,已终止但父进程尚未回收其资源
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
user 15678 0.0 0.1 150000 15360 pts/0 T 10:04 0:00 vim
# T (Stopped):进程已停止运行,通常通过信号暂停
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
user 20000 0.1 0.3 300000 30720 pts/1 Sl+ 10:05 0:02 firefox
# S:可中断睡眠状态
# l:多线程进程
# +:前台进程组
| 状态码 | 含义 | 示例场景 |
|---|---|---|
| R | 运行中 | top、正在执行的脚本 |
| S | 可中断睡眠 | 等待输入的 bash、Web 服务器 |
| D | 不可中断睡眠 | 内核 I/O 操作(如磁盘写入) |
| Z | 僵尸进程 | 已终止但父进程未回收的进程 |
| T | 停止态 | 被暂停的进程(如 Ctrl+Z) |
| s | 会话首进程 | 登录 shell |
| l | 多线程进程 | Firefox、Java 应用 |
| + | 前台进程组 | 当前终端中运行的进程 |
8.说明IPC通信和RPC通信实现的方式。


# 应用场景对比
# IPC 适用场景
手机系统内:
- 桌面应用与通知服务通信
- 多媒体服务与播放器进程交互
# RPC 适用场景
分布式系统:
- 用户设备调用云端 AI 模型接口
- 微服务架构中的订单服务调用支付服务
9.总结Linux,前台和后台作业的区别,并说明如何在前台和后台中进行状态转换。
一、前台作业与后台作业的核心区别
1. 终端控制权
- 前台作业:
- 占据当前终端的控制权,接收终端的输入 / 输出(stdin/stdout/stderr)。
- 终端的键盘信号(如
Ctrl+C、Ctrl+Z)直接作用于前台作业。 - 示例:执行
vim test.txt时,终端被 Vim 占据,需退出后才能执行其他命令。
- 后台作业:
- 不占据终端控制权,终端可继续执行其他命令。
- 默认不接收终端的键盘信号(需特殊处理),但可通过作业控制命令管理。
- 示例:执行
sleep 60 &后,睡眠进程在后台运行,终端立即返回命令提示符。
2. 进程状态与信号处理
- 前台作业:
- 状态通常为 运行(Running) 或 停止(Stopped)(如被
Ctrl+Z暂停)。 - 直接响应终端信号:
Ctrl+C:发送SIGINT终止进程。Ctrl+Z:发送SIGTSTP暂停进程。
- 状态通常为 运行(Running) 或 停止(Stopped)(如被
- 后台作业:
- 状态通常为 运行(Running) 或 停止(Stopped),但需通过
bg命令恢复运行。 - 默认忽略部分终端信号(如
Ctrl+C不影响后台作业),但可通过stty tostop配置让后台作业接收SIGTTOU信号。
- 状态通常为 运行(Running) 或 停止(Stopped),但需通过
3. 输入 / 输出重定向
- 前台作业:
- 自动关联终端的标准输入 / 输出,可直接交互(如命令行工具)。
- 后台作业:
- 若未重定向输出,其输出会打印到终端(可能干扰当前操作)。
- 建议通过
&> file重定向输出,或用nohup防止输出被中断。
二、前台与后台作业的状态转换方法
1. 启动作业到前台或后台
- 前台启动:直接输入命令,如
top(终端被占据)。 - 后台启动:在命令末尾加
&,如find / -name "log" &。
2. 前台作业→后台暂停(Stopped)
-
快捷键:
Ctrl+Z(发送SIGTSTP信号,作业进入暂停状态)。 -
示例:
$ vim test.txt # 前台启动Vim Ctrl+Z # 暂停Vim,返回终端 [1]+ Stopped (tty input) vim test.txt
3. 暂停作业→后台运行
-
命令:
bg [作业编号](将暂停的作业转为后台运行)。 -
示例:
$ bg 1 # 让编号为1的暂停作业在后台运行 [1]+ vim test.txt &
4. 暂停 / 后台作业→前台运行
-
命令:
fg [作业编号](将后台或暂停的作业提到前台)。 -
示例:
$ fg 1 # 让编号为1的作业回到前台 vim test.txt # 终端重新被Vim占据
5. 查看所有作业列表
-
命令:
jobs [-l](-l显示进程 PID)。 -
示例:
$ jobs -l [1]+ 12345 Running find / -name "log" & [2]- 67890 Stopped vim test.txt
6. 终止后台作业
-
命令:
kill %作业编号或kill 进程PID。 -
示例:
$ kill %1 # 终止编号为1的后台作业 $ kill 12345 # 终止PID为12345的进程
三、特殊场景:后台作业与终端退出
- 问题:终端退出时,后台作业默认会被终止(收到
SIGHUP信号)。 - 解决方案:
- 用
nohup命令包裹作业,如nohup sleep 1000 &(忽略SIGHUP信号)。 - 输出重定向:
nohup command &> output.log &(避免输出到终端)。 - 使用
screen或tmux终端复用工具,保持会话持续运行。
- 用
四、关键命令总结
| 操作 | 命令 / 快捷键 | 示例 |
|---|---|---|
| 后台启动作业 | command & | sleep 60 & |
| 暂停前台作业 | Ctrl+Z | 在 Vim 中按 Ctrl+Z |
| 查看作业列表 | jobs | jobs -l |
| 后台暂停作业→后台运行 | bg %N | bg %1 |
| 后台 / 暂停作业→前台 | fg %N | fg %1 |
| 终止作业 | kill %N 或 kill PID | kill %1 或 kill 12345 |
| 防止终端退出终止作业 | nohup command & | nohup ./script.sh & |
总结
- 前台作业:独占终端,直接响应键盘信号,适合需要交互的任务。
- 后台作业:释放终端,需通过作业控制命令管理,适合长时间运行的非交互任务。
- 状态转换核心:利用
Ctrl+Z、bg、fg、jobs等命令实现作业在 运行、暂停、前台、后台 之间的切换,结合nohup或终端复用工具可确保后台作业持久运行。
10.实现定时任务,每日凌晨1点,删除指定文件(自己创建即可)
# 创建脚本
vi auto_delete_files.sh
#!/bin/bash
# 指定要删除文件的目录
TARGET_DIR="/data/test1"
# 日志文件路径
LOG_FILE="/var/log/auto_delete_files.log"
# 检查目录是否存在
if [ ! -d "$TARGET_DIR" ]; then
echo "错误: 目录 $TARGET_DIR 不存在" >> "$LOG_FILE"
exit 1
fi
# 删除目录下的所有文件(不删除子目录)
echo "$(date '+%Y-%m-%d %H:%M:%S') - 开始删除 $TARGET_DIR 下的文件" >> "$LOG_FILE"
find "$TARGET_DIR" -type f -exec rm -f {} \; 2>> "$LOG_FILE"
echo "$(date '+%Y-%m-%d %H:%M:%S') - 删除完成" >> "$LOG_FILE"
# 添加执行权限
chmod +x /usr/local/bin/auto_delete_files.sh
# 编辑定时任务
crontab -e
0 1 * * * /usr/local/bin/auto_delete_files.sh
11.实现定时任务每月月初对指定文件进行压缩(自己创建文件)
# 创建脚本
vi
#!/bin/bash
# 指定要压缩的源目录(请修改为实际目录)
SOURCE_DIR="/data/archivefile/"
# 指定压缩文件存放的目标目录(请修改为实际目录)
TARGET_DIR="/data/archives"
# 日志文件路径
LOG_FILE="/var/log/auto_archive_files.log"
# 获取当前年月,用于生成归档文件名
YEAR=$(date '+%Y')
MONTH=$(date '+%m')
ARCHIVE_NAME="files_${YEAR}${MONTH}.tar.gz"
# 检查源目录是否存在
if [ ! -d "$SOURCE_DIR" ]; then
echo "错误: 源目录 $SOURCE_DIR 不存在" >> "$LOG_FILE"
exit 1
fi
# 检查目标目录是否存在,不存在则创建
mkdir -p "$TARGET_DIR"
# 执行压缩操作
echo "$(date '+%Y-%m-%d %H:%M:%S') - 开始压缩 $SOURCE_DIR 下的文件" >> "$LOG_FILE"
tar -czf "${TARGET_DIR}/${ARCHIVE_NAME}" -C "$SOURCE_DIR" . 2>> "$LOG_FILE"
# 检查压缩是否成功
if [ $? -eq 0 ]; then
echo "$(date '+%Y-%m-%d %H:%M:%S') - 压缩完成,文件保存为 ${TARGET_DIR}/${ARCHIVE_NAME}" >> "$LOG_FILE"
else
echo "$(date '+%Y-%m-%d %H:%M:%S') - 压缩失败" >> "$LOG_FILE"
exit 1
fi
# 添加执行权限
chmod +x /usr/local/bin/auto_archive_files.sh
# 添加定时任务:
crontab -e
0 2 1 * * /usr/local/bin/auto_archive_files.sh
12.总结Linux系统的启动流程
主流linux的启动流程对比本质就是古早SysVinit和新晋systemd之间对比
12.1centos6系统流程
1.硬件启动阶段
- 开机初始化
- 按下电源键,硬件通电
- BIOS(基本输入输出系统)开始工作
- BIOS 功能
- 初始化 CPU、内存、硬盘等关键硬件
- 执行 POST(加电自检)检测硬件状态
- 设置中断向量表,控制硬件中断响应
- 确定启动设备顺序(如硬盘优先、U 盘 / 光盘备选)
- MBR 加载
- BIOS 从启动设备读取 0 磁道 1 扇区(512 字节)
- 将 MBR(主引导记录)加载到内存 0x7C00 地址
- MBR 结构:
- 前 446 字节:主引导程序(如 GRUB Stage1)
- 中间 64 字节:分区表(记录硬盘分区信息)
- 最后 2 字节:结束标志(0xAA55)
2.GRUB 引导阶段
- Stage1(MBR 引导)
- 位于 MBR 的 446 字节程序
- 功能:识别并加载 Stage1.5 或 Stage2
- Stage1.5(可选)
- 位于 MBR 之后的扇区
- 功能:识别文件系统(如 ext4、NTFS),为加载 Stage2 做准备
- Stage2(主引导程序)
- 通常存放在
/boot/grub/目录 - 功能:
- 显示启动菜单(可选择不同内核或操作系统)
- 加载内核镜像(vmlinuz)和临时根文件系统(initramfs)
- 传递内核参数(如 root = 指定根分区、quiet = 静默启动)
- 通常存放在
3.内核初始化阶段
- 内核加载与解压
- 内核镜像(vmlinuz)被加载到内存并解压
- 初始化 CPU、内存管理、设备驱动框架
- 临时根文件系统
- 挂载 initramfs(临时根文件系统)
- 包含必要驱动和工具,用于挂载真正的根分区
- 启动 init 进程
- 内核启动第一个用户级进程:
/sbin/init(PID=1) - 根据系统配置(SysV 或 systemd)初始化系统环境
- 内核启动第一个用户级进程:
4.系统初始化阶段(SysV init 体系)
-
运行级别配置
-
/etc/inittab
定义运行级别(0-6):
- 0:关机
- 1:单用户模式
- 3:多用户命令行模式
- 5:图形界面模式
- 6:重启
-
-
系统初始化脚本
-
/etc/rc.d/rc.sysinit
执行基础设置:
- 设置环境变量(PATH、语言、时区)
- 挂载文件系统(根据
/etc/fstab) - 激活 SELinux/AppArmor 安全模块
- 加载硬件驱动模块
-
-
服务启动
- 根据运行级别启动对应服务:
/etc/rc.d/rc[运行级别].d/目录下的脚本控制服务启停- S 开头的脚本:启动服务(如 S10network)
- K 开头的脚本:关闭服务(如 K90httpd)
- 根据运行级别启动对应服务:
5.用户登录阶段
- 终端启动
- 运行级别 3:启动 6 个虚拟终端(Ctrl+Alt+F1~F6)
- 运行级别 5:自动启动 X Window 系统
- 登录验证
- 文本终端:
- 用户输入用户名(校验
/etc/passwd) - 输入密码(校验
/etc/shadow哈希值)
- 用户输入用户名(校验
- 图形界面:由 Display Manager(如 GDM、LightDM)处理登录
- 文本终端:
- 用户环境加载
- 登录成功后加载用户配置:
- 全局配置:
/etc/profile - 用户配置:
~/.bashrc、~/.bash_profile
- 全局配置:
- 登录成功后加载用户配置:
6.特殊情况处理
- 图形界面启动(运行级别 5):
- X Window 系统初始化
- 启动 Display Manager(如 GNOME、KDE)
- 显示登录界面,等待用户认证
- 故障恢复模式:
- 单用户模式(运行级别 1):仅启动基本服务,用于系统修复
- 救援模式:从 LiveCD/USB 启动,挂载原系统进行维护
12.2Ubuntu 系统启动流程
- 硬件启动与 BIOS 阶段
- 加电自检(POST),检测硬件状态(CPU、内存、磁盘等)。
- 加载 MBR(主引导记录),启动 GRUB2 引导程序(位于
/boot/grub/)。
- GRUB2 引导阶段
- 配置文件:默认配置存于
/etc/default/grub,生成最终引导配置的命令为grub-mkconfig -o /boot/grub/grub.cfg。 - 功能:显示启动菜单,加载内核镜像(vmlinuz)和临时根文件系统(initramfs),传递内核参数。
- 内核初始化阶段
- 内核镜像(vmlinuz)被加载到内存并解压,初始化硬件设备(CPU、内存、磁盘等)。
- 挂载临时根文件系统(initramfs),包含启动必需的驱动和工具。
- 启动
systemd进程(PID=1),替代传统的init作为系统第一个用户级进程。
- systemd 初始化阶段
- 核心特点:以 “目标单元(Targets)” 替代传统运行级别:
graphical.target:对应图形界面模式(类似 SysV 的运行级别 5,Ubuntu 默认优先)。multi-user.target:对应多用户命令行模式(类似 SysV 的运行级别 3)。
- 服务管理:
- 系统服务单元文件位于
/lib/systemd/system/,自定义服务覆盖文件位于/etc/systemd/system/。 - 服务操作命令:
systemctl start/stop/enable/disable [服务名](支持并行启动,依赖优先)。
- 系统服务单元文件位于
- 系统服务启动
- 按依赖关系加载关键 target:
local-fs.target:挂载本地文件系统(替代传统/etc/rc.d/rc.sysinit)。sysinit.target:初始化系统(加载内核模块、设置交换空间等)。basic.target:启动基础服务(如日志服务、udev 设备管理)。- 最终加载默认目标(
graphical.target或multi-user.target),启动对应级别的服务。
- 用户登录阶段
- 文本模式:由
getty@tty1.service等管理虚拟终端(可通过Ctrl+Alt+F1~F6切换)。 - 图形模式:
- 默认显示管理器:Ubuntu 22.04+ 为 GDM(GNOME Display Manager),旧版本为 LightDM。
- 启动桌面环境:默认 GNOME。
12.3rocky系统启动流程
- 硬件启动与 BIOS 阶段
- 与 Ubuntu 一致:加电自检(POST),加载 MBR,启动 GRUB2 引导程序(位于
/boot/grub2/)。
- GRUB2 引导阶段
- 配置文件:默认配置存于
/etc/default/grub,生成最终引导配置的命令为grub2-mkconfig -o /boot/grub2/grub.cfg(文件名和路径含grub2后缀,与 Ubuntu 区分)。 - 功能:同 Ubuntu,显示启动菜单,加载内核和 initramfs。
- 内核初始化阶段
- 与 Ubuntu 一致:内核解压并初始化硬件,挂载 initramfs,启动
systemd进程(PID=1)。
- systemd 初始化阶段
- 核心特点:目标单元(Targets)机制与 Ubuntu 一致,但默认目标不同:
- 默认启动
multi-user.target(多用户命令行模式),需手动切换至graphical.target启用图形界面。
- 默认启动
- 服务管理:
- 单元文件位置与 Ubuntu 一致(
/lib/systemd/system/和/etc/systemd/system/)。 - 兼容传统 SysVinit 脚本(通过
systemd-sysv-generator转换)。
- 单元文件位置与 Ubuntu 一致(
- 系统服务启动
- target 加载顺序与 Ubuntu 基本一致,但服务依赖存在差异:
- 网络服务默认使用
NetworkManager(而非 Ubuntu 常用的systemd-networkd)。 - 更贴近 RHEL 生态的服务配置(如
firewalld防火墙、chronyd时间同步)。
- 网络服务默认使用
- 用户登录阶段
- 文本模式:由
getty@tty1.service系列服务管理虚拟终端,与 Ubuntu 一致。 - 图形模式:
- 默认显示管理器:GDM(GNOME Display Manager)。
- 启动桌面环境:默认 GNOME(与 Ubuntu 一致,但预装组件更贴近 RHEL 规范)。
12.4总结对比
| 对比项 | 传统 SysVinit | Ubuntu(systemd) | Rocky Linux 9(systemd) |
|---|---|---|---|
| 初始化系统 | SysVinit(/sbin/init) | systemd | systemd |
| 运行级别 | 0-6(如运行级别 5 = 图形界面) | 由.target 替代(如graphical.target) | 同 Ubuntu |
| 服务配置 | /etc/init.d/和/etc/rc.d/ | /lib/systemd/system/ | 同 Ubuntu |
| 默认图形管理器 | 视发行版而定(如 GDM、KDM) | LightDM(Ubuntu 22.04 + 为 GDM) | GDM |
| 服务启动方式 | 串行(按顺序执行脚本) | 并行(依赖关系优先) | 同 Ubuntu |
| 系统配置文件 | /etc/inittab、/etc/fstab | /etc/systemd/、/etc/fstab | 同 Ubuntu |
13.总结内核设计流派及特点。
单内核(Monolithic Kernel)
定义:将进程管理、内存管理、文件系统、设备驱动、网络协议等所有核心功能集中在同一内核空间,模块间通过直接函数调用通信。
- 优势:模块通信无跨空间开销,效率高、执行速度快;
- 劣势:结构庞大、耦合度高,单个模块故障可能导致内核崩溃,扩展性较差;
- 典型例子:Linux、Unix。
微内核(Microkernel)
定义:仅保留进程调度、内存地址空间管理、基础进程间通信(IPC)等核心功能于内核空间,其他功能(文件系统、设备驱动、网络协议等)作为 “服务进程” 运行在用户空间,通过 IPC 与内核交互。
- 优势:结构精简、模块化强,单个服务故障不影响内核,可靠性与安全性高,易于扩展和移植;
- 劣势:IPC 存在跨空间开销,整体效率略低;
- 典型例子:Minix、QNX、L4 系列。
混合内核(Hybrid Kernel)
定义:融合单内核与微内核设计,核心功能(调度、内存管理等)保留在内核空间以保证效率,部分非核心功能(文件系统、驱动等)设计为可动态加载的模块,兼具模块化特性。
- 优势:兼顾单内核的效率(核心功能直接交互)与微内核的灵活性(模块可独立扩展);
- 劣势:设计复杂度高,需平衡 “集成度” 与 “模块化”;
- 典型例子:Windows NT(及后续 Windows 内核)、Mac OS 的 XNU 内核。
外核(Exokernel)
定义:仅负责硬件资源(CPU 时间片、内存页、I/O 端口等)的保护与底层分配,不提供文件系统、进程模型等高层抽象;用户程序通过 “库操作系统(LibOS)” 定制资源管理逻辑。
- 优势:灵活性极致,用户可按需优化资源使用(适合高性能计算等场景),资源利用率高;
- 劣势:用户程序需处理复杂资源管理逻辑,通用性差,实现难度大;
- 典型例子:MIT 的 Exokernel(实验性系统)。
14.总结systemd服务配置文件
systemd 是现代 Linux 系统的初始化系统和服务管理器,通过配置文件(称为单元文件,Unit Files)管理系统资源。以下是 systemd 服务配置文件的核心概念、结构和常见配置项总结:
一、单元文件基础
- 单元类型与扩展名
- .service:定义系统服务(如
nginx.service)。 - .socket:定义套接字或 FIFO 通信端点(如
sshd.socket)。 - .target:逻辑分组单元,用于组织其他单元(如
multi-user.target)。 - **.**timer:定义定时器,替代传统的
cron任务(如logrotate.timer)。 - 其他:
.mount、.automount、.path等。
- 文件位置
-
系统级
:
/usr/lib/systemd/system/:软件包安装的默认配置。/etc/systemd/system/:管理员自定义配置(优先级高于前者)。
-
用户级:
~/.config/systemd/user/。
二、服务配置文件结构
- 基本 sections
[Unit]
Description=描述信息
Documentation=文档URL
Requires=依赖的其他单元
After=在哪些单元后启动
Before=在哪些单元前启动
[Service]
Type=服务类型
ExecStart=启动命令
ExecStop=停止命令
ExecReload=重载命令
Restart=重启策略
User=运行用户
Group=运行组
WorkingDirectory=工作目录
[Install]
WantedBy=多用户目标(通常为 multi-user.target)
- 关键配置项详解
[Unit] 部分
- Description:服务描述,显示在
systemctl status输出中。 - Documentation:服务文档 URL(如
man:nginx(8))。 - Requires:强依赖,被依赖的单元必须启动成功。
- Wants:弱依赖,被依赖的单元失败不影响当前服务。
- After/Before:定义启动顺序,但不隐含依赖关系。
[Service] 部分
-
Type
:服务类型,常见值:
simple(默认):ExecStart 直接启动主进程。forking:后台运行(如守护进程,需ExecStart调用fork())。oneshot:一次性任务(如系统初始化脚本)。notify:服务启动后会发送通知(需配合NotifyAccess=all)。
-
ExecStart/ExecStop/ExecReload
:
- 服务启动、停止、重载的命令(支持
$环境变量)。 - 可使用
+前缀表示需要特权执行(如+ /sbin/ifup eth0)。
- 服务启动、停止、重载的命令(支持
-
Restart
:重启策略,常见值:
no(默认):不重启。on-failure:仅在异常退出(非 0 状态码)时重启。always:无论何种原因退出都重启。
-
User/Group:指定服务运行的用户和组。
-
EnvironmentFile:加载环境变量文件(如
EnvironmentFile=/etc/sysconfig/nginx)。
[Install] 部分
- WantedBy/RequiredBy:
- 定义服务安装后所属的目标(target)。
- 例如
WantedBy=multi-user.target表示在多用户模式下启用。
三、常用配置示例
- 简单服务(如 Nginx)
[Unit]
Description=The NGINX HTTP and reverse proxy server
After=network.target remote-fs.target nss-lookup.target
[Service]
Type=forking
PIDFile=/run/nginx.pid
ExecStartPre=/usr/sbin/nginx -t
ExecStart=/usr/sbin/nginx
ExecReload=/usr/sbin/nginx -s reload
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true
[Install]
WantedBy=multi-user.target
- 一次性任务(如磁盘清理)
[Unit]
Description=Daily disk cleanup
[Service]
Type=oneshot
ExecStart=/usr/local/bin/cleanup.sh
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
- 定时器任务(替代 cron)
# myscript.timer
[Unit]
Description=Run myscript daily
[Timer]
OnCalendar=daily
Persistent=true
[Install]
WantedBy=timers.target
# myscript.service
[Unit]
Description=My script
[Service]
Type=oneshot
ExecStart=/usr/local/bin/myscript.sh
四、管理命令
-
重载配置:
systemctl daemon-reload # 修改配置后需重载 -
服务控制:
systemctl start|stop|restart|reload nginx.service systemctl enable|disable nginx.service # 设置开机启动 systemctl status nginx.service # 查看状态 -
查看依赖关系:
systemctl list-dependencies nginx.service -
调试技巧:
systemctl cat nginx.service # 查看实际生效的配置 systemd-analyze verify nginx.service # 检查配置文件语法
五、高级特性
-
资源限制:
[Service] CPUQuota=50% # 限制CPU使用率 MemoryMax=100M # 限制最大内存 -
临时文件系统:
[Service] PrivateTmp=true # 为服务创建独立的/tmp目录 -
套接字激活:
# sshd.socket [Socket] ListenStream=22 -
条件启动:
[Unit] ConditionPathExists=/etc/nginx/nginx.conf # 存在特定文件时才启动
总结
systemd 服务配置文件通过结构化的 .service 文件实现灵活的服务管理,其核心特点包括:
- 模块化设计:清晰分离服务定义、依赖关系和安装配置。
- 丰富的生命周期管理:支持启动、停止、重载等多种操作。
- 强大的依赖控制:通过
Requires、Wants、After等实现复杂的启动顺序。 - 资源隔离:支持 CPU、内存等资源限制,提高安全性。
15.总结DNS域名三级结构,DNS服务工作原理,涉及递归和迭代查询原理
DNS 域名三级结构、服务工作原理及查询机制总结
一、DNS 域名三级结构(层次化命名体系)
DNS 域名采用树形层次结构,从右至左依次为高层到低层,典型的三级结构包括:
- 根域(Root Domain)
- 位置:域名最右端,用
.表示(常省略)。 - 作用:DNS 层级的最顶层,存储所有顶级域的权威服务器信息。
- 示例:
example.com.的根域为.。
2. 顶级域(Top-Level Domain, TLD)
- 位置:根域左侧的第一层域名。
- 分类:
- 通用顶级域(gTLD):如
.com(商业)、.org(组织)、.net(网络)、.edu(教育)等。 - 国家 / 地区顶级域(ccTLD):如
.cn(中国)、.us(美国)、.jp(日本)等。 - 新顶级域(nTLD):如
.xyz、.online、.shop等。
- 通用顶级域(gTLD):如
- 作用:标识域名的性质或所属地区,存储对应二级域的权威服务器信息。
- 二级域(Second-Level Domain, SLD)
- 位置:顶级域左侧的第二层域名,由用户注册和管理。
- 示例:
example.com中的example是二级域,com是顶级域。 - 扩展:子域(Subdomain)
二级域左侧的层级(如www.example.com中的www),属于二级域的分支,可由用户自行划分(如mail.example.com、blog.example.com)。
总结结构示例
主机名 二级域 顶级域 根域
| | | |
www.example.com.
二、DNS 服务工作原理(域名解析流程)
DNS(Domain Name System)是将域名转换为 IP 地址的分布式数据库系统,工作原理如下:
- 核心组件
-
DNS 客户端(解析器):发起域名查询的程序(如浏览器、
nslookup工具)。 -
DNS 服务器
:按层级分为 4 类:
- 根服务器(Root Server):全球 13 组(A~M),存储顶级域服务器地址。
- 顶级域服务器(TLD Server):存储对应顶级域下二级域的权威服务器地址。
- 权威服务器(Authoritative Server):存储特定域名的 IP 映射记录(如
example.com的权威服务器)。 - 递归解析器(Local DNS Server):为客户端提供递归查询服务的本地服务器(如运营商 DNS、Google DNS 8.8.8.8)。
-
域名解析流程(以
www.example.com为例) -
客户端发起查询:向本地递归解析器发送
www.example.com的 IP 查询请求。 -
本地递归解析器检查缓存:若缓存中有记录,直接返回 IP;否则进入下一步。
-
递归解析器查询根服务器:获取
.com顶级域服务器的地址。 -
递归解析器查询顶级域服务器:获取
example.com二级域的权威服务器地址。 -
递归解析器查询权威服务器:获取
www.example.com的 IP 地址(如A记录)。 -
返回结果:权威服务器将 IP 返回给递归解析器,后者缓存后再返回给客户端。
-
关键机制
-
缓存机制:各级服务器和客户端会缓存解析结果,减少重复查询(TTL 时间控制缓存有效期)。
-
记录类型
:
A:域名到 IPv4 地址的映射。AAAA:域名到 IPv6 地址的映射。NS:指定域名的权威服务器。CNAME:域名别名(如www.example.com指向alias.example.com)。MX:邮件服务器地址。
三、递归查询与迭代查询原理
DNS 查询分为两种模式,核心区别在于查询过程中服务器的角色和交互方式。
- 递归查询(Recursive Query)
-
特点:客户端只需向递归解析器发送一次查询,解析器全程代理查询并返回最终结果。
-
流程示例
:
- 客户端 → 本地递归解析器:“请告诉我
www.example.com的 IP”。 - 递归解析器若缓存无结果,依次查询根服务器、顶级域服务器、权威服务器,直到获取 IP。
- 递归解析器将结果返回给客户端。
- 客户端 → 本地递归解析器:“请告诉我
-
应用场景:客户端与本地递归解析器之间(如用户电脑与运营商 DNS)。
- 迭代查询(Iterative Query)
-
特点:客户端需逐步向不同服务器发送查询,服务器返回下一步查询的地址(而非最终结果)。
-
流程示例
:
- 客户端 → 根服务器:“
www.example.com的 IP 是多少?” - 根服务器 → 客户端:“去问
.com顶级域服务器(地址 X)。” - 客户端 →
.com顶级域服务器:“www.example.com的 IP 是多少?” - 顶级域服务器 → 客户端:“去问
example.com的权威服务器(地址 Y)。” - 客户端 → 权威服务器:“
www.example.com的 IP 是多少?” - 权威服务器 → 客户端:“IP 是 1.2.3.4。”
- 客户端 → 根服务器:“
-
应用场景:服务器与服务器之间(如递归解析器与根服务器、顶级域服务器的交互)。
- 对比总结
| 特性 | 递归查询 | 迭代查询 |
|---|---|---|
| 客户端工作量 | 只需发起一次查询,等待结果 | 需要主动向多台服务器发起多次查询 |
| 服务器角色 | 递归解析器作为代理,全程处理查询 | 服务器仅返回下一步查询的地址 |
| 网络交互次数 | 客户端与递归解析器之间 1 次交互 | 客户端与多台服务器之间多次交互 |
| 实际应用 | 客户端 → 本地递归解析器 | 递归解析器 → 根服务器 → 顶级域服务器 |
16.总结DNS服务器类型,解析答案,正反解析域,资源记录定义。
一、DNS 服务器类型
DNS 系统由多种功能不同的服务器组成,形成层次化的分布式架构:
1. 根服务器(Root DNS Server)
- 功能:存储顶级域(TLD)的权威服务器信息,是 DNS 查询的起点。
- 数量与分布:全球 13 组逻辑根服务器(A~M),通过任播技术分布在多个物理节点。
- 示例:
a.root-servers.net(IP:198.41.0.4)。
2. 顶级域服务器(TLD Server)
- 功能:管理特定顶级域(如
.com、.org、.cn)的权威服务器信息。 - 分类:
- 通用顶级域服务器(gTLD):管理
.com、.net等。 - 国家 / 地区顶级域服务器(ccTLD):管理
.cn、.jp等。
- 通用顶级域服务器(gTLD):管理
- 示例:
.com顶级域服务器由 Verisign 运营。
3. 权威服务器(Authoritative Server)
- 功能:存储特定域名的实际解析记录(如
example.com的 IP 地址),是域名解析的最终来源。 - 类型:
- 主权威服务器:直接管理域名区文件的服务器。
- 从权威服务器:从主服务器同步区文件的副本服务器。
- 配置:通过
NS(名称服务器)记录指定。
4. 递归解析器(Recursive Resolver)
-
功能:为客户端提供递归查询服务,缓存解析结果以提高效率。
-
常见部署
:
- 运营商 DNS:如中国电信的
202.96.128.166。 - 公共 DNS:如 Google 的
8.8.8.8、Cloudflare 的1.1.1.1。
- 运营商 DNS:如中国电信的
5. 缓存服务器(Caching Server)
- 功能:缓存近期查询结果,减少对上游服务器的访问。
- 特点:不负责权威解析,仅加速已有查询的响应。
二、DNS 解析答案类型
DNS 服务器返回的响应分为以下几类:
1. 权威答案(Authoritative Answer)
- 来源:由域名的权威服务器直接返回。
- 标志:响应中
AA(Authoritative Answer)位为 1。 - 示例:
example.com的权威服务器返回的A记录。
2. 非权威答案(Non-Authoritative Answer)
- 来源:由递归解析器或缓存服务器返回(非权威服务器)。
- 特点:基于缓存结果,不包含
AA标志。
3. 肯定答案(Positive Answer)
- 含义:成功解析到域名对应的 IP 地址或其他记录。
- 示例:返回
www.example.com的 IP 为1.2.3.4。
4. 否定答案(Negative Answer)
- 含义:域名不存在或无对应记录。
- 分类:
- NXDOMAIN:域名不存在(如
nonexistent.example.com)。 - NODATA:域名存在,但无指定类型的记录(如
example.com无MX记录)。
- NXDOMAIN:域名不存在(如
三、正向解析与反向解析域
DNS 解析分为两种方向,对应不同的查询方式和用途:
1. 正向解析(Forward DNS)
- 定义:从域名到 IP 地址的解析(如查询
www.example.com的 IP)。 - 核心记录:
A(IPv4)和AAAA(IPv6)记录。 - 域结构:基于域名的层级结构(如
www.example.com)。
2. 反向解析(Reverse DNS)
-
定义:从 IP 地址到域名的解析(如查询
1.2.3.4对应的域名)。 -
核心记录:
PTR(Pointer)记录。 -
域结构:使用
in-addr.arpa(IPv4)或
ip6.arpa(IPv6)特殊域:
- IPv4 示例:IP
1.2.3.4对应的反向域名是4.3.2.1.in-addr.arpa。 - 配置:在反向区文件中为每个 IP 分配
PTR记录。
- IPv4 示例:IP
四、DNS 资源记录(RR, Resource Record)
DNS 数据库存储的各种记录类型,定义了域名与其他数据的映射关系:
1. 常用资源记录类型
| 记录类型 | 含义 | 示例 |
|---|---|---|
A | IPv4 地址映射 | www.example.com. A 1.2.3.4 |
AAAA | IPv6 地址映射 | www.example.com. AAAA 2001:db8::1 |
NS | 名称服务器记录 | example.com. NS ns1.example.com. |
CNAME | 别名记录 | www.example.com. CNAME server1.example.com. |
MX | 邮件交换记录 | example.com. MX 10 mail.example.com. |
PTR | 反向解析记录 | 4.3.2.1.in-addr.arpa. PTR server.example.com. |
SOA | 起始授权机构记录 | example.com. SOA ns1.example.com. admin.example.com. (序列号 刷新时间 ...) |
TXT | 文本记录 | example.com. TXT "v=spf1 mx -all" |
SRV | 服务发现记录 | _service._proto.example.com. SRV 优先级 权重 端口 目标主机. |
2. 记录格式与字段
每条记录通常包含以下字段:
域名 TTL 类别 类型 值
- 域名:记录适用的域名(如
www.example.com)。 - TTL:缓存时间(秒),控制记录在其他服务器中的缓存有效期。
- 类别:通常为
IN(Internet)。 - 类型:记录类型(如
A、MX)。 - 值:记录的具体内容(如 IP 地址、服务器名)。


被折叠的 条评论
为什么被折叠?



