基础信息栏
学习日期:2026-04-23
所属模块:Linux、云运维、网络基础
学习难度:进阶级
核心标签:#Linux 网络 #Shell 编程 #子网划分 #TCP/IP #数组 #阶乘
学习目标:掌握网卡配置、网络扫描、Shell 数组、IP 计算、路由判断、子网划分、包传递流程
前置知识:Linux 基础命令、TCP/IP 基础、Shell 语法
一、核心知识笔记(理论 + 实操)
1. /etc/sysconfig/network-scripts/ifcfg-eth0 配置格式
标准定义:CentOS/RHEL 系列以太网网卡核心配置文件,用于持久化网络参数,重启网络服务生效。
完整字段解析:
- TYPE=Ethernet:网络类型为以太网
- BOOTPROTO=static/dhcp/none:IP 获取方式(静态 / 动态 / 无)
- NAME=eth0:网卡逻辑名称
- DEVICE=eth0:系统识别的设备名
- ONBOOT=yes:开机自动激活网卡
- IPADDR=192.168.1.10:静态 IP 地址
- NETMASK=255.255.255.0:子网掩码
- GATEWAY=192.168.1.1:默认网关
- DNS1=223.5.5.5:首选 DNS
- DNS2=223.6.6.6:备用 DNS
- PREFIX=24:子网前缀长度(替代 NETMASK)
- IPV6INIT=no:关闭 IPv6
- USERCTL=no:禁止普通用户控制网卡
重启网络命令:
systemctl restart network
# 或
nmcli c reload
2. 脚本判断网段内在线主机(ping 扫描)
功能说明:自动获取本机网段,批量 ping 检测,输出在线主机列表。
#!/bin/bash
# 获取本机所在网段(适配多网卡)
subnet=$(ip addr show $(ip route | grep default | awk '{print $5}') | grep inet | grep -v inet6 | awk '{print $2}' | cut -d'/' -f1 | cut -d'.' -f1-3)
echo "扫描网段:$subnet.1-254"
echo "在线主机如下:"
for i in {1..254}; do
# -c 1 发1个包,-W 1 超时1秒
ping -c 1 -W 1 $subnet.$i >/dev/null 2>&1
if [ $? -eq 0 ]; then
echo -e "\033[32m $subnet.$i 在线 \033[0m"
fi
done
3. while read line 计算 /etc/passwd 用户 ID 总和
说明:逐行读取 /etc/passwd,提取 UID(第 3 列),过滤系统无效 UID,累加求和。
#!/bin/bash
sum=0
# IFS=: 按冒号分割,只读取第3列
while IFS=: read -r _ _ uid _ _ _ _; do
# 判断是否为纯数字 UID
if [[ $uid =~ ^[0-9]+$ ]]; then
sum=$((sum + uid))
fi
done < /etc/passwd
echo "当前系统所有用户 UID 总和:$sum"
4. 索引数组、关联数组、字符串处理、高级变量(含示例)
索引数组(下标数字)
# 定义
arr=("apple" "banana" "orange")
# 取值
echo ${arr[0]} # 第一个元素
echo ${arr[-1]} # 最后一个元素
echo ${arr[@]} # 所有元素
echo ${#arr[@]} # 数组长度
# 遍历
for i in ${arr[@]}; do echo $i; done
关联数组(key-value)
# 必须先声明
declare -A student
student[name]="Tom"
student[age]="22"
student[class]="CS"
# 取值
echo ${student[name]}
echo ${!student[@]} # 所有key
echo ${student[@]} # 所有value
字符串处理
str="Linux-Shell-2026"
echo ${#str} # 长度
echo ${str:0:5} # 截取 0开始,长度5
echo ${str//-/_} # 替换所有-为_
echo ${str^^} # 转大写
echo ${str,,} # 转小写
高级变量
- $0:脚本自身文件名
- 9:位置参数
- $#:参数个数
- $*:所有参数(整体)
- $@:所有参数(独立)
- $?:上一条命令退出码(0 成功,非 0 失败)
- :当前进程
- $!:后台最后一个进程 PID
5. 求 10 个随机数的最大值与最小值
#!/bin/bash
nums=()
# 生成10个0~32767随机数
for ((i=0;i<10;i++)); do
nums[$i]=$RANDOM
done
echo "10个随机数:${nums[@]}"
max=${nums[0]}
min=${nums[0]}
for n in "${nums[@]}"; do
(( n > max )) && max=$n
(( n < min )) && min=$n
done
echo "最大值:$max"
echo "最小值:$min"
6. 递归调用实现阶乘算法
#!/bin/bash
factorial() {
local n=$1
# 递归终止条件
if (( n <= 1 )); then
echo 1
else
# 递归调用自身 n-1
echo $(( n * $(factorial $((n-1))) ))
fi
}
# 调用示例:求 5 的阶乘
result=$(factorial 5)
echo "5! = $result"
7. 主机到主机的数据包传递过程(精细版)
-
应用层:应用程序生成数据,交给传输层。
-
传输层:加 TCP/UDP 头(源端口、目标端口、序号、校验和)。
-
网络层:加 IP 头(源 IP、目标 IP、协议号、TTL)。
-
数据链路层:
- 查 ARP 表获取目标 MAC
- 封装 MAC 头(源 MAC、目标 MAC、类型)
-
物理层:转为电 / 光信号发送。
-
转发过程:
- 同一网段:交换机根据 MAC 转发
- 不同网段:路由器查路由表,跨网段转发
-
目标主机:
- 自下而上逐层解包头
- 按端口交给对应应用程序
8. IP 地址 A、B、C、D 类总结及 IP 组成
IP 地址组成:32 位二进制 → 网络位 + 主机位
-
A 类:1~126
- 掩码:/8(255.0.0.0)
- 首位:0
- 网络数:126,主机数:2^24-2
-
B 类:128~191
- 掩码:/16(255.255.0.0)
- 首位:10
- 网络数:16384,主机数:2^16-2
-
C 类:192~223
- 掩码:/24(255.255.255.0)
- 首位:110
- 网络数:209 万,主机数:2^8-2=254
-
D 类:224~239
- 组播地址,无掩码、无主机位
-
E 类:240~255,保留
特殊地址:
- 127.0.0.0/8:本地回环
- 0.0.0.0:默认路由
- 255.255.255.255:全网广播
9. 201.222.200.111/18 计算
计算步骤:
-
前缀 /18 → 子网掩码:18 个 1
- 二进制:11111111.11111111.11000000.00000000
- 十进制:255.255.192.0
-
主机位:32-18=14 位
-
可用主机数:2^14 - 2 = 16382
- 减 2:网络号、广播地址不可用
10. A (10.0.1.1/16) 与 B (10.0.2.2/24) 通信判断
A 的判断逻辑:
- A 使用自己的子网掩码 /16 计算
- A 网络位:10.0.0.0
- B 的 IP:10.0.2.2 在 10.0.0.0/16 范围内
- A 认为与 B 在同一网段,直接发 ARP 请求
B 的判断逻辑:
- B 使用自己的掩码 /24
- B 网络位:10.0.2.0
- A 的 IP:10.0.1.1 不在 B 的网段
- B 会把回包发给网关,不直接回复 A
结论:
- A 能发 ARP,但 B 不直接回应
- 无法正常双向通信
11. 将 10.0.0.0/8 划分 32 个子网
计算步骤:
- 子网数 32 → 2^5=32,需要借 5 位主机位
- 原掩码:/8
- 新掩码:8+5=13 → /13
- 掩码十进制:255.248.0.0
- 每个子网主机位:32-13=19 位
- 可用主机数:2^19 - 2 = 524,286
第一个子网:10.0.0.0/13
第二个子网:10.8.0.0/13
步长:8.0.0
二、本节学习总结
-
网络配置:掌握 ifcfg-eth0 完整字段、重启方式、IP / 网关 / DNS 配置。
-
Shell 脚本:
- 批量 ping 扫描在线主机
- 读取 /etc/passwd 计算 UID 总和
- 数组、字符串、高级变量熟练使用
- 随机数极值、递归阶乘实现
-
网络原理:
- 数据包完整传递流程
- A/B/C/D 类 IP 划分与地址组成
- 子网掩码、主机数、网段计算
- 不同掩码主机通信判断逻辑
-
子网划分:可根据子网数快速计算新掩码、主机数、网段范围。
三、面试高频考点
1.Shell 编程面试题
- 索引数组与关联数组区别?
- @ 区别?
- $? 含义?0 和非 0 代表什么?
- 如何遍历数组 / 文件?
- 递归函数的核心要素?
- 如何生成随机数?如何取最大 / 最小?
2.Linux 网络面试题
- ifcfg-eth0 常用配置字段?
- 同一网段 / 不同网段通信流程?
- ARP 作用?工作过程?
- A/B/C 类 IP 范围、掩码、主机数?
- 如何计算子网掩码、可用主机数?
- 两台主机掩码不同,能否通信?
- 数据包从主机 A 到主机 B 的完整流程?
- 什么是网络位、主机位、广播地址?
3.实战面试题
- 写脚本扫描局域网在线主机。
- 写脚本计算 /etc/passwd UID 总和。
- 给定 IP / 前缀,计算掩码、主机数、网段。
- 两台主机掩码不同,判断是否互通并说明原因。
四、面试高频考点・答案
一、Shell 编程面试题
1. 索引数组与关联数组区别
- 索引数组:下标是数字,默认从 0 开始,无需提前声明。
- 关联数组:下标是字符串(Key) ,必须用
declare -A声明,键值对存储。
2. @ 区别
$*:所有参数视为一个整体字符串。$@:所有参数视为独立个体,遍历时更常用。- 被双引号包裹时差异最明显。
3. $? 含义?0 和非 0 代表什么
$?:上一条命令 / 脚本的退出状态码。- 0:执行成功。
- 非 0:执行失败(1 通用错误,127 命令未找到等)。
4. 如何遍历数组 / 文件
- 遍历数组:
for i in "${arr[@]}"; do echo $i; done
- 遍历文件(按行):
while read line; do echo $line; done < file.txt
5. 递归函数的核心要素
- 终止条件:必须有出口,否则死循环。
- 自身调用:函数内部调用自己。
- 参数递减:每次调用向终止条件靠近。
6. 如何生成随机数?如何取最大 / 最小
- 随机数:
$RANDOM(0~32767)。 - 取最值:先把第一个值赋给 max/min,再循环逐一比较更新。
二、Linux 网络面试题
1. ifcfg-eth0 常用配置字段
TYPE=Ethernet
BOOTPROTO=static/dhcp
NAME/DEVICE=eth0
ONBOOT=yes
IPADDR=
NETMASK/PREFIX=
GATEWAY=
DNS1=
IPV6INIT=no
2. 同一网段 / 不同网段通信流程
-
同一网段:
- 源主机 ARP 请求目标 MAC。
- 目标回复 MAC。
- 交换机直接二层转发。
-
不同网段:
- 源主机发给网关。
- 路由器查路由表转发。
- 目标网段内再走二层通信。
3. ARP 作用?工作过程
-
作用:根据 IP → MAC 地址解析。
-
过程:
- 源发广播 ARP 请求:谁是这个 IP?
- 目标单播回复:我的 MAC 是 xx。
- 双方缓存 ARP 条目。
4. A/B/C 类 IP 范围、掩码、主机数
- A 类:1~126,/8,主机数 2^24-2。
- B 类:128~191,/16,主机数 2^16-2。
- C 类:192~223,/24,主机数 254。
- D 类:224~239,组播。
5. 如何计算子网掩码、可用主机数
- 掩码:前缀 /n → 前 n 位为 1,转十进制。
- 主机位:32 - n。
- 可用主机:2^ 主机位 - 2(减网络号 + 广播地址)。
6. 两台主机掩码不同,能否通信
- 不一定。
- 一方认为同网段、一方认为不同网段 → 单向通、双向不通。
- 必须双方都认为在同一网段,才能正常互通。
7. 数据包从 A 到 B 完整流程
- 应用层数据 → 传输层(加端口)→ 网络层(加 IP)→ 链路层(加 MAC)。
- 查 ARP 获取 MAC,封装帧发出。
- 交换机 / 路由器转发。
- 目标主机自下而上解包,交付应用。
8. 什么是网络位、主机位、广播地址
- 网络位:标识网段,相同则同网段。
- 主机位:标识网段内具体主机。
- 广播地址:主机位全 1,向本网段所有主机发送。
三、实战面试题
1. 写脚本扫描局域网内在线主机(详细思路 + 完整脚本 + 说明)
题目要求
写一个 Shell 脚本,自动检测当前主机所在网段,批量 ping 扫描 1~254,输出在线主机 IP。
详细实现思路
- 获取本机网卡与 IP:通过默认路由找到出口网卡,避免多网卡干扰。
- 提取网段前缀:如 192.168.1,只保留前 3 段。
- 循环 ping 扫描:对 1~254 逐个发 1 个包,超时 1 秒,提高速度。
- 判断结果:用
$?判断是否 ping 通。 - 输出在线主机:绿色高亮显示,清晰易读。
完整脚本
#!/bin/bash
# 功能:扫描本网段所有在线主机
# 作者:云运维学习笔记
# 1. 获取默认路由使用的网卡
eth=$(ip route | grep default | awk '{print $5}')
# 2. 获取本机IP并提取网段前缀(前3段)
local_ip=$(ip addr show $eth | grep inet | grep -v inet6 | awk '{print $2}' | cut -d'/' -f1)
subnet=$(echo $local_ip | cut -d'.' -f1-3)
echo "===================================================="
echo "当前本机IP:$local_ip"
echo "扫描网段:$subnet.1-254"
echo "===================================================="
echo "在线主机列表:"
# 3. 批量扫描
for i in {1..254};do
ping -c 1 -W 1 $subnet.$i >/dev/null 2>&1
if [ $? -eq 0 ];then
echo -e "\033[32m [在线] $subnet.$i \033[0m"
fi
done
面试可口述要点
- 用
ip route取出口网卡,保证准确性。 ping -c 1 -W 1提高扫描速度。- 通过
$?判断命令是否成功。 - 输出彩色提示,便于查看。
2. 写脚本计算 /etc/passwd 中所有用户 UID 总和
题目要求
使用 while read line 读取 /etc/passwd,计算所有有效用户 UID 的总和。
详细实现思路
/etc/passwd格式:用户名:密码占位:UID:GID:注释:家目录:Shell。- 目标:取第 3 列 UID。
- 过滤:只保留纯数字 UID,排除异常行。
- 累加:初始化 sum=0,逐行相加。
- 输出最终结果。
完整脚本
#!/bin/bash
# 功能:计算/etc/passwd所有用户UID总和
sum=0
# 逐行读取,按冒号分割,直接取第3列uid
while IFS=: read -r user x uid gid comment home shell;do
# 判断uid是否为纯数字(过滤非法/无效行)
if [[ "$uid" =~ ^[0-9]+$ ]];then
sum=$((sum + uid))
fi
done < /etc/passwd
echo "========================================"
echo "系统所有有效用户 UID 总和:$sum"
echo "========================================"
面试可口述要点
IFS=:按冒号分段,直接取列,不用 cut,效率更高。[[ "$uid" =~ ^[0-9]+$ ]]正则过滤,保证只加数字。- 使用
while read标准读取文件方式。 - 变量作用域清晰,无脏数据。
3. 给定 IP / 前缀,计算子网掩码、主机数、网段范围
题目示例
以 201.222.200.111/18 为例,计算:
- 子网掩码
- 可用主机数
- 网段范围
详细计算步骤(面试必按这个说)
-
确定前缀位数
/18表示前 18 位是网络位。 -
计算子网掩码
前 18 位全 1,后 14 位全 0:
11111111.11111111.11000000.00000000转十进制:
255.255.192.0
-
计算主机位
32 - 18 = 14 位 -
计算可用主机数
公式:
2^主机位 - 2减 2 原因:网络号、广播地址不可分配给主机。
2^14 = 16384 16384 - 2 = 16382可用主机数:16382
-
网段范围
块大小(增量):
256 - 192 = 64第三个字节:
200 所在段:192网络地址:
201.222.192.0/18广播地址:
201.222.255.255
最终答案
- 子网掩码:
255.255.192.0 - 可用主机数:
16382 - 网段:
201.222.192.0 ~ 201.222.255.255
4. 两台主机掩码不同,判断是否互通并说明原因
题目
A:10.0.1.1/16
B:10.0.2.2/24
问:A 如何判断是否同一网段?A 和 B 能否通信?为什么?
详细回答
① A 的判断逻辑(A 用自己的掩码 /16 判断)
-
A 的掩码:
255.255.0.0 -
A 对 B 做 按位与运算:
10.0.2.2 & 255.255.0.0 = 10.0.0.0 -
A 自己的网络位:
10.0.1.1 & 255.255.0.0 = 10.0.0.0 -
结论:A 认为 B 和自己在同一网段。
② B 的判断逻辑(B 用自己的掩码 /24 判断)
-
B 的掩码:
255.255.255.0 -
B 对 A 做按位与:
10.0.1.1 & 255.255.255.0 = 10.0.1.0 -
B 自己的网络位:
10.0.2.2 & 255.255.255.0 = 10.0.2.0 -
结论:B 认为 A 不在同一网段。
③ 通信结果
- A 发:直接发 ARP 广播请求 B 的 MAC。
- B 收:收到后,回包不直接发给 A,而是交给网关。
- 最终:双向无法正常通信。
最终答案
A 使用自己 /16 掩码计算,认为 B 在同一网段;B 使用 /24 掩码,认为 A 不在同一网段。双方判断不一致,因此无法正常双向通信。
5. 把 10.0.0.0/8 划分 32 个子网
题目
将 10.0.0.0/8 划分成 32 个子网,求:
- 新子网掩码
- 每个子网主机数
- 前两个子网范围
详细步骤
-
求需要借多少位
子网数 32 →
2^5 = 32需要 借 5 位主机位 做子网位。
-
计算新掩码
原掩码:
/8新掩码:
8 + 5 = /13二进制:
11111111.11111000.00000000.00000000十进制:255.248.0.0
-
计算每个子网主机数
主机位 = 32 - 13 = 19 位
可用主机 =
2^19 - 2 = 524286 -
计算块大小(网段步长)
第二个字节:
256 - 248 = 8每段间隔:
8.0.0 -
前两个子网
子网 1:
10.0.0.0/13子网 2:
10.8.0.0/13
最终答案
- 掩码:
255.248.0.0(/13) - 主机数:
524286 - 步长:
8.0.0
6.整体总结Shell 实战:重点考察文件读取、循环、条件判断、命令返回值、数组与字符串。
- 网络计算:核心是按位与、网络位、主机位、掩码、主机数。
- 互通判断:必须双方都认为同网段才能通;一方认为不同则不通。
- 子网划分:公式固定:
借位=log2(子网数),新掩码 = 原掩码 + 借位。