学习目标

  • 理解本节涉及的核心主题:Linux 系统日志管理、日志分析与处理、查看日志、使用 journalctl 查看 systemd 日志。
  • 掌握重点命令或工具:journalctllogrotate
  • 能够结合示例完成常见操作,并理解关键参数、使用场景与结果差异。
  • 能够识别本节相关的常见风险、易错点或排查思路。

学习重点

  • 主题范围:Linux 系统日志管理、日志分析与处理、查看日志、使用 journalctl 查看 systemd 日志、配置日志轮转(logrotate)、总结
  • 重点命令:journalctllogrotate
  • 学习重点:命令用途、关键参数、典型场景、与相近命令的区别
  • 复习方式:先理解场景,再动手练习,最后对照结果检查

Linux 系统日志管理

日志分析与处理

日志分析与处理是系统管理员日常工作的重要部分,涉及日志的查看、筛选、分析以及自动化处理。

查看日志

有效地查看日志文件是分析和诊断问题的第一步。以下介绍几种常用的方法和工具。

使用 cat 查看完整日志文件

cat 命令用于将文件内容输出到标准输出,适合查看小型日志文件。

示例:查看 syslog 文件

sudo cat /var/log/syslog

注意事项

  • 对于大型日志文件,cat 会一次性输出所有内容,可能导致终端卡顿。
使用 less 分页查看日志文件

less 命令提供了分页查看功能,适合浏览大型日志文件。

示例:分页查看 auth.log 文件

sudo less /var/log/auth.log

常用操作

  • 向下翻页:按 Space 键或 f 键。
  • 向上翻页:按 b 键。
  • 搜索关键词:按 / 键,输入关键词后按 Enter
  • 退出:按 q 键。
使用 tail 查看日志文件的末尾部分

tail 命令用于查看文件的最后几行,适合快速查看最新的日志条目。

基本用法

tail /var/log/kern.log

查看指定行数

tail -n 50 /var/log/kern.log

实时监控(-f 选项)

tail -f 命令用于实时监控日志文件的新增内容,适合观察实时事件。

示例:实时监控 boot.log

sudo tail -f /var/log/boot.log

停止实时监控

Ctrl + C 键。

使用 journalctl 查看 systemd 日志

journalctl 是 systemd 提供的日志管理工具,用于查看和管理由 systemd 日志守护进程记录的日志信息。

基本用法

查看所有日志

sudo journalctl

按时间顺序查看日志

sudo journalctl --since "2024-04-01" --until "2024-04-27"

查看当前引导的日志

sudo journalctl -b

查看前一个引导的日志

sudo journalctl -b -1
按时间过滤日志(--since, --until 选项)

示例:查看过去一小时的日志

sudo journalctl --since "1 hour ago"

示例:查看特定日期范围的日志

sudo journalctl --since "2024-04-25" --until "2024-04-26 14:00"
查看特定服务的日志(-u 选项)

示例:查看 sshd 服务的日志

sudo journalctl -u sshd

实时监控特定服务的日志

sudo journalctl -u sshd -f
组合使用与高级筛选

根据优先级过滤日志

示例:查看所有错误级别及以上的日志

sudo journalctl -p err

指定多个服务

sudo journalctl -u sshd -u nginx

查看内核日志

sudo journalctl -k

结合使用多个选项

示例:查看 nginx 服务在过去一天内的错误日志

sudo journalctl -u nginx -p err --since "yesterday"

配置日志轮转(logrotate

日志轮转是管理日志文件大小和数量的重要机制,防止日志文件过大占用过多磁盘空间,并确保日志的长期可用性。

基本概念与作用
  • 日志轮转:定期对日志文件进行重命名、压缩和清理,确保日志文件不会无限制增长。
  • 配置文件logrotate 的配置文件定义了日志轮转的策略和规则。
配置文件位置与结构
  • 主配置文件/etc/logrotate.conf
  • 单独配置文件目录/etc/logrotate.d/

主配置文件示例

weekly

rotate 4

create

dateext

#compress

include /etc/logrotate.d

/var/log/wtmp {
    missingok
    monthly
    create 0664 root utmp
    minsize 1M
    rotate 1
}

/var/log/btmp {
    missingok
    monthly
    create 0600 root utmp
    rotate 1
}

单独配置文件示例(如 /etc/logrotate.d/nginx

/var/log/nginx/*.log {
    daily
    missingok
    rotate 14
    compress
    delaycompress
    notifempty
    create 0640 www-data adm
    sharedscripts
    postrotate
        [ -f /var/run/nginx.pid ] && kill -USR1 `cat /var/run/nginx.pid`
    endscript
}
设置日志轮转规则
  • 频率daily(每日)、weekly(每周)、monthly(每月)。
  • 保留数量rotate N,保留最近 N 个轮转日志。
  • 压缩选项compress,启用日志压缩。
  • 延迟压缩delaycompress,延迟压缩直到下次轮转。
  • 空文件处理notifempty,不轮转空日志文件。
  • 创建新日志文件create mode owner group,在轮转后创建新的日志文件并设置权限。

示例:为 /var/log/myapp.log 配置每日轮转,保留7天,压缩旧日志

/etc/logrotate.d/myapp 创建或编辑配置文件:

/var/log/myapp.log {
    daily
    rotate 7
    compress
    missingok
    notifempty
    create 0640 myuser mygroup
    sharedscripts
    postrotate
        systemctl reload myapp.service > /dev/null 2>/dev/null || true
    endscript
}
手动运行日志轮转

有时需要手动触发日志轮转,特别是在进行配置更改后或处理紧急情况时。

命令:

sudo logrotate /etc/logrotate.conf

强制轮转

使用 -f 选项强制进行日志轮转,无论配置文件中是否满足轮转条件。

sudo logrotate -f /etc/logrotate.conf
常见配置示例与最佳实践
  • 定期轮转系统日志
    系统日志通常按周或月进行轮转,保留4-8个轮转周期。
    示例:在 /etc/logrotate.conf 中设置

    /var/log/syslog {
        weekly
        rotate 8
        compress
        missingok
        notifempty
        delaycompress
        postrotate
            /usr/lib/rsyslog/rsyslog-rotate
        endscript
    }
    
  • 为不同应用程序设置不同的轮转策略
    根据应用程序的重要性和日志产生量,设置不同的轮转频率和保留数量。
    示例:为高流量 Web 服务器设置每日轮转,保留30天
    /etc/logrotate.d/nginx 中配置:

    /var/log/nginx/*.log {
        daily
        rotate 30
        compress
        missingok
        notifempty
        create 0640 www-data adm
        sharedscripts
        postrotate
            [ -f /var/run/nginx.pid ] && kill -USR1 `cat /var/run/nginx.pid`
        endscript
    }
    
  • 优化日志压缩
    启用压缩可以节省磁盘空间,但可能会增加 CPU 负载。根据系统资源和需求选择是否启用压缩。
    示例:启用压缩并延迟压缩

    compress
    delaycompress
    
  • 监控日志轮转
    定期检查轮转是否按预期进行,确保日志文件不会无限制增长。
    示例:查看日志轮转状态

    sudo tail /var/log/logrotate.log
    

    配置 logrotate 日志

    /etc/logrotate.conf 中添加:

    verbose
    

总结

Linux 系统日志管理是系统维护和安全监控的重要环节。通过了解常见日志文件的作用与内容,掌握日志查看与分析的方法,以及配置日志轮转策略,系统管理员能够有效地监控系统运行状态、诊断问题并确保日志的长期可用性。合理配置日志管理工具和策略,能够显著提升系统的稳定性和安全性。

以下是基于具体实例的应用总结:

  • 查看 syslog 文件的最新日志条目
    sudo tail -n 50 /var/log/syslog
    
  • 使用 less 分页查看 auth.log 文件
    sudo less /var/log/auth.log
    
  • 实时监控 kern.log 文件的新增日志
    sudo tail -f /var/log/kern.log
    
  • 使用 journalctl 查看 sshd 服务的最近日志
    sudo journalctl -u sshd --since "2024-04-25"
    
  • 配置 logrotate 每周轮转 daemon.log,保留4周的日志,启用压缩
    /etc/logrotate.d/daemon 中添加:
    /var/log/daemon.log {
        weekly
        rotate 4
        compress
        missingok
        notifempty
        create 0640 root adm
        postrotate
            /usr/lib/rsyslog/rsyslog-rotate
        endscript
    }
    
  • 手动运行 logrotate 并强制轮转所有日志
    sudo logrotate -f /etc/logrotate.conf
    

Bash 脚本基础与自动化

基础脚本语法

Bash 脚本的基础语法包括脚本的结构、变量定义与引用、以及控制结构。掌握这些基础知识是编写有效脚本的前提。

脚本的结构与基本命令

Shebang 行(#!/bin/bash

每个 Bash 脚本的第一行通常是 Shebang 行,用于指定脚本解释器。这行代码告诉系统使用哪个解释器来执行脚本。

示例:

#!/bin/bash
编写与保存脚本文件

编写 Bash 脚本可以使用任何文本编辑器,如 nanovimgedit 等。脚本文件通常以 .sh 作为扩展名,便于识别。

示例:创建一个简单的脚本文件

nano hello.sh

内容:

#!/bin/bash
echo "Hello, World!"
赋予执行权限(chmod +x

在执行脚本之前,需要为脚本文件赋予执行权限。可以使用 chmod 命令来修改文件权限。

示例:

chmod +x hello.sh
执行脚本(./script.sh

赋予执行权限后,可以通过以下方式执行脚本:

示例:

./hello.sh

输出:

Hello, World!

变量定义与引用

变量在 Bash 脚本中用于存储和管理数据。理解变量的定义与引用是编写动态脚本的关键。

定义变量

在 Bash 中,变量可以通过简单的赋值语句进行定义。变量名区分大小写,通常使用大写字母来命名环境变量,小写字母用于脚本内部变量。

示例:

#!/bin/bash
GREETING="Hello"
NAME="Alice"
引用变量

引用变量时,需要在变量名前加上美元符号 $。使用大括号 {} 可以明确变量的边界,尤其在变量名与其他字符相邻时。

示例:

#!/bin/bash
GREETING="Hello"
NAME="Alice"
echo "$GREETING, $NAME!"
echo "${GREETING}, ${NAME}!"

输出:

Hello, Alice!
Hello, Alice!
环境变量与局部变量
  • 环境变量:对所有子进程可见,通常用于配置系统行为。
    示例:
    export PATH="/usr/local/bin:$PATH"
    
  • 局部变量:仅在当前脚本或函数内可见,默认情况下在脚本中定义的变量都是局部变量。
    示例:
    NAME="Bob"
    
变量命名规则与最佳实践
  • 命名规则
    • 变量名只能包含字母、数字和下划线 _
    • 变量名不能以数字开头。
    • 避免使用系统保留的变量名,如 PATHHOME 等。
  • 最佳实践
    • 使用有意义的变量名,便于理解和维护。
    • 采用统一的命名风格,如全大写用于环境变量,全小写或小驼峰用于局部变量。
    • 使用大括号 {} 来引用变量,避免歧义。

示例:

#!/bin/bash
USER_NAME="Charlie"
user_age=30
echo "User: ${USER_NAME}, Age: ${user_age}"

输出:

User: Charlie, Age: 30

控制结构

控制结构用于控制脚本的执行流程,包括条件判断和循环结构。掌握这些结构可以编写更复杂和灵活的脚本。

if 语句

if 语句用于根据条件执行不同的代码块。它是 Bash 中最常用的控制结构之一。

基本语法
if [ 条件 ]; then
    # 条件为真时执行的命令
fi

示例:

#!/bin/bash
NUMBER=10

if [ $NUMBER -gt 5 ]; then
    echo "Number is greater than 5"
fi

输出:

Number is greater than 5
使用条件表达式

Bash 支持多种条件表达式,包括整数比较、字符串比较和文件测试。

  • 整数比较

    • -eq:等于
    • -ne:不等于
    • -gt:大于
    • -lt:小于
    • -ge:大于或等于
    • -le:小于或等于 示例:
    if [ $NUMBER -eq 10 ]; then
        echo "Number is exactly 10"
    fi
    
  • 字符串比较

    • =:等于
    • !=:不等于
    • <:字典序小于
    • >:字典序大于
    • -z:字符串长度为零
    • -n:字符串长度不为零 示例:
    STRING="Hello"
    
    if [ "$STRING" = "Hello" ]; then
        echo "Greeting is Hello"
    fi
    
  • 文件测试

    • -e:文件存在
    • -f:是一个普通文件
    • -d:是一个目录
    • -r:文件可读
    • -w:文件可写
    • -x:文件可执行 示例:
    FILE="/etc/passwd"
    
    if [ -f "$FILE" ]; then
        echo "$FILE exists and is a regular file"
    fi
    
elifelse 分支

elifelse 用于处理多种条件和默认情况,使条件判断更加灵活。

基本语法

if [ 条件1 ]; then
    # 条件1为真时执行的命令
elif [ 条件2 ]; then
    # 条件2为真时执行的命令
else
    # 以上条件均不满足时执行的命令
fi

示例:

#!/bin/bash
NUMBER=7

if [ $NUMBER -gt 10 ]; then
    echo "Number is greater than 10"
elif [ $NUMBER -eq 10 ]; then
    echo "Number is exactly 10"
else
    echo "Number is less than 10"
fi

输出:

Number is less than 10
for 循环

for 循环用于遍历列表或数组中的元素,对每个元素执行指定的命令。

基本语法
for VARIABLE in 列表; do
    # 对每个元素执行的命令
done

示例:

#!/bin/bash
for COLOR in red green blue; do
    echo "Color: $COLOR"
done

输出:

Color: red
Color: green
Color: blue
迭代数组与列表

for 循环可以用于遍历数组或通过命令生成的列表。

示例:遍历数组

#!/bin/bash
FRUITS=("apple" "banana" "cherry")

for FRUIT in "${FRUITS[@]}"; do
    echo "Fruit: $FRUIT"
done

输出:

Fruit: apple
Fruit: banana
Fruit: cherry
嵌套循环

for 循环中嵌套另一个循环,可以处理多维数据或复杂的遍历需求。

示例:

#!/bin/bash
ADJECTIVES=("quick" "lazy")
NOUNS=("fox" "dog")

for ADJ in "${ADJECTIVES[@]}"; do
    for NOUN in "${NOUNS[@]}"; do
        echo "The $ADJ brown $NOUN jumps over the lazy dog."
    done
done

输出:

The quick brown fox jumps over the lazy dog.
The quick brown dog jumps over the lazy dog.
The lazy brown fox jumps over the lazy dog.
The lazy brown dog jumps over the lazy dog.
while 循环

while 循环根据指定的条件持续执行命令,直到条件不再满足。

基本语法
while [ 条件 ]; do
    # 循环体内执行的命令
done

示例:

#!/bin/bash
COUNT=1

while [ $COUNT -le 5 ]; do
    echo "Count: $COUNT"
    COUNT=$((COUNT + 1))
done

输出:

Count: 1
Count: 2
Count: 3
Count: 4
Count: 5
使用条件判断

条件可以是整数比较、字符串比较或文件测试,与 if 语句类似。

示例:检查文件是否存在

#!/bin/bash
FILE="/tmp/myfile.txt"

while [ -f "$FILE" ]; do
    echo "$FILE exists."
    sleep 10
done

echo "$FILE does not exist anymore."
无限循环与终止条件

无限循环常用于需要持续运行的脚本,如守护进程。需要使用特定条件或信号来终止循环。

示例:

#!/bin/bash

while true; do
    echo "Press [CTRL+C] to stop.."
    sleep 5
done

终止方式:

CTRL+C 键终止脚本执行。


本节总结

  • 本节主要围绕 Linux 系统日志管理、日志分析与处理、查看日志、使用 journalctl 查看 systemd 日志、配置日志轮转(logrotate) 展开。
  • 需要重点掌握的命令或工具包括:journalctllogrotate
  • 学习时应优先抓住「命令解决什么问题、在什么场景下使用、执行后会产生什么结果」。
  • 对涉及权限、覆盖、网络、系统服务、删除或安全配置的操作,建议先在测试环境练习。

复习建议

  • 先用自己的话复述本节每个主题或命令的作用,避免只记参数不懂用途。
  • 按原文示例至少手敲一遍典型命令,并观察输出变化。
  • 对高风险操作先确认路径、权限和目标对象,再执行实际命令。
  • 可优先复习这些高频命令:journalctllogrotate