You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助:修正Bash脚本以正确提取Windows驱动INF文件的硬件ID并构建MySQL数据库

求助:修正Bash脚本以正确提取Windows驱动INF文件的硬件ID并构建MySQL数据库

我正在开发一个Windows 10/11驱动自动安装系统,之前从DriverPack下载了驱动合集(合集本身没问题,但配套的安装管理软件疑似带病毒)。现在我可以安装几乎所有Windows驱动,但每次搜索正确的.inf文件耗时极长——驱动合集存在我那台Ubuntu 22.04.1服务器(命名为FREEBNT)的SAMBA共享里,每次安装要花20多分钟才能定位到目标.inf。

最近我想到一个优化方案:用MySQL搭建一个硬件ID与.inf文件路径的映射数据库,再写PowerShell脚本通过数据库配合SAMBA快速下载安装驱动。ChatGPT帮我生成了基础代码,但目前卡在第一步——生成数据库的Bash脚本有问题,无法正确提取INF文件里的硬件ID。

FREEBNT同时担任MySQL服务器和SAMBA服务器,我打算在这台机器上运行Bash脚本,把所有.inf文件的硬件ID和对应的Windows可访问路径导入数据库。


我当前使用的Bash脚本

#!/bin/bash

# Set up MySQL database connection parameters
db_user="mymysqluser"
db_pass="mymysqlpass"
db_name="drivers"
db_host="127.0.0.1"

# Set up the path to your drivers collection
drivers_path="/free/fr/drivers/"

# Loop through all INF files in the drivers collection
for inf_file in $(find "$drivers_path" -type f -name "*.inf"); do
    # Extract hardware IDs from INF file
    hwids=$(grep -iE "^driverver|^pci|usb\\\\" "$inf_file" | awk -F ",|=" '{print $2}' | tr -d ' ' | sort -u)
    
    #convert the inf file path to a path readable by Windows systems through SAMBA (added by borhacker)
    inf_file2=$(echo $inf_file | sed 's/\/free\/fr\/drivers\//\\\\192.168.1.2\\Fr-drivers\\/')
    inf_file3=$(echo $inf_file2 | sed 's/\//\\/g')
    
    # Loop through all hardware IDs and insert them into the database
    for hwid in $hwids; do
        echo "Inserting $hwid for $inf_file3 into database..."
        mysql -u $db_user -p$db_pass -h $db_host $db_name -e "INSERT INTO drivers (hwid, path) VALUES ('$hwid', '$inf_file3');"
    done
done

我已完成的修改

我自己添加了路径转换逻辑,能把Linux下的路径:
/free/fr/drivers/bluetooth/DP_Bluetooth_22094/MediaTek/FORCED/10x64/7921_1.3.14.133_tequila/mtkbtfilter.inf

转换成Windows能识别的SAMBA路径:
\\192.168.1.2\Fr-drivers\bluetooth\DP_Bluetooth_22094\MediaTek\FORCED\10x64\7921_1.3.14.133_tequila\mtkbtfilter.inf

这部分功能正常,没有问题。


当前遇到的问题

我搞不懂脚本里提取硬件ID的那段代码,现在运行脚本时,提取出来的根本不是硬件ID,而是驱动版本日期之类的内容,比如运行输出:

root@freebnt:/home/borhacker# ./indexdrivers-edit.sh
Inserting 07/10/2016 for \\192.168.1.2\Fr-drivers\video\DP_Video_nVIDIA-XP_22080\nVidia\FORCED\5x86\368.81\nvmmi.inf into database...
mysql: [Warning] Using a password on the command line interface can be insecure.
Inserting 07/10/2016 for \\192.168.1.2\Fr-drivers\video\DP_Video_nVIDIA-XP_22080\nVidia\FORCED\5x86\368.81\nvbli.inf into database...
mysql: [Warning] Using a password on the command line interface can be insecure.
...

我需要修正这段提取硬件ID的代码,让脚本能正确识别INF文件里的硬件ID(比如PCI\VEN_10DE&DEV_1C82、USB\VID_046D&PID_C52F这类格式),并正确插入数据库。


问题根源与修正方案

1. 问题出在哪?

原来的grep命令错误匹配了^driverver(这是驱动版本行,格式为DriverVer=07/10/2016,368.81,awk提取第二个字段自然拿到日期),同时错误匹配^pci(硬件ID不会以pci开头,而是PCI\),导致完全提取不到正确的硬件ID。

2. 正确的硬件ID提取逻辑

Windows INF文件里的硬件ID通常在[Manufacturer]对应的设备项中,格式为PCI\VEN_XXXX&DEV_XXXX、USB\VID_XXXX&PID_XXXX、ACPI\XXXX等,一般出现在等号后方,部分行还会用逗号分隔多个硬件ID。

此外,部分INF文件采用UTF-16LE编码(Windows默认),直接用grep读取会乱码,需要先转码为UTF-8。

3. 修正后的完整脚本

#!/bin/bash

# Set up MySQL database connection parameters
db_user="mymysqluser"
db_pass="mymysqlpass"
db_name="drivers"
db_host="127.0.0.1"

# Set up the path to your drivers collection
drivers_path="/free/fr/drivers/"

# Loop through all INF files in the drivers collection
find "$drivers_path" -type f -name "*.inf" | while read -r inf_file; do
    # 处理INF文件编码:尝试转码为UTF-8,失败则直接读取
    if iconv -f UTF-16LE -t UTF-8 "$inf_file" >/dev/null 2>&1; then
        inf_content=$(iconv -f UTF-16LE -t UTF-8 "$inf_file")
    else
        inf_content=$(cat "$inf_file")
    fi

    # 提取硬件ID:匹配等号后包含PCI\、USB\、ACPI\、HID\的内容,处理多个ID的情况
    hwids=$(echo "$inf_content" | grep -iE "=.*(PCI\\\USB\\\ACPI\\\HID\\\)" | \
            awk -F "=" '{
                gsub(/["']/, "", $2)
                split($2, ids, /,/)
                for(id in ids) {
                    trimmed = gensub(/^[[:space:]]+|[[:space:]]+$/, "", "g", ids[id])
                    if (trimmed ~ /^(PCI|USB|ACPI|HID)\\\/) {
                        print trimmed
                    }
                }
            }' | tr -d ' ' | sort -u)

    # 如果没有提取到硬件ID,尝试另一种匹配方式(直接找带VEN_/VID_的行)
    if [ -z "$hwids" ]; then
        hwids=$(echo "$inf_content" | grep -iE "(VEN_|VID_)" | \
                awk '{
                    for(i=1; i<=NF; i++) {
                        if ($i ~ /VEN_|VID_/) {
                            gsub(/["']/, "", $i)
                            print $i
                        }
                    }
                }' | tr -d ' ' | sort -u)
    fi

    # 跳过无硬件ID的文件
    if [ -z "$hwids" ]; then
        echo "No hardware IDs found for $inf_file, skipping..."
        continue
    fi

    # 转换为Windows可访问的SAMBA路径
    inf_file3=$(echo "$inf_file" | sed 's/\/free\/fr\/drivers\//\\\\192.168.1.2\\Fr-drivers\\/' | sed 's/\//\\/g')

    # 插入数据库:转义SQL特殊字符避免注入
    for hwid in $hwids; do
        escaped_hwid=$(echo "$hwid" | sed "s/'/''/g")
        escaped_path=$(echo "$inf_file3" | sed "s/'/''/g")
        echo "Inserting $escaped_hwid for $escaped_path into database..."
        mysql -u "$db_user" -p"$db_pass" -h "$db_host" "$db_name" -e "INSERT INTO drivers (hwid, path) VALUES ('$escaped_hwid', '$escaped_path');"
    done
done

4. 额外优化说明

  • 增加了编码处理:自动识别UTF-16LE编码的INF文件并转码,避免乱码导致提取失败
  • 增加了双重提取逻辑:第一种方式失败时,尝试匹配带VEN_/VID_的硬件ID
  • 增加了SQL注入防护:转义字符串中的单引号,避免破坏SQL语句
  • 增加了跳过逻辑:对无硬件ID的INF文件直接跳过,减少无效操作

备注:内容来源于stack exchange,提问作者charlesfreejazz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.23 10:54:52