晓铧.

Do more of what makes you happy.

第四周作业

1.通过网络配置命令,让主机可以上网。 ip, netmask, gateway, dns,主机名。相关命令总结,最终可以通过这些配置让你的主机上网

查看网络接口详细信息
​ ip address show是用于显示网络接口配置信息的命令可以简写ip a

    [root@rocky-12 ~]# 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 
       valid_lft forever preferred_lft forever
2: ens160: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 00:0c:29:d4:a1:6e brd ff:ff:ff:ff:ff:ff
    altname enp3s0
    inet 10.0.0.12/24 brd 10.0.0.255 scope global noprefixroute ens160
       valid_lft forever preferred_lft forever
    inet6 fe80::de65:2813:b16c:8bfa/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever
3: ens224: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 00:0c:29:d4:a1:78 brd ff:ff:ff:ff:ff:ff
    altname enp19s0
inet 10.0.0.12/24 brd 10.0.0.255 scope global noprefixroute ens160
  • inet :代表 IPv4 地址信息。
  • 10.0.0.12/24` :分配给该接口的 IPv4 地址是 10.0.0.12,子网掩码长度为 24 位,即子网掩码为 255.255.255.0,这意味着该接口所在的子网范围是从 10.0.0.0 到 10.0.0.255。
  • brd 10.0.0.255 :表示该接口所在子网的广播地址为 10.0.0.255,当需要向整个子网发送广播数据时,就会使用这个地址。
  • scope global :说明该地址的作用范围是全局的,可以在整个网络中进行通信,而不仅仅局限于本机或特定的局部范围。
  • noprefixroute :这个参数表示没有为该地址自动创建前缀路由,前缀路由通常是基于网络前缀(即子网)来自动配置的路由条目,在某些情况下可能不需要系统自动生成此类路由,所以会使用这个参数。
  • ens160 :再次表明这是 ens160 接口。

2.主机名的修改

临时修改

# 查看当前主机名
hostname
# 修改主机名
hostname new_hostname

永久修改

# 编辑 /etc/hostname 文件  注意:new_hostname为你的主机名
echo "new_hostname" > /etc/hostname
# 对于基于 systemd 的系统,还需要更新系统的主机名
hostnamectl set-hostname new_hostname

3.网络的连通性

测试ip与网关

ping 10.0.0.12            # 测试网关连通性
traceroute 8.8.8.8        # 追踪路由路径

测试DNS解析

nslookup magedu.com       # 查询 DNS 解析
dig magedu.com            # 更详细的 DNS 查询

检查网络接口状态

ip addr show eth0         # 查看 IP 配置
ip route show             # 查看路由表

4.网关配置

临时配置

# 使用 route 命令
route add default gw 192.168.112.1

# 使用 ip 路由
ip route add default via 192.168.112.1 dev eth160

永久配置

ubuntu在 /etc/network/interfaces 中添加;CentOS/RHEL:在 /etc/sysconfig/network-scripts/ifcfg-eth0 中添加

gateway 192.168.112.1
DNS配置

临时设置

# 直接写入 resolv.conf
echo "nameserver 8.8.8.8" | sudo tee /etc/resolv.conf

永久设置

sudo sed -i '/nameserver/d' /etc/resolv.conf
echo "nameserver 8.8.8.8" >> /etc/resolv.conf
echo "nameserver 8.8.4.4" >> /etc/resolv.conf

2.解析/etc/sysconfig/network-scripts/ifcfg-eth0配置格式。

vim /etc/sysconfig/network-scripts/ifcfg-eth0
TYPE=Ethernet
PROXY_METHOD=none
BROWSER_ONLY=no
BOOTPROTO=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=ens160
UUID=a094d883-f1a7-4015-9cf6-3dac7d553d19
DEVICE=ens160
ONBOOT=yes
IPADDR=10.0.0.14
PREFIX=24
GATEWAY=10.0.0.2
DNS1=10.0.0.2

配置参数说明

1.TYPE:配置文件接口类型。在/etc/sysconfig/network-scripts/目录有多种网络配置文件,有Ethernet 、IPsec等类型
Ethernetji表明该网络接口类型为以太网
IPsec定义加密隧道、认证规则等安全策略,与具体网卡无关
2.PROXY_METHOD:一般用于定义代理支持的 HTTP 请求方法
none:不限制代理方法,允许所有 HTTP 方法(如 GET、POST、PUT 等)。
get:仅允许通过代理发起 GET 请求。
post:仅允许通过代理发起 POST 请求。
put:仅允许 PUT 请求(常用于文件上传)。
delete:仅允许 DELETE 请求(用于删除资源)。
3.BROWSER_ONLY 通常用于控制是否仅通过浏览器环境执行操
no:不限于浏览器环境,允许非浏览器工具(如命令行、API 调用)。
yes:仅限浏览器环境(如通过浏览器插件或前端脚本执行)。
true:同 yes,布尔值表示启用浏览器限制。
false:同 no,布尔值表示禁用限制
4.BOOTPROTO:定义网卡 IP 地址的获取方式
none:不指定协议,通常与静态 IP 配合使用(需手动配置 IPADDR 等参数)
static:静态 IP 地址(需手动配置 IPADDR、NETMASK、GATEWAY 等)
dhcp:通过 DHCP 动态获取 IP 地址
5.DEFROUTE:是否将该网卡设为默认路由
6.IPV4_FAILURE_FATAL:是否在 IPv4 配置失败时触发系统致命错误
7.IPV6INIT:是否启用 IPv6 协议支持
8.IPV6_AUTOCONF:是否启用 IPv6 地址的无状态自动配置
9.IPV6_DEFROUTE:指定该接口是否为 IPv6 默认路由的出口
10.IPV6_FAILURE_FATAL:控制 IPv6 配置失败时的系统行为
yes:启用默认路由(默认网关生效)。
no:禁用默认路由(需其他网卡设置默认网关
11.NAME=ens160 这里指网络接口名称
12.UUID 网络接口的唯一标识符(UUID)
13.DEVICE 设备名称:eth0
14.ONBOOT 是否自动开启
15.IPADDR ipv4静态地址
16.PREFIX=24 网络前缀长度:24(表示子网掩码为255.255.255.0)
17.GATEWAY 默认网关:10.0.0.2
18.DNS1 DNS服务器地址:10.0.0.2(首选DNS服务器)

3.基于配置文件或命令完成bond0配置

方法一:通过 NetworkManager 命令配置

步骤 1:创建 bond0 接口

nmcli connection add type bond con-name bond0 ifname bond0 mode active-backup miimon 100
连接 "bond0" (4ceb69ce-8516-4291-9d85-e52cd60968e5) 已成功添加。

步骤 2:添加从接口( enslaved interfaces)

[root@rocky-12 ~]# nmcli connection add type bond-slave con-name bond0-port1 ifname ens160 master bond0
nmcli connection add type bond-slave con-name bond0-port2 ifname ens224 master bond0
连接 "bond0-port1" (240fa582-beaf-4b7a-a941-8b6dce89f6e6) 已成功添加。
连接 "bond0-port2" (ea79e49b-618b-41c3-8bec-3ac5bf6541ff) 已成功添加。

步骤 3:配置 IP 地址(静态或 DHCP)

[root@rocky-12 ~]# nmcli connection modify bond0 ipv4.addresses "10.0.0.110/24" \
ipv4.gateway "10.0.0.1" \
ipv4.dns "8.8.8.8 8.8.4.4" \
ipv4.method manual
nmcli connection modify bond0 ipv4.method auto

步骤 4:激活配置

[root@rocky-12 ~]# nmcli connection up bond0
nmcli connection up bond0-port1
nmcli connection up bond0-port2
连接已成功激活(master waiting for slaves)(D-Bus 活动路径:/org/freedesktop/NetworkManager/ActiveConnection/5)
方法二:手动编辑配置文件(适用于传统网络服务

步骤 1:创建 bond0 配置文件

vim /etc/sysconfig/network-scripts/ifcfg-bond0
DEVICE=bond0
TYPE=Bond
NAME=bond0
BONDING_MASTER=yes
BOOTPROTO=none
ONBOOT=yes
IPADDR=192.168.1.10
PREFIX=24
GATEWAY=192.168.1.1
DNS1=8.8.8.8
DNS2=8.8.4.4
BONDING_OPTS="mode=active-backup miimon=100"

步骤 2:配置从接口

sudo vi /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0
TYPE=Ethernet
BOOTPROTO=none
ONBOOT=yes
MASTER=bond0
SLAVE=yes

步骤 3:重启网络服务

sudo systemctl restart network

4.通过ifconfig命令结果找到ip地址.

ifconfig 是一个用于显示和配置网络接口信息的命令,在该命令的输出结果中可以找到网络接口对应的 IP 地址;需通过安装 net-tools 包来使用 ifconfig

ubuntu使用apt,redhat系列使用yum下载

yum install net-tool
[root@openeuler-14 ~]# ifconfig
ens160: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 10.0.0.14  netmask 255.255.255.0  broadcast 10.0.0.255
        inet6 fe80::20c:29ff:fe2e:e70a  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:2e:e7:0a  txqueuelen 1000  (Ethernet)
        RX packets 1155  bytes 403608 (394.1 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 1081  bytes 95644 (93.4 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

每个网络接口的信息块以接口名称开头(如 eth0ens33ens160 等)。在每个信息块中,inet 后面跟着的就是该接口的 IPv4 地址,inet6 后面跟着的则是 IPv6 地址。,ens160 接口的 IPv4 地址是 10.0.0.14,lo(本地回环接口)的 IPv4 地址是 127.0.0.1ether:MAC 地址00:0c:29:2e:e7:0a

5.用脚本判断 你主机所在网络内在线的主机IP有哪些? ping通则在线。

代码如下:

#!/bin/bash
NW=10.0.0.
PREFIX=24
for i in {1..254};do
    IP=$NW$i
    ping -c 1 -w 1 $IP &> /dev/null && echo $IP is 在线 || echo $IP is 不在线
done

执行代码:

[root@rocky-12 ~]# vim test.sh
[root@rocky-12 ~]# ./test.sh 
10.0.0.1 is 不在线
10.0.0.2 is 在线
10.0.0.3 is 不在线
10.0.0.4 is 不在线
10.0.0.5 is 不在线
10.0.0.6 is 不在线
10.0.0.7 is 不在线
10.0.0.8 is 不在线
10.0.0.9 is 不在线
10.0.0.10 is 不在线
10.0.0.11 is 不在线
10.0.0.12 is 在线
10.0.0.13 is 不在线
^Z
[1]+  已停止               ./test.sh

6.使用while read line和/etc/passwd,计算用户id总和。

代码如下:

#!/bin/bash
# 初始化总和变量
total_uid=0
# 逐行读取/etc/passwd文件
while IFS=':' read -r username password uid gid _; do
    # 累加UID到总和
    total_uid=$((total_uid + uid))
done < /etc/passwd
# 输出结果
echo "所有用户UID总和为: $total_uid"

执行代码:

[root@rocky-12 ~]# ./test.sh 
所有用户UID总和为: 118751

7.总结索引数组和关联数组,字符串处理,高级变量使用及示例。

一、索引数组与关联数组

索引数组:使用整数作为索引(从0开始)

# 直接赋值
arr=("apple" "banana" "orange")
# 或逐个赋值
arr[0]="apple"; arr[1]="banana"

关联数组:使用字符串作为键(Bash 4.0+支持)。

declare -A assoc_arr
assoc_arr["name"]="Alice"; assoc_arr["age"]=25
echo ${assoc_arr["name"]}  # 输出: Alice
echo ${!assoc_arr[@]}      # 输出所有键: name age

二、字符串处理

功能 语法 示例
获取字符串长度 ${#str} str="hello"; echo ${#str} → 5
截取子串(起始位置) ${str:position} str="hello"; echo ${str:1} → "ello"
截取子串(起始+长度) ${str:position:length} str="hello"; echo ${str:1:3} → "ell"
删除前缀 ${str#substring} str="hello"; echo ${str#he} → "llo"
删除后缀 ${str%substring} str="hello"; echo ${str%lo} → "hel"
全局替换 ${str//old/new} str="hello"; echo ${str//l/L} → "heLLo"
str="Hello, World!"

# 全部转大写 ${str^^}
echo ${str^^}  # 输出: HELLO, WORLD!

# 全部转小写 ${str,,}
echo ${str,,}  # 输出: hello, world!

# 首字母转大写 ${str^}
echo ${str^}  # 输出: Hello, World!(仅第一个字符大写)

三、高级变量的使用

语法 功能 示例
${var:-default} 变量不存在或为空时返回默认值 echo ${a:-"default"} → "default"
${var:+alternative} 变量存在且非空时返回替代值 a="value"; echo ${a:+yes} → "yes"
${var:?error} 变量不存在或为空时报错并退出 unset a; echo ${a:?Missing} → 报错
${var:offset:length} 截取子串(从offset开始,长度length) str="hello"; echo ${str:1:3} → "ell"

1.位置参数:

# 位置参数: $1, $2, ..., $9, ${10}, ...
# 示例脚本 test.sh: echo "第一个参数: $1, 第二个参数: $2"
# 执行: ./test.sh hello world → 输出: 第一个参数: hello, 第二个参数: world

# 特殊变量
echo "脚本名称: $0"        # 输出: test.sh
echo "参数个数: $#"        # 输出: 2
echo "所有参数: $*"        # 输出: hello world(作为单个字符串)
echo "所有参数: $@"        # 输出: hello world(作为多个字符串)
echo "进程ID: $$"          # 输出: 12345(当前脚本的PID)
echo "最后命令退出状态: $?"  # 输出: 0(成功)或非零值(失败)

2.命令替换

# 方法1:反引号
current_dir=`pwd`

# 方法2:$()(推荐)
files=$(ls -l | wc -l)

echo "当前目录: $current_dir"
echo "文件数量: $files"

8.求10个随机数的最大值与最小值。

代码如下:

#!/bin/bash
# 生成10个1-100的随机数并存入数组
nums=()
for i in {1..10}; do
    nums+=($((RANDOM % 100 + 1)))
done
# 初始化最值
max=${nums[0]}
min=${nums[0]}
# 遍历比较
for num in "${nums[@]}"; do
    if [ $num -gt $max ]; then
        max=$num
    elif [ $num -lt $min ]; then
        min=$num
    fi
done
# 输出结果
echo "生成的随机数: ${nums[@]}"
echo "最大值: $max"
echo "最小值: $min"

执行代码:

[root@rocky-12 ~]# ./test.sh 
生成的随机数: 1 83 27 15 88 31 73 90 19 57
最大值: 90
最小值: 1

9.使用递归调用,完成阶乘算法实现。

代码如下:

#!/bin/bash
# 定义阶乘函数
factorial() {
    local n=$1
    # 基本情况:n=0 或 n=1 时返回 1
    if [[ $n -eq 0 || $n -eq 1 ]]; then
        echo 1
    else
        # 递归调用:n! = n * (n-1)!
        local result=$(factorial $((n-1)))
        echo $((n * result))
    fi
}
# 主程序:获取用户输入并计算阶乘
read -p "请输入一个非负整数: " num

# 检查输入是否为非负整数
if [[ ! $num =~ ^[0-9]+$ ]]; then
    echo "错误:请输入非负整数。"
    exit 1
fi
# 调用阶乘函数并输出结果
result=$(factorial "$num")
echo "$num 的阶乘是: $result"

执行代码:

[root@rocky-12 ~]# ./test.sh 
请输入一个非负整数: 4
4 的阶乘是: 24

10.解析进程和线程的区别? 解析进程的结构。

对比维度 进程(Process) 线程(Thread)
基本定义 进程是操作系统资源分配的基本单位,它 表示一个正在执行的程序实例。每个进程 都有自己独立的代码和数据空间(程序上 下文),以及系统分配的资源,如内存、 文件句柄等。 线程是任务调度和执行的基本单位,它是进 程中的一个执行实体。线程共享进程的资 源,但每个线程都有自己独立的运行栈和程 序计数器(PC)。线程使得程序能够并发执 行多个任务。
资源分配 拥有独立的地址空间、文件描述符、打开的文件、信号处理句柄等系统资源。 共享所属进程的地址空间、全局变量、打开的文件、信号处理逻辑等资源。
地址空间 每个进程有独立的虚拟地址空间(用户空间 + 内核空间),不同进程地址空间隔离。 同一进程内的线程共享用户空间(代码段、数据段、堆),但每个线程有独立的栈空间和寄存器状态。
调度单位 传统 Unix 中进程是调度单位,Linux 中进程和线程统一调度(通过 task_struct 管理)。 是 CPU 调度的最小单位,调度开销远小于进程。
创建与销毁开销 需复制整个地址空间(fork() 时通过写时复制优化,但仍有较大开销)。 仅需分配栈空间、初始化寄存器和线程控制块(TCB),开销极小(约为进程的 1%~10%)。
并发与同步 进程间并发通过 IPC(管道、共享内存、Socket 等)通信,天然隔离,安全性高。 线程间共享资源,需通过互斥锁、条件变量等机制避免竞态条件,同步复杂度高。
独立性 进程间互不干扰,一个进程崩溃不影响其他进程(除非共享内存未正确释放)。 线程崩溃可能导致整个进程崩溃(因共享地址空间)。
系统调用影响 进程的系统调用(如 fork()exec())会创建新的独立实体。 线程的系统调用(如 pthread_create())仅在进程内创建执行流,不改变地址空间。
典型应用场景 多进程:需要强隔离性(如 Docker 容器、守护进程); 单进程多实例:如多个 vim 窗口。 多线程:高性能并发(如 Web 服务器处理多个请求)、共享数据的高效协作(如视频解码模块)。

包含关系

一个进程可以拥有多个线程,但一个线程只能属于一个进程。线程是进程的一部分,也被称为轻量级进程

资源分配

进程拥有独立的内存单元和资源,而线程则共享进程的资源。这使得线程在切换时开销较小,因为不需要
切换整个进程的上下文。
一个进程的崩溃通常不会影响到其他进程(除了一些特殊情况,如共享内存被破坏等)。而线程的独立性
相对较低,由于它们共享进程的资源,如果一个线程出现错误,可能会影响到整个进程的运行,甚至导致进程
崩溃。例如,一个线程在访问共享资源时出现越界访问等错误,可能会破坏进程的地址空间,导致其他线程也
无法正常运行。

并发和并行

并发:
进程和线程都可以实现并发执行。并发是指多个任务在同一时间段内交替执行,而不是同时执行。进程并
发通常通过时间片轮转等调度算法来实现。
并行:
线程更易于实现并行执行,因为线程间的切换开销较小。并行是指多个任务在同一时间段内同时执行,这
通常需要多核处理器或超线程技术的支持。多个线程在同一进程内并发执行,可以充分利用多核处理器的优
势,提高程序的执行效率。

1.进程控制块(PCB)

  • 数据结构:

    task_struct是内核中表示进程的核心数据结构,包含进程状态、PID、父进程指针、优先级、内存映射等信息
    
  • 关键字段:

    • pid:进程唯一标识符。
    • mm_struct:指向内存描述符,管理进程的地址空间(代码段、数据段、堆、栈)。
    • thread_group:线程组信息,同一进程的线程共享此结构。
    • state:进程状态(如R就绪、S睡眠、Z僵尸)。

2. 内存布局

  • 用户空间(3GB):
    • 代码段(.text):只读区域,存放程序指令。
    • 数据段(.data):存储已初始化的全局变量和静态变量。
    • BSS段:存储未初始化的全局变量和静态变量。
    • 堆(Heap):动态内存分配区域,通过malloc()/free()管理。
    • 栈(Stack):存储函数调用上下文(局部变量、返回地址)。
  • 内核空间(1GB):存放内核代码和数据,进程通过系统调用进入此区域。

3. 进程状态与转换

  • 主要状态
    • R(运行中/就绪):可被CPU调度执行。
    • S(可中断睡眠):等待资源(如I/O操作)。
    • D(不可中断睡眠):通常因磁盘I/O阻塞,无法被信号中断。
    • T(停止):因信号(如SIGSTOP)暂停。
    • Z(僵尸态):已终止但父进程未回收资源。
  • 状态转换:通过调度器、信号、资源释放等触发。

4. 进程间关系

  • 进程树:通过fork()创建的子进程形成树状结构,init进程(PID 1)为根节点。
  • 线程组:同一进程的线程共享task_structtgid(线程组ID),表现为单一线程组

11.结合进程管理命令,说明进程各种状态。

状态 符号 描述 查看命令 管理命令
运行态 R 正在运行或就绪(等待CPU调度) `ps aux grep R<br>top`
睡眠态 S 可中断睡眠(等待I/O或信号) `ps -eo stat grep S`
不可中断睡眠 D 等待I/O完成(无法被信号中断) `ps -eo stat grep D`
停止态 T 被信号暂停(如SIGSTOP `ps -eo stat grep T`
僵尸态 Z 进程已终止但未被父进程回收 `ps -eo stat grep Z`

12.说明IPC通信和RPC通信实现的方式。

一、IPC(进程间通信)的实现方式
  1. 管道(Pipe)
  • 原理:基于文件描述符的半双工通信管道,分为无名管道和命名管道
    • 无名管道:仅用于有血缘关系的进程(如父子进程),生命周期随父进程结束而销毁。
    • 命名管道:通过文件系统中的路径(如/tmp/pipe_fifo)创建,支持无血缘关系进程通信,删除文件后管道失效。
  • 特点:简单易用,但单向传输、缓冲区大小固定(通常 4KB)、不支持消息边界。
  • 示例ps aux | grep ssh|即为无名管道,将前一个进程输出传递给后一个进程。
2. 消息队列(Message Queue)
  • 原理:内核维护的消息链表,每个消息有类型和数据内容,进程通过msgsnd/msgrcv读写。
  • 特点:支持消息类型过滤、异步通信,避免管道的同步阻塞;但存在内核空间与用户空间的数据拷贝开销。
  • 系统调用msgget(创建 / 获取队列)、msgsnd(发送消息)、msgrcv(接收消息)。
3. 共享内存(Shared Memory)
  • 原理:多个进程映射同一段物理内存,直接读写数据(无需内核拷贝),需配合信号量 / 互斥锁实现同步。
  • 特点:IPC 中速度最快(无数据拷贝),适合大量数据交换;但需手动处理同步和内存释放(避免内存泄漏)。
  • 系统调用shmget(创建共享内存)、shmat(映射到进程地址空间)、shmdt(解除映射)。
4. 信号量(Semaphore)
  • 原理:内核维护的计数器,用于进程间同步(如互斥访问共享资源),分为二元信号量(互斥锁)和计数信号量(资源计数)。
  • 特点:不传输数据,仅控制资源访问顺序,常与共享内存配合使用。
  • 系统调用semget(创建信号量)、semop(PV 操作)、semctl(控制信号量)。
5. 信号(Signal)
  • 原理:异步通知机制(如SIGINT中断进程),用于简单事件通知(如进程终止、硬件异常)。
  • 特点:仅能传递有限类型的信号(如 1~31 为标准信号,34~64 为实时信号),不适合数据传输。
  • 示例kill -9 <PID> 发送SIGKILL信号强制终止进程。
6. 套接字(Socket)

原理:支持本地(AF_UNIX)和网络(AF_INET)通信,本地套接字通过文件系统路径(如/tmp/socket.sock)实现同一主机进程通信。

特点:通用、支持全双工通信,可跨语言 / 跨平台;但相比共享内存等方式,存在轻微的协议处理开销。

应用场景:本地微服务间通信(如 Docker 容器通过本地套接字通信)。

RPC(远程过程调用)的实现方式

基本实现流程

  • 客户端桩(Stub):将本地调用参数序列化为网络消息。
  • 服务端骨架(Skeleton):接收消息、反序列化参数并调用实际服务。
  • 通信协议:如TCP/UDP,处理数据传输和错误重试。

13.总结Linux,前台和后台作业的区别,并说明如何在前台和后台中进行状态转换。

维度 前台作业(Foreground Job) 后台作业(Background Job)
终端交互 独占终端输入/输出(如vim编辑文件时,无法同时运行其他命令) 不占用终端,运行时无交互(如sleep 100 &在后台运行)
资源占用 高优先级,直接占用CPU和I/O资源 低优先级,与终端解耦,可与其他后台任务并行
信号响应 接收用户信号(如Ctrl+C终止、Ctrl+Z挂起) 默认忽略Ctrl+C,但可被kill命令终止
终端依赖 关闭终端会发送SIGHUP信号终止进程 独立于终端,关闭终端后仍可运行(需配合nohupdisown
启动方式 直接执行命令(如./program 命令末尾加&(如./program &)或通过bg命令切换
  1. jobs:列出当前终端的所有作业,显示作业编号、状态(如 RunningStopped)和命令
jobs  # 列出所有后台作业
jobs -l # 显示作业的进程ID(PID)
  1. bg <作业编号>:将挂起(Stopped)的后台作业恢复为运行状态。

    bg %1           # 将作业号1的进程恢复为后台运行
    
  2. fg <作业编号>:将后台作业(挂起或运行)调至前台运行。

    fg %1           # 将作业号1的进程切换到前台
    
  3. %作业编号:引用作业(如 %1 表示第一个作业,%+ 表示当前作业,%- 表示前一个作业)

    符号 含义 示例 操作结果
    %1 作业号为1的任务 bg %1 将作业1放到后台运行
    %+ 当前最近的后台任务(默认%1 fg %+ 调回最近的后台任务到前台
    %- 前一个后台任务(作业号递减) fg %- 调回次近的后台任务到前台

14.实现定时任务,每日凌晨1点,删除指定文件(自己创建即可)

#创建测试文件
mkdir -p /tmp/delete_me
touch /tmp/delete_me/file.txt
# 打开定时任务编辑器
crontab -e
# 添加一行(按 i 进入编辑模式)
0 1 * * * rm -rf /tmp/delete_me/*
# 保存退出(按 Esc,输入 :wq,回车)

15.实现定时任务每月月初对指定文件进行压缩(自己创建文件)

#创建测试文件
mkdir -p /data/logs
touch /data/logs/app_{1..5}.log
# 打开定时任务编辑器
crontab -e
# 添加一行
0 0 1 * * tar -czf /data/logs/$(date +\%Y\%m)_logs.tar.gz /data/logs/*.log && rm -f /data/logs/*.log
# 保存退出(按 Esc,输入 :wq,回车)

16.通过shell编程完成,30鸡和兔的头,80鸡和兔的脚,分别有几只鸡,几只兔?

执行代码

#!/bin/bash

#输入总头数和总脚数
head=30
foot=80
rabbit=$(( ( foot - 2 * head ) / 2 ))
chicken=$((head - rabbit ))

#输出结果
echo "鸡的数量:$chicken"
echo "兔的数量:$rabbit"

执行结果

[root@rocky-12 ~]# chmod u+x test.sh
[root@rocky-12 ~]# ./test.sh
鸡的数量:20
兔的数量:10

17.结合编程的for循环,条件测试,条件组合,完成批量创建100个用户

1)for遍历1..100
2)先id判断是否存在
3)用户存在则说明存在,用户不存在则添加用户并说明已添加。

执行代码

#!/bin/bash

# 遍历 1 到 100
for i in $(seq 1 100); do
    username="user$i"
    # 使用 id 命令判断用户是否存在
    if id "$username" &>/dev/null; then
        echo "用户 $username 已存在。"
    else
        # 添加用户
        useradd "$username"
        if [ $? -eq 0 ]; then
            echo "用户 $username 已添加。"
        else
            echo "添加用户 $username 失败。"
        fi
    fi
done9

执行结果

[root@rocky-12 ~]# ./test.sh
用户 user1 已添加。
用户 user2 已添加。
用户 user3 已添加。
用户 user4 已添加。
用户 user5 已添加。
用户 user6 已添加。
用户 user7 已添加。
用户 user8 已添加。
用户 user9 已添加。
用户 user10 已添加
^C

18.练习题:联系top,htop, iotop,iostat等课程相关工具的使用

  1. top 是动态监控系统进程和资源的核心工具,支持交互式操作。

    top [选项]
        -d 5:设置刷新间隔为5秒。
    	-b:批处理模式(输出到文件)。
    	-p 1234:监控指定进程。
    
    字段 含义 示例
    %CPU 进程占用CPU百分比(动态刷新) 0.3%
    %MEM 进程占用物理内存百分比 2.1%
    STAT 进程状态(R=运行,S=睡眠,Z=僵尸) S
    TIME+ 进程累计CPU时间 00:00.12
    COMMAND 进程名称或命令行 nginx: master
  2. htoptop的升级版,提供更友好的界面和高级功能。

    # 安装(CentOS)
    sudo yum install htop
    # 启动
    htop
    
  3. iotop 专用于监控进程的磁盘I/O活动,定位高负载进程。

    # 安装(Ubuntu)
    sudo apt install iotop
    # 启动(仅显示有I/O的进程)
    iotop -o
    
    字段 含义 示例
    DISK READ 磁盘读取速率(KB/s) 1.20 K/s
    DISK WRITE 磁盘写入速率(KB/s) 3.45 K/s
    IO% I/O等待时间占比(高值表示瓶颈) 85%
    TID 线程ID(与进程ID关联) 3411
  4. iostat 提供CPU和磁盘I/O的统计信息,适合长期性能监控。

# Ubuntu/Debian
sudo apt install sysstat

# CentOS/RHEL
sudo yum install sysstat

iostat -x 1      # 每秒显示一次扩展统计信息(-x参数显示详细磁盘指标)
iostat -c 1      # 只显示CPU统计信息
iostat -d sda 1  # 只显示sda磁盘的信息

19.练习课程中awk的使用

一、Awk 基础语法

awk '模式 { 动作 }' 文件名
awk '/error/ {print}' log.txt                               #打印包含 "error" 的行
awk -F: '$3 > 30 {print $1}' /etc/passwd                    # 打印年龄大于30的用户
awk -v RS='\0' -F'\t' '{print $1, $2}'                      # RS设为NULL字符,按制表符分割
变量 说明 示例
$0 当前行完整内容 `echo "abc"
$n 第n个字段(默认分隔符为空格) `echo "a b c"
NR 当前行号 `seq 3
NF 当前字段数 `echo "a b"
FS 输入字段分隔符(默认空格) awk -F',' '{print $1}' data.csv
OFS 输出字段分隔符(默认空格) `awk 'BEGIN{OFS="
  • BEGIN 块:在处理输入前执行(仅一次)。

  • 主循环:对每一行执行一次。

  • END 块:处理完所有输入后执行(仅一次)

    # 格式化数字和字符串
    awk '{printf "%-10s %10.2f\n", $1, $2*1.5}' data.txt
    # %-10s:左对齐字符串,宽度10
    # %10.2f:右对齐浮点数,宽度10,保留2位小数
    
posted @ 2025-05-12 12:00  晓铧  阅读(97)  评论(0)    收藏  举报