Week3-2026-01-27
Week3-2026-01-27
总结变量命名规则,不同类型变量(环境变量,位置变量,只读变量,局部变量,状态变量)如何使用。
#命名规则:
变量名通常只能包含字母(A-Z, a-z)、数字(0-9)和下划线(_),并且不能以数字开头
大小写敏感:大多数现代语言中的变量名是区分大小写的,这意味着myVar和myvar会被视为两个不同的变量。
避免保留字:变量名不应与语言的关键字(保留字)相同,因为这会导致语法错误或覆盖内置功能。
有意义的名字:变量名应该具有描述性,能够反映它所代表的数据的意义。
命名约定:根据不同的上下文,采用合适的命名约定,如驼峰式(camelCase)、帕斯卡命名法(PascalCase)或者下划线分隔(snake_case)等。
#环境变量
环境变量是在操作系统层面定义的,它们影响着程序运行时的行为。环境变量命名通常遵循以下规范:
使用全大写字母以提高可读性。
多个单词之间用下划线分隔。
避免使用特殊字符,只使用字母、数字和下划线。
保持简洁且具有描述性。
避免与系统已有的环境变量名冲突。
例如,在Debian系统中,常见的环境变量有PATH, HOME, USER等。
#位置变量(预定义变量)
位置变量是指那些用于向脚本传递参数的变量。这些变量的名字通常是固定的,比如在Shell脚本中,$0代表脚本名称,$1到$9代表传递给脚本的前九个参数。
#只读变量
只读变量一旦被赋值就不能再改变其值。创建只读变量时,除了要遵守一般的变量命名规则外,还需要使用特定的关键字如readonly来声明。
例如,在Bash中可以这样创建一个只读变量:
readonly PI=3.14
#局部变量
局部变量是在函数或代码块内部声明的变量,它们的作用域仅限于该函数或代码块内。局部变量同样需要遵守基本的命名规则,并且最好能够清晰地表达变量的目的。
#状态变量
状态变量通常用来保存程序执行过程中的某些状态信息。它们可以是任何类型的变量,但关键在于它们的用途。状态变量的命名应当明确表达其所代表的状态,以便于理解和调试。
综上所述,变量命名不仅关乎语法正确性,还直接影响到代码的质量。理解并遵循适当的命名规则以及合理利用不同类型的变量对于编写高质量的软件至关重要。在实际开发过程中,开发者还应参考具体编程语言或环境的具体要求,以确保变量命名符合最佳实践。
编写一个脚本猜数字,使用判断提示用户比目标数字是大还是小
root@test-VirtualBox:~# cat cainum.sh
#!/bin/bash
#简单的猜数脚本
num=$[RANDOM%100+1]
while :
do
read -p "计算机生成了一个1-100的随机数字,请输入你猜测的数字:" num1
if [ "$num1" -eq "$num" ]
then
echo "你真聪明,猜对了!"
exit
elif [ "$num1" -gt "$num" ]
then
echo "猜大了!"
else
echo "猜小了!"
fi
done
使用while read line和/etc/passwd,计算用户id总和。
root@test-VirtualBox:~/week3# /bin/bash calcpasswd.sh
系统所有用户的 UID 总和为: 72500
root@test-VirtualBox:~/week3# cat calcpasswd.sh
#!/bin/bash
# 初始化总和变量
total_uid_sum=0
# 使用 while read 逐行读取 /etc/passwd 文件
while IFS=':' read -r username password uid gid user_info home_dir shell; do
# 检查 UID 是否为数字,以避免非有效数据
if [[ "$uid" =~ ^[0-9]+$ ]]; then
# 累加用户 ID
total_uid_sum=$((total_uid_sum + uid))
fi
done < /etc/passwd
# 输出最终的用户 ID 总和
echo "系统所有用户的 UID 总和为: $total_uid_sum"
总结索引数组和关联数组,字符串处理,高级变量使用及示例。
索引数组使用整数索引,支持空缺索引和动态添加 。
关联数组必须使用 declare -A 声明,支持字符串键 。
字符串处理支持截取、替换、删除前后缀等操作 。
高级变量包括只读变量、整型变量、局部变量等 。
求10个随机数的最大值与最小值。
#!/bin/bash
# 初始化数组保存随机数
random_numbers=()
# 初始化最大值和最小值变量
max=0
min=0
echo "生成的10个随机数如下:"
# 生成10个随机数并进行比较
for ((i=1; i<=10; i++))
do
num=$RANDOM
random_numbers+=($num)
# 第一次循环初始化最大值和最小值
if [ $i -eq 1 ]; then
max=$num
min=$num
fi
# 更新最大值和最小值
if [ $num -gt $max ]; then
max=$num
fi
if [ $num -lt $min ]; then
min=$num
fi
# 打印当前生成的数字
echo "第$i个随机数: $num"
done
# 输出结果
echo "------------------------"
echo "所有随机数: ${random_numbers[@]}"
echo "最大值: $max"
echo "最小值: $min"
root@test-VirtualBox:~/week3# /bin/bash rand.sh
生成的10个随机数如下:
第1个随机数: 6601
第2个随机数: 32159
第3个随机数: 26244
第4个随机数: 10805
第5个随机数: 6409
第6个随机数: 22513
第7个随机数: 13935
第8个随机数: 21174
第9个随机数: 21413
第10个随机数: 4578
------------------------
所有随机数: 6601 32159 26244 10805 6409 22513 13935 21174 21413 4578
最大值: 32159
最小值: 4578
使用递归调用,完成阶乘算法实现。
root@test-VirtualBox:~/week3# cat jiec.sh
#!/bin/bash
# 定义递归函数计算阶乘
factorial() {
local n=$1
# 基准条件:0! 和 1! 都等于 1
if [ $n -le 1 ]; then
echo 1
else
# 递归调用:n! = n * (n-1)!
local prev=$(factorial $((n - 1)))
echo $((n * prev))
fi
}
# 主程序入口
main() {
read -p "请输入一个非负整数以计算其阶乘: " num
# 输入验证:是否为非负整数
if [[ "$num" =~ ^[0-9]+$ ]]; then
result=$(factorial $num)
echo "$num! = $result"
else
echo "输入无效,请输入一个非负整数。"
exit 1
fi
}
# 调用主函数
main
root@test-VirtualBox:~/week3# /bin/bash jiec.sh
请输入一个非负整数以计算其阶乘: 4
4! = 24
通过shell编程完成,30鸡和兔的头,80鸡和兔的脚,分别有几只鸡,几只兔?
root@test-VirtualBox:~/week3# cat jitu.sh
#!/bin/bash
# 鸡兔同笼问题求解
# 已知条件:
# 总头数 = 30
# 总脚数 = 80
# 定义变量
total_heads=30
total_feet=80
# 遍历鸡的数量(从0到30)
for ((chickens=0; chickens<=total_heads; chickens++)); do
rabbits=$((total_heads - chickens)) # 计算兔的数量
feet=$((chickens * 2 + rabbits * 4)) # 计算总脚数
# 判断是否符合脚数条件
if [ "$feet" -eq "$total_feet" ]; then
echo "找到解:"
echo "鸡的数量: $chickens 只"
echo "兔的数量: $rabbits 只"
exit 0
fi
done
# 如果没有找到解
echo "无解!请检查输入条件是否正确。"
root@test-VirtualBox:~/week3# /bin/bash jitu.sh
找到解:
鸡的数量: 20 只
兔的数量: 10 只
结合编程的for循环,条件测试,条件组合,完成批量创建100个用户,
1)for遍历1..100
2)先id判断是否存在
3)用户存在则说明存在,用户不存在则添加用户并说明已添加。
root@test-VirtualBox:~/week3# cat cuser.sh
#!/bin/bash
# 批量创建100个用户脚本
# 用户名格式:user1, user2, ..., user100
# 使用 for 循环遍历数字1到100
for i in {1..100}; do
username="user$i"
# 使用 id 命令判断用户是否存在
if id "$username" &>/dev/null; then
echo "用户 $username 已存在,跳过创建。"
else
# 用户不存在,使用 useradd 创建用户
useradd "$username"
echo "成功创建用户: $username"
fi
done
root@test-VirtualBox:~/week3# /bin/bash cuser.sh
成功创建用户: user1
.
.
.
.
成功创建用户: user100
root@test-VirtualBox:~/week3# /bin/bash cuser.sh
用户 user1 已存在,跳过创建。
.
.
.
.
用户 user100 已存在,跳过创建。
解析进程和线程的区别? 解析进程的结构。
进程
操作系统的进行资源分配的基本单位,是一个程序的一次执行过程,有父进程和子进程之分,可用kill命令(子进程)或killall命令(父进程)来结束程序的进程
线程
是进程内的调度和执行的基本单位,一个进程可以包含多个线程。线程共享进程的资源,但每个线程有自己独立的栈、寄存器状态和程序计数器
结合进程管理命令,说明进程各种状态。
根据kill命令相关的信号指标,常用的进程状态基本上有如下几种:
1) 无需关闭进程而让其重读配置文件
2) 中止正在运行的进程,相当于ctrl+c
3) 相当于ctrl+\
9) 强制杀死正在运行的进程,可能会导致数据丢失,慎用
15) 终止正在运行的进程,默认信号
18) 继续运行
19) 后台休眠
说明IPC通信和RPC通信实现的方式。
IPC通信(进程间通信) RPC通信(远程过程调用)
| 特性 | IPC(本地) | RPC(远程) |
|---|---|---|
| 通信范围 | 同一主机进程间 | 跨主机或网络服务间 |
| 性能 | 高 | 依赖网络,有延迟需要带宽 |
| 实现复杂度 | 简单 | 复杂 |
| 同步机制 | 内核或用户态同步 | 通常需框架支持 |
| 数据传输方式 | 共享内存、管道、消息队列 | TCP、HTTP等 |
| 适用场景 | 本地服务通信、系统调用 | 微服务、分布式系统 |
总结Linux,前台和后台作业的区别,并说明如何在前台和后台中进行状态转换。
sleep 10000 & #当前终端下放到后台运行,终端结束,任务也结束
nohup sleep 10000 >> /dev/null 2>&1 & #后台执行的程序信息无论正确还是错误全部放入/dev/null,关闭终端,任务依然还在
#任务的前后台切换及结束
root@test-VirtualBox:~# sleep 10000
^Z
[1]+ 已停止 sleep 10000
root@test-VirtualBox:~# bg
[1]+ sleep 10000 &
root@test-VirtualBox:~# jobs
[1]+ 运行中 sleep 10000 &
root@test-VirtualBox:~# kill %1
root@test-VirtualBox:~# jobs
[1]+ 已终止 sleep 10000
root@test-VirtualBox:~# fg
-bash: fg: 当前: 无此任务
实现定时任务,每日凌晨1点,删除指定文件(自己创建即可)
root@test-VirtualBox:~/week3/logs# cat dellog.sh
#!/bin/bash
# 设置要删除的文件路径
LOG_FILE="/root/week3/logs"
# 设置日志路径(用于记录执行情况)
LOG_OUTPUT="/var/log/clean_log_output.log"
# 写入开始时间
echo "[$(date '+%Y-%m-%d %H:%M:%S')] 开始执行删除任务..." >> "$LOG_OUTPUT"
# 判断文件是否存在
if [ -f "$LOG_FILE" ]; then
rm -f "$LOG_FILE"
if [ $? -eq 0 ]; then
echo "[$(date '+%Y-%m-%d %H:%M:%S')] 文件 $LOG_FILE 删除成功" >> "$LOG_OUTPUT"
else
echo "[$(date '+%Y-%m-%d %H:%M:%S')] 文件 $LOG_FILE 删除失败" >> "$LOG_OUTPUT"
fi
else
echo "[$(date '+%Y-%m-%d %H:%M:%S')] 文件 $LOG_FILE 不存在,跳过删除" >> "$LOG_OUTPUT"
fi
root@test-VirtualBox:~/week3/logs# crontab -e
root@test-VirtualBox:~/week3/logs# cat /var/spool/cron/crontabs/root
# DO NOT EDIT THIS FILE - edit the master and reinstall.
# (/tmp/crontab.FaKASr/crontab installed on Tue Jan 27 20:48:50 2026)
# (Cron version -- $Id: crontab.c,v 2.13 1994/01/17 03:20:37 vixie Exp $)
# Edit this file to introduce tasks to be run by cron.
#
# Each task to run has to be defined through a single line
# indicating with different fields when the task will be run
# and what command to run for the task
#
# To define the time you can provide concrete values for
# minute (m), hour (h), day of month (dom), month (mon),
# and day of week (dow) or use '*' in these fields (for 'any').
#
# Notice that tasks will be started based on the cron's system
# daemon's notion of time and timezones.
#
# Output of the crontab jobs (including errors) is sent through
# email to the user the crontab file belongs to (unless redirected).
#
# For example, you can run a backup of all your user accounts
# at 5 a.m every week with:
# 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/
#
# For more information see the manual pages of crontab(5) and cron(8)
#
# m h dom mon dow command
0 1 * * * /root/week3/logs/dellog.sh
实现定时任务每月月初对指定文件进行压缩(自己创建文件)
root@test-VirtualBox:~/week3/tar# cat tar_m.sh
#!/bin/bash
# 设置压缩目标路径
SOURCE_DIR="/root/week3/tar"
BACKUP_DIR="/root/week3/bak"
DATE=$(date +"%Y%m%d")
ARCHIVE_NAME="backup_$DATE.tar.gz"
LOG_FILE="/var/log/monthly_compress.log"
# 写入日志
echo "[$(date '+%Y-%m-%d %H:%M:%S')] 开始执行压缩任务..." >> "$LOG_FILE"
# 检查源目录是否存在
if [ -d "$SOURCE_DIR" ]; then
# 执行压缩
tar -czf "$BACKUP_DIR/$ARCHIVE_NAME" -C "$(dirname "$SOURCE_DIR")" "$(basename "$SOURCE_DIR")"
if [ $? -eq 0 ]; then
echo "[$(date '+%Y-%m-%d %H:%M:%S')] 压缩成功: $BACKUP_DIR/$ARCHIVE_NAME" >> "$LOG_FILE"
else
echo "[$(date '+%Y-%m-%d %H:%M:%S')] 压缩失败" >> "$LOG_FILE"
fi
else
echo "[$(date '+%Y-%m-%d %H:%M:%S')] 源目录 $SOURCE_DIR 不存在" >> "$LOG_FILE"
fi
root@test-VirtualBox:~/week3/tar# crontab -e
root@test-VirtualBox:~/week3/tar# cat /var/spool/cron/crontabs/root
# DO NOT EDIT THIS FILE - edit the master and reinstall.
# (/tmp/crontab.FaKASr/crontab installed on Tue Jan 27 20:48:50 2026)
# (Cron version -- $Id: crontab.c,v 2.13 1994/01/17 03:20:37 vixie Exp $)
# Edit this file to introduce tasks to be run by cron.
#
# Each task to run has to be defined through a single line
# indicating with different fields when the task will be run
# and what command to run for the task
#
# To define the time you can provide concrete values for
# minute (m), hour (h), day of month (dom), month (mon),
# and day of week (dow) or use '*' in these fields (for 'any').
#
# Notice that tasks will be started based on the cron's system
# daemon's notion of time and timezones.
#
# Output of the crontab jobs (including errors) is sent through
# email to the user the crontab file belongs to (unless redirected).
#
# For example, you can run a backup of all your user accounts
# at 5 a.m every week with:
# 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/
#
# For more information see the manual pages of crontab(5) and cron(8)
#
# m h dom mon dow command
0 1 * * * /root/week3/logs/dellog.sh
0 0 1 * * /root/week3/tar/tar_m.sh
总结内核设计流派及特点。
| 对比维度 | 单内核(Monolithic Kernel) | 微内核(Micro Kernel) | 混合内核(Hybird Kernel) |
|---|---|---|---|
| 核心设计目标 | 高性能有限,集成所有核心功能以减少模块通信开销 | 高稳定性与安全性有限,通过极简内核隔离故障影响 | 平衡性能与灵活性,核心功能保效率,非核心功能可动态调整 |
| 功能部署位置 | 进程调度、内存管理、文件系统、设备驱动等所有核心功能全在内核空间运行 | 仅保留进程调度、内存管理、IPC等最基础功能在内核空间,文件系统、驱动等全在用户空间以服务运行。强制拆分功能到用户空间,牺牲部分性能换稳定性。 | 基础核心功能(进程、内存管理)在内核空间,驱动、文件系统等可灵活选择内核/用户空间(或通过动态模块加载) |
| 模块通信方式 | 模块间直接函数调用(同一内核空间,无跨空间通信开销) | 强制通过进程间通信(IPC)实现模块交互(用户太服务于内核、服务之间均需IPC),兼顾性能与扩展性。 | 内核空间内模块直接调用,跨空间模块按需使用IPC或动态加载机制 |
| 典型代表系统 | Linux(传统架构)、BSD、早期Unix | QNX、Minix、早期WindowsNT设计 | Windows(NT之后架构)、Linux(通过LKM实现类混合特性) |
| 核心优势 | 性能高(减少IPC通信损耗,适合服务器、嵌入式等效率敏感场景);实现简单(功能集中,无需复杂通信机制) | 稳定性强(用户态服务崩溃不影响内核,适合汽车电子、医疗设备等高可靠场景);权限隔离严格(安全性高) | 兼顾性能(核心功能内核态高效运行)与灵活(非核心功能可动态扩展,无需重启内核);适配场景广(桌面、服务器、嵌入式均可优化) |
| 核心缺点 | 耦合度高(修改功能需重编内核并重启,灵活性差);风险集中(内核故障易导致系统整体崩溃) | 性能开销大(频繁IPC通信降低效率,复杂场景下性能低于单内核);开发复杂(需设计高效IPC机制) | 设计复杂(需权衡功能部署边界,避免内核态膨胀);调试难度高(跨空间交互问题定位困难) |
通过网络配置命令,让主机可以上网。 ip, netmask, gateway, dns,主机名。相关命令总结,最终可以通过这些配置让你的主机上网。
[root@localhost ~]# cat /etc/sysconfig/network-scripts/ifcfg-enp0s3
TYPE=Ethernet
PROXY_METHOD=none
BROWSER_ONLY=no
BOOTPROTO=dhcp #启动协议:dhcp为自动获取,static或none表示静态,需要自己手动指定
DEFROUTE=yes #默认路由:是
IPV4_FAILURE_FATAL=no
IPV6INIT=yes
IPV6_AUTOCONF=yes
IPV6_DEFROUTE=yes
IPV6_FAILURE_FATAL=no
IPV6_ADDR_GEN_MODE=eui64
NAME=enp0s3 #可改可不改
UUID=76d6da72-19fb-4c60-b3c4-07309bdc0f94 #设备唯一的标识
DEVICE=enp0s3
ONBOOT=yes #开机是否直接启动
[root@localhost ~]# nmcli device
DEVICE TYPE STATE CONNECTION
enp0s3 ethernet 已连接 enp0s3
lo loopback 连接(外部) lo
enp0s8 ethernet 已断开 --
[root@localhost ~]# nmcli device up enp0s8
设备 "enp0s8" 成功以 "8dea5c21-f4b7-43ba-9d3e-6116fbde4683" 激活。
[root@localhost ~]# ls /etc/sysconfig/network-scripts/
ifcfg-enp0s3 ifcfg-enp0s8
[root@localhost ~]# nmcli device
DEVICE TYPE STATE CONNECTION
enp0s3 ethernet 已连接 enp0s3
enp0s8 ethernet 已连接 enp0s8
lo loopback 连接(外部) lo
#默认网卡重启NetworkManager服务即可
[root@localhost ~]# vim /etc/sysconfig/network-scripts/ifcfg-enp0s8
#对于新增的网卡
[root@localhost ~]# nmcli device down enp0s8
成功断开设备 "enp0s8"。
[root@localhost ~]# nmcli device up enp0s8
设备 "enp0s8" 成功以 "00cb8299-feb9-55b6-a378-3fdc720e0bc6" 激活。
[root@localhost ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host noprefixroute
valid_lft forever preferred_lft forever
2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 08:00:27:71:75:26 brd ff:ff:ff:ff:ff:ff
inet 10.0.2.15/24 brd 10.0.2.255 scope global dynamic noprefixroute enp0s3
valid_lft 86277sec preferred_lft 86277sec
inet6 fd17:625c:f037:2:a00:27ff:fe71:7526/64 scope global dynamic noprefixroute
valid_lft 86279sec preferred_lft 14279sec
inet6 fe80::a00:27ff:fe71:7526/64 scope link noprefixroute
valid_lft forever preferred_lft forever
3: enp0s8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 08:00:27:06:f1:e6 brd ff:ff:ff:ff:ff:ff
inet 192.168.3.250/24 brd 192.168.3.255 scope global noprefixroute enp0s8
valid_lft forever preferred_lft forever
inet6 fe80::a00:27ff:fe06:f1e6/64 scope link proto kernel_ll
valid_lft forever preferred_lft forever
#上述操作之后IP地址已经更改
解析/etc/sysconfig/network-scripts/ifcfg-eth0配置格式。
[root@localhost ~]# cat /etc/sysconfig/network-scripts/ifcfg-enp0s3
TYPE=Ethernet
PROXY_METHOD=none
BROWSER_ONLY=no
BOOTPROTO=dhcp #启动协议:dhcp为自动获取,static或none表示静态,需要自己手动指定
DEFROUTE=yes #默认路由:是
IPV4_FAILURE_FATAL=no
IPV6INIT=yes
IPV6_AUTOCONF=yes
IPV6_DEFROUTE=yes
IPV6_FAILURE_FATAL=no
IPV6_ADDR_GEN_MODE=eui64
NAME=enp0s3 #可改可不改
UUID=76d6da72-19fb-4c60-b3c4-07309bdc0f94 #设备唯一的标识
DEVICE=enp0s3
ONBOOT=yes #开机是否直接启动
基于配置文件或命令完成bond0配置
暂时不会,后续再补
通过ifconfig命令结果找到ip地址.
root@test-VirtualBox:~/week3/tar# ifconfig | grep inet | head -n 1
inet 10.0.2.15 netmask 255.255.255.0 broadcast 10.0.2.255
使用脚本判断 你主机所在网络内在线的主机IP有哪些? ping通则在线。
暂时不会,后续再补
浙公网安备 33010602011771号