零基础开始的网工之路第十九天------shell编程实战

目录

题目一:系统信息收集脚本

题目二:用户管理配置脚本

题目三:磁盘空间管理脚本

题目四:网络配置检查脚本

题目五:系统日志分析脚本


题目一:系统信息收集脚本

编写一个脚本名为 collect_system_info.sh,实现以下功能:

  1. 收集系统的基本信息,包括但不限于操作系统版本、内核版本、主机名,并将这些信息输出到一个名为 system_info.txt 的文件中,每个信息占一行,并加上清晰的说明标签。

  2. 统计当前系统中正在运行的进程数量,并将结果追加到 system_info.txt 文件中,格式为“正在运行的进程数量:[具体数量]”。

  3. 使用合适的命令查找系统中占用 CPU 资源最多的前 5 个进程(如果系统有相关命令支持的话),并将它们的进程 ID 和进程名称输出到 system_info.txt 文件中,格式为“占用 CPU 多的进程:进程 ID - 进程名称”,每个进程占一行。如果系统无法直接找出前 5 个,可根据实际情况尽可能多地找出占用高的进程展示。

解:

[root@bogon ~]# vim collect_system_info.sh
​
echo "内核版本:" >> system_info.txt
uname -r >> system_info.txt
​
echo "主机名:" >> system_info.txt
hostname >> system_info.txt
​
# 2. 统计正在运行的进程数量并追加到文件
echo -e "\n正在运行的进程数量:" >> system_info.txt
ps -e | wc -l >> system_info.txt
​
# 3. 查找占用CPU资源最多的前5个进程
echo -e "\n占用CPU多的进程:" >> system_info.txt
ps -eo pid,comm,%cpu --sort=-%cpu | head -n 6 | tail -n 5 | while read line; do
    pid=$(echo "$line" | cut -d ' ' -f 1)
    cmd=$(echo "$line" | cut -d ' ' -f 2)
    echo "$pid - $cmd" >> system_info.txt
done

验证:

[root@bogon ~]# ./collect_system_info.sh
[root@bogon ~]# cat system_info.txt
操作系统版本: Rocky Linux 8.10 (Green Obsidian)
内核版本: 4.18.0-553.el8_10.x86_64
主机名: bogon
正在运行的进程数量: 299
​
占用 CPU 多的进程:
1334 - /usr/libexec/platform-python
1118 - /usr/bin/vmtoolsd
246363 - [kworker/2:2-pm]
1 - /usr/lib/systemd/systemd
2 - [kthreadd]

题目二:用户管理配置脚本

创建一个脚本名为 user_config.sh,完成以下任务:

  1. 接受一个用户名为参数,如果该用户不存在,则创建这个用户,并设置一个随机生成的 8 位包含大小写字母和数字的密码(可借助相关命令或工具实现随机密码生成)。将用户信息(用户名和密码)追加到一个名为 users.txt 的文件中,格式为“用户名:密码”。

  2. 为新创建的用户添加一个备注信息,备注信息内容为“新创建用户于[当前日期]”,使用 chfn 命令实现(如果系统支持)。如果系统没有 chfn 命令,可将备注信息以一种合适的方式记录下来,比如在 users.txt 文件中用户名对应行的末尾添加备注。

  3. 将该用户添加到一个名为 common_group 的用户组中(如果该用户组不存在,则先创建它)。

解:

[root@bogon ~]# vim user_config.sh
    echo "$username:$password:$comment" >> "$password_file"
  
    # 2. 尝试使用chfn添加备注信息(如果可用)
    if type chfn &>/dev/null; then
        chfn -f "$comment" "$username"
    fi
​
    # 3. 检查并创建common_group组(如果不存在)
    if ! grep -q "^${group_name}:" /etc/group; then
        groupadd "$group_name"
    fi
​
    # 将用户添加到common_group组
    usermod -aG "$group_name" "$username"
​
    echo "用户 $username 已创建并配置完成。"
else
    echo "用户 $username 已存在。"
fi

验证

[root@bogon ~]# chmod +x user_config.sh
[root@bogon ~]# ./user_config.sh usr1
正在更改 usr1 的 finger 信息。
​
Finger 信息已更改。
用户 usr1 已创建并配置完成。
[root@bogon ~]# cat users.txt
usr1:0UmAWkcc:新创建用户于2025-06-09
[root@bogon ~]# groups usr1
usr1 : usr1 common_group
​

题目三:磁盘空间管理脚本

编写一个脚本名为 disk_management.sh,执行以下操作:

  1. 查找系统中磁盘空间使用率超过 80%的分区,将这些分区的挂载点和使用率信息输出到一个名为 disk_usage_report.txt 文件中,格式为“挂载点:使用率%”,每个分区占一行。

  2. 对于使用率超过 90%的分区,找出其中占用空间最大的前 10 个目录(如果可以通过命令直接实现的话,可使用合适的命令和参数),并将它们的路径和占用空间大小(以合适的单位显示,如 MB 或 GB)输出到一个名为 large_directories.txt 文件中,格式为“目录路径:占用空间大小”,每个目录占一行。如果无法直接找出前 10 个,尽可能多地找出大目录展示。

  3. 创建一个 cron 任务(如果系统支持 cron),让这个脚本每天凌晨 3 点自动执行一次,以持续监测磁盘空间情况。

解:

[root@bogon ~]# vim disk_management.sh
    usage=$(echo "$line" | tr -s ' ' | cut -d' ' -f5 | tr -d '%')
  
​
            # 查找大目录并排序,限制10个结果
            du -h --max-depth=1 "$mount_point" 2>/dev/null | sort -hr | head -11 | while read -r size dir; do
                # 跳过总计行
                if [ "$dir" != "$mount_point" ]; then
                    echo "$dir:$size" >> "$large_dirs_report"
                fi
            done
            echo "" >> "$large_dirs_report"
        fi
    fi
done
​
# 3. 设置cron任务(不使用crontab命令)
cron_job="0 3 * * * root $(pwd)/disk_management.sh"
cron_file="/etc/cron.d/disk_management"

验证

[root@bogon ~]# ./disk_management.sh
磁盘空间检查完成。报告已生成:
- 高使用率分区: disk_usage_report.txt
- 大目录列表: large_directories.txt

题目四:网络配置检查脚本

创建一个脚本名为 network_check.sh,实现以下功能:

  1. 检查系统的网络连接状态,判断是否能够正常访问互联网(可以尝试访问一个知名的、稳定的外网地址,如谷歌的公共 DNS 服务器 8.8.8.8),如果能访问则输出“网络连接正常”,否则输出“网络连接故障”。

  2. 列出当前系统中所有的网络接口及其 IP 地址,并将结果输出到一个名为 network_info.txt 文件中,格式为“网络接口:IP 地址”,每个接口占一行。

  3. 检查系统的防火墙规则(如果系统有防火墙),将当前启用的防火墙规则列表输出到一个名为 firewall_rules.txt 文件中。如果系统没有防火墙或者无法直接获取规则列表,可以输出“无防火墙或无法获取规则信息”到该文件中。

解:

[root@bogon ~]# vim network_check.sh
#!/bin/bash
​
# 1. 检查网络连接状态
check_internet() {
    if ping -c 3 8.8.8.8 >/dev/null 2>&1; then
        echo "网络连接正常"
    else
        echo "网络连接故障"
    fi
}
​
# 2:列出所有网络接口及其IP地址
list_network_interfaces() {
    echo "网络接口信息已保存到 network_info.txt"
    > network_info.txt  # 清空文件
    
    # 获取所有网络接口名称
    interfaces=$(ls /sys/class/net)
    
    for intf in $interfaces; do
        # 获取IP地址
        ip=$(ip addr show $intf | grep 'inet ' | tr -s ' ' | cut -d ' ' -f 3 | cut -d '/' -f 1)
        
        if [ -n "$ip" ]; then
            echo "网络接口:$intf IP地址:$ip" >> network_info.txt
        else
            echo "网络接口:$intf IP地址:无" >> network_info.txt
        fi
    done
}
​
# 3. 检查防火墙规则
check_firewall() {
    firewall_file="firewall_rules.txt"
    > "$firewall_file"  # 清空文件
    
    # 检查firewalld是否运行
    if systemctl is-active firewalld >/dev/null 2>&1; then
        firewall-cmd --list-all >> "$firewall_file" 2>&1
    # 检查iptables是否可用
    elif type iptables >/dev/null 2>&1 && iptables -L >/dev/null 2>&1; then
        iptables -L >> "$firewall_file" 2>&1
    else
        echo "无防火墙或无法获取规则信息" >> "$firewall_file"
    fi
}
​
# 执行所有检查
echo "=== 网络状态检查 ==="
check_internet
echo
​
echo "=== 网络接口信息 ==="
list_interfaces
echo "网络接口信息已保存到 network_info.txt"
cat network_info.txt
echo
​
echo "=== 防火墙检查 ==="
check_firewall
echo "防火墙规则已保存到 firewall_rules.txt"
cat firewall_rules.txt

验证

[root@bogon ~]# ./network_check.sh
=== 网络状态检查 ===
网络连接正常
​
=== 网络接口信息 ===
网络接口信息已保存到 network_info.txt
​
=== 防火墙检查 ===
防火墙规则已保存到 firewall_rules.txt
public (active)
  target: default
  icmp-block-inversion: no
  interfaces: ens160
  sources: 
  services: cockpit dhcpv6-client ssh
  ports: 
  protocols: 
  forward: no
  masquerade: no
  forward-ports: 
  source-ports: 
  icmp-blocks: 
  rich rules: 

题目五:系统日志分析脚本

编写一个脚本名为 log_analysis.sh,完成以下任务:

  1. 分析系统的一个关键应用程序的日志文件(假设日志文件路径为 /var/log/app.log),统计该日志文件中在过去 24 小时内出现错误信息(假设错误信息有特定的关键字,如 ERROR)的次数,并将结果输出到一个名为 error_count.txt 文件中,内容仅包含错误次数的数字。

  2. 找出包含错误信息的日志行中,出现频率最高的前 3 个错误消息内容(如果有多行错误信息内容相同,则视为同一类错误),并将它们及其出现次数输出到一个名为 top_errors.txt 文件中,格式为“错误消息:出现次数”,每个错误消息占一行。

  3. 将所有包含错误信息的日志行提取出来,保存到一个新的文件名为 errors.log 的文件中。

#!/bin/bash
​
log_file="/var/log/app.log"
error_count_file="error_count.txt"
top_errors_file="top_errors.txt"
errors_log_file="errors.log"
​
# 获取24小时前的时间戳(兼容Rocky 8)
twenty_four_hours_ago=$(date -d "24 hours ago" +"%Y-%m-%d %H:%M:%S")
​
# 1. 统计过去24小时内的ERROR出现次数
error_count=0
> "$error_count_file"
> "$errors_log_file"
​
while IFS= read -r line; do
    # 检查时间是否在24小时内(简单字符串比较)
    log_time=$(echo "$line" | cut -d' ' -f1-3 2>/dev/null)
    if [[ "$log_time" > "$twenty_four_hours_ago" ]] || [[ "$log_time" == "$twenty_four_hours_ago" ]]; then
        if [[ "$line" == *"ERROR"* ]]; then
            ((error_count++))
            echo "$line" >> "$errors_log_file"
        fi
    fi
done < "$log_file"
​
echo "$error_count" > "$error_count_file"
​
# 2. 找出出现频率最高的前3个错误消息
declare -A error_messages
​
while IFS= read -r line; do
    # 提取错误消息(简单地从ERROR关键字后开始)
    error_msg=$(echo "$line" | grep -o "ERROR.*" 2>/dev/null)
    if [ -n "$error_msg" ]; then
        ((error_messages["$error_msg"]++))
    fi
done < "$errors_log_file"
​
# 排序并获取前3个错误
> "$top_errors_file"
for error in "${!error_messages[@]}"; do
    echo "${error_messages["$error"]} $error"
done | sort -nr | head -3 | while read -r count error; do
    echo "$error:$count" >> "$top_errors_file"
done
​
echo "日志分析完成:"
echo "- 过去24小时错误次数: $(cat $error_count_file)"
echo "- 前3个常见错误已保存到 $top_errors_file"
echo "- 所有错误日志已保存到 $errors_log_file"
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值