Сейчас, когда поддержка JFX для ARM со стороны Oracle прекращена, я бы попробовал https://wiki.openjdk.java.net/display/OpenJFX/Building+OpenJFX
Это хорошая ситуация для использования 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
, как требуется.
В основном это дубликат новых строк и переменной bash , хотя это не распространяется на массивы. Оттуда, чтобы использовать переменную, содержащую несколько строк, вам нужно разделить расширение параметра на новую строку и пропустить подстановку, и в зависимости от ваших данных, возможно, избежать других искажений:
usbs=$( lsusb... )
IFS=$'\n' # ksh bash zsh; in other shells you may need to quote an actual newline
set -o noglob # or more tersely set -f
for i in $usbs; do
printf '%s\n' "$i" # not echo which sometimes modifies some data
done
# if you do further things in the same script (or function) you may
# need to re-set IFS and/or glob, which may require saving them first
Для массива readarray/mapfile
, предложенный Джесси _b, является самым простым, поскольку он уже разбивается на строки. Но вы можете сделать это "вручную" так же, как описано выше :
set -o noglob # ditto
IFS=$'\n' usbs=( $( lsusb... ) ) # only ksh up has arrays so $'' safe
# set +o noglob or set +f if needed
for i in "${usbs[@]}"; do # quoted array[@] forces splits equal to array elements only
printf '%s\n' "$i"
done