bash, zsh : объявить [*] (о боже)

Я работаю со сценарием bash со следующим синтаксисом

$ declare -a THIS[*]

Это кажется незаконным в zsh (я получаю ошибку «совпадений не найдено: ЭТО [*]»). Может ли кто-нибудь помочь мне перевести это на zsh?

Кроме того, что означает синтаксис [*]? (Я знаю, что мы объявляем массив, но почему [*]?)

обновить

Чтобы привести пример использования кода и объяснить, насколько он действителен, я скопировал несколько строк из сообщения Эрика Энгстрома на ssh без пароля

declare -a SSSHA_KEYS[*]

# --- PARSE ARGS --- #
sssha_parse_args() {
  local OPTIND=1
  while getopts "xe:k:t:" OPT; do
    #echo "$OPT $OPTARG $OPTIND"
    case $OPT in
      t) SSSHA_ARGS="-t $OPTARG" ;;
      e) SSSHA_ENV="$OPTARG" ;;
      k) [ -f "${OPTARG}" ] && SSSHA_KEYS[${#SSSHA_KEYS[*]}]="$OPTARG" ;;
      x) SSSHA_STOP_ON_EXIT=$OPT
    esac
  done
  shift $(($OPTIND - 1))

  # set default key, if none specified
  if [ -z "${SSSHA_KEYS[*]}" ]; then
    for key in $HOME/.ssh/id_[rd]sa; do
      [ -f "$key" ] && SSSHA_KEYS[${#SSSHA_KEYS[*]}]="$key"
    done
  fi
}

Я считаю, что [*] используется как своего рода динамический итератор (поскольку мы не знаем, сколько элементов у него будет позже). Я просто хотел бы узнать об эквивалентном объявлении в zsh!


person danodonovan    schedule 17.04.2012    source источник
comment
Что вы подразумеваете под (о боже)?!   -  person Shahbaz    schedule 17.04.2012
comment
Точно невозможно контролировать, сколько места может занимать массив в zsh (если только вы не хотите сделать его доступным только для чтения), поэтому просто попробуйте сделать declare -a SSSHA_KEYS. Доверяя объяснению @ormaaj, эти объявления должны быть равными. Другой выложенный код, скорее всего, будет работать без модификаций, кроме SSSHA_KEYS[${#SSSHA_KEYS[*]}]=smth: он собирается добавить ключ, я прав? Используйте SSHA_KEYS+=( smth ), так как индексы массива zsh начинаются с 1, а ARR[ARR_LENGTH] будет назначаться последнему элементу, а не после него.   -  person ZyX    schedule 17.04.2012


Ответы (1)


Только у Баша есть declare. У kshes и zsh есть typeset. Этот код не имеет смысла во всех них, и поскольку оболочки не согласны с анализом аргументов для команд объявления, таких как declare и typeset (в Bash, в частности, -a изменяет синтаксический анализ определенным образом), он делать различные непредсказуемые, потенциально опасные вещи в каждом.

В частности, как Bash интерпретирует это - со страницы руководства:

объявить -имя [индекс] также принимается; индекс игнорируется.

Итак, поскольку он не заключен в кавычки - если в текущем каталоге есть файл с именем THIS*, тогда Bash выдаст ошибку недопустимого имени из-за расширения пути. В противном случае он просто создаст пустой массив с именем «THIS».

Что означает [*], зависит от контекста. Не заключенный в кавычки в обычном контексте оценки команды, это класс символов, соответствующий только буквальным звездочкам. Если используется в расширении параметра после имени массива, он расширяет все элементы массива до одного слова, разделенного первым символом IFS.

declare в bash объявляет переменные, возвращает их значения, устанавливает атрибуты и влияет на область действия функции. См.: http://wiki.bash-hackers.org/commands/builtin/declare

изменить: учитывая пример, который сейчас находится в вопросе, в bash поведение такое, как описано выше. [*] следует удалить из declare. Этот код имеет ряд других проблем, таких как попытка поместить аргументы в строки, использование имен переменных с заглавными буквами и использование [ вместо [[ в сценарии, который явно не предназначен для работы на минимальном POSIX sh.

person ormaaj    schedule 17.04.2012
comment
Zsh имеет declare, но это псевдоним для набора текста. Примечание: если вы сделаете emulate bash, затем declare -a THIS[*], тогда сообщение изменится: declare: THIS[*]: can't create local array elements, если THIS не определено, и declare: THIS[*]: array elements must be scalar, если THIS определено с помощью declare -a THIS. Я не знаю, что должен делать declare -a THIS[*] и в каком контексте он вызывается, поэтому больше ничего не могу сказать. - person ZyX; 17.04.2012
comment
* emulate bash совпадает с emulate sh. - person ZyX; 17.04.2012
comment
@ZyX Ах да, я должен был догадаться, что declare является частью его функций совместимости. Я могу вспомнить несколько краеугольных случаев только для Bash, где THIS[*] может возникнуть само по себе, но это определенно не то, что большинство людей знает или волнует, и определенно не имеет значения здесь (например, аргумент для unset, большинство других связаны с косвенным расширением). - person ormaaj; 17.04.2012
comment
@ormaaj - здесь уместны случаи, когда появляется THIS[*], так как я спрашиваю, что это значит. - person danodonovan; 17.04.2012
comment
@danodonovan Без дополнительного контекста невозможно сказать, о чем думал тот, кто это написал. Они, вероятно, понятия не имеют, как работают массивы. Я думал, что уже ответил на него. Если в текущем каталоге окажется файл с именем THIS*, вы получите ошибку недопустимого имени, иначе в Bash объявление пустого массива с указанием индекса просто создает массив и игнорирует указанный индекс, что в случае * и неассоциативный индексированный массив недействителен. В любом случае, это не то, что кто-либо когда-либо хотел бы. - person ormaaj; 17.04.2012