马哥sre云计算运维第4次作业
一、解析/etc/sysconfig/network-scripts/ifcfg-eth0配置格式
TYPE=Ethernet# 网络类型,这里为以太网类型PROXY_METHOD=none# 代理方法:没有BROWSER_ONLY=no# 只浏览器使用: 否 如果只是配置网卡的话,没啥用可以去掉BOOTPROTO=none# 启动协议: 无(或者写成static),不使用DHCP自动获取IP,是静态配置方式DEFROUTE=yes# 默认路由: 启用IPV4_FAILURE_FATAL=no# ipv4故障致命性:否(关于ipv4配置失败会不会导致网络启动失败)IPV6INIT=yes# ipv6初始化:是(启用ipv6)IPV6_AUTOCONF=yes# ipv6自动配置:是(系统自动配置ipv6地址)IPV6_DEFROUTE=yes# ipv6默认路由:是(ipv6的路由)IPV6_FAILURE_FATAL=no# ipv6故障致命性:否(关于ipv6配置失败会不会导致网络启动失败)IPV6_ADDR_GEN_MODE=stable-privacy# IP地址生成模式NAME=eth0# 网络接口名称UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx# 网络接口的唯一标识符DEVICE=eth0# 设备名称(与网络接口名称一致)ONBOOT=no# 开启时自启动IPADDR=10.0.0.13# ipv4地址,静态配置的、PREFIX=24# IP地址掩码GATEWAY=10.0.0.2# 默认网关DNS1=10.0.0.2# DNS服务器地址DNS2=8.8.8.8# 次选DNS二、使用脚本判断 你主机所在网络内在线的主机IP有哪些? ping通则在线。
[root@Rocky10-12 ~]# cat -n testPing.sh1#!/bin/bash2# *********************************3# * 功能:测试网络内在线的主机IP4# * 作者:王波5# * 联系:wangbo@qq.com6# * 版本:2026-04-267# *********************************89# 网络位10ip_network="10.0.0"11# 在线主机数初始化12online_hosts=01314# 这里简单点,24位的掩码,所以有254个主机15foriin{1..254}16do17# 后台ping,-c ping一次,-w 等待1s,不加的话需要等待10s18ping-c1-w1"${ip_network}.${i}">/dev/null2>&119# 判断上次执行命令的效果20if[$?-eq0]21then22# 成功输出ip,并且总数加123echo"${ip_network}.${i}在线"24((online_hosts++))25else26echo"${ip_network}.${i}不在线"27fi28done2930printf"总共有%d台主机在线"$online_hosts结果:
[root@Rocky10-12 ~]# /bin/bash testPing.sh10.0.0.1 在线10.0.0.2 在线10.0.0.3 不在线10.0.0.4 不在线10.0.0.5 不在线10.0.0.6 不在线10.0.0.7 不在线10.0.0.8 不在线10.0.0.9 不在线10.0.0.10 不在线10.0.0.11 不在线10.0.0.12 在线10.0.0.13 在线10.0.0.14 不在线10.0.0.15 不在线10.0.0.16 不在线10.0.0.17 不在线10.0.0.18 不在线10.0.0.19 不在线10.0.0.20 不在线10.0.0.21 不在线10.0.0.22 不在线10.0.0.23 不在线10.0.0.24 不在线10.0.0.25 不在线10.0.0.26 不在线10.0.0.27 不在线10.0.0.28 不在线10.0.0.29 不在线10.0.0.30 不在线 总共有4台主机在线三、使用while read line和/etc/passwd,计算用户id总和。
1#!/bin/bash2# *********************************3# * 功能:计算id总和4# * 作者:王波5# * 联系:wangbo@qq.com6# * 版本:2026-04-267# *********************************89# 用户总数初始化10id_sum=01112# 循环的方式逐行提取13whilereadline14do15# $()执行命令,然后复制给uid变量. <<< 将单行字符串重定向16uid=$(cut-d:-f3<<<"${line}")17# 判断是否大于100018if["${uid}"-gt1000]19then20echo"${uid}"21# 如果大的话,就自增22((id_sum++))23fi24done</etc/passwd2526printf"用户个数总共为%d""${id_sum}"结果
[root@Rocky10-12 ~]# /bin/bash calac_id_nums.sh6553410011002100310041005用户个数总共为6四、总结索引数组和关联数组,字符串处理,高级变量使用及示例。
数组:有序的元素序列,它将有限个类型相同的数据放到一个集合中,这个集合就是数组。
- 数组样式:
- 一维数组:数组[下标]
- 二位数组:数组[行下标][列下标]
- 三位数组:数组[行下标][列下标][页下标]
- bash支持一维数组(不支持多维数组),并且没有限定数组的大小。
- 数组元素的下标由0开始编号。
- 下标可以是整数或算术表达式,其值应大于或等于0
- 数组的创建:
- 用括号来表示数组,数组元素用空格符号分割开
array_name=(value1 ... valuen)- 有单行定义、多行定义、单元素定义、命令定义等多种样式
- 单行定义:
array_name=(value0 value1 value2 value3) - 多行定义:
array_name=(value0 value1 value2 value3) - 单元素定义:
array_name[0]=value- 单元素定义的时候,可以不使用连续的下标,而且下标的范围没有限制.
- 命令定义:
- 是value的值以命令方式来获取
array=($(ls /tmp/))
- 是value的值以命令方式来获取
- 单行定义:
- 数组取值:
- 获取内容:读取数组元素值可以根据元素的下标值来获取
${array_name[index]}${array_name[@]:起始位置:获取数量}- 获取所有的元素内容,下标位置写"@“或者”*"
- 获取数组索引
${!array_name[index]}- 获取所有的元素位置,下标位置写"@“或者”*"
- 获取数组长度的方法与获取字符串长度的方法相同
${#array_name[index]}- 获取具体的元素长度,指定其下标值,从0开始
- 获取所有的元素个数,下标位置写"@“或者”*"
- 获取内容:读取数组元素值可以根据元素的下标值来获取
- 数组变动:
- 元素修改:
- 元素内容替换:
array_name[index]=值 - 元素部分内容替换,可以参考字符串替换格式:
${array_name[index]/原内容/新内容}- 默认是演示效果,原数组未被修改,如果真要更改需要结合单元素内容替换
- 元素内容替换:
- 元素删除
- 使用unset来实现
- 删除单元素:
unset array_name[index] - 删除整个数组:
unset array_name- 支持同时删除多个数组名字
- 元素修改:
- 数组关联
- 数组的定制主要有两种:
2. 定制索引数组 - 数组的索引是普通的数字
1.declare -a array_name
2. 普通数组可以不事先声明,直接使用
3. 定制关联数组 - 数组的索引是自定义的字母
1.declare -A array_name
2. 关联数组必须先声明,再使用,不然就是将索引数组转换为关联数组,但是他们之间不可以相互转换。bash [root@Rocky10-12 ~ ]# aaa=([yingyu]="32" [yuwen]="67" [shuxue]="65") 当前位置: ~ [root@Rocky10-12 ~ ]# declare -A aaa -bash: declare: aaa: 无法将索引数组转换为关联数组
- 数组的定制主要有两种:
字符串
- 基础知识:
- 字符串计数:
${#file}获取字符串的长度 - 在shell环境中,默认情况下,会将所有的信息,都认为是 字符串。
- 字符串计数:
- 字符串截取:
${var:pos:length}变量var从pos开始截取length个字符,pos为空表示从0开始${file:0:5}从0开始【第1个字符】,截取5个字符${file:5:5}从5开始【第6个字符】,截取5个字符${file::5}从0开始【第1个字符】,截取5个字符${file:0-6:3}从倒数第6个字符开始,截取之后的3个字符${file: -4}返回字符串最后四个字符,-前面是"空格"
- 字符串表达式:
- 内容比较判断:
str1 == str2判断str1和str2字符串内容一致str1 != str2判断str1和str2字符串内容不一致,!表示相反的意思
- 内容空值判断
-z str空值判断,获取字符串长度,长度为0,返回True-n "str"非空值判断,获取字符串长度,长度不为0,返回True
- 内容比较判断:
高级变量
- 变量间接引用:通过一个变量名去引用另一个变量的值。
# 定义一个变量名name=var# 定义实际变量var="hello world"# 间接引用:${!name} 相当于取 $var 的值echo${!name}# 输出:hello world# ${!var} 中的 ! 表示间接引用,只能用于一层。- 特殊变量及其高级操作
- $0, $1, $2… 位置参数
- $# 参数个数
- $@ 所有参数(作为独立字符串)
- $* 所有参数(作为单个字符串)
- $? 上一条命令的退出状态
- $$ 当前 Shell 的 PID
五、求10个随机数的最大值与最小值
#!/bin/bash# *********************************# * 功能:Sehll 脚本模板# * 作者:王波# * 联系:wangbo@qq.com# * 版本:2026-04-26# *********************************# 定义一个临时存储的值tmp=0# 用循环定义一个随即数组,里面有十个随机数foriin{1..10}do# (()) 只计算不输出,$(())计算后输出random_array[$((i-1))]=$RANDOMecho"${random_array[$((i-1))]}"done# 使用冒泡算法排序# 控制轮数foriin{1..9}doforjin{1..9}doif[${random_array[$((j-1))]}-lt${random_array[$j]}]then# 交换tmp=${random_array[$((j-1))]}random_array[$((j-1))]=${random_array[$j]}random_array[$j]=$tmpfidonedoneecho"-----------------------"# 输出最大最小值printf"max is %d, min is %d"${random_array[0]}${random_array[9]}结果
[root@Rocky10-12 ~]# /bin/bash random_max_min.sh2812518268207363241610373668940951845644511489----------------------- max is32416, min is1489六、使用递归调用,完成阶乘算法实现。
#!/bin/bash# *********************************# * 功能:Sehll 脚本模板# * 作者:王波# * 联系:wangbo@qq.com# * 版本:2026-04-26# *********************************factorial(){# 加上local后 每次调用都有独立的 n,通过local语法,将变量的作用范围限制在一段代码块范围中。localn=$1# 基线条件:0! = 1, 1! = 1if[$n-le1];thenecho1else# 递归条件:n! = n * (n-1)!localsub=$((n-1))localsub_result=$(factorial $sub)echo$((n*sub_result))fi}# 读取read-p"请输入一个非负整数:"numif[$num-lt0];thenecho"错误:阶乘只适用于非负整数!"exit1firesult=$(factorial $num)echo"${num}! =${result}"结果
[root@Rocky10-12 ~]# /bin/bash factorial.sh请输入一个非负整数:66!=720七、总结主机到主机的包传递过程。
- 发送方判断是否在同一网段:
- 用自己的子网掩码与目标IP做逻辑与运算,得到目标网络号;
- 再与自己IP和自己的掩码运算得到自己的网络号。
- 若两者相等,则在同一网段,否则在不同网段。
- 获取下一跳MAC地址:
- 若在同一网段,目标MAC就是目标主机的MAC,发送ARP广播请求目标IP对应的MAC。
- 若在不同网段,目标MAC是默认网关的MAC,发送ARP请求网关IP的MAC。
- 封装数据帧:
- 源MAC为本机,目标MAC为下一跳(目标主机或网关)的MAC,IP头中源IP和目标IP保持不变。
- 数据从应用层开始依次封装段头、包头、帧头
- 链路层发送:将帧发送到物理链路。
- 中间路由器处理:
- 路由器收到帧,检查目标MAC是否为自己接收接口的MAC,是则接收;否则丢弃。
- 解封出IP包,根据目标IP查找路由表,决定出接口和下一跳IP。
- 下一跳IP的MAC通过ARP获取(若不在ARP缓存中)。
- 重新封装:源MAC改为出接口的MAC,目标MAC改为下一跳的MAC,IP头不变。
- 最终到达目标主机:
- 目标主机收到帧,检查目标MAC为自己,解封IP包。
- 检查目标IP为自己,将数据交给上层协议(如TCP/UDP)。
八、总结IP地址 A, B, C, D 类,并解析IP地址的组成
- IP地址的基本组成
- IP地址由32位二进制组成,通常用点分十进制表示
- IPv4地址 = 网络位 + 主机位
- 192.168.1.1
- 11000000.10101000.00000001.00000001
- 每个分割的段 = 8位二进制(0-255)
- IP地址分类
类别 首位bit 网络位长度 主机位长度 地址范围 默认子网掩码 用途 A类 0 8位 24位 0.0.0.0 - 127.255.255.255 255.0.0.0 超大型网络 B类 10 16位 16位 128.0.0.0 - 191.255.255.255 255.255.0.0 中型网络 C类 110 24位 8位 192.0.0.0 - 223.255.255.255 255.255.255.0 小型网络 D类 1110 无 无 224.0.0.0 - 239.255.255.255 无 组播地址 E类 1111 无 无 240.0.0.0 - 255.255.255.255 无 科研保留
九、201.222.200.111/18计算主机数?子网掩码?说明计算方法
- 可用主机数 = 2^14 - 2 = 16384 - 2 = 16382
- 子网掩码:/18 表示前18位为1,后14位为0。点分十进制为:255.255.192.0
十、当A(10.0.1.1/16)与B(10.0.2.2/24)通信,A如何判断是否在同一个网段?A和B能否通信?
- 每台主机都用自己的子网掩码来判断目标是否在同一网段
- 目标网络号 = 目标IP & 自己的子网掩码
- 自己网络号 = 自己IP & 自己的子网掩码
- 如果 目标网络号 == 自己网络号 → 同一网段,直接通信
- 如果 不相等 → 不同网段,走网关
- B的IP:10.0.2.2 00001010.00000000.00000010.00000010 (10.0.2.2)
- A的掩码:255.255.0.0 11111111. 11111111. 00000000.00000000 (255.255.0.0)
- B的网络号:00001010.00000000.00000000.00000000 → 10.0.0.0
- B的网络号(从A视角):00001010.00000000.00000000.00000000 = 10.0.0.0
- A 认为 B 的网络号也是 10.0.0.0/16。
- A的网络号也是通过根据自己的IP和掩码用逻辑与演算出来的。
- 由此,A认为B和自己是在一个网段。
- A和B不能直接双向通信,B不认为A和自己同网段。
- B 用自己掩码 /24 计算:10.0.1.1 & 255.255.255.0 = 10.0.1.0/24
- B 自己的网络号是 10.0.2.0/24
- B 不会直接发 ARP 给 A,而是将包发给默认网关.配置了网关就可以通信,如果没有配置就没有返程。
十一、 如何将10.0.0.0/8划分32个子网?求每个子网的掩码,主机数。
- 将 10.0.0.0/8 划分为 32 个子网,需要从主机位借用 5 位(因为 2^5 = 32)。
- 借 n 位,子网数量 = 2^n
- 借后的子网的主机数和掩码
- 掩码:8+5=/13,即 255.248.0.0
- 主机数量:2^(32-13)-2=524286
