Ассоциативные массивы в сценариях оболочки

Походит на потенциальную проблему с жестким диском. Поведение, которое Вы описываете, точно, что Вы видели бы, прекратил ли жесткий диск внезапно отвечать на запросы или начал возвращать ошибки. Попытайтесь работать smartctl -a /dev/sda, где sda устройство Вашего жесткого диска, чтобы видеть, зарегистрировал ли жесткий диск какие-либо ошибки.

Вы видели бы объяснение ошибки в ядре dmesg вывод. Конечно, если Вы не можете войти в систему, Вы не можете работать dmesg. Однако, если Вы входите в систему сначала и выполняете команду на текстовой консоли, это может все еще быть в памяти так, чтобы Вы могли выполнить ее снова после того, как система отказала.

Другая опция состояла бы в том, чтобы использовать netconsole функция Linux для отправки отладочной информации непосредственно в другую машину вместо того, чтобы писать это в диск. Это немного хитро для установки и требует двух машин, но является хорошей вещью попробовать, если все остальное перестало работать.

10
02.02.2016, 15:05
4 ответа

Оболочки с ассоциативными массивами

Некоторые современные оболочки обеспечивают ассоциативные массивы: ksh93, колотите ≥4, zsh. В ksh93 и ударе, если a ассоциативный массив, затем "${!a[@]}" массив его ключей:

for k in "${!a[@]}"; do
  echo "$k -> ${a[$k]}"
done

В zsh тот синтаксис только работает в ksh режиме эмуляции. Иначе необходимо использовать собственный синтаксис zsh:

for k in "${(@k)a}"; do
  echo "$k -> $a[$k]"
done

${(k)a} также работы, если a не имеет пустого ключа.

В zsh Вы могли также циклично выполниться на обоих keys и vгалереи одновременно:

for k v ("${(@kv)a}") echo "$k -> $v"

Оболочки без ассоциативных массивов

Эмуляция ассоциативных массивов в оболочках, которые не имеют их, является намного большим количеством работы. При необходимости в ассоциативных массивах пора, вероятно, ввести более крупный инструмент, такой как ksh93 или Perl.

При необходимости в ассоциативных массивах в простой оболочке POSIX вот способ моделировать их, когда ключи ограничиваются для содержания только символов 0-9A-Z_a-z (Цифры ASCII, буквы и подчеркивание). Под этим предположением ключи могут использоваться в качестве части имен переменной. Функции ниже действия на массиве, определенном префиксом именования, “основой”, которая не должна содержать два последовательных символа нижнего подчеркивания.

## ainit STEM
## Declare an empty associative array named STEM.
ainit () {
  eval "__aa__${1}=' '"
}
## akeys STEM
## List the keys in the associatve array named STEM.
akeys () {
  eval "echo \"\$__aa__${1}\""
}
## aget STEM KEY VAR
## Set VAR to the value of KEY in the associative array named STEM.
## If KEY is not present, unset VAR.
aget () {
  eval "unset $3
        case \$__aa__${1} in
          *\" $2 \"*) $3=\$__aa__${1}__$2;;
        esac"
}
## aset STEM KEY VALUE
## Set KEY to VALUE in the associative array named STEM.
aset () {
  eval "__aa__${1}__${2}=\$3
        case \$__aa__${1} in
          *\" $2 \"*) :;;
          *) __aa__${1}=\"\${__aa__${1}}$2 \";;
        esac"
}
## aunset STEM KEY
## Remove KEY from the associative array named STEM.
aunset () {
  eval "unset __aa__${1}__${2}
        case \$__aa__${1} in
          *\" $2 \"*) __aa__${1}=\"\${__aa__${1}%%* $2 } \${__aa__${1}#* $2 }\";;
        esac"
}

(Предупреждение, непротестированный код. Обнаружение ошибок для синтаксически недопустимых основ и ключей не обеспечивается.)

19
27.01.2020, 20:00

Я не уверен, что Вы подразумеваете под хранилищем, но можно выполнить итерации по ключам с помощью ${!array[@]} синтаксис:

$ typeset -A foo=([key1]=bar [key2]=baz);
$ echo "${!foo[@]}" 
key2 key1

Так, для итерации:

$ for key in "${!foo[@]}"; do echo "$key : ${foo[$key]}"; done
key2 : baz
key1 : bar

Я нашел хорошее, короткое учебное руководство на этом здесь.


Как указано в комментариях ниже, ассоциативные массивы были включены bash версия 4. Посмотрите здесь для статьи в журнале Linux на предмете.

5
27.01.2020, 20:00
  • 1
    (bash version 4 only) Это - важная вещь отметить. Традиционно, bash массивы являются числовыми только. –  Ricky Beam 29.01.2014, 01:07
  • 2
    Вы могли бы хотеть использовать typeset вместо declare в Ваших примерах. Это сделало бы их портативными между ударом 4 и ksh93, который сначала реализовал ассоциативные массивы оболочки. –  jlliagre 29.01.2014, 03:00

Оболочки без ассоциативных массивов

Это не так сложно, когда ключи ограничены [0-9A-Za-z _] (числа, буквы, подчеркивание).

Хитрость заключается в том, что вместо сохранения в массиве [ $ key ] сохраняются в переменных array_ $ key .

Установить:

eval "array_$key='$value'"

Получить:

value=`eval echo '$'array_$key`

Примечание: Значения не могут содержать ' (одинарные кавычки).

0
27.01.2020, 20:00

это работает в bash

cert="first"
web="second"
declare -A assoc_array=(["cert"]="${cert}" ["web"]="${web}")
echo "first is" ${assoc_array[cert]}
echo "second is" ${assoc_array[web]}

ИЛИ

#loop
for i in "${assoc_array[@]}"
do
   echo "$i"
done

Нет необходимости использовать eval afaik

-1
27.01.2020, 20:00

Теги

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