Linux 日志分析全攻略:快速从海量日志中定位问题

Linux 日志分析全攻略:快速从海量日志中定位问题

1. 引言

在Linux系统管理和故障排查过程中,日志分析是不可或缺的核心技能。面对GB甚至TB级别的日志数据,如何快速定位问题成为每个系统管理员必须掌握的技能。本教程将深入讲解Linux日志分析的完整流程和方法,从基础命令到高级技巧,帮助您构建系统的日志分析能力。

2. Linux 日志系统基础

2.1 主要日志文件位置

bash 复制代码
# 系统核心日志目录
/var/log/

# 重要日志文件
/var/log/messages    # 常规系统消息
/var/log/syslog      # 系统日志
/var/log/auth.log    # 认证相关日志(Debian/Ubuntu)
/var/log/secure      # 认证相关日志(CentOS/RHEL)
/var/log/kern.log    # 内核日志
/var/log/dmesg       # 系统启动消息
/var/log/boot.log    # 启动日志
/var/log/cron        # 计划任务日志
/var/log/maillog     # 邮件服务日志
/var/log/httpd/      # Apache日志目录
/var/log/nginx/      # Nginx日志目录
/var/log/mysql/      # MySQL日志目录

2.2 日志文件查看基础命令

bash 复制代码
# 实时查看日志更新
tail -f /var/log/syslog
tail -f /var/log/messages

# 查看最后100行日志
tail -n 100 /var/log/syslog

# 查看从第1000行开始的所有日志
tail -n +1000 /var/log/syslog

# 查看前100行日志
head -n 100 /var/log/syslog

# 查看整个日志文件
cat /var/log/syslog

# 分页查看日志
less /var/log/syslog

# 实时监控多个日志文件
multitail /var/log/syslog /var/log/auth.log

3. 日志分析流程总览

以下流程图展示了完整的日志分析流程:

graph TD A[开始日志分析] --> B[确定分析目标] B --> C[收集相关日志] C --> D[预处理和过滤] D --> E[模式识别和分析] E --> F{是否定位问题?} F -->|否| G[调整分析策略] G --> D F -->|是| H[问题验证和解决] H --> I[文档记录] I --> J[预防措施实施] J --> K[分析完成] style A fill:#2c3e50,color:white style B fill:#3498db,color:white style C fill:#3498db,color:white style D fill:#e74c3c,color:white style E fill:#e74c3c,color:white style F fill:#f39c12,color:white style G fill:#f39c12,color:white style H fill:#27ae60,color:white style I fill:#27ae60,color:white style J fill:#27ae60,color:white style K fill:#2c3e50,color:white

4. 基础日志分析命令

4.1 grep 命令的强大用法

bash 复制代码
# 基础搜索
grep "error" /var/log/syslog
grep -i "error" /var/log/syslog          # 忽略大小写
grep -r "connection refused" /var/log/   # 递归搜索目录

# 高级搜索技巧
grep -E "error|fail|critical" /var/log/syslog          # 多模式搜索
grep -v "debug" /var/log/syslog                         # 排除模式
grep -A 5 -B 5 "segmentation fault" /var/log/syslog    # 显示匹配前后5行
grep -c "authentication failure" /var/log/auth.log     # 统计匹配次数
grep -n "timeout" /var/log/syslog                      # 显示行号

# 组合使用示例:查找最近1小时内包含error的日志
grep "error" /var/log/syslog | grep "$(date '+%b %e %H:' -d '1 hour ago')"

4.2 awk 高级文本处理

bash 复制代码
# 提取特定字段
awk '{print $1, $2, $5}' /var/log/syslog                    # 打印第1,2,5列
awk -F':' '{print $1, $NF}' /var/log/auth.log              # 使用冒号分隔符

# 条件过滤
awk '$6 == "ERROR" {print $0}' /var/log/syslog             # 第6列为ERROR的行
awk 'NR >= 1000 && NR <= 2000 {print $0}' /var/log/syslog  # 特定行范围

# 统计和分析
awk '{count[$6]++} END {for (level in count) print level, count[level]}' /var/log/syslog

# 复杂条件处理
awk '
/ERROR/ {
    error_count++
    if ($6 ~ /timeout/) timeout_errors++
}
END {
    print "总错误数:", error_count
    print "超时错误数:", timeout_errors
    print "超时错误比例:", (timeout_errors/error_count)*100 "%"
}
' /var/log/syslog

4.3 sed 流编辑器应用

bash 复制代码
# 文本替换和过滤
sed 's/error/ERROR/g' /var/log/syslog                      # 替换文本
sed -n '100,200p' /var/log/syslog                         # 提取特定行范围
sed '/debug/d' /var/log/syslog                            # 删除包含debug的行

# 复杂文本处理
sed -e 's/.*error.*/\U&/' -e 's/warning/WARNING/g' /var/log/syslog

5. 高级日志分析技术

5.1 日志时间范围分析

bash 复制代码
#!/bin/bash
# 分析特定时间段的日志

LOG_FILE="/var/log/syslog"
START_TIME="$(date '+%b %e %H:%M:%S' -d '2 hours ago')"
END_TIME="$(date '+%b %e %H:%M:%S' -d '1 hour ago')"

echo "分析时间范围: $START_TIME 到 $END_TIME"
echo "=========================================="

# 使用awk处理时间范围
awk -v start="$START_TIME" -v end="$END_TIME" '
$1" "$2" "$3 >= start && $1" "$2" "$3 <= end {
    print $0
}
' "$LOG_FILE" | head -20

5.2 错误频率统计脚本

bash 复制代码
#!/bin/bash
# 错误频率统计分析脚本

LOG_FILE="${1:-/var/log/syslog}"
OUTPUT_FILE="/tmp/error_analysis_$(date +%Y%m%d_%H%M%S).txt"

{
    echo "错误分析报告 - $(date)"
    echo "日志文件: $LOG_FILE"
    echo "=========================================="
    
    # 错误级别统计
    echo "1. 错误级别分布:"
    echo "------------------------------------------"
    awk '
    {
        for(i=1; i<=NF; i++) {
            if ($i ~ /(ERROR|ERR|error|Error|FATAL|Fatal|WARNING|Warning|WARN|INFO|Info|DEBUG|Debug)/) {
                level = $i
                gsub(/[^a-zA-Z]/, "", level)
                if (level != "") {
                    count[toupper(level)]++
                }
            }
        }
    }
    END {
        for (l in count) {
            printf "%-10s: %d\n", l, count[l]
        }
    }' "$LOG_FILE"
    
    echo ""
    echo "2. 高频错误消息:"
    echo "------------------------------------------"
    grep -i "error\|fail\|critical\|exception" "$LOG_FILE" | \
    awk '{
        # 提取错误消息的关键部分
        for(i=1; i<=NF; i++) {
            if ($i ~ /error|fail|critical|exception/i) {
                msg = substr($0, index($0, $i))
                break
            }
        }
        count[msg]++
    } 
    END {
        for (m in count) {
            if (count[m] > 1) {
                printf "%3d 次: %s\n", count[m], m
            }
        }
    }' | sort -nr | head -10
    
} | tee "$OUTPUT_FILE"

echo "详细报告已保存至: $OUTPUT_FILE"

5.3 实时日志监控系统

bash 复制代码
#!/bin/bash
# 实时日志监控和告警脚本

MONITOR_FILE="/var/log/syslog"
ALERT_PATTERNS=("error" "fail" "critical" "panic" "out of memory" "segmentation fault")
ALERT_EMAIL="admin@company.com"

# 颜色定义
RED='\033[0;31m'
YELLOW='\033[1;33m'
GREEN='\033[0;32m'
NC='\033[0m' # No Color

echo "启动实时日志监控系统..."
echo "监控文件: $MONITOR_FILE"
echo "监控模式: ${ALERT_PATTERNS[*]}"
echo "按 Ctrl+C 停止监控"
echo "----------------------------------------"

tail -n 0 -F "$MONITOR_FILE" | while read line; do
    for pattern in "${ALERT_PATTERNS[@]}"; do
        if echo "$line" | grep -qi "$pattern"; then
            TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')
            
            # 根据模式严重程度设置颜色
            if [[ "$pattern" =~ (error|fail|critical|panic) ]]; then
                COLOR=$RED
                LEVEL="HIGH"
            else
                COLOR=$YELLOW
                LEVEL="MEDIUM"
            fi
            
            echo -e "${COLOR}[$TIMESTAMP] [$LEVEL] 检测到 '$pattern':${NC}"
            echo -e "${COLOR}$line${NC}"
            echo "----------------------------------------"
            
            # 高严重级别告警发送邮件
            if [[ "$LEVEL" == "HIGH" ]]; then
                echo "检测到高严重级别错误,发送告警邮件..."
                {
                    echo "主题: 系统告警 - 检测到 $pattern"
                    echo "时间: $TIMESTAMP"
                    echo "日志内容: $line"
                    echo "服务器: $(hostname)"
                } | mail -s "系统告警检测" "$ALERT_EMAIL"
            fi
            break
        fi
    done
done

6. 专业日志分析工具

6.1 logwatch 配置和使用

bash 复制代码
# 安装logwatch
# Ubuntu/Debian
sudo apt-get update
sudo apt-get install logwatch

# CentOS/RHEL
sudo yum install logwatch

# 配置logwatch
sudo nano /usr/share/logwatch/default.conf/logwatch.conf

# 主要配置项示例
LogDir = /var/log
TmpDir = /tmp
Output = mail
Format = html
MailTo = admin@company.com
MailFrom = logwatch@$(hostname)
Range = yesterday
Detail = High

# 立即运行logwatch
sudo logwatch --output stdout --format text --range today
sudo logwatch --output mail --format html --range yesterday

# 自定义服务配置
sudo mkdir -p /etc/logwatch/conf/services
sudo nano /etc/logwatch/conf/services/httpd.conf

6.2 journalctl 系统日志分析

bash 复制代码
# 基础查询
journalctl                          # 查看所有日志
journalctl -f                       # 实时监控
journalctl -n 50                    # 最后50行
journalctl --since "1 hour ago"     # 最近1小时日志

# 高级过滤
journalctl -p err                   # 仅错误级别
journalctl -p warning..err          # 警告到错误级别
journalctl --since "2024-01-01" --until "2024-01-02"
journalctl _SYSTEMD_UNIT=ssh.service # 特定服务日志

# 组合查询和输出
journalctl -p err --since "today" --output json-pretty
journalctl --since "yesterday" --until "today" | grep -i "fail"

# 性能分析
journalctl --since "1 hour ago" --output json | jq '._EXE' | sort | uniq -c | sort -nr

7. 实战案例:Web服务器故障排查

7.1 Nginx 错误日志分析

bash 复制代码
#!/bin/bash
# Nginx错误日志深度分析

NGINX_ERROR_LOG="/var/log/nginx/error.log"
REPORT_FILE="/tmp/nginx_error_analysis_$(date +%Y%m%d_%H%M%S).html"

# 生成HTML报告
cat > "$REPORT_FILE" << EOF
<html>
<head>
    <title>Nginx错误日志分析报告</title>
    <style>
        body { font-family: Arial, sans-serif; margin: 20px; background-color: #1e1e1e; color: white; }
        .container { max-width: 1200px; margin: 0 auto; }
        .section { background: #2d2d2d; padding: 20px; margin: 10px 0; border-radius: 5px; }
        .critical { color: #ff4444; font-weight: bold; }
        .warning { color: #ffaa00; }
        .info { color: #44ff44; }
        table { width: 100%; border-collapse: collapse; }
        th, td { padding: 8px; text-align: left; border-bottom: 1px solid #444; }
        th { background-color: #333; }
    </style>
</head>
<body>
    <div class="container">
        <h1>Nginx错误日志分析报告</h1>
        <p>生成时间: $(date)</p>
        <p>分析文件: $NGINX_ERROR_LOG</p>
EOF

# 错误统计
{
    echo "<div class='section'>"
    echo "<h2>错误级别统计</h2>"
    echo "<table>"
    echo "<tr><th>错误级别</th><th>出现次数</th><th>百分比</th></tr>"
    
    awk '
    /emerg|alert|crit|error|warn|notice|info|debug/ {
        for(i=1; i<=NF; i++) {
            if ($i ~ /emerg|alert|crit|error|warn|notice|info|debug/) {
                level = $i
                count[level]++
                total++
                break
            }
        }
    }
    END {
        for (l in count) {
            printf "<tr><td class=\"%s\">%s</td><td>%d</td><td>%.2f%%</td></tr>\n", 
                (l~/emerg|alert|crit/?"critical":(l~/error/?"warning":"info")), 
                l, count[l], (count[l]/total)*100
        }
    }' "$NGINX_ERROR_LOG"
    
    echo "</table>"
    echo "</div>"
} >> "$REPORT_FILE"

# 高频错误IP分析
{
    echo "<div class='section'>"
    echo "<h2>客户端IP错误统计</h2>"
    echo "<table>"
    echo "<tr><th>客户端IP</th><th>错误次数</th><th>最后出现时间</th></tr>"
    
    awk '
    {
        # 提取IP地址
        for(i=1; i<=NF; i++) {
            if ($i ~ /^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$/) {
                ip = $i
                ip_count[ip]++
                last_seen[ip] = $1 " " $2
                break
            }
        }
    }
    END {
        for (ip in ip_count) {
            if (ip_count[ip] > 5) {  # 只显示错误次数超过5次的IP
                print "<tr><td>" ip "</td><td>" ip_count[ip] "</td><td>" last_seen[ip] "</td></tr>"
            }
        }
    }' "$NGINX_ERROR_LOG" | sort -k2 -nr | head -10
    
    echo "</table>"
    echo "</div>"
} >> "$REPORT_FILE"

cat >> "$REPORT_FILE" << EOF
    </div>
</body>
</html>
EOF

echo "Nginx错误分析报告已生成: $REPORT_FILE"

7.2 数据库连接问题排查

bash 复制代码
#!/bin/bash
# 数据库连接问题分析

LOG_FILES="/var/log/syslog /var/log/messages /var/log/mysql/error.log"
TIME_RANGE="2 hours ago"

echo "数据库连接问题分析报告"
echo "生成时间: $(date)"
echo "分析时间范围: $TIME_RANGE 到现在"
echo "=========================================="

# 搜索数据库连接相关错误
for log_file in $LOG_FILES; do
    if [ -f "$log_file" ]; then
        echo "分析文件: $log_file"
        echo "------------------------------------------"
        
        # 时间范围过滤和错误搜索
        awk -v start_time="$(date '+%b %e %H:%M:%S' -d "$TIME_RANGE")" '
        $0 >= start_time {
            if (/mysql|mariadb|database/ && /connect|timeout|refused|error|fail/) {
                print $0
                count++
            }
        }
        END {
            if (count > 0) {
                print "发现 " count " 个相关错误"
            } else {
                print "未发现数据库连接错误"
            }
        }' "$log_file"
        
        echo ""
    fi
done

# 检查当前数据库连接状态
echo "当前数据库连接状态:"
echo "------------------------------------------"
mysqladmin processlist 2>/dev/null || echo "无法连接到数据库"

# 检查数据库端口状态
echo ""
echo "数据库端口(3306)状态:"
netstat -tln | grep 3306 || echo "数据库端口未监听"

8. 自动化日志分析系统

8.1 综合日志分析脚本

bash 复制代码
#!/bin/bash
# 综合日志分析系统

LOG_DIR="/var/log"
OUTPUT_DIR="/tmp/log_analysis"
REPORT_FILE="$OUTPUT_DIR/comprehensive_analysis_$(date +%Y%m%d_%H%M%S).txt"

# 创建输出目录
mkdir -p "$OUTPUT_DIR"

{
    echo "综合日志分析报告"
    echo "生成时间: $(date)"
    echo "服务器: $(hostname)"
    echo "=========================================="
    echo ""
    
    # 系统基本信息
    echo "1. 系统基本信息"
    echo "------------------------------------------"
    echo "主机名: $(hostname)"
    echo "IP地址: $(hostname -I)"
    echo "运行时间: $(uptime)"
    echo "系统负载: $(cat /proc/loadavg)"
    echo ""
    
    # 磁盘空间检查
    echo "2. 磁盘空间状态"
    echo "------------------------------------------"
    df -h | grep -E "(Filesystem|/dev/sd|/dev/mapper)"
    echo ""
    
    # 内存使用情况
    echo "3. 内存使用情况"
    echo "------------------------------------------"
    free -h
    echo ""
    
    # 关键错误统计
    echo "4. 关键错误统计"
    echo "------------------------------------------"
    
    # 分析各个日志文件的错误
    for log_file in syslog messages; do
        if [ -f "$LOG_DIR/$log_file" ]; then
            echo "文件: $LOG_DIR/$log_file"
            grep -i "error\|fail\|critical" "$LOG_DIR/$log_file" | \
            awk '
            {
                count++
                # 按小时统计
                hour = substr($3,1,2)
                hourly_count[hour]++
            }
            END {
                print "  总错误数:", count
                print "  按小时分布:"
                for (h=0; h<24; h++) {
                    hh = sprintf("%02d", h)
                    printf "    %s时: %d次\n", hh, hourly_count[hh]
                }
            }'
            echo ""
        fi
    done
    
    # 认证失败分析
    echo "5. 认证失败分析"
    echo "------------------------------------------"
    for auth_log in auth.log secure; do
        if [ -f "$LOG_DIR/$auth_log" ]; then
            echo "认证日志文件: $LOG_DIR/$auth_log"
            grep -i "fail" "$LOG_DIR/$auth_log" | \
            awk '
            /authentication failure|failed password/ {
                count++
                # 提取用户名
                for(i=1; i<=NF; i++) {
                    if ($i == "user") {
                        user = $(i+1)
                        user_count[user]++
                        break
                    }
                }
            }
            END {
                print "  认证失败总数:", count
                print "  按用户分布:"
                for (user in user_count) {
                    printf "    用户 %s: %d次\n", user, user_count[user]
                }
            }'
        fi
    done
    echo ""
    
    # 服务状态检查
    echo "6. 关键服务状态"
    echo "------------------------------------------"
    for service in ssh nginx apache2 mysql; do
        if systemctl is-active --quiet "$service"; then
            echo "  $service: 运行中"
        else
            echo "  $service: 未运行"
        fi
    done
    
} | tee "$REPORT_FILE"

echo ""
echo "详细分析报告已保存至: $REPORT_FILE"

8.2 日志轮转和归档策略

bash 复制代码
#!/bin/bash
# 日志归档和清理脚本

LOG_DIR="/var/log"
ARCHIVE_DIR="/var/log/archive"
RETENTION_DAYS=30

# 创建归档目录
mkdir -p "$ARCHIVE_DIR"

echo "开始日志归档处理..."
echo "归档目录: $ARCHIVE_DIR"
echo "保留天数: $RETENTION_DAYS"
echo "=========================================="

# 归档7天前的日志文件
find "$LOG_DIR" -name "*.log.*" -type f -mtime +7 | while read logfile; do
    if [[ "$logfile" != *"archive"* ]]; then
        filename=$(basename "$logfile")
        archive_name="${filename}.$(date +%Y%m%d).gz"
        
        echo "归档文件: $logfile -> $ARCHIVE_DIR/$archive_name"
        gzip -c "$logfile" > "$ARCHIVE_DIR/$archive_name"
        
        # 验证归档成功后删除原文件
        if [ $? -eq 0 ] && [ -f "$ARCHIVE_DIR/$archive_name" ]; then
            rm "$logfile"
            echo "  归档成功,原文件已删除"
        else
            echo "  归档失败,保留原文件"
        fi
    fi
done

# 清理过期的归档文件
echo ""
echo "清理过期归档文件..."
find "$ARCHIVE_DIR" -name "*.gz" -type f -mtime +$RETENTION_DAYS | while read archive; do
    echo "删除过期归档: $archive"
    rm "$archive"
done

echo "日志归档处理完成"

9. 高级技巧和最佳实践

9.1 正则表达式在日志分析中的应用

bash 复制代码
#!/bin/bash
# 高级正则表达式日志分析

LOG_FILE="/var/log/syslog"

echo "高级正则表达式日志分析"
echo "=========================================="

# IP地址提取和分析
echo "1. IP地址分析"
echo "------------------------------------------"
grep -oE "\b([0-9]{1,3}\.){3}[0-9]{1,3}\b" "$LOG_FILE" | \
sort | uniq -c | sort -nr | head -10

echo ""

# URL提取和分析
echo "2. URL路径分析"
echo "------------------------------------------"
grep -oE "GET /[^ ]*|POST /[^ ]*" "$LOG_FILE" 2>/dev/null | \
sort | uniq -c | sort -nr | head -10

echo ""

# 时间模式分析
echo "3. 错误时间分布"
echo "------------------------------------------"
grep -i "error" "$LOG_FILE" | \
grep -oE "[A-Z][a-z]{2} [ 0-9][0-9] [0-9]{2}:[0-9]{2}:[0-9]{2}" | \
awk '{count[substr($0,1,6)]++} END {for (d in count) print d, count[d]}' | \
sort

9.2 性能优化的大日志文件处理

bash 复制代码
#!/bin/bash
# 大日志文件高效处理技巧

LOG_FILE="$1"
TEMP_DIR="/tmp/log_analysis_$$"

mkdir -p "$TEMP_DIR"

echo "大日志文件处理优化"
echo "文件: $LOG_FILE"
echo "大小: $(du -h "$LOG_FILE" | cut -f1)"
echo "=========================================="

# 方法1: 使用split分割大文件
echo "1. 文件分割处理"
split -l 100000 "$LOG_FILE" "$TEMP_DIR/log_chunk_"

# 并行处理各个块
for chunk in "$TEMP_DIR"/log_chunk_*; do
    {
        grep -i "error" "$chunk" > "${chunk}.errors"
    } &
done

wait

# 合并结果
cat "$TEMP_DIR"/*.errors > "$TEMP_DIR/all_errors.txt"
echo "错误提取完成: $(wc -l < "$TEMP_DIR/all_errors.txt") 行"

# 方法2: 使用awk高效处理
echo ""
echo "2. 使用AWK进行高效分析"
awk '
# 只处理包含时间戳的行
/^[A-Z][a-z]{2} [ 0-9][0-9] [0-9]{2}:[0-9]{2}:[0-9]{2}/ {
    # 错误统计
    if (/error/i) errors++
    if (/warn/i) warnings++
    if (/fail/i) failures++
    
    # IP统计
    for(i=1; i<=NF; i++) {
        if ($i ~ /^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$/) {
            ip_count[$i]++
            break
        }
    }
}
END {
    print "错误统计:"
    print "  Errors:", errors
    print "  Warnings:", warnings
    print "  Failures:", failures
    print ""
    print "高频IP地址:"
    count = 0
    for (ip in ip_count) {
        if (ip_count[ip] > 10) {
            print "  " ip ": " ip_count[ip] "次"
            if (++count >= 5) break
        }
    }
}' "$LOG_FILE"

# 清理临时文件
rm -rf "$TEMP_DIR"

10. 总结

通过本教程的详细讲解,您应该已经掌握了:

  1. 基础命令熟练运用 - grep, awk, sed等核心工具
  2. 分析流程系统化 - 从问题定位到解决的完整流程
  3. 实战脚本开发 - 可以编写自动化分析脚本
  4. 高级技巧掌握 - 正则表达式、性能优化等
  5. 工具链完善 - logwatch, journalctl等专业工具

日志分析是一个需要持续实践和积累经验的领域。建议您:

  • 定期运行分析脚本,建立基线
  • 保存历史分析报告,便于趋势分析
  • 建立告警机制,及时发现问题
  • 不断优化分析策略和脚本

记住,优秀的系统管理员不是等待问题发生,而是通过日志分析预见和预防问题。

相关推荐
_Power_Y2 小时前
Linux&git入门&设计模式(常考点)
linux·git·设计模式
海蓝可知天湛2 小时前
Ubuntu24.10禁用该源...+vmware无法复制黏贴“天坑闭环”——从 DNS 诡异解析到 Ubuntu EOL 引发的 apt 404排除折腾记
linux·服务器·安全·ubuntu·aigc·bug
vvw&2 小时前
如何在 Ubuntu 24.04 上安装和使用 AdGuard
linux·运维·服务器·ubuntu·adguard
遇见火星3 小时前
Linux 网络配置实战:RHEL/CentOS 7+ 永久静态路由配置与优先级调整全攻略
linux·网络·centos·静态路由·centos 7
安审若无4 小时前
linux怎么检查磁盘是否有坏道
linux·运维·服务器
HalvmånEver4 小时前
Linux的第二章 : 基础的指令(二)
linux·运维·服务器·开发语言·学习
大梦南柯4 小时前
linux创建网站
linux·运维·服务器
刘永鑫Adam4 小时前
代码管理及Linux模拟工具Git for Windows安装使用教程
linux·运维·服务器·git
孙同学_4 小时前
【Linux篇】信号从哪来?到哪去?—— Linux信号的产生方式与保存机制
linux·运维·服务器