В OSX Yosemite, почему я могу установить много переменных среды для приложений с графическим интерфейсом, но не могу установить определенную переменную PATH

16

После того, как я разобрался с проблемами PATH в OSX до релиза Mavericks, проблемы возвращаются в Yosemite !!!

Поэтому я хочу имитировать старую launch.confфункцию в новой версии Mac OSX 10.10 Yosemite, чтобы иметь доступную переменную среды PATH в приложениях с графическим интерфейсом, таких как Carbon Emacs или RStudio . Я использовал отличную идею пользовательского стекового потока для настройки сценария оболочки, который настраивает переменные среды с помощью launchctl. (См. Его ответ stackoverflow здесь .) Это работает для большинства переменных среды, но не для переменной PATH .

1. Что я наделал?

Сначала я написал /etc/environment.rcсценарий, похожий на:

launchctl setenv PATH /Users/halloleo/bin:/usr/texbin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
launchctl setenv JAVA_HOME /usr/local/jdk1.7
launchctl setenv ENVIRONMENT_RC "yes"

Затем я создал списки для launchd(списки этих и других упомянутых сценариев в приложении ниже). Затем я активировал их

$ sudo launchctrl load ...

Затем я отключил path_helperутилиту в /etc/профиле оболочки файла инициализации , чтобы она не перезаписывала environment.rcнастройки. И вот наконец я перезапустил машину.

2. Каков эффект?

Когда я запустить терминал новые переменные среды JAVA_HOMEи ENVIRONMENT_RCустанавливаются в соответствии environment.rc, но PATH устанавливается в

/ USR / бен: / бен

Чтобы удостовериться, что bashфайл инициализации не помешал мне, я вместо этого написал небольшой скрипт на Python (также в приложении), чтобы показать переменные в текущей среде, и я выполняю это напрямую, дважды щелкнув оболочку Platypus . Снова устанавливаются новые переменные, в то время как PATH имеет системное значение по умолчанию.

Так почему я могу установить другие переменные, но не переменную PATH? И как я могу решить это единым способом ?

Обновить:

Ситуация очень озадачивает: оболочка ( bashпо крайней мере) в Terminal или Emacs получит установленный вами путь PATH launchctl, но другие приложения с графическим интерфейсом не сделают этого, например, упомянутый минимальный скрипт на python, вызываемый через Platypus, не будет отображать ваш пользовательский путь. И даже сам Emacs не знает правильного PATH: вы замечаете это, например, когда запускаете команду Emacs M-x ispell-buffer; инструмент unix, ispellкоторый пытается вызвать emacs, не будет найден, если он находится на вашем пути.


аппендикс

net.halloleo.environment.plist, файл конфигурации launchd в /Library/LaunchDaemons/:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>KeepAlive</key>
    <false/>
    <key>Label</key>
    <string>net.halloleo.environment</string>
    <key>ProgramArguments</key>
    <array>
        <string>/bin/sh</string>
        <string>/etc/environment.rc</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
    <key>WatchPaths</key>
    <array>
        <string>/etc/environment.rc</string>
    </array>
</dict>
</plist>

net.halloleo.environment-user.plist, файл конфигурации launchd в /Library/LaunchAgents/:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>KeepAlive</key>
    <false/>
    <key>Label</key>
    <string>net.halloleo.environment-user</string>
    <key>ProgramArguments</key>
    <array>
        <string>/bin/sh</string>
        <string>/etc/environment.rc</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
    <key>WatchPaths</key>
    <array>
        <string>/etc/environment.rc</string>
    </array>
</dict>
</plist>

/etc/profile, модифицированный стартовый файл bash:

# System-wide .profile for sh(1)

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

if [ "${BASH-no}" != "no" ]; then
    [ -r /etc/bashrc ] && . /etc/bashrc
fi

show_environ.pyскрипт, отображающий все переменные окружения:

import os
print (os.environ)
halloleo
источник

Ответы:

3

PATH в Yosemite можно и нужно устанавливать в файле / etc / paths. Просто добавьте свой путь в конец этого файла:

/usr/bin
/bin
/your/custom/path

Скрипт / etc / environment в оригинальном посте обеспечивает поддержку переменной PATH в приложениях с графическим интерфейсом (протестировано с Emacs).

Ursa
источник
5
Это работает только для оболочек, которые вызывают /usr/libexec/path_helperво время процесса инициализации. Приложения с графическим интерфейсом не получают путь в соответствии с /etc/paths- и я специально спросил о приложениях с графическим интерфейсом.
Halloleo
Я обновил ответ и скрипт / etc / environment в оригинальном сообщении
ursa
Это два ответа, которые вы даете - также ОП говорит, что / etc / environment не работает
user151019
@mark (1) после того, как этот вопрос был поднят, я обновил / etc / environment, и теперь он поддерживает PATH. (2) ответ здесь - использовать / etc / paths
ursa
2
@ mark Да, и это именно моя точка зрения, проблема и вопрос: как я могу установить переменную окружения PATH для самих приложений GUI при запуске через Finder? Тем не менее, никакого реального общего решения для этого не предвидится ...
halloleo
2

Это меня озадачило надолго (ну, последние пару часов). В конце я наткнулся на этот отчет об ошибке, который, похоже, точно описывает мою проблему (я не уверен, насколько она связана с вашей проблемой, но, похоже, есть ошибка в Yosemite / launchd в сочетании с PATH и такими скриптами, как как питон:

http://www.openradar.me/18945659

Похоже, решение состоит в том, чтобы запустить скрипт оболочки, который затем запускает питон. Не совсем то, что мне нравится, но так оно и есть ....

Клод
источник
Спасибо за ссылку на отчет об ошибке. Хорошо, что сейчас это настоящая ошибка. Я нашел другое сцепление вокруг него; Я опубликую это здесь.
Halloleo
1

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

Это очевидно ошибка в launchd, переменные среды, передаваемые в программу, должны быть уникальными.

StenSoft
источник
1
Классный фоновый ответ! Я полагаю, что это не настоящий способ обойти это в оболочках или есть?
Привет,
@halloleo Вы можете запустить команду, sh -c 'YOUR ORIGINAL COMMAND'которая передает ее через оболочку, выбирая PATHнабор в launchd.
Стенсофт