Это хорошая ситуация для использования readarray/mapfile:
readarray -t usbs < <(lsblk -o NAME,TRAN,VENDOR,MODEL | grep usb)
Это создаст массив с вашим выводом, где каждая строка будет разделена на отдельный элемент.
В вашем случае получится такой массив, как:
usbs=(
'sdb usb Kingston DataTraveler 2.0'
'sdc usb Kingston DT 101 G2'
)
Как и вы, вы присваиваете весь вывод одной переменной (, а не массиву ), что по существу делает это:
usbs='sdb usb Kingston DataTraveler 2.0
sdc usb Kingston DT 101 G2 '
Чтобы сделать это массивом, вы должны:
usbs=($(lsblk -o NAME,TRAN,VENDOR,MODEL | grep usb))
, но это сделало бы каждое слово, разделенное пробелом, отдельным элементом, что эквивалентно:
usbs=(
sdb
usb
Kingston
DataTraveler
2.0
sdc
usb
Kingston
DT
101
G2
)
Как было указано несколькими комментаторами, и это, как правило, лучшая практика во все времена, переменные должны заключаться в кавычки. В этом случае вы должны и, как правило, всегда должны заключать свои переменные в кавычки.
First, I'd say it's not the right way to address the problem. It's a bit like saying "You should not murder people because otherwise you'll go to jail."
Similarly, you don't quote your variable because otherwise you're introducing security vulnerabilities. You quote your variables because it is wrong not to (but if the fear of the jail can help, why not).
- Stéphane Chazelas
В случае for i in ${usbs[@]}; do
i
будет установлено на каждое слово (, разделенное пробелом )в usbs
. Если вы процитируете его как for i in "${usbs[@]}"; do
,тогда i
будет установлен для каждого элемента из usbs
, как требуется.