Установка переменных среды через launchd.conf больше не работает в OS X Yosemite / El Capitan / macOS Sierra / Mojave?

Похоже, что launchd.conf больше не загружает мою переменную среды. Кто-нибудь еще заметил это?

Есть ли другое решение для постоянной установки переменных среды?


person Tosh    schedule 19.08.2014    source источник


Ответы (9)


Создайте environment.plist файл в ~/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>Label</key>
  <string>my.startup</string>
  <key>ProgramArguments</key>
  <array>
    <string>sh</string>
    <string>-c</string>
    <string>
    launchctl setenv PRODUCTS_PATH /Users/mortimer/Projects/my_products
    launchctl setenv ANDROID_NDK_HOME /Applications/android-ndk
    launchctl setenv PATH $PATH:/Applications/gradle/bin
    </string>

  </array>
  <key>RunAtLoad</key>
  <true/>
</dict>
</plist>

Вы можете добавить множество launchctl команд внутри блока <string></string>.

plist активируется после перезагрузки системы. Вы также можете использовать launchctl load ~/Library/LaunchAgents/environment.plist, чтобы запустить его немедленно.

[Изменить]

То же решение работает и в El Capitan.

Xcode 7.0+ по умолчанию не оценивает переменные среды. Старое поведение можно включить с помощью этой команды:

defaults write com.apple.dt.Xcode UseSanitizedBuildSystemEnvironment -bool NO

[Изменить]

Есть пара ситуаций, когда это не совсем работает. Если компьютер перезагружен и выбран параметр «Открывать окна при повторном входе в систему», повторно открытые окна могут не видеть переменные (возможно, они открываются до запуска агента). Кроме того, если вы войдете в систему через ssh, переменные не будут установлены (поэтому вам нужно будет установить их в ~ / .bash_profile). Наконец, похоже, это не работает для PATH на El Capitan и Sierra. Это необходимо установить с помощью «launchctl config user path ...» и в / etc / paths.

person MortimerGoro    schedule 27.10.2014
comment
Перезагрузка не требуется! Вы можете выполнить launchctl start environment.plist и перезапустить приложение, необходимое для получения новых переменных env;) - person hasvn; 07.11.2014
comment
Для меня это не сработает с переменной PATH. Поэтому в дополнение к этому подходу для установки других переменных я установил переменную PATH в моем ~ / .bash_profile. Это может сработать не для всех случаев, но пока у меня нет проблем. - person djule5; 17.12.2014
comment
@ djule5 У меня работает PATH, я использую эту строку, чтобы добавить градиент к пути: launchctl setenv PATH $ PATH: / Applications / gradle / bin - person MortimerGoro; 17.12.2014
comment
Это также помогло создать новые переменные среды в Йосемити. Спасибо! - person n00b; 21.01.2015
comment
Мне также пришлось перезагрузить Mac, чтобы это сработало. Недостаточно было выполнить команду запуска launchctl с последующим перезапуском приложения с графическим интерфейсом (Eclipse). - person Dave Hartnoll; 16.02.2015
comment
Разобрался: для работы без перезагрузки должен быть launchctl load environment.plist, а не start - person Dave Hartnoll; 16.02.2015
comment
Этот метод работает для меня лучше, чем метод от ruario, так как у меня есть настройка boxen + homebrew - указатели переменных для приложений с графическим интерфейсом лучше использовать plist, чем отдельные файлы сценариев Apple. - person Glorithm; 13.04.2015
comment
забавно ... для меня перезапуск не сработал, только launchctl ... вернулся к поиску способа установить это при запуске ›.‹ - person bia.migueis; 25.05.2015
comment
Работал. Просто возникла небольшая проблема: если у вас открыто окно терминала, закройте его и перезапустите. Странно, но необходимо в моем случае. - person Iker Jamardo Zugaza; 21.07.2015
comment
@IkerJamardoZugaza, это не странно - env ​​должен быть там до запуска приложения, т.е. terminal.app - person mmmmmm; 12.10.2015
comment
О да. Ничего похожего на непонятный параметр конфигурации, который появляется ровно 9 раз во всем Интернете (google UseSanitizedBuildSystemEnvironment). - person Ohad Schneider; 20.10.2015
comment
@MortimerGoro Я использовал это, чтобы указать на новую версию Qt (5.5 вместо 4.8.7). Сделал следующее -: ‹string› launchctl setenv QTDIR /usr/local/Cellar/qt5/5.5 ‹/string›, а затем launchctl load ~ / Library / LaunchAgents / environment.plist. При выполнении qmake --version я все еще вижу QMake версии 2.01a. Использование Qt версии 4.8.7 в /usr/local/Cellar/qt/4.8.7/lib - что я делаю не так? Я на йосемите 10.10.5. - person ekta; 24.02.2016
comment
Это сработало для меня (El Capitan): - Добавить переменную среды в XML (как объяснено в ответе) - Выполнить launchctl unload ~/Library/LaunchAgents/environment.plist - Выполнить launchctl load ~/Library/LaunchAgents/environment.plist - Выход Terminal - Перезапустить Terminal, и новая переменная среды должна быть доступна (вы можете перечислить все переменные с помощью printenv) Примечание. Поскольку это XML, ваши переменные должны соответствовать правилам синтаксиса XML. Так, например, значение переменной не может содержать амперсанд (&). - person asherbar; 22.09.2016
comment
Также работает на Sierra - person Shwouchk; 06.10.2016
comment
это наиболее разумное и актуальное решение среди сотен других. должно быть в какой-то документации или что-то в этом роде. - person Display Name; 29.01.2017
comment
sudo launchctl config user path $PATH работает на Мохаве - person Ivan Romanov; 13.11.2018

[Исходный ответ]: вы по-прежнему можете использовать launchctl setenv variablename value, чтобы задать переменную, которая будет использоваться всеми приложениями (графическими приложениями, запускаемыми через Dock или Spotlight, в дополнение к тем запустил через терминал).

Очевидно, вы не захотите делать это каждый раз при входе в систему.

[Изменить]: чтобы этого не произошло, запустите AppleScript Editor, введите следующую команду:

do shell script "launchctl setenv variablename value"

(Используйте несколько строк, если вы хотите установить несколько переменных)

Теперь сохраните (_4 _ + _ 5_) как Формат файла: Приложение. Наконец, откройте System SettingsПользователи и группыЭлементы входа и добавьте новое приложение.

[Исходный ответ]: чтобы обойти это место, все переменные, которые вы хотите определить в коротком сценарии оболочки, посмотрите на этот предыдущий ответ о том, как запустить сценарий при входе в MacOS. Таким образом, сценарий будет вызываться при входе пользователя в систему.

[Изменить]: Ни одно из решений не является идеальным, поскольку переменные будут установлены только для этого конкретного пользователя, но я надеюсь / предполагаю, что это может быть все, что вам нужно.

Если у вас несколько пользователей, вы можете вручную установить элемент входа для каждого из них или разместить копию com.user.loginscript.plist в каждом из их локальных < em> Library / LaunchAgents, указывая на тот же сценарий оболочки.

Конечно, ни один из этих обходных путей не так удобен, как /etc/launchd.conf.

[Дальнейшее редактирование]: пользователь ниже упоминает, что это не сработало для него. Однако я тестировал на нескольких машинах Yosemite, и у меня это работает. Если у вас возникла проблема, помните, что вам нужно будет перезапустить приложения, чтобы это вступило в силу. Кроме того, если вы устанавливаете переменные в терминале через ~ / .profile или ~ / .bash_profile, они переопределяют значения, установленные через launchctl setenv для < strong> приложения запускались из оболочки.

person ruario    schedule 18.09.2014
comment
Насколько я могу судить, одним из недостатков этого метода является то, что переменные не будут установлены для других приложений, запускаемых при входе в систему. Так, например, если вы откроете Терминал, переменная будет установлена, но если вы выйдете из системы и снова включитесь, после автоматического перезапуска Терминала, переменная будет сброшена ... - person JasonD; 20.10.2014
comment
Я пробовал это решение, и у меня оно тоже не сработало. Но я специально ожидаю, что моя Java IDE (IntelliJ) подберет изменения моего пути, а это не так. С терминала все работает нормально. Это может быть ошибка в IntelliJ. По-прежнему расстраивает то, что Apple удалила эту функциональность. Я позвонил в Apple, и они мне не помогли. - person Jason; 21.10.2014
comment
Это работает для меня, но знаете ли вы, что нужно сделать, чтобы добавить переменные среды в sudo? - person etiennenoel; 11.11.2014
comment
Чертовски здорово, спасибо. У меня работал над Yosemite, чтобы передать переменные env в приложение ruby, которое выполняется через launchd и rvm. - person Dogweather; 10.12.2014
comment
Это будет работать в целом, однако в Yosemite есть ошибка (по крайней мере, 10.10.0 и 10.10.1), когда установка $ PATH не работает таким образом. Apple знает об ошибке. В настоящее время (по состоянию на 10.10.1) нет известного способа установить общесистемный $ PATH для приложений с графическим интерфейсом. - person TJ Luoma; 20.12.2014
comment
После того, как вы воспользуетесь одним из вышеупомянутых методов и перезагрузите свой ноутбук - убедитесь, что вы явно повторно открываете приложения (например, iTerm, терминал, Eclipse, IDEA или что-то еще, что вы используете). Если вы не перезапускаете их явно и если при перезагрузке OSx был установлен флажок «Перезапускать окна при повторном входе в систему» ​​(что по умолчанию) - эти программы не будут читать новые переменные среды. - person Ran; 15.03.2015
comment
1. launchctl setenv variablename value, а затем 2. перезапустить оболочку - сработало для меня - person Chicago; 08.01.2017

В Mac OS X 10.10 Yosemite можно установить переменные среды с помощью 3 файлов + 2 команд.

Главный файл с определением переменных среды:

$ ls -la /etc/environment 
-r-xr-xr-x  1 root  wheel  369 Oct 21 04:42 /etc/environment
$ cat /etc/environment
#!/bin/sh

set -e

syslog -s -l warn "Set environment variables with /etc/environment $(whoami) - start"

launchctl setenv JAVA_HOME      /usr/local/jdk1.7
launchctl setenv MAVEN_HOME     /opt/local/share/java/maven3

if [ -x /usr/libexec/path_helper ]; then
    export PATH=""
    eval `/usr/libexec/path_helper -s`
    launchctl setenv PATH $PATH
fi

osascript -e 'tell app "Dock" to quit'

syslog -s -l warn "Set environment variables with /etc/environment $(whoami) - complete"

Определение службы для загрузки переменных среды для пользовательских приложений (терминал, IDE, ...):

$ ls -la /Library/LaunchAgents/environment.user.plist
-rw-------  1 root  wheel  504 Oct 21 04:37 /Library/LaunchAgents/environment.user.plist
$ sudo cat /Library/LaunchAgents/environment.user.plist
<?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>Label</key>
    <string>environment.user</string>
    <key>ProgramArguments</key>
    <array>
            <string>/etc/environment</string>
    </array>
    <key>KeepAlive</key>
    <false/>
    <key>RunAtLoad</key>
    <true/>
    <key>WatchPaths</key>
    <array>
        <string>/etc/environment</string>
    </array>
</dict>
</plist>

То же определение службы для пользовательских приложений root:

$ ls -la /Library/LaunchDaemons/environment.plist
-rw-------  1 root  wheel  499 Oct 21 04:38 /Library/LaunchDaemons/environment.plist
$ sudo cat /Library/LaunchDaemons/environment.plist
<?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>Label</key>
    <string>environment</string>
    <key>ProgramArguments</key>
    <array>
            <string>/etc/environment</string>
    </array>
    <key>KeepAlive</key>
    <false/>
    <key>RunAtLoad</key>
    <true/>
    <key>WatchPaths</key>
    <array>
        <string>/etc/environment</string>
    </array>
</dict>
</plist>

И, наконец, мы должны зарегистрировать эти службы:

$ launchctl load -w /Library/LaunchAgents/environment.user.plist
$ sudo launchctl load -w /Library/LaunchDaemons/environment.plist

Что мы получаем:

  1. Единственное место для объявления системных переменных окружения: / etc / environment
  2. Мгновенное автоматическое обновление переменных среды после модификации файла / etc / environment - просто перезапустите приложение.

Вопросы / проблемы:

Чтобы ваши переменные env корректно принимались приложениями после перезагрузки системы, вам потребуется:

  • либо войдите дважды: логин => выход => логин
  • или закрыть и снова открыть приложения вручную, где должны быть взяты переменные env
  • или НЕ используйте функцию «Повторно открывать окна при повторном входе в систему».

Это происходит из-за того, что Apple отрицает явное упорядочивание загруженных сервисов, поэтому переменные env регистрируются параллельно с обработкой «очереди повторного открытия».

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

person ursa    schedule 21.10.2014
comment
Отличная идея. Я пробовал это, и он работает для большинства переменных среды (например, JAVA_HOME), но не для переменной PATH (см. мой вопрос в вопросе разные). - person halloleo; 28.10.2014
comment
ПУТЬ должен быть установлен в файле / etc / paths. Просто добавьте свой собственный путь в конец этого файла. - person ursa; 28.10.2014
comment
Я не очень хорошо знаком с launchd, но нельзя ли загрузить эти демоны при загрузке (т.е. перед входом в систему)? Это должно обойти все проблемы, о которых вы упомянули. - person Egon; 09.11.2014
comment
Мне нравится описанный выше подход, но у меня есть странная проблема. После перезагрузки genet VARNAME возвращает мне правильное значение, но echo $ VARNAME ничего не возвращает. Что может быть причиной этого? Я разместил это в stackoverflow.com/questions/27045137/ и надеюсь, что у кого-нибудь есть идея - person ctp; 20.11.2014
comment
Убедитесь, что права доступа к файлу / etc / environment соответствуют описанию выше. - person imanuelcostigan; 06.12.2014
comment
Я хотел вмешаться и упомянуть, что я пробовал различные методы для установки пользовательских переменных среды для OSX Yosemite, и это решение, похоже, работает лучше всего. Ни одно из этих решений не кажется мне очень чистым, но это было самым простым и работало для всех моих программ. - person CoBrA2168; 29.04.2015
comment
В моем вопросе Я описываю, как использовать описанный выше подход для повторного использования моих экспортов оболочки, чтобы иметь только один истинный источник для переменных среды, то есть в моем случае мой .zshrc. Я считаю это продолжением описанного выше подхода. - person ; 12.07.2015

Цитируется из

Apple Developer Relations 10-Oct-2014 09:12 PM

После долгих раздумий инженеры удалили эту функцию. Файл /etc/launchd.conf был намеренно удален из соображений безопасности. В качестве обходного пути вы можете запустить launchctl limit как root на ранней стадии загрузки, возможно, из LaunchDaemon. (...)

Решение:

Поместите код в /Library/LaunchDaemons/com.apple.launchd.limit.plist с помощью bash-скрипта:

#!/bin/bash

echo '<?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>Label</key>
        <string>eicar</string>
        <key>ProgramArguments</key>
        <array>
                <string>/bin/launchctl</string>
                <string>limit</string>
                <string>core</string>
                <string>unlimited</string>
        </array>
        <key>RunAtLoad</key>
        <true/>
        <key>ServiceIPC</key>
        <false/>
</dict>
</plist>' | sudo tee /Library/LaunchDaemons/com.apple.launchd.limit.plist
person aax    schedule 11.10.2014
comment
Вы можете объяснить это поподробнее? Я не могу понять, как «Решить проблему» соотносится с исходной проблемой! - person Nick H247; 16.10.2014
comment
Не OP, но я думаю, что суть здесь такова: поместите этот список в /Library/LaunchDaemons и вместо того, чтобы указывать launchctl запустить команду limit, попросите его запустить команду setenv с PATH и строкой пути в качестве аргументов. launchd должен автоматически загрузиться при запуске и почти сразу же стать как бы самоизменяющимся. - person Laird Nelson; 17.10.2014
comment
Xml скопирован не полностью. Строка doctype должна читать <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">. - person UloPe; 20.10.2014
comment
@aax какая часть этого списка фактически устанавливает переменную окружения? - person HairOfTheDog; 13.11.2014

Вот команды для восстановления старого поведения:

# create a script that calls launchctl iterating through /etc/launchd.conf
echo '#!/bin/sh

while read line || [[ -n $line ]] ; do launchctl $line ; done < /etc/launchd.conf;
' > /usr/local/bin/launchd.conf.sh

# make it executable
chmod +x /usr/local/bin/launchd.conf.sh

# launch the script at startup
echo '<?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>Label</key>
  <string>launchd.conf</string>
  <key>ProgramArguments</key>
  <array>
    <string>sh</string>
    <string>-c</string>
    <string>/usr/local/bin/launchd.conf.sh</string>
  </array>
  <key>RunAtLoad</key>
  <true/>
</dict>
</plist>
' > /Library/LaunchAgents/launchd.conf.plist

Теперь вы можете указывать такие команды, как setenv JAVA_HOME /Library/Java/Home в /etc/launchd.conf.

Проверил на Эль-Капитане.

person yanchenko    schedule 06.10.2015

Что сработало для меня (вдохновлено благодарностью aax):

Вставьте это в /Library/LaunchDaemons/com.apple.launchd.limit.plist, затем перезагрузитесь:

<?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>Label</key>
  <string>eicar</string>
  <key>ProgramArguments</key>
  <array>
    <string>/bin/launchctl</string>
    <string>limit</string>
    <string>maxfiles</string>
    <string>16384</string>
    <string>16384</string>
  </array>
  <key>RunAtLoad</key>
  <true/>
  <key>ServiceIPC</key>
  <false/>
</dict>
</plist>

Если нужно пошагово:

  • Запустить терминал
  • Введите sudo su, затем введите свой пароль, чтобы войти в систему как root.
  • Введите vi /Library/LaunchDaemons/com.apple.launchd.limit.plist.
  • В редакторе vi нажмите клавишу i, чтобы войти в режим вставки, затем вставьте точное содержимое кода, указанное выше (⌘+v). Это приведет к ограничению до 16384 файлов на процесс и всего 16384 файлов.
  • Сохраните файл и выйдите с помощью esc, затем :wq
  • Перезагрузите систему и убедитесь, что она работает, с помощью команды launchctl limit.

Надеюсь, это вам помогло.

person Baptiste    schedule 21.10.2014
comment
Какое отношение имеет это решение к настройке переменных среды? - person HairOfTheDog; 13.11.2014

Вы можете дать https://github.com/ersiner/osx-env-sync попытка. Он обрабатывает приложения как командной строки, так и графического интерфейса из единого источника и работает с последней версией OS X (Yosemite).

Вы можете использовать замену пути и другие уловки с оболочкой, поскольку то, что вы пишете, является обычным сценарием bash, который в первую очередь должен быть получен с помощью bash. Без ограничений .. (Ознакомьтесь с документацией osx-env-sync, и вы поймете, как он достигает этого.)

Я ответил на аналогичный вопрос здесь, где вы найдете больше .

person Ersin Er    schedule 07.09.2015

Решение состоит в том, чтобы добавить вашу переменную в /etc/profile. Дальше все работает как положено! Конечно, вы ДОЛЖНЫ сделать это как пользователь root с sudo nano / etc / profile. Если вы отредактируете его любым другим способом, система будет жаловаться на поврежденный / etc / profile, даже если вы измените права доступа на root.

person Ilias    schedule 18.10.2014
comment
Добавление переменных среды в профиль намного хуже, поскольку влияет только на процессы оболочки. - person UloPe; 20.10.2014

Я добавил переменные в ~ / .bash_profile следующим образом. После того, как вы закончите, перезапустите / выйдите из системы и войдите в систему.

export M2_HOME=/Users/robin/softwares/apache-maven-3.2.3
export ANT_HOME=/Users/robin/softwares/apache-ant-1.9.4
launchctl setenv M2_HOME $M2_HOME
launchctl setenv ANT_HOME $ANT_HOME
export PATH=/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/Users/robin/softwares/apache-maven-3.2.3/bin:/Users/robin/softwares/apache-ant-1.9.4/bin
launchctl setenv PATH $PATH

ПРИМЕЧАНИЕ: без перезапуска / выхода и входа в систему вы можете применить эти изменения, используя;

source ~/.bash_profile
person Robin    schedule 17.01.2015
comment
Обратите внимание, что вам не нужно выходить и снова входить. Просто используйте команду source, то есть source .bash_profile. - person Michael; 20.01.2015
comment
Кроме того, проблема с этим методом заключается в том, что вам все равно нужно открыть терминал, прежде чем переменные среды станут доступными. Лучше сделать то, что указано в первом ответе, чтобы они были доступны без необходимости открывать терминал. - person Michael; 20.01.2015
comment
Это не работает с приложениями, загруженными через SpotLight. stackoverflow.com/questions/135688/ - person Rasika Perera; 06.03.2015
comment
Использование файлов конфигурации bash мало помогает, поскольку предполагает, что у вас всегда есть bash как предок процесса, среду которого вы пытаетесь воздействовать. Spotlight, поисковик, emacs, xcode, cronjobs, запускаемые агенты, любая IDE, браузеры с системой управления версиями и т. Д. И т. Д. - у всех не будет bash в качестве предка. Единственный процесс, который может охватывать их последовательно, - это запуск. - person Ben Hyde; 15.03.2015