Как именно рассчитывается PATH?

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

  1. Как именно рассчитывается PATH для bash?
  2. Как именно он рассчитывается для других оболочек? (Я предполагаю, что это зависит от оболочки, но что общего между всеми оболочками?)
  3. Как именно он рассчитывается для приложений с графическим интерфейсом?
  4. Я пропустил другой способ запуска вещей? Делают ли демоны что-то другое? (Я так не думаю? Но, может быть...)

Кроме того, я сейчас на High Sierra, но я вижу, как некоторые люди упомянули, что в какой-то момент это изменилось?

Я видел этот ответ и этот , но оба, похоже, явно сосредоточены на том, что происходит внутри bash.

Что вы имеете в виду под фразой «как рассчитывается PATH ? Это переменная среды, которая устанавливается
@ Аллан, да, но как именно он установлен? Дело не только .bash_profileв том, например, что к моменту запуска в PATH уже есть что-то (вот почему мы добавляем в начало или конец). Он рассчитывается путем рассмотрения некоторой последовательности источников и запуска некоторой последовательности сценариев, но что это такое ?
Я голосую за то, чтобы закрыть этот вопрос как слишком широкий. Пожалуйста, отредактируйте вопрос, чтобы ограничить его конкретной проблемой с достаточной детализацией, чтобы найти адекватный ответ. Не задавайте сразу несколько разных вопросов.
@user3439894 user3439894 Не могли бы вы порекомендовать задавать каждый из них как отдельный вопрос? Потому что кажется, что это будет огромное количество совпадений, и некоторые ответы, вероятно, будут идентичными.
Это действительно очень широкий вопрос. Но вот несколько советов: bash и другие оболочки в стиле борна, а также csh и родственные оболочки могут использоваться path_helperдля установки переменной PATH. Проверьте его справочную страницу; вы обнаружите, что они читают /etc/pathsи /etc/paths.d/*для содержания. Пользователям других оболочек рекомендуется адаптировать этот метод; таким образом, все оболочки получают один и тот же PATH.

Ответы (3)

Я собираюсь объединить 1 и 2, потому что все оболочки читают файлы при запуске.

PATH наследуется от родительского процесса. Это ключевая концепция, которую вам необходимо понять.

PATH сначала жестко запрограммирован в ядре:

sysctl user.cs_path
user.cs_path: /usr/bin:/bin:/usr/sbin:/sbin

launchd, который действует как initможно настроить для изменения этого ПУТИ. В общем не меняется.

Приложение loginwindow.app настроит среду, когда вы войдете в свой компьютер. PATH будет проверено, что он был установлен, или он будет установлен на жестко запрограммированный путь в ядре или измененный путь, установленный launchd. Это похоже на вызов loginwindow.app login -pf <username>.

На этом этапе пользователь LaunchAgent или LaunchDaemon может изменить PATH.

Это будет ПУТЬ, доступный для приложений с графическим интерфейсом из Finder. (Ранние версии OS X могли использовать ~/.MacOSX/environment.plist для изменения PATH для приложений с графическим интерфейсом). Теперь, если это кажется сложным, это не так, и более вероятно, как и я, доступный PATH/usr/bin:/bin:/usr/sbin:/sbin

Когда вы запускаете Terminal.app, он сначала вызывает login(login -pf ), что запускает вашу оболочку для обработки как оболочку входа. Соответствующие файлы в /etc и вашей домашней папке читаются. Теперь PATH должен отличаться от установленного в loginwindow.app. Помните, мы говорили о наследовании? Если вы запускаете приложение с графическим интерфейсом из сеанса терминала, то ПУТЬ, доступный для приложения с графическим интерфейсом, будет таким же, как и установленный оболочкой.

Что касается демонов, то они обычно запускаются по их абсолютному пути.

Спасибо, черт возьми, за объяснение того, как во все это вписывается launchd! Никто другой не мог сказать мне!
Запущенный — это просто еще один процесс, который работает так же, как и все остальные. Он наследует среду и устанавливает среду для процессов, которые он разветвляет.

Со страницы руководства для PATH ( man path):

Путь поиска команд. Это разделенный двоеточиями список каталогов, в которых оболочка ищет команды (см. ВЫПОЛНЕНИЕ КОМАНД ниже).... Путь по умолчанию зависит от системы и задается администратором, устанавливающим bash. Обычное значение: ``/usr/gnu/bin:/usr/local/bin:/usr/ucb:/bin:/usr/bin''.

Итак, из этого, за исключением справочной страницы bash, мы видим, что путь bash (изначально):

  • зависит от системы и не зависит от оболочки
  • устанавливается тем, кто установил bash (в данном случае Apple)
  • имеет значение по умолчанию

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

  • ~/.bashrc
  • ~/.bash_profile

В macOS этот файл /etc/pathsиспользуется для настройки путей поиска:

/usr/local/bin
/usr/bin
/bin
/usr/sbin
/sbin

Кроме того, путь изначально настраивается утилитой /usr/libexec/path_helper, которая создает путь на основе содержимого/etc/paths.d

Вызывается из /etc/profileкоторой задается общесистемный профиль bash (индивидуальные задаются в ~/.profile)

Что касается приложений с графическим интерфейсом, путь к оболочке действительно не имеет значения. Единственный раз, когда приложение с графическим интерфейсом (Cocoa, Quartz, Metal) имеет какое-либо отношение к PATH, - это когда оно открывает оболочку (интерактивную или неинтерактивную). В этот момент он будет использовать среду PATH как установленную или вносить любые необходимые изменения во время выполнения.

Различные оболочки

Каждая из оболочек имеет свой общесистемный профиль (как и bash), который устанавливает начальный PATH (путем вызова утилиты path_helper)

  • Зш =/etc/zprofile
  • Кш =/etc/profile
  • Кш =/etc/csh.login
Да, но не все запускается через bash, верно? Если я запускаю eshell в emacs или korn shell, то он не будет проходить тот же процесс. Я понимаю, что в каждой оболочке это будет по-разному, но это совершенно другое или ОС предоставляет «общую базу для инициализации»? А как насчет приложений, запущенных через Spotlight? Как рассчитывается PATH, который они видят?
Терминология важна - путь не рассчитывается. Это установлено. Вы путаете ОС с оболочкой. Оболочка — это не что иное, как среда для выполнения команд в ОС.
Достаточно честно, Аллан, хотя я не уверен, какой другой термин использовать. Путь действительно установлен (с точки зрения скриптов), но с точки зрения приложения, которое может использовать PATH, для создания текущей переменной env PATH был выполнен ряд шагов. Что касается приложений с графическим интерфейсом, то, что вы не используете PATH, отличается от того, что он недоступен. Вы можете сделать system attribute PATHчто-то в AppleScript, верно? Ценность, которую я там вижу... откуда она? Какую серию шагов прошла ОС для его установки?
Это все больше и больше похоже на то, что у вас проблема XY . В чем проблема, с которой вы столкнулись, потому что AppleScript не нужно устанавливать путь к оболочке.
Вроде... У меня действительно нет проблем (ну, у меня есть, и его pyenv не устанавливается должным образом, но я могу понять это, имея базовое понимание), я ищу более глубокое понимание того, как это работает, а не для решения чего-либо конкретного.
Вот почему он помечен (у меня нет) как слишком широкий. Первое, на что я бы хотел, чтобы вы посмотрели, это Справочное руководство по Bash , которое даст вам хорошее представление о том, как все это работает.
Ха-ха, я понял и ценю попытку ответить на него. Процесс bash для построения PATH на самом деле меня меньше всего интересует , поскольку, как вы говорите, он достаточно хорошо документирован. Меня смущают другие вещи (например, что увидят приложения с графическим интерфейсом или что увидит мой профиль eshell).

Все: Пожалуйста, поймите, что Apple со временем изменила парадигму Paths в Sierra (см. https://lluad.com/blog/os-x-system-path/ ), HighSierra и Mojave. Path_helper теперь работает несколько иначе, кажется, потому что он заблокировал для меня окна терминала, которые я могу освободить и нормально работать, закомментировав

# if [ -x /usr/libexec/path_helper ]; then
#   eval `/usr/libexec/path_helper -s`
#  fi

в /etc/profile.

У меня есть скрипты, которые фиксируют путь, потому что у меня работает несколько инструментов (ядро из них установлено Homebrew, но это только около 15 из 25, которые я использую каждый день), и их нужно настроить для использования в .app приложений, при запуске сценария .sh и для автозапуска в защищенной последовательности загрузки в Mojave. Это сбивает с толку, но наверняка Мохаве изменил требуемую структуру, и мне нужно активировать ее самостоятельно.

Что это означает для этого конкретного вопроса, так это то, что вопрос актуален во всей его широте и что на него должны ответить разработчики, которые почувствовали боль и исправили свои системы для Мохаве, а также пришли из различных «миров», таких как обычные IDE. , XCode, Eclipse, Bean, Intellij и т. д. Также для тех, кто зависит от стеков homebrew или mamp и т. д. А для тех, кто занимается работой с докером, .node, vm и т. д., и другими более глубокими инструментами. По мере того, как Apple внедряет большую безопасность, наши вещи сломаются, но я рад, что Apple делает свою работу. Нам нужно сделать свое, поэтому нам нужны передовые люди, чтобы передать новую мудрость. Статьи, которым 6 и более месяцев, просто сбивают нас с толку.

Почему-то это не отвечает на вопрос, заданный выше. Если ответ находится на странице, на которую вы ссылаетесь, кратко изложите его прямо в своем сообщении (и, возможно, сократите последующие абзацы). Кроме того, не просто упоминайте, что вы делаете что-то по-другому, но также объясните/покажите, как вы это делаете.