MST

星途 面试题库

面试题:Bash管道与过滤器在系统管理场景的复杂应用

在一个Linux服务器上,有多个服务进程在运行,其日志文件分布在不同目录下(假设日志文件后缀为`.log`)。现在需要通过Bash管道和过滤器完成以下任务:收集所有日志文件中在过去一小时内记录的、包含特定错误关键字(如`ERROR: Connection refused`)的行,将这些行按时间戳排序,输出到一个新文件中,并统计出现该错误关键字的次数。同时,要考虑如何处理日志文件可能非常大以及不同日志文件时间格式不一致的情况,详细阐述你的实现步骤及脚本代码。
43.9万 热度难度
编程语言Bash

知识考点

AI 面试

面试题答案

一键面试
  1. 实现步骤
    • 收集过去一小时内的日志行
      • 不同日志文件时间格式不一致,需要针对每种可能的时间格式写相应的时间解析函数。例如常见的时间格式如YYYY - MM - DD HH:MM:SSMM/DD/YYYY HH:MM:SS等。
      • 遍历所有日志文件(后缀为.log),读取每一行,根据时间格式解析时间,判断是否在过去一小时内。
    • 筛选包含特定错误关键字的行:在上述筛选出的行中,查找包含ERROR: Connection refused的行。
    • 按时间戳排序:将筛选出的行,根据解析出的时间戳进行排序。
    • 输出到新文件并统计次数:将排序后的行输出到一个新文件,并统计出现ERROR: Connection refused的行数。
  2. 脚本代码
#!/bin/bash

# 定义错误关键字
error_keyword="ERROR: Connection refused"
# 定义新文件路径
output_file="error_summary.log"
# 获取当前时间一小时前的时间戳
one_hour_ago=$(date -d "1 hour ago" +%s)

# 清空输出文件
> $output_file

# 定义一个函数来解析常见的时间格式为时间戳
parse_time() {
    local time_str=$1
    local timestamp
    # 尝试解析 YYYY - MM - DD HH:MM:SS 格式
    timestamp=$(date -d "$time_str" +%s 2>/dev/null)
    if [[ -n $timestamp ]]; then
        echo $timestamp
        return
    fi
    # 尝试解析 MM/DD/YYYY HH:MM:SS 格式
    timestamp=$(date -d "$(echo $time_str | awk -F'/' '{print $2"/"$1"/"$3}')" +%s 2>/dev/null)
    if [[ -n $timestamp ]]; then
        echo $timestamp
        return
    fi
    # 如果都不匹配,返回空
    echo ""
}

# 初始化错误计数
error_count=0

# 遍历所有.log文件
for log_file in $(find / -name "*.log"); do
    while read -r line; do
        # 尝试提取时间部分,这里假设时间在开头
        time_str=$(echo $line | awk '{print $1" "$2}' | sed's/[[:punct:]]//g')
        timestamp=$(parse_time "$time_str")
        if [[ -n $timestamp && $timestamp -ge $one_hour_ago ]]; then
            if [[ $line == *$error_keyword* ]]; then
                echo $line >> $output_file
                ((error_count++))
            fi
        fi
    done < $log_file
done

# 按时间戳排序(假设时间在开头,再次解析时间并排序)
sort -t " " -k1,2 -o $output_file $output_file

# 输出错误次数
echo "Total occurrences of '$error_keyword': $error_count"

这段脚本首先定义了错误关键字和输出文件路径,计算出一小时前的时间戳。然后通过parse_time函数尝试解析常见的时间格式为时间戳。接着遍历所有.log文件,筛选出过去一小时内包含错误关键字的行,写入输出文件并统计次数。最后对输出文件按时间戳排序,并输出错误关键字出现的总次数。注意:此脚本中的时间格式解析只是示例,实际应用中可能需要根据真实日志时间格式进行调整。