首页 > 解决方案 > 获取设备 ID 的 Shell 脚本

问题描述

好吧,伙计们,我被难住了。下面是一段脚本,旨在通过名称识别设备并打印它所连接的 tty 信息。由于任何时候都可以连接多个这些设备,因此我需要选择编号最小的接口。舔完这部分后,我会将输出定义为变量并使用输出运行 hamlib 脚本,以便我的装备可以与计算机通信。

无论如何,我似乎找不到只捕获第一行的好方法。我已经在我能想到的任何类型的迭代中尝试了 head、awk、sed,输出要么给我两行输出,要么根本没有输出。

这是脚本:

#!/bin/bash
for sysdevpath in $(find /sys/bus/usb/devices/usb*/ -name dev); do
(
    syspath="${sysdevpath%/dev}"
    devname="$(udevadm info -q name -p $syspath)"
    [[ "$devname" == "bus/"* ]] && exit
    eval "$(udevadm info -q property --export -p $syspath)"
    [[ -z "$ID_SERIAL" ]] && exit
    echo "/dev/$devname - $ID_SERIAL" | grep CP2105 | sort | uniq | cut -b 6-12 |
head -1
)
done

输出:

floridomd@GE72VR-7RF:~$ ./port-testing.sh
ttyUSB1
ttyUSB2

我在这里想念什么?

标签: shellhead

解决方案


仅捕获第一行

我需要将输出定义为变量

因此,只需获取第一行并将其放入变量中。

variable=$(
    find /sys/bus/usb/devices/usb*/ -name dev |
    while IFS= read -r sysdevpath; do
       ....
    done | head -n1
)

笔记:

  • echo "" | sort | uniq- 很奇怪 - 为什么 sort 和 uniq 只有一行?这不像是一条改变位置的线。

  • echo "" | grep不在里面if也很奇怪。只需使用if. 你似乎想要if [[ "$ID_SERIAL" == CP2105 ]]; then echo "$devname"; fi

  • for ...; do ( stuff ); done也很奇怪,但有道理 - 你这里eval的输出udevadm。我想我会让它更明显:

    for ...; do
      (
         stuff
      )
    done
    
  • for i in $(...)是一种反模式。不要做。相反,您似乎想要find ... | while IFS= read -r sysdevpath; door for sysdevpath in /sys/bus/usb/devices/usb*/**/dev

  • 使用if cmd1; then cmd2; fis 而不是cmd1 && cmd2为了可读性和可维护性以及一致的退出状态(考虑set -e)。

  • 另请参阅https://mywiki.wooledge.org/BashFAQ/001

  • 用 shellcheck 检查你的脚本。


推荐阅读