Aqui, se lsusb der um erro, a mensagem de erro não será redirecionada, apenas erros de grep . Os erros de lsusb continuam a ser os usuais stderr , ou seja, o terminal (ou o que quer que seja stderr quando o script foi iniciado.
VENDOR=$(lsusb -D "$DEVICE" | grep idVendor 2>&1)
Por exemplo,
$ blah=$(ls -l /nonexisting | grep foo 2>&1)
ls: cannot access '/nonexisting': No such file or directory
$ echo "blah: '$blah'"
blah: ''
Você precisará redirecionar ambas as saídas como um grupo para que a substituição do comando capture o erro também:
$ blah=$( { ls -l /nonexisting | grep foo; } 2>&1)
$ echo "blah: '$blah'"
blah: 'ls: cannot access '/nonexisting': No such file or directory'
Usar redirecionamentos separados como $( foo 2>&1 | grep 2>&1 ) enviaria os erros do primeiro comando para o pipe e para grep para filtrar, o que no exemplo acima produziria novamente uma saída vazia.