Как избежать столкновения / загрязнения пространства имен в сценарии, предназначенном для поиска?

Я хочу реализовать скрипт foo.sh который завершается исполнением командной bar (с некоторыми аргументами). Панель команд изменяет текущую среду оболочки, а это значит, что foo.sh должен быть найден 1 . (BTW, реализация bar полностью вне моего контроля.)

Цель большей части кода в foo.sh – вычислить аргументы, которые будут переданы в bar .

Чтобы сохранить foo.sh достаточно удобочитаемым / поддерживаемым, я обнаружил, что должен определить много вспомогательных переменных. К сожалению, это создает основу для

  1. конфликты пространства имен (т.е. слияние существующих параметров)
  2. загрязнение пространства имен (т.е. загромождение окружающей среды избыточными параметрами)

Один из возможных способов избежать или, по крайней мере, смягчить эти проблемы – поставить большую часть foo.sh в функцию (со всеми ее переменными, объявленными как local ), которая перекликается с подходящей строкой кода, которая будет отображаться в пределах вызывающий объем; например

 { __messy_calculation () { local xyz ... local bar_arg_1 bar_arg_2 ... ... echo "bar $bar_arg_1 bar_arg_2 ..." } eval "$( __messy_calculation )" } always { unfunction __messy_calculation } 

Это устраняет проблему загрязнения пространства имен и уменьшает проблему столкновения пространства имен с именем функции. (Хотя я не большой поклонник использования eval).

Я полагаю, что эта ситуация достаточно общая, что уже существуют стандартные способы ее решения. Если это так, пожалуйста, дайте мне знать.


1 В случае, если мои рассуждения испорчены, позвольте мне добавить, что если я поместил весь код, включая вызов в bar , в функцию, когда я выполняю эту функцию в командной строке, текущая среда остается незатронутой, что делает функцию бесполезный. Напротив, если я исхожу из строки, которая выполняет вызов в bar , текущая среда изменяется, как ожидалось.

One Solution collect form web for “Как избежать столкновения / загрязнения пространства имен в сценарии, предназначенном для поиска?”

Для переменных можно использовать анонимную функцию (как отмечено в комментарии выше). Это означает, что вы можете определить столько переменных, сколько хотите. Те, которые вы хотите скрыть от префикса вызывающего абонента с local , те, которые вы хотите сообщить вызывающему абоненту, который вы обычно определяете:

 function { local my_var=foo your_var=bar : ... } 

Но для функций, которые не будут работать, поскольку они не могут быть объявлены local . У меня была эта проблема в моем zshrc и я решил префикс всех имен моих «локальных» функций с короткой строкой (например, вы занимаете пространства имен на C) и для того, чтобы сделать подстановочный unfunction в конце:

 function foo-do-something () { : ... } function foo-do-some-more-stuff () { : ... } function foo-main () { local my_var=oof you_var=rab foo-do-something for bar foo-do-some-more-stuff with baz } foo-main unfunction -m 'foo-*' 

По моему мнению, это не оптимальное решение (я бы предпочел локальные функции), но он работает для меня.

  • «переключатель» на основе оболочки
  • Когда я пытаюсь добавить Android SDK в свой PATH, он дает контекстную ошибку
  • Поиск в обратном и прямом направлениях осуществляется с помощью vi-режима в zsh
  • ~ поведение оператора glob с пустым шаблоном
  • Есть ли преимущество в использовании ksh над zsh?
  • Bindkey для выполнения команды (Zsh)
  • Как отключить автозаполнение для sudo ...?
  • $ * переменная функции zsh приводит к неожиданным результатам
  • Разбор JSON на оболочке
  • echo {Z..A}; out {Z..A}; Почему?
  • Автоматически исправить путь при запуске команды из истории?
  • Interesting Posts
    Linux и Unix - лучшая ОС в мире.