Наследование модификаций пути против наследования псевдонимов

Вопрос или проблема

Моя оболочка для входа – zsh. Я добавил следующие две строки в свой файл .zprofile:

path+=$HOME/foobar123
alias foo='echo bar'

Затем, если я переключусь на bash или fish, введя bash или fish и нажав Return, echo $PATH продолжит показывать часть foobar123, но алиас foo не будет работать.

Почему это так? Почему алиасы и изменения пути обрабатываются по-разному?

path – это массив переменных оболочки, связанный с переменной оболочки PATH, которая, в свою очередь, связана с переменной окружения PATH.

При выполнении команды вся память процесса очищается.

Переменные окружения – это способ передачи данных в разных запусках. Как и аргументы команд, они представляют собой список строк, разделенных нулевыми символами, но в отличие от аргументов, по соглашению:

  • они принимают форму VAR=значения
  • команды (будь то оболочки или что-то еще) запоминают список переменных окружения, которые они получили при выполнении, и передают их командам, которые они выполняют, если они или их дочерние процессы это делают, реализуя таким образом форму унаследованной и унаследуемой среды. Есть стандартный C API (putenv(), setenv(), unsetenv(), переменная environ), чтобы поддерживать этот список запомненных переменных окружения (environ) и выполнять команды, передавая этот список (execl(), execvp()… которые являются оболочками для системного вызова execve()).

Специфически для оболочек, помимо этого, они создают переменную в своем языке для некоторых переменных окружения, которые они получают, и имя которой совместимо с именем переменной оболочки. Оболочки, подобные Bourne, могут продвигать переменную оболочки в переменную окружения с помощью встроенной команды export (другие оболочки имеют эквиваленты).

Оболочки csh, tcsh, zsh, yash, fish имеют способы связывать $PATH или другие переменные со значениями, разделенными : (в основном переменные окружения, такие как PATH), с массивами переменных.

Для сравнения, perl (также интерпретатор языков программирования, но не оболочка) сопоставляет переменные окружения со своими ассоциативными массивами %ENV (например, переменная окружения PATH доступна в $ENV{PATH}), awk делает то же самое через ENVIRON["PATH"], vim имеет $var для переменных окружения, в то время как для своих собственных переменных просто var или @x для регистров и т.д.

В заключение, переменные окружения, такие как PATH, являются универсальными и понимаются всеми и наследуются (по соглашению) по мере выполнения.

Нет эквивалента для алиасов оболочки, что является (плохой) особенностью некоторых оболочек (не всех), изначально введенной в csh, синтаксис которой варьируется от оболочки к оболочке, и не существует других структур данных в каком-либо языке.

Некоторые оболочки, такие как rc и его производные или bash, могут экспортировать свои функции (также массивы в rc и его производных), чтобы сделать это, они захватывают переменные окружения, где определение функции хранится в специфическом формате, но только другие экземпляры той же оболочки могут загружать эти переменные из окружения и восстанавливать функции (или массивы), которые они закодировали. Эти переменные не имеют смысла для других оболочек (или perl, vim, awk…), синтаксис которых в любом случае отличается.

Чтобы передать свой список алиасов zsh в bash для создания эквивалентных алиасов bash, вам нужно создать код на языке bash, который, будучи выполненным, восстановит эти алиасы. bash и zsh имеют некоторый общий синтаксис, в частности, основной синтаксис встроенной команды alias был скопирован в обе оболочки из оболочки Korn, а не из csh, но zsh добавила больше функций, таких как глобальные алиасы или алиасы с суффиксами и не имеет тех же ограничений, что и bash, когда речь идет об именах алиасов, а алиасы bash не могут содержать нулевые символы ни в имени, ни в значении, поэтому не все алиасы zsh могут быть преобразованы в алиасы bash.

Синтаксис кавычек также отличается между двумя оболочками, хотя они понимают одинарные кавычки одинаково (если только rcquotes не включен в zsh). zsh делает список своих простых алиасов доступным в специальном ассоциативном массиве $aliases, и, как и bash, может выводить список определений алиасов с помощью alias -L.

Но в последнем случае он не всегда использует одинарные кавычки и может выводить алиасы, имя или значения которых не будут работать в bash, поэтому вам лучше обойти $aliases, отфильтровать те, которые не могут работать в bash, и сделать кавычки вручную (как с флагом расширения параметра qq).

Ответ или решение

Наследование изменений в PATH против наследования псевдонимов

Введение

Когда вы используете терминал, система выполняет интерпретацию ваших команд в зависимости от выбранной оболочки, такой как bash или zsh. В этом контексте важно понимать разницу между наследованием изменений в переменной среды PATH и наследованием псевдонимов. Данная статья подробнее объясняет, почему изменения в PATH продолжают действовать при переключении между оболочками, в то время как псевдонимы не наследуются.

Изменения в PATH: как это работает?

Переменные окружения, такие как PATH, представляют собой способ передачи данных между процессами и оболочками. Когда вы добавляете новый путь в переменную PATH в вашем файле ~/.zprofile, вы фактически обновляете массив, связанный с переменной окружения:

path+=$HOME/foobar123

При запуске новой оболочки, такой как bash или fish, эта переменная среды наследуется. В результате вы увидите, что содержимое переменной PATH (включая добавленный вами путь) продолжает существовать в новой оболочке. Это объясняется тем, что переменные окружения автоматически передаются детям (подпроцессам) и могут быть использованы другими программами и процессами.

Псевдонимы: их ограничения

С другой стороны, псевдонимы определяются на уровне оболочки и существуют только в её контексте. Когда вы создаете псевдоним, например:

alias foo='echo bar'

Этот псевдоним является частью локальной среды командной оболочки zsh и не передается новым процессам bash или fish. Причиной этого является то, что псевдонимы не являются общепринятыми переменными управления, такими как PATH, и их синтаксис и использование зависят от конкретной оболочки.

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

Возможные пути интеграции

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

Заключение

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

Поиск выхода

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

Оцените материал
Добавить комментарий

Капча загружается...