Bash -v test не работает с ассоциативными массивами в 4.3.46

Если вы не хотите вникать в настоящие протоколы маршрутизации, лучшим предложением будет постоянно работающая программа, которая проверяет два первых прыжка (с вашими выдуманными адресами, это ' d быть 161.0.0.1 и 171.0.0.1) регулярно и устанавливает то, что отвечает, как маршрут по умолчанию. Вероятно, вы могли бы сделать это на выбранном вами языке сценариев, хотя я, вероятно, сделал бы это сам на C. Фактически, у меня есть (но больше не могу найти этот код). Это достаточно просто сделать правильно, и выполнение этого на языке C значительно снижает влияние на ваш сервер.

3
07.11.2016, 04:23
2 ответа

Текущее руководство bash по массивам говорит

Переменная массива считается установленной, если подстрому индексу присвоено значение.

Так что, ИМХО, вам придется сделать что-то другое для ассоциативных массивов. Я не могу сказать, является ли это недавним изменением в поведении bash.

Другим способом определения is_var_set было бы (ab)использовать declare builtin, используя следующее:

Состояние возврата равно нулю, если ... одно из имен не является допустимым именем переменной оболочки ...

function is_var_set {
  declare -p "${1:?"No var provided to 'is_var_set'! "}" >& /dev/null
}

Вышесказанное будет работать для имен переменных верхнего уровня, но не для каких-либо конкретных элементов массива.

2
27.01.2020, 21:18

Вам нужно протестировать массив, а не (только) элемент 0.

[[ -v array[@] ]] 

Это не удается:

$ declare -A array=(["a"]="element 1")
$ declare -p array
declare -A array=([a]="element 1" )

$ [[ -v array ]] && echo yes            # nothing is printed.

Но это работает:

$ [[ -v array[@] ]] && echo yes
yes

Итак измените свою функцию на:

function is_var_set {
    local avar="${1:?"No var provided to 'is_var_set'!"}[@]"
    [[ -v "$avar" ]]
}

Проверьте это с помощью этого сценария:

function is_var_set {
    local avar="${1:?"No var provided to 'is_var_set'!"}[@]"
    [[ -v "$avar" ]] && echo "$1 set: yes" || echo "$1 set: no"
    echo
}

var=wer
echo "array scalar $(declare -p var)"
is_var_set var

var=( foo bar baz )
echo "var indexed array $(declare -p var)"
is_var_set var

unset var
echo "var associative array $(declare -p var)"
is_var_set var

declare -A var=(["a"]="element 1")
echo "var associative array $(declare -p var)"
is_var_set var
2
27.01.2020, 21:18

Теги

Похожие вопросы