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

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

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

Ответ 1

Создайте 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 на Эль-Капитане и Сьерре. Это нужно установить с помощью "пути пользователя запускает путь..." и в/etc/paths.

Ответ 2

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

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

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

do shell script "launchctl setenv variablename value"

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

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

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

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

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

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

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

Ответ 3

Можно задать переменные среды в 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

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

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

Проблемы/проблемы:

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

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

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

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

Ответ 4

Процитировано из

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

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

Решение:

Поместите код в /Library/LaunchDaemons/com.apple.launchd.limit.plist на bash - script:

#!/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

Ответ 5

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

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

Проверено на El Capitan.

Ответ 6

Что для меня работало (вдохновлено спасибо 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, затем введите свой пароль для входа в систему с правами пользователя
  • Введите vi/Library/LaunchDaemons/com.apple.launchd.limit.plist
  • В редакторе vi нажмите клавишу i, чтобы войти в режим вставки, затем вставьте точный код выше (⌘+v). Это приведет к ограничению до 16384 файлов на каждый процесс и 16384 файлов.
  • Сохраните файл и закройте его с помощью esc, затем :wq
  • Перезагрузите свою систему и убедитесь, что она работает с помощью команды limitctl limit

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

Ответ 7

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

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

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

Ответ 8

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

Ответ 9

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