一、指令(df 和 lsblk)

挂载 和不挂载 区别
不挂载,你就打不开U盘里的任何文件;挂载了,你才能像打开自己电脑的C盘、D盘一样浏览U盘内容。

打个通俗的比喻

状态电脑的角度你的体验
未挂载我知道插了个U盘 (sdb),但我还没决定把它放在哪个窗口打开。你看得见设备名,但点不开,找不到文件
已挂载我已经把U盘的内容映射到了 /media/usb 这个窗口。你打开 /media/usb 就能看到U盘里的照片、文档。
  • 不挂载 = 硬件识别,但无路可走 → 无法访问数据
  • 挂载 = 建立访问路径 → 可以读写文件
# 查看已挂载的USB存储
df -h | grep /media
# 查看块设备(U盘通常显示为 sdX)
[root@localhost kms8.113]# lsblk
NAME            MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
sda               8:0    1 111.8G  0 disk
├─sda1            8:1    1   200M  0 part /boot/efi
├─sda2            8:2    1     1G  0 part /boot
└─sda3            8:3    1 110.6G  0 part
  ├─klas-root   252:0    0    69G  0 lvm  /
  ├─klas-swap   252:1    0     8G  0 lvm  [SWAP]
  └─klas-backup 252:2    0  33.7G  0 lvm
sdb               8:16   1  29.8G  0 disk
└─sdb1            8:17   1  29.8G  0 part
sr0              11:0    1     2M  0 rom

根据 lsblk 的输出,U盘是 sdb 设备(29.8G 大小),但它没有自动挂载(因为 df -h 没有输出 /media 相关的内容)。

需要手动挂载。按以下步骤操作:

# 1. 创建挂载点(如果不存在)
sudo mkdir -p /media/usb

# 2. 挂载U盘(使用第一分区)
sudo mount /dev/sdb1 /media/usb

# 3. 验证挂载成功
df -h /media/usb

挂载后,U盘内容就在 /media/usb 目录下。

使用完卸载

sudo umount /media/usb
  • 执行 df -h | grep /media 没输出:说明系统没有自动帮你挂载(Linux服务器默认不自动挂载外来U盘,这是出于安全和管理考虑)。
  • 执行 lsblk 能看到 sdb:只说明物理连接正常,驱动识别了硬件,但还没给你分配访问路径。

之前blog: linux 的 df基础指令 也提到挂载这个问题

详细解析指令 lsblk

lsblk
NAME            MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
sda               8:0    1 111.8G  0 disk
├─sda1            8:1    1   200M  0 part /boot/efi
├─sda2            8:2    1     1G  0 part /boot
└─sda3            8:3    1 110.6G  0 part
  ├─klas-root   252:0    0    69G  0 lvm  /
  ├─klas-swap   252:1    0     8G  0 lvm  [SWAP]
  └─klas-backup 252:2    0  33.7G  0 lvm
sdb               8:16   1  29.8G  0 disk
└─sdb1            8:17   1  29.8G  0 part
sr0              11:0    1     2M  0 rom

lsblk 是一个非常有用的 Linux 命令,名字是 List Block Devices 的缩写,中文意思是 “列出所有块设备”
1. 什么是"块设备"?
简单理解,块设备就是硬盘、U盘、SSD、SD卡这类可以随机读写、有固定大小的存储设备。它们的特点是:

  • 以"块"(通常是 512 字节或 4KB)为单位读写数据
  • 可以被分区、格式化、挂载

常见的块设备:

设备类型设备名示例
SATA/SAS 硬盘/dev/sda, /dev/sdb
NVMe SSD/dev/nvme0n1
虚拟磁盘 (虚拟机)/dev/vda
光盘/ISO/dev/sr0
SD卡/读卡器/dev/mmcblk0
LVM 逻辑卷/dev/mapper/klas-root

2. lsblk 命令的作用
lsblk 以树形结构显示系统中所有的块设备,清晰展示:

  • 设备之间的父子关系(如:硬盘 → 分区)
  • 每个设备的大小
  • 挂载点(MOUNTPOINT)

3. 各列的含义

列名含义
NAME设备名称(如 sda = 第一块硬盘,sdb = 第二块硬盘)
MAJ:MIN主设备号:次设备号(内核用来识别设备的编号)
RM是否可移除(Removable)。1 = 可移除(如U盘),0 = 不可移除(如内置硬盘)
SIZE设备大小
RO是否只读(Read-Only)。0 = 可读写,1 = 只读
TYPE设备类型:• disk = 物理磁盘• part = 分区• lvm = LVM逻辑卷• rom = 光盘/ISO
MOUNTPOINT挂载点(设备被挂载到哪个目录)

4. 树形结构的解读
sda (整个硬盘)
├─sda1 (第一个分区) → 挂载到 /boot/efi
├─sda2 (第二个分区) → 挂载到 /boot
└─sda3 (第三个分区)
├─klas-root (LVM逻辑卷) → 挂载到 /
├─klas-swap (交换分区)
└─klas-backup (备份卷)

缩进表示父子关系:

  • 没有缩进的 sda、sdb、sr0 是顶层设备(物理磁盘或光盘)
  • 有缩进的 sda1、sda2、sda3 是分区(属于 sda)
  • 更深缩进的 klas-root 是LVM逻辑卷(建立在 sda3 之上)

二、dmesg

dmesg 是一个 Linux 系统下的核心指令,全称是 “display message”(显示消息)或 “driver message”(驱动消息)。

简单说:它是一个用于查看系统内核启动和运行日志的命令。

详细解释
当你的Linux系统启动时,内核(系统的核心)会检测所有硬件(CPU、内存、硬盘、USB接口、网卡等),并加载对应的驱动程序。这个过程会产生大量的日志消息。dmesg 命令就是用来显示这些消息的。

dmesg 能帮你干什么?

  • 查看硬件识别情况:判断新插的设备(如U盘、外置硬盘、USB转串口线)有没有被系统发现。
  • 诊断硬件错误:当有硬件不工作、报错、死机时,dmesg 里通常会留下错误记录。
  • 查看启动过程:看看系统在开机时有没有奇怪的报错。

刚插入一个USB(Ukey),执行 dmesg 或者 sudo dmesg | tail -30 | grep -i usb

[776638.324649] usb 3-2: new full-speed USB device number 3 using xhci_hcd
[776638.532207] usb 3-2: New USB device found, idVendor=3a59, idProduct=4458, bcdDevice= 1.00
[776638.540897] usb 3-2: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[776638.548545] usb 3-2: Product: USBKEY
[776638.552974] usb 3-2: Manufacturer: USBKEY
[776638.567253] usb-storage 3-2:1.0: USB Mass Storage device detected
[776638.573964] scsi host5: usb-storage 3-2:1.0
[776639.637462] scsi 5:0:0:0: CD-ROM            USBKEY   MSCA             1.00 PQ: 0 ANSI: 2
[776639.646352] scsi 5:0:0:0: Attached scsi generic sg2 type 5
[776639.658808] sr 5:0:0:0: [sr0] scsi3-mmc drive: 40x/40x writer cd/rw xa/form2 cdda tray
[776639.667250] cdrom: Uniform CD-ROM driver Revision: 3.20
[776639.673164] sr 5:0:0:0: Attached scsi CD-ROM sr0

设备ID:idVendor=3a59, idProduct=4458

[776638.324649] usb 3-2: new full-speed USB device number 3 using xhci_hcd
↑ ↑ ↑
Bus Port Device编号

Bus 3 (USB控制器3)
Device 3 (该总线上第3个设备)

你插在服务器上的设备 Bus 003 Device 003: ID 3a59:4458 虽然在产品描述里写了 USBKEY,但它的实际接口类是 Mass Storage(存储设备),这意味着它是一个普通U盘或读卡器,不是国密UKey。下面要证实

三、指令(lsusb)

lsusb
Bus 004 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 003 Device 002: ID 058f:6366 Alcor Micro Corp. Multi Flash Reader
Bus 003 Device 003: ID 3a59:4458
Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 002: ID 1a86:7523 QinHeng Electronics HL-340 USB-Serial adapter
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

详细解释如下指令

lsusb -v -s 003:003 2>/dev/null | grep -E "bInterfaceClass|bInterfaceSubClass|bInterfaceProtocol"

      bInterfaceClass         8 Mass Storage
      bInterfaceSubClass      6 SCSI
      bInterfaceProtocol     80 Bulk-Only

1. 命令各部分含义

部分含义
lsusb列出USB设备的命令
-vverbose(详细模式),显示设备的完整描述符信息
-s 003:003指定设备:Bus 003, Device 003(之前看的设备)
2>/dev/null把错误输出扔到黑洞里(忽略权限警告,让输出更干净)
|管道符,不必多说
grep -E用扩展正则表达式进行筛选
“bInterfaceClass|bInterfaceSubClass|bInterfaceProtocol”只显示包含这三个关键词的行

2. 这三个字段是什么意思?
这三个字段是USB设备的接口描述符,共同定义了设备的功能类型。它们是USB协议中的标准字段,由设备固件决定,无法通过软件修改。

字段含义常见值举例
bInterfaceClass接口类8 = Mass Storage(U盘/读卡器),11 = Smart Card(智能卡/UKey),255 = Vendor Specific(厂商自定义,国密Key常用)
bInterfaceSubClass接口子类6 = SCSI(存储设备使用SCSI命令集)
bInterfaceProtocol接口协议80 = Bulk-Only(批量传输,存储设备常用)

3. 类比理解
在这里插入图片描述
4. 结果
输出 8 Mass Storage → 普通U盘
输出 11 Smart Card 或 255 Vendor Specific → 可能是国密UKey

详细解释如下指令

lsusb -t

以树形结构显示 USB 总线的连接层次和设备信息

  • lsusb:命令本身是 “List USB” 的缩写,用于列出系统中的所有 USB 设备。
  • -t:这个参数代表 “Tree”(树形)。
/:  Bus 02.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/6p, 5000M
    |__ Port 1: Dev 2, If 0, Class=Mass Storage, Driver=usb-storage, 5000M
/:  Bus 01.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/12p, 480M
    |__ Port 3: Dev 2, If 0, Class=Hub, Driver=hub/4p, 480M
        |__ Port 1: Dev 3, If 0, Class=Human Interface Device, Driver=usbhid, 12M
        |__ Port 3: Dev 4, If 0, Class=Vendor Specific Class, Driver=r8188eu, 480M

通过这个输出可以解读出:

  • 电脑有两个 USB 总线(Bus 02 和 Bus 01)。
  • Bus 02 是 5000M 速度(即 USB 3.0/3.1 超高速),上面连了一个 U 盘(Mass Storage)
  • Bus 01 是 480M 速度(即 USB 2.0 高速),上面连了一个集线器(Hub),集线器上接着鼠标(HID,12M 全速)和一个无线网卡(480M)。

常用的对比与用途:

  • lsusb(不加参数):以列表形式列出设备,主要是查看设备的 ID 和名称
  • lsusb -t:查看设备的物理插接结构和拓扑关系,对排查设备是否被正确识别、判断设备插在哪个端口上非常有帮助。

需要使用场景:

当你想要了解 “我的 U 盘到底有没有被识别为高速模式?” 或者 “这个 USB 摄像头挂在哪个集线器下面?” 时,运行 lsusb -t 就能一目了然

四、项目代码读取不到Ukey

排查顺序

  1. SKF库文件是否存在
  2. 库文件位数是否匹配Java
  3. SKF库和服务器是否匹配
  4. 是否插入的ukey
  5. Docker中USB设备是否映射
  6. 厂商驱动是否安装

项目代码看到服务器读取: libSKFInterface

    public static SkfInterface INSTANCE = (SkfInterface) Native.load(
            Platform.isWindows() ? "WTSKFInterface" : "SKFInterface", SkfInterface.class);//注意   api库的名称和路径

执行指令查找(排查1,2,3没问题)

find /usr/lib /lib /usr/local/lib -name "*SKF*.so" 2>/dev/null
/usr/lib/libSKFInterface.so

# 64位Java只能加载64位的 .so 文件(我这个正确)
java -version
java version "1.8.0_333"
Java(TM) SE Runtime Environment (build 1.8.0_333-b02)
Java HotSpot(TM) 64-Bit Server VM (build 25.333-b02, mixed mode)
[root@localhost ~]# file /usr/lib/libSKFInterface.so
/usr/lib/libSKFInterface.so: ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), statically linked, with debug_info, not stripped

#如果输出 x86_64,那你的系统是 Intel/AMD 架构,ARM版本的 .so 文件无法使用,但是我这个是架构匹配
uname -m
aarch64

上面 dmesg和lsusb 两个指令结合(排查4有问题)

排查问题5
如何看Docker中USB设备是否映射?

  • 方法一:在容器内查看 USB 设备(最直接)
# 进入你的容器(根据日志,容器名/ID 可能是包含 kms 的)
docker exec -it <容器名或ID> /bin/bash

# 然后在内执行:
lsusb
  • 方法二:查看容器启动参数(检查是否挂载了设备)
# 查看容器的详细配置
docker inspect <容器名或ID> | grep -A 10 "Devices"

关键字段:
“PathOnHost”:宿主机的设备路径
“PathInContainer”:容器内的设备路径
“CgroupPermissions”:权限(如 rwm 表示读写)

示例输出(表示已映射):

"Devices": [
    {
        "PathOnHost": "/dev/ttyUSB0",
        "PathInContainer": "/dev/ttyUSB0",
        "CgroupPermissions": "rwm"
    }
]

示例输出(表示没有映射 USB 设备):

"Devices": null  或  "Devices": []

排查问题6,排查4都过不去看啥6

五、额外尝试(U盘,读卡器,Ukey区别)

U盘是“一体式”的存储设备,读卡器是“分离式”的转接工具
在这里插入图片描述
简单记忆

U盘 = 自带房子的车(能直接住)
读卡器 = 拖车(需要挂载一个房车才能住)
国密UKey = 保险柜(不能住人,只能安全存放贵重物品)

你插的是"拖车"(读卡器),即使你给它挂了"房车"(插了存储卡),它仍然只是一个存储设备,变不成"保险柜"(国密UKey

更多推荐