Есть ли менее запутанный способ установки массива $ path локально внутри функции?

Есть ли менее трудоемкий способ для установки локальной версии массива $path чем то, что показано в следующем фрагменте?

 foo () { local holdpath holdpath=($path) local path path=($holdpath) if ( some_condition ) path=( $PREFIX $path ) # do stuff } 

Я имею в виду конкретно песню и танец с holdpath

Если вместо этого я определяю

 foo () { local path=($path) if ( some_condition ) path=( $PREFIX $path ) # do stuff } 

… первое присваивание path вызывает ошибку с bad pattern . Конечно, если вместо этого я определяю

 foo () { local path path=($path) if ( some_condition ) path=( $PREFIX $path ) # do stuff } 

… первое присваивание path не имеет значения (т. е. его можно опустить без изменения результатов); с или без него $path будет пустым.

РЕДАКТИРОВАТЬ:

Следующий скрипт проверяет различные предложения, которые я получил до сих пор:

 foo_0 () { echo ${#path} local PATH=$PATH echo ${#path} } foo_1 () { echo ${#path} eval "local path; path=(${(q)path})" echo ${#path} } foo_2 () { echo ${#path} eval "$(local -p path)" echo ${#path} } for i ( 0 1 2 ) { fn=foo_$i echo "# $fn" $fn echo } 

Выход:

 # foo_0 22 22 # foo_1 22 1 # foo_2 22 22 

Таким образом, выходы для foo_0 и foo_2 по меньшей мере согласуются с тем, что я пытаюсь достичь. Что-то не работает с foo_1 как указано выше, но я избавляюсь от (q) в назначении path , т. foo_1

 foo_1 () { echo ${#path} eval "local path; path=($path)" echo ${#path} } 

… тогда результат совпадает с foo_0 и foo_2 . К сожалению, даже после прочтения документации для q квалификатора пару раз, я не совсем понимаю, что она должна делать в оригинальном рецепте.

Кроме того, я не понимаю, почему следующий вариант командной строки foo_0 отличается от следующего выше:

 % (foo_0a () { echo ${#path}; local PATH=$PATH; echo ${#path} }; foo_0a) 22 1 

FWIW, соответствующие варианты командной строки foo_1 и foo_2 дают те же результаты, что и их оригиналы в скрипте:

 % (foo_1a () { echo ${#path}; eval "local path; path=(${(q)path})"; echo ${#path} }; foo_1a) 22 1 % (foo_2a () { echo ${#path}; eval "$(local -p path)"; echo ${#path}; }; foo_2a) 22 22 

Кроме того, во всех вышеизложенных случаях, когда echo ${#path} производит 1 вместо 22 причина в том, что локальная переменная $path содержит все отдельные пути в одной строке, разделенные пробелами.

2 Solutions collect form web for “Есть ли менее запутанный способ установки массива $ path локально внутри функции?”

В то время как для связанных массивов вы можете использовать ответ rici , в общем случае, вы могли бы сделать:

 foo() { eval "local array; array=(${(q)array[@]})" ... } 

(q) – это цитировать элементы массивов. Например, для значения $PATH like /foo bar:/x$y , "${(q)path[@]}" будет расширяться до /foo\ bar /x\$y . Нам нужно избежать этих символов пробела и доллара, потому что эта строка передается в eval .

Вы также можете сделать:

 foo() { eval "$(local -p array)" ... } 

который будет работать с любым типом переменной, но это вызывает дополнительный процесс.

Используйте скалярную форму PATH вместо path массива. Создание одного из этих локально эффективно делает их локальными, поэтому:

 foo() { local PATH=$PATH if ( some_condition ) path=( $PREFIX $path ) # do stuff } 

(Обратите внимание, что это не будет работать, если какой-либо компонент пути имеет встроенный : )

К сожалению, невозможно инициализировать параметр локального массива в одном из операторов, что делает невозможным инициализацию локального параметра массива с использованием его исходного значения.

  • Right Distro для текстовых потребностей
  • обмена или синхронизации истории между Zsh и Bash
  • scp-шаблон не работает в zsh
  • zsh: команда не найдена: {compinstall, compinit, compdef}
  • Как отключить «auto cd» в zsh с помощью oh-my-zsh
  • При применении команд к группам строк из stdin
  • Как создать функцию в zsh, которая вызывает существующую команду с тем же именем?
  • Сценарий Shell / Bash: Правильно отказаться от привилегий
  • Как фильтровать glob в zsh
  • Где zsh и mksh несовместимы с bash?
  • Проблема Tmux Terminfo с привязкой клавиш Zsh
  • Linux и Unix - лучшая ОС в мире.