Глобальный ассоциативный массив виден только при повторном запуске сценария

Вы загрузили html-страницу по URL-адресу, а не по каталогу. Вы можете проверить это, запустив catдля этого файла.

2
15.08.2019, 15:42
1 ответ

declare / typesetбез -gобъявляет переменные в текущей области в дополнение к установке типа.

Здесь, поскольку declare -A audioExtension=(...)в конечном итоге выполняется внутри функции Source, это приводит к тому, что переменная audioExtensionобъявляется локальной для этой функции, и, как следствие, ее определение теряется после возврата Source.

Вы можете изменить его на typeset -Ag audioExtension=(...), который всегда объявляет переменную в глобальной области видимости (отличается от zsh/mksh/yash, где typeset -gтолько предотвращает локальную переменную (только обновляет тип /атрибуты и значение ); имеет значение, когда ваша функция Sourceвызывается из самой другой функции; см. bash vs zsh :область видимости и `набор текста -g`для подробностей ).

Если вы использовали ksh93вместо bash(, это оболочка bash, заимствовавшая этот синтаксис ассоциативного массива из ), вы могли бы определить свою функцию Sourceкак:

Source() {
 ...
}

в отличие от:

function Source {
 ...
}

В ksh93 функции, определенные с синтаксисом стиля Bourne -func() cmd, не имеют локальной области видимости, в то время как function func {имеют статическую локальную область видимости (здесь есть только одна глобальная область и одна локальная на -область действия, а не стек локальных областей ).

Вbash(и других оболочках с локальной областью видимости )нет аналогичного способа иметь функцию, которая не вводила бы новую область видимости. Вы можете использовать aliasвместо:

shopt -s expand_aliases
if [ "$debug" -gt 0 ]; then
  alias Source='time source'
else
  alias Source=source
fi

(обратите внимание, что псевдонимы раскрываются во время чтения кода , а не во время его выполнения).

Это будет иметь функциональное значение по сравнению с вашим функциональным подходом в том, что в:

Source./myfile | other-cmd

Мы бы синхронизировали как source myfile, так и other-cmd, так как они расширены до time source./myfile | other-cmd, в то время как в функциональном подходе мы бы использовали только синхронизацию source./myfile.

Использование source=(time source); "${source[@]}" /some/fileне сработает (вызовет timeавтономную утилиту вместо bashключевого слова time ).

2
27.01.2020, 22:08

Теги

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