У меня почти есть та же установка. Набор внутренних дисков и одного внешнего USB.
# dmesg
ugen5.3: <Seagate> at usbus5
umass1: <Seagate External, class 0/0, rev 2.10/0.12, addr 3> on usbus5
umass1: SCSI over Bulk-Only; quirks = 0x4100
umass1:9:1:-1: Attached to scbus9
da4 at umass-sim1 bus 1 scbus9 target 0 lun 0
da4: <Seagate External SG12> Fixed Direct Access SCSI-4 device
da4: 40.000MB/s transfers
da4: 1907729MB (3907029164 512 byte sectors: 255H 63S/T 243201C)
# usbconfig
ugen5.3: <External Seagate> at usbus5, cfg=0 md=HOST spd=HIGH (480Mbps) pwr=ON
# camcontrol inquiry da4 -R
pass9: 40.000MB/s transfers
Таким образом для ответа на первый вопрос "-подключенный к корректному USB-порту", можно проверить это с usbconfig -u 1 -a 2
команда. Если это возвращается ugen1.2: <Elements 1042 Western Digital>
чем он соединен правильно. Учитывая, что ugen1.2 является портом USB3. И я думаю в Вашем случае, можно безопасно принять это Elements 1042
должно быть достойно Elements 1042
как примечания Killermist.
Скорость может быть проверена (в Вашем случае) с любым usbconfig -u 1 -a 2
команда или camcontrol inquiry da1 -R
. В моем примере 480 Мбит/с приблизительно 57,2 МБ/с. Но из-за протокола usb наверху, я, вероятно, не могу достигнуть той пропускной способности. Так 40 МБ/с, что возвраты драйвера передачи звучат реалистичными мне.
/bin/sh
в настоящее время практически не является оболочкой Борна ни на одной из систем (даже Solaris, которая была одной из последних основных систем, включивших ее, теперь переключился на POSIX sh для своей /bin/sh в Solaris 11). /bin/sh
был оболочкой Томпсона в начале 70-х годов. Панцирь Борна заменил его в Unix V7 в 1979 г.
/bin/sh
был панцирем Борна в течение многих лет после этого (или панцирем Альмквиста, свободная реимплементация на BSD).
В настоящее время /bin/sh
чаще всего является интерпретатором или другим для языка POSIX sh
, который сам по себе основан на подмножестве языка ksh88 (и надмножестве языка оболочки Борна с некоторыми несовместимостями).
Оболочка Борна или спецификация языка POSIX sh не поддерживают массивы. Вернее, они имеют только один массив: позиционные параметры ($1
, $2
, $@
, поэтому и один массив на функцию тоже).
ksh88 действительно имел массивы, которые вы устанавливаете с помощью set -A
, но они не были указаны в POSIX sh, так как синтаксис неудобен и не очень удобен.
Другие оболочки с переменными массивов/списков включают в себя: csh
/tcsh
, rc
, es
, bash
(которые в основном копировали синтаксис ksh способом ksh93), yash
, zsh
, fish
каждый из которых имеет свой синтаксис (rc
панцирь когда-то созданного преемника Unix, fish
и zsh
являются наиболее последовательными). ..
В стандарте sh
(также работает в современных версиях панциря Борна):
set '1st element' 2 3 # setting the array
set -- "$@" more # adding elements to the end of the array
shift 2 # removing elements (here 2) from the beginning of the array
printf '<%s>\n' "$@" # passing all the elements of the $@ array
# as arguments to a command
for i do # looping over the elements of the $@ array ($1, $2...)
printf 'Looping over "%s"\n' "$i"
done
printf '%s\n' "$1" # accessing individual element of the array.
# up to the 9th only with the Bourne shell though
# (only the Bourne shell), and note that you need
# the braces (as in "${10}") past the 9th in other
# shells.
printf '%s\n' "$# elements in the array"
printf '%s\n' "$*" # join the elements of the array with the
# first character (byte in some implementations)
# of $IFS (not in the Bourne shell where it's on
# space instead regardless of the value of $IFS)
(обратите внимание, что в оболочке Борна и ksh88, $IFS
должен содержать символ пробела, чтобы "$@"
работал правильно (ошибка), а в оболочке Борна вы не можете получить доступ к элементам выше $9
(${10}
не сработает, вы все равно можете сделать сдвиг 1; эхо "$9"
или цикл над ними))).
В обычном оболочке Борна нет массивов. Вы можете использовать следующий способ создания массива и его обхода:
#!/bin/sh
# ARRAY.sh: example usage of arrays in Bourne Shell
array_traverse()
{
for i in $(seq 1 $2)
do
current_value=$1$i
echo $(eval echo \$$current_value)
done
return 1
}
ARRAY_1=one
ARRAY_2=two
ARRAY_3=333
array_traverse ARRAY_ 3
Независимо от того, какой способ использования массивов в sh
выберете, он всегда будет громоздким. Рассмотрите возможность использования другого языка, например, Python
или Perl
, если только вы не застряли на очень ограниченной платформе или не хотите чему-то научиться.
Как сказано другое, оболочка Bourne не имеет True массивов.
Однако, в зависимости от того, что вам нужно сделать, разграниченные строки должны достаться:
sentence="I don't need arrays because I can use delimited strings"
for word in $sentence
do
printf '%s\n' "$word"
done
Если типичные разделители (пространство, вкладка и новая линия) не хватает, вы можете установить IFS
к тому, что Разделитель, который вы хотите перед циклом.
И если вам нужно создать массив программно, вы можете просто создать разграниченную строку.
Способ моделирования массивов в тире (его можно адаптировать для любого количества измерений array):
(Обратите внимание, что использование команды seq
требует, чтобы для параметра IFS
было установлено значение "" (ПРОБЕЛ = значение по умолчанию). Вы можете использовать while ... do ...
или do ... while ...
циклы вместо этого, чтобы избежать этого (я оставил seq
в рамках лучшей иллюстрации того, что делает код).)
#!/bin/sh
## The following functions implement vectors (arrays) operations in dash:
## Definition of a vector <v>:
## v_0 - variable that stores the number of elements of the vector
## v_1..v_n, where n=v_0 - variables that store the values of the vector elements
VectorAddElementNext () {
# Vector Add Element Next
# Adds the string contained in variable $2 in the next element position (vector length + 1) in vector $1
local elem_value
local vector_length
local elem_name
eval elem_value=\"\$$2\"
eval vector_length=\$$1\_0
if [ -z "$vector_length" ]; then
vector_length=$((0))
fi
vector_length=$(( vector_length + 1 ))
elem_name=$1_$vector_length
eval $elem_name=\"\$elem_value\"
eval $1_0=$vector_length
}
VectorAddElementDVNext () {
# Vector Add Element Direct Value Next
# Adds the string $2 in the next element position (vector length + 1) in vector $1
local elem_value
local vector_length
local elem_name
eval elem_value="$2"
eval vector_length=\$$1\_0
if [ -z "$vector_length" ]; then
vector_length=$((0))
fi
vector_length=$(( vector_length + 1 ))
elem_name=$1_$vector_length
eval $elem_name=\"\$elem_value\"
eval $1_0=$vector_length
}
VectorAddElement () {
# Vector Add Element
# Adds the string contained in the variable $3 in the position contained in $2 (variable or direct value) in the vector $1
local elem_value
local elem_position
local vector_length
local elem_name
eval elem_value=\"\$$3\"
elem_position=$(($2))
eval vector_length=\$$1\_0
if [ -z "$vector_length" ]; then
vector_length=$((0))
fi
if [ $elem_position -ge $vector_length ]; then
vector_length=$elem_position
fi
elem_name=$1_$elem_position
eval $elem_name=\"\$elem_value\"
if [ ! $elem_position -eq 0 ]; then
eval $1_0=$vector_length
fi
}
VectorAddElementDV () {
# Vector Add Element
# Adds the string $3 in the position $2 (variable or direct value) in the vector $1
local elem_value
local elem_position
local vector_length
local elem_name
eval elem_value="$3"
elem_position=$(($2))
eval vector_length=\$$1\_0
if [ -z "$vector_length" ]; then
vector_length=$((0))
fi
if [ $elem_position -ge $vector_length ]; then
vector_length=$elem_position
fi
elem_name=$1_$elem_position
eval $elem_name=\"\$elem_value\"
if [ ! $elem_position -eq 0 ]; then
eval $1_0=$vector_length
fi
}
VectorPrint () {
# Vector Print
# Prints all the elements names and values of the vector $1 on sepparate lines
local vector_length
vector_length=$(($1_0))
if [ "$vector_length" = "0" ]; then
echo "Vector \"$1\" is empty!"
else
echo "Vector \"$1\":"
for i in $(seq 1 $vector_length); do
eval echo \"[$i]: \\\"\$$1\_$i\\\"\"
###OR: eval printf \'\%s\\\n\' \"[\$i]: \\\"\$$1\_$i\\\"\"
done
fi
}
VectorDestroy () {
# Vector Destroy
# Empties all the elements values of the vector $1
local vector_length
vector_length=$(($1_0))
if [ ! "$vector_length" = "0" ]; then
for i in $(seq 1 $vector_length); do
unset $1_$i
done
unset $1_0
fi
}
##################
### MAIN START ###
##################
## Setting vector 'params' with all the parameters received by the script:
for i in $(seq 1 $#); do
eval param="\${$i}"
VectorAddElementNext params param
done
# Printing the vector 'params':
VectorPrint params
read temp
## Setting vector 'params2' with the elements of the vector 'params' in reversed order:
if [ -n "$params_0" ]; then
for i in $(seq 1 $params_0); do
count=$((params_0-i+1))
VectorAddElement params2 count params_$i
done
fi
# Printing the vector 'params2':
VectorPrint params2
read temp
## Getting the values of 'params2'`s elements and printing them:
if [ -n "$params2_0" ]; then
echo "Printing the elements of the vector 'params2':"
for i in $(seq 1 $params2_0); do
eval current_elem_value=\"\$params2\_$i\"
echo "params2_$i=\"$current_elem_value\""
done
else
echo "Vector 'params2' is empty!"
fi
read temp
## Creating a two dimensional array ('a'):
for i in $(seq 1 10); do
VectorAddElement a 0 i
for j in $(seq 1 8); do
value=$(( 8 * ( i - 1 ) + j ))
VectorAddElementDV a_$i $j $value
done
done
## Manually printing the two dimensional array ('a'):
echo "Printing the two-dimensional array 'a':"
if [ -n "$a_0" ]; then
for i in $(seq 1 $a_0); do
eval current_vector_lenght=\$a\_$i\_0
if [ -n "$current_vector_lenght" ]; then
for j in $(seq 1 $current_vector_lenght); do
eval value=\"\$a\_$i\_$j\"
printf "$value "
done
fi
printf "\n"
done
fi
################
### MAIN END ###
################