One option could be to use system()
directly from within awk
:
1. Validate
Validate by requesting device from lsusb
:
lsusb | awk '/Tascam.*Hub$/{ system("lsusb -d " $6) }'
That would take vendor:product
, (field 6), from whole lines matching:
Tascam<Anything zero or more times>Hub<END-OF-LINE>
and execute: lsusb -d vendor:product
This would execute on all matching Tascam hubs.
2. Real call
Actually call usbreset
:
lsusb | sudo awk '/Tascam.*Hub$/{ system("/usr/bin/usbreset " $6) }'
Or perhaps better, exit if error:
lsusb | sudo awk '/Tascam.*Hub/{ if (system("/usr/bin/usbreset " $6)) exit 1 }'
As system(expression)
return exit status of the command, and 0
is success, one can use if ()
to check as if status is <> 0 it would proceed with exit 1
. Exit with something else then 0
to signal error.
Optionally use != 0
if you find that easier to read. And perhaps throw in an error.
lsusb | sudo awk '
/Tascam.*Hub/ {
if (system("/usr/bin/usbreset " $6) != 0) {
print "usbreset failed" >"/dev/stderr"
exit 1
}
}'
3. Wrapper + filter on Device
If you want to filter by device-number, it would likely be best to wrap it in a shell-script (which you likely would anyhow), and then do something like:
#! /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
}'
Note on usbreset
Not able to install it locally, but looks like some take argument as:
/dev/bus/usb/<bus>/<device-number>
In that case you might need to use something like:
# 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. Note on things in question:
grep
when awk
is next up is an unnecessary step. awk
matches regular expressions – and it in this case it is a simple string (in your code).
awk '/^foo/{ this line starts with foo }'
etc.
printf $6 "\n"
Looks like you want to print $6
+ line-feed. That would be either of:
print $6
printf "%s\n", $6
It also tells awk to use $6
as format string. This can go bad, and is in general not a good thing to do. If $6
was for example foo%dbar
, awk would expect a digit as arameter. etc.
printf "/usr/bin/usbreset %d", $6
, say "print digit" and here value is "$6". As field six is hex:hex
the printf statement will only print the first digits, if any, else zero.
12a1:06df
-> 12
a112:3619
-> 0
lsusb | grep "Tascam" | awk '{printf "/usr/bin/usbreset %d", $6}'
– Beaker Jul 02 '21 at 01:17usbreset
take an arbitrary number of device IDs? I.e.usbreset ID1 ID2 ID3 ...
or only one at a time? – ibuprofen Jul 02 '21 at 03:07