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

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

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

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 в Эль-Капитане и Сьерре. Это должно быть установлено через 'launchctl config user path ...' и в /etc/paths.

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

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

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

do shell script "launchctl setenv variablename value"

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

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

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

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

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

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

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

Можно установить переменные окружения в 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-переменные были правильно приняты приложениями после перезагрузки системы, вам потребуется:

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

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

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

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

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

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

# 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,

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

Что сработало для меня (вдохновлено благодарностью 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

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

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

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

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

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

Я добавил переменные в ~/.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
Другие вопросы по тегам