Похоже, вы пытаетесь использовать ассоциативный массив, который невозможен в версии bash по умолчанию, которая поставляется с macos, поэтому для этого вам придется обновить bash до версии 4 или выше, но вам также потребуется изменить:
declare -a _name _hash
с по
declare -A _name _hash
В качестве стандартного массива единственное, что может быть в индексах, это целые числа, и вы можете выполнять арифметическое расширение внутри [... ]
, поэтому он задыхается от нецелочисленных/недопустимых операций, которые вы там расширяете.
Как указал jesse _b , проблема в том, что ваш массив не является ассоциативным массивом. bash
в macOS не знает, как работать с ассоциативными массивами, поэтому подумайте о том, чтобы переписать его в zsh
или использовать обычные массивы. В качестве альтернативы установите обновленную оболочку bash
, используя, например,. Homebrew и исправьте declare -a
на declare -A
.
Следующее будет работать со значением по умолчанию bash
в macOS, при условии, что jq
также установлено:
menu_select_server () {
local server_json=file.json # JSON containing server config
# Set positional parameters to list of servers
eval "$( jq -r '[ "set --", (.[].name|@sh) ] | @tsv' "$server_json" )"
# Select wanted server
local PS3='Select server: '
select SELECTED_SERVER; do
[[ -n $SELECTED_SERVER ]] && break
done
# Get corresponding hash
SELECTED_HASH=$(
jq -r --argjson i "$REPLY" \
'.[($i-1)].hash' "$server_json"
)
}
Здесь мы анализируем файл дважды, один раз, чтобы получить список серверов, и один раз, чтобы получить хеш для выбранного сервера, но было бы легко сделать что-то похожее на то, что вы делаете, и просто переключиться на использование $REPLY
выходит из цикла select
для получения хэша:
menu_select_server () {
local server_json=file.json # JSON containing server config
local name hash
local hashes=()
set --
# Read names into list of positional parameters
# Read hashes into "hashes" array
while IFS=$'\t' read -r name hash; do
set -- "$@" "$name"
hashes+=( "$hash" )
done < <( jq -r '.[] | [.name,.hash ] | @tsv' "$server_json" )
# or:
# jq -r 'map([.name,.hash ] | @tsv)[]' "$server_json"
# Select wanted server
local PS3='Select server: '
select SELECTED_SERVER; do
[[ -n $SELECTED_SERVER ]] && break
done
# Get corresponding hash
SELECTED_HASH=${hashes[REPLY-1]}
}