1. 验证

1. 验证

我有一个 USB 设备,我希望自动重置,当前有两个 USB 设备,但有时可能会有更多。

[user1@gs10 devt]$ lsusb
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 007: ID 1604:10c0 Tascam Dell Integrated Hub

注意事项:

  • 设备编号会定期更改(固件问题(我这边))
  • 当插入不同的 Tascam Hub 时,ID 将是动态的
  • 字符串也可能会改变,空格,破折号。

我要重置的设备是Device 007。我识别设备ID的方法如下:

[user1@gs10 devt]$ lsusb | grep "Tascam" | awk '{printf $6 "\n"}'
1d6b:0003

工作正常。现在我想将内核的 usbreset 命令作为单行命令运行,而无需手动输入供应商 ID,有什么建议吗?

我的尝试和目标:

lsusb | grep "Tascam" | awk '{printf "/usr/bin/usbreset %d", $6}'
[user1@gs10 devt]$ sudo /usr/bin/usbreset 1d6b:0003

答案1

一种选择是system()直接从内部使用awk


1. 验证

通过从以下位置请求设备进行验证lsusb

lsusb | awk '/Tascam.*Hub$/{ system("lsusb -d " $6) }' 

这将从匹配的整行中获取vendor:product, (字段 6):

  • Tascam<Anything zero or more times>Hub<END-OF-LINE>

并执行:lsusb -d vendor:product

这将执行于全部匹配 Tascam 轮毂


2.真实通话

实际上调用usbreset

lsusb | sudo awk '/Tascam.*Hub$/{ system("/usr/bin/usbreset " $6) }' 

或者也许更好,如果出现错误则退出:

lsusb | sudo awk '/Tascam.*Hub/{ if (system("/usr/bin/usbreset " $6)) exit 1 }' 

作为system(expression)返回命令的退出状态,如果0成功,可以使用它if ()来检查状态是否为<> 0,它将继续exit 1。用其他东西退出然后0发出错误信号。

!= 0如果您发现更容易阅读,则可以选择使用。也许会抛出一个错误。

lsusb | sudo awk '
/Tascam.*Hub/ { 
    if (system("/usr/bin/usbreset " $6) != 0) {
        print "usbreset failed" >"/dev/stderr"
        exit 1 
    } 
}'

3. 设备上的包装器+过滤器

如果你想筛选根据设备号,最好将其包装在 shell 脚本中(无论如何您都可能会这样做),然后执行以下操作:

#! /bin/sh -

# Check argument is given
if [ -z "$1" ]; then
    printf 'Missing device number\n' >&2
    exit 1
fi

# Check sudo or abort
sudo echo >/dev/null || exit 1

lsusb |
sudo awk -v dev="$1" '
BEGIN {
    dev = sprintf("%03d:", dev)
    eno = 1
}
$4 == dev && /Tascam.*Hub/ {
    if (system("/usr/bin/usbreset " $6) != 0) {
        eno = 2
    } else {
        eno = 0
    }
    # Exit on first match of device-number + name
    exit
}
END {
    if (eno == 0)
        print "OK"
    else if (eno == 1)
        print "No device found" >"/dev/stderr"
    else if (eno == 2)
        print "usbreset failed" >"/dev/stderr"
    exit eno
}'

注意事项usbreset

无法在本地安装它,但看起来有些人将参数视为:

/dev/bus/usb/<bus>/<device-number>

在这种情况下,你可能需要使用类似的东西:

# Testing:

system(sprintf("ls -l /dev/bus/usb/%03d/%03d", $2, $4))

# Testing:

system(sprintf("/usr/bin/usbreset /dev/bus/usb/%03d/%03d", $2, $4))

4.有关问题的注意事项:

  1. grepawk下一步是什么时候是一个不必要的步骤。awk匹配正则表达式 - 在本例中它是一个简单的字符串(在您的代码中)。

awk '/^foo/{ this line starts with foo }'ETC。

  1. printf $6 "\n"

看起来你想打印$6+换行。那将是:

print $6
printf "%s\n", $6

它还告诉 awk 用作$6格式字符串。这可能会变得很糟糕,而且通常不是一件好事。$6例如,如果是foo%dbar,awk 会期望一个数字作为参数。 ETC。

  1. printf "/usr/bin/usbreset %d", $6, 说“打印数字”这里的值是“6 美元”。由于字段 6hex:hex打印函数语句将只打印第一个数字(如果有),否则为零。
  • 12a1:06df->12
  • a112:3619->0

答案2

听起来这可能就是您想要做的:

$ cat file | awk '$7=="Tascam"{print $6}' | xargs echo sudo /usr/bin/usbreset
sudo /usr/bin/usbreset 1604:10c0

或者:

$ echo sudo /usr/bin/usbreset "$(cat file | awk '$7=="Tascam"{print $6}')"
sudo /usr/bin/usbreset 1604:10c0

当您对输出感到满意并且想要实际执行当前回显的命令时,替换cat filelsusb并删除。echo

相关内容