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

树莓派USB格式化脚本中lsblk命令执行异常问题咨询

问题根因

你遇到的错误本质是Bash命令解析顺序的问题:
Bash解析命令的优先级是:先处理重定向、通配符展开,再执行变量替换。你把/dev/sd* 2>/dev/null放到字符串变量xtra中,后续执行$DETECTOR时,变量替换得到的内容会被全部当成lsblk的参数,不会再解析其中的重定向规则,也不会对通配符做展开,所以lsblk会把/dev/sd*、2>、/dev/null都当成要查询的块设备路径,自然就报错了。

修复后的完整脚本
#!/bin/bash

# 定义USB设备检测函数
get_usb_devices() {
    # 开启nullglob:通配符无匹配时返回空数组,而非返回通配符本身
    shopt -s nullglob
    local sd_devs=(/dev/sd*)
    shopt -u nullglob

    # 无匹配设备时直接返回空
    if [ ${#sd_devs[@]} -eq 0 ]; then
        return
    fi

    # 正常调用lsblk,重定向直接写在命令中
    lsblk -n -o NAME,SIZE,TYPE "${sd_devs[@]}" 2>/dev/null
}

zenity --info --text="Remove all USB devices" --width=620 --height=200
not_in=$(get_usb_devices)
zenity --info --text="Insert USB device to format" --width=420 --height=100
usb_in=$(get_usb_devices)

# 提取新增设备,直接过滤diff结果中>开头的新增行,丢弃diff格式符号
# 以下是两种常用提取方式,按需选择:
# 1. 仅提取设备名存入数组
drive=($(diff <(echo "$not_in") <(echo "$usb_in") | grep '^>' | sed 's/^> *//' | awk '{print $1}'))
# 2. 保留完整的设备信息(名称、大小、类型)存入数组,每行一个元素
# mapfile -t drive < <(diff <(echo "$not_in") <(echo "$usb_in") | grep '^>' | sed 's/^> *//')

# 测试输出
echo "===== 无设备时输出 ====="
echo "$not_in"
echo -e "\n===== 插入设备后输出 ====="
echo "$usb_in"
echo -e "\n===== 新增设备数组内容 ====="
printf "%s\n" "${drive[@]}"
关键调整说明
  • 弃用字符串存储命令的写法,改用Bash函数封装检测逻辑,符合Bash的解析规则,通配符、重定向都能正常生效
  • 增加nullglob选项处理无USB设备的场景,避免通配符无匹配时直接把/dev/sd*字符串传给lsblk
  • 优化新增设备提取逻辑,直接过滤diff的输出结果,避免多余的非ASCII符号(如树结构的└─字符)和diff格式符污染数组内容
  • 若需要保留每行完整的设备信息,可使用mapfile按行存入数组,避免空格拆分问题

内容的提问来源于stack exchange,提问作者Thomas Loves Tech

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 07:24:03