Сброс USB с использованием вывода lsusb

Это извлечет все символы перед последним «двоеточием» и удалит скобки [ ] как в приведенном вами примере.

rev <yourfile.txt | cut -d: -f2- | rev | tr -d '[]'

Замените yourfile.txt на имя вашего файла или удалите слово <yourfile.txt, чтобы прочитать стандартный вывод.

1
02.07.2021, 04:18
2 ответа

Одним из вариантов может быть использование 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. Оболочка + фильтр на устройстве

Если вы хотите фильтровать по номеру -устройства, лучше всего поместить его в оболочку -скрипт (, которую вы, скорее всего, в любом случае ), а затем сделать что-то вроде:

#! /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. grep, когда awkследует за ним, является ненужным шагом. awkсоответствует регулярным выражениям — и в данном случае это простая строка (в вашем коде ).

awk '/^foo/{ this line starts with foo }'и т. д.

  1. printf $6 "\n"

Похоже, вы хотите напечатать $6+ перевод строки -. Это может быть либо:

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

Он также указывает awk использовать $6в качестве строки формата. Это может испортиться, и в целом это нехорошо. Если бы $6было, например, foo%dbar, awk ожидал бы цифру в качестве параметра. и т. д.

  1. printf "/usr/bin/usbreset %d", $6,скажем "печатная цифра" и здесь значение "6 долларов" . Поскольку поле шесть равно hex:hex, оператор printf будет печатать только первые цифры, если они есть, иначе ноль.
  • 12a1:06df->12
  • a112:3619->0
3
28.07.2021, 11:21

Похоже, это то, что вы пытаетесь сделать:

$ 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 fileна lsusbи удалите echo, когда вы довольны результатом и хотите фактически выполнить команду, отображаемую в данный момент.

1
28.07.2021, 11:21

Теги

Похожие вопросы