Linux lsmod命令

模块状态查看: lsmod命令用于显示当前Linux内核中已加载的模块信息,是内核模块管理的重要工具。

命令简介

lsmod(list modules)命令用于显示当前Linux内核中已加载的模块信息。它读取/proc/modules文件的内容,并以易于阅读的格式显示模块名称、大小、使用计数和依赖关系。

主要功能
  • 显示已加载的内核模块列表
  • 显示模块大小和使用计数
  • 显示模块之间的依赖关系
  • 实时监控模块加载状态
  • 故障排除和系统分析
适用场景
  • 系统调试和故障排除
  • 驱动程序和模块开发
  • 系统性能分析
  • 安全审计和监控
  • 硬件兼容性检查

命令语法

lsmod [选项]

参数说明

选项 说明
-h, --help 显示帮助信息
-V, --version 显示版本信息
-F, --format 指定输出格式(部分版本支持)

输出格式详解

lsmod命令的输出通常包含三列:

lsmod输出示例
Module                  Size  Used by
usb_storage            65536  1
uas                    24576  0
nls_utf8               16384  1
isofs                  45056  1
fuse                  139264  3
nls_iso8859_1          16384  1
usbhid                 57344  0
hid                   135168  2 usbhid,hid_generic

各列含义说明

列名 说明 示例
Module 模块名称 usb_storage, fuse
Size 模块占用内存大小(字节) 65536(64KB)
Used by
  • 数字:使用该模块的其他模块数量
  • 名称:依赖该模块的其他模块名称
  • -1:表示模块正在卸载中
  • 0:表示没有模块依赖
1, usbhid,hid_generic

使用示例

lsmod命令通常不需要root权限,所有用户都可以查看模块信息。

1. 基本用法 - 查看所有已加载模块

直接运行lsmod命令查看所有已加载的内核模块:

# 查看所有已加载模块
lsmod

# 查看模块数量
lsmod | wc -l

# 查看前10个模块
lsmod | head -10

# 查看后10个模块
lsmod | tail -10

2. 查找特定模块

使用grep过滤特定模块:

# 查找USB相关模块
lsmod | grep -i usb

# 查找网络相关模块
lsmod | grep -E "(net|eth|ip|tcp|udp)"

# 查找文件系统模块
lsmod | grep -E "(ext|ntfs|fat|fuse|xfs|btrfs)"

# 查找特定模块(如fuse)
lsmod | grep fuse

# 不区分大小写查找
lsmod | grep -i wireless

3. 分析模块依赖关系

查看模块的使用情况和依赖关系:

# 查看哪些模块被其他模块使用
lsmod | grep -v " 0$"

# 查看没有依赖的模块(Used by为0)
lsmod | grep " 0$"

# 查看使用计数最多的模块
lsmod | sort -k3 -nr | head -10

# 查看占用内存最大的模块
lsmod | sort -k2 -nr | head -10

4. 结合其他命令使用

lsmod可以与其他命令结合使用:

# 结合awk格式化输出
lsmod | awk '{printf "%-30s %10s %s\n", $1, $2, $3}'

# 计算所有模块占用的总内存
lsmod | awk '{sum += $2} END {print "总内存占用: " sum/1024 " KB"}'

# 显示模块详细信息(结合modinfo)
lsmod | grep usb_storage | awk '{print $1}' | xargs modinfo

# 监控模块加载变化
watch -n 1 lsmod

# 保存模块列表到文件
lsmod > modules_list.txt
lsmod | tee modules_backup.txt

5. 实用脚本示例

创建实用的模块分析脚本:

#!/bin/bash
# 模块分析脚本

echo "=== 系统模块分析报告 ==="
echo "生成时间: $(date)"
echo ""

# 1. 模块统计
TOTAL_MODULES=$(lsmod | wc -l)
echo "1. 模块统计:"
echo "   已加载模块总数: $((TOTAL_MODULES-1))"  # 减去标题行
echo ""

# 2. 占用内存统计
echo "2. 内存占用分析:"
lsmod | tail -n +2 | awk '
{
    modules[$1] = $2;
    total += $2;
}
END {
    printf "   总内存占用: %.2f MB\n", total/1048576;

    # 找出占用最多的5个模块
    print "   内存占用最多的5个模块:";
    n = asorti(modules, sorted_modules, "@val_num_desc");
    for (i=1; i<=5 && i<=n; i++) {
        mod = sorted_modules[i];
        printf "     %-30s %.2f MB\n", mod, modules[mod]/1048576;
    }
}'
echo ""

# 3. 使用计数分析
echo "3. 模块使用分析:"
lsmod | tail -n +2 | awk '
{
    if ($3 == "0") {
        unused++;
    } else {
        used++;
        # 提取使用计数(如果只是数字)
        if ($3 ~ /^[0-9]+$/) {
            use_count = $3;
        } else {
            # 如果包含模块名,统计逗号分隔的数量
            use_count = split($3, arr, ",");
        }
        if (use_count > max_use) {
            max_use = use_count;
            max_mod = $1;
        }
    }
}
END {
    printf "   被使用的模块: %d\n", used;
    printf "   未被使用的模块: %d\n", unused;
    printf "   最多依赖的模块: %s (%d个依赖)\n", max_mod, max_use;
}'
echo ""

# 4. 常见模块检查
echo "4. 常见模块状态:"
for module in fuse usb_storage nvidia nfs overlay ext4; do
    if lsmod | grep -q "^$module "; then
        echo "   $module: ✓ 已加载"
    else
        echo "   $module: ✗ 未加载"
    fi
done

相关命令

命令 描述 与lsmod的关系
insmod 加载内核模块 lsmod查看加载结果
rmmod 移除内核模块 lsmod确认移除后状态
modprobe 智能加载/移除模块(处理依赖) lsmod查看模块状态
modinfo 显示模块详细信息 lsmod查看基本信息,modinfo查看详细信息
depmod 生成模块依赖关系 lsmod显示运行时依赖
dmesg 查看内核日志 lsmod查看模块状态,dmesg查看加载日志

实际应用场景

场景1:硬件故障排除
#!/bin/bash
# 硬件驱动故障排除脚本

echo "=== 硬件驱动检查 ==="

# 检查USB驱动
echo "1. USB相关模块:"
lsmod | grep -E "(usb|uhci|ohci|ehci|xhci)" | while read line; do
    echo "   $line"
done

# 检查网络驱动
echo ""
echo "2. 网络相关模块:"
NET_MODULES=$(lsmod | grep -E "(eth|net|wireless|wlan|ath|rtl|iwl)" | wc -l)
if [ $NET_MODULES -gt 0 ]; then
    lsmod | grep -E "(eth|net|wireless|wlan|ath|rtl|iwl)" | while read line; do
        echo "   $line"
    done
else
    echo "   未检测到网络驱动模块"
fi

# 检查图形驱动
echo ""
echo "3. 图形相关模块:"
if lsmod | grep -q "nvidia"; then
    echo "   NVIDIA驱动已加载"
elif lsmod | grep -q "amdgpu"; then
    echo "   AMD GPU驱动已加载"
elif lsmod | grep -q "i915"; then
    echo "   Intel集成显卡驱动已加载"
else
    echo "   未检测到专用图形驱动"
fi

# 检查存储驱动
echo ""
echo "4. 存储相关模块:"
lsmod | grep -E "(sd|ahci|nvme|scsi|sata)" | head -5 | while read line; do
    echo "   $line"
done

echo ""
echo "=== 检查完成 ==="
场景2:系统安全审计
#!/bin/bash
# 系统安全审计 - 内核模块检查

echo "=== 内核模块安全审计 ==="
echo "审计时间: $(date)"
echo ""

# 1. 检查可疑模块
SUSPICIOUS_PATTERNS="(sniffer|keylogger|rootkit|backdoor|hack)"
echo "1. 可疑模块检查:"
SUSPICIOUS_FOUND=$(lsmod | grep -i -E "$SUSPICIOUS_PATTERNS")
if [ -n "$SUSPICIOUS_FOUND" ]; then
    echo "   警告:发现可疑模块!"
    echo "$SUSPICIOUS_FOUND" | while read line; do
        echo "   ! $line"
    done
else
    echo "   未发现明显可疑模块"
fi

# 2. 检查隐藏模块(通过/proc/modules对比)
echo ""
echo "2. 隐藏模块检查:"
LSMOD_COUNT=$(lsmod | wc -l)
PROC_MODULES_COUNT=$(cat /proc/modules | wc -l)

if [ "$LSMOD_COUNT" -ne "$PROC_MODULES_COUNT" ]; then
    echo "   警告:lsmod和/proc/modules模块数量不一致!"
    echo "   lsmod显示: $((LSMOD_COUNT-1)) 个模块"
    echo "   /proc/modules显示: $PROC_MODULES_COUNT 个模块"
    echo "   可能存在隐藏模块"
else
    echo "   lsmod和/proc/modules模块数量一致"
fi

# 3. 检查无线网络监控模块
echo ""
echo "3. 无线网络监控模块:"
MONITOR_MODULES="(ath9k|rtl8187|rt2800usb)"
MONITOR_FOUND=$(lsmod | grep -E "$MONITOR_MODULES")
if [ -n "$MONITOR_FOUND" ]; then
    echo "   发现无线监控相关模块:"
    echo "$MONITOR_FOUND" | while read line; do
        echo "   $line"
    done
else
    echo "   未发现无线监控相关模块"
fi

# 4. 检查虚拟化相关模块
echo ""
echo "4. 虚拟化相关模块:"
VIRT_MODULES=$(lsmod | grep -E "(kvm|virt|vbox|vmware)" | wc -l)
if [ $VIRT_MODULES -gt 0 ]; then
    echo "   发现虚拟化相关模块 ($VIRT_MODULES 个):"
    lsmod | grep -E "(kvm|virt|vbox|vmware)" | while read line; do
        echo "   $line"
    done
else
    echo "   未发现虚拟化相关模块"
fi

echo ""
echo "=== 审计完成 ==="
echo "建议:定期检查模块列表,注意异常模块加载"
场景3:性能监控和优化
#!/bin/bash
# 内核模块性能监控脚本

echo "=== 内核模块性能监控 ==="
echo "监控时间: $(date)"
echo "监控间隔: 5秒"
echo "按 Ctrl+C 停止监控"
echo ""

# 创建临时文件记录初始状态
TEMP_FILE=$(mktemp)
lsmod > "$TEMP_FILE"

# 监控循环
while true; do
    clear
    echo "=== 内核模块性能监控 ==="
    echo "时间: $(date)"
    echo ""

    # 获取当前模块状态
    CURRENT_MODULES=$(mktemp)
    lsmod > "$CURRENT_MODULES"

    # 1. 模块变化检测
    echo "1. 模块变化检测:"
    NEW_MODULES=$(comm -13 "$TEMP_FILE" "$CURRENT_MODULES" | grep -v "Module" | wc -l)
    REMOVED_MODULES=$(comm -23 "$TEMP_FILE" "$CURRENT_MODULES" | grep -v "Module" | wc -l)

    if [ "$NEW_MODULES" -gt 0 ]; then
        echo "   新加载模块: $NEW_MODULES 个"
        comm -13 "$TEMP_FILE" "$CURRENT_MODULES" | tail -n +2 | while read line; do
            echo "   + $(echo $line | awk '{print $1}')"
        done
    else
        echo "   无新模块加载"
    fi

    if [ "$REMOVED_MODULES" -gt 0 ]; then
        echo "   已卸载模块: $REMOVED_MODULES 个"
        comm -23 "$TEMP_FILE" "$CURRENT_MODULES" | tail -n +2 | while read line; do
            echo "   - $(echo $line | awk '{print $1}')"
        done
    else
        echo "   无模块卸载"
    fi

    # 2. 内存使用统计
    echo ""
    echo "2. 内存使用统计:"
    TOTAL_MEM=$(lsmod | tail -n +2 | awk '{sum += $2} END {print sum/1024}')
    echo "   总内存占用: ${TOTAL_MEM} KB"

    # 3. 使用计数监控
    echo ""
    echo "3. 高使用率模块:"
    lsmod | tail -n +2 | awk '
    $3 ~ /^[0-9]+$/ && $3 > 5 {
        printf "   %-25s 使用计数: %d\n", $1, $3
    }' | head -5

    # 4. 监控特定关键模块
    echo ""
    echo "4. 关键模块状态:"
    for module in ext4 fuse overlay nfs usb_storage; do
        if grep -q "^$module " "$CURRENT_MODULES"; then
            STATUS=$(grep "^$module " "$CURRENT_MODULES" | awk '{print "大小: " $2/1024 " KB, 使用: " $3}')
            echo "   $module: ✓ $STATUS"
        else
            echo "   $module: ✗ 未加载"
        fi
    done

    # 更新临时文件
    cp "$CURRENT_MODULES" "$TEMP_FILE"

    # 清理临时文件
    rm -f "$CURRENT_MODULES"

    # 等待5秒
    echo ""
    echo "下次更新: 5秒后..."
    sleep 5
done

# 清理
rm -f "$TEMP_FILE"

常见问题解答

A: "Used by"列显示模块的使用情况:

  • 数字: 表示有多少个其他模块依赖此模块。例如"3"表示有3个模块依赖此模块。
  • 模块名: 列出具体依赖此模块的其他模块名称,多个模块用逗号分隔。
  • 组合: 有时会显示"1 module_name",表示有一个模块依赖,并且显示该模块名。
  • 0: 表示没有其他模块依赖此模块。
  • -1: 表示模块正在卸载过程中。
# 示例说明
Module          Size  Used by
fuse           139264 3           # 有3个模块依赖fuse
usbhid          57344 0           # 没有模块依赖usbhid
hid            135168 2 usbhid    # 有2个模块依赖hid,其中一个是usbhid

A: 两者显示相同的信息,但格式不同:

# lsmod的输出(格式化,易读)
lsmod

# /proc/modules的输出(原始格式)
cat /proc/modules

# 比较两者
diff <(lsmod | tail -n +2 | sort) <(cat /proc/modules | awk '{print $1,$2,$3,$4}' | sort)

# /proc/modules格式说明:
# 字段1:模块名
# 字段2:模块大小
# 字段3:引用计数
# 字段4:依赖模块列表(逗号分隔)
# 字段5:状态(Live, Loading, Unloading)
# 字段6:内存偏移量
# 字段7:等号后面是模块的.init.text等段信息

lsmod实际上就是读取并格式化显示/proc/modules的内容。

A: 使用modinfo命令查看模块的详细信息:

# 查看模块详细信息
modinfo fuse

# 结合lsmod查看所有已加载模块的详细信息
lsmod | awk 'NR>1 {print $1}' | xargs -I {} modinfo {}

# 查看模块参数
modinfo -p fuse

# 查看模块文件路径
modinfo -n fuse

# 查看模块依赖关系
modprobe --show-depends fuse

# 查看模块在内核日志中的加载信息
dmesg | grep fuse

A: 有几种方法可以监控模块的变化:

# 方法1:使用watch命令实时监控
watch -n 1 lsmod

# 方法2:监控内核日志
watch -n 1 'dmesg | tail -20'

# 方法3:使用脚本记录变化
#!/bin/bash
PREV=$(mktemp)
lsmod > $PREV
while true; do
    sleep 1
    CURR=$(mktemp)
    lsmod > $CURR
    diff $PREV $CURR && echo "无变化" || echo "有变化"
    mv $CURR $PREV
done

# 方法4:使用systemtap或perf(高级工具)
# 需要安装systemtap
# stap -e 'probe module.load { printf("%s loaded\n", module_name()) }'

# 方法5:监控/sys/module/目录
watch -n 1 'ls /sys/module/ | wc -l'

最佳实践

应该做的
  • 定期检查模块列表,了解系统状态
  • 在安装新硬件前检查相关驱动模块
  • 故障排除时先检查相关模块是否加载
  • 结合dmesg查看模块加载日志
  • 使用modinfo查看模块详细信息
不应该做的
  • 不要随意卸载不了解的模块
  • 不要仅凭模块名判断其功能
  • 不要忽略模块使用计数(可能导致系统崩溃)
  • 不要在未备份的情况下修改关键模块
  • 不要在生产环境中随意测试模块操作
命令总结
  • lsmod 用于显示当前加载的内核模块信息
  • 输出格式: 模块名、大小(字节)、使用情况
  • 数据源: 读取/proc/modules文件
  • 常用场景: 系统调试、硬件检查、安全审计、性能监控
  • 相关命令: insmod, rmmod, modprobe, modinfo, dmesg
  • 权限要求: 普通用户可查看,无需特殊权限
  • 重要提示: 模块使用计数为0时才可以安全卸载

模块管理完整工作流

  1. 查看状态: lsmod 查看已加载模块
  2. 获取信息: modinfo 模块名 查看详细信息
  3. 检查依赖: modprobe --show-depends 模块名
  4. 加载模块: modprobe 模块名insmod 模块.ko
  5. 验证加载: lsmod | grep 模块名dmesg | tail -20
  6. 卸载模块: rmmod 模块名(确保使用计数为0)
  7. 监控变化: watch -n 1 lsmod 或监控/proc/modules