Задаването на променливи на средата чрез 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 vars;) - person hasvn; 07.11.2014
comment
Това няма да работи с променливата PATH за мен. Така че в допълнение към този подход за настройка на други променливи, аз зададох променливата PATH в моя ~/.bash_profile. Това може и да не работи във всеки случай, но досега не съм имал проблем. - person djule5; 17.12.2014
comment
@djule5 PATH работи за мен, използвам този ред, за да добавя gradle към пътя: launchctl setenv PATH $PATH:/Applications/gradle/bin - person MortimerGoro; 17.12.2014
comment
Това също работи за създаване на нови променливи на средата в Yosemite. Благодаря! - person n00b; 21.01.2015
comment
Също така трябваше да рестартирам Mac, за да работи това. Не беше достатъчно да се изпълни командата launchctl start, последвана от рестартиране на приложението GUI (Eclipse). - person Dave Hartnoll; 16.02.2015
comment
Разбрах го: За да работи без рестартиране, трябва да бъде launchctl load environment.plist, а не start - person Dave Hartnoll; 16.02.2015
comment
Този метод работи по-добре за мен от този от ruario, тъй като имам настройка на boxen + homebrew - променливи указатели за GUI приложения е по-добре да се използва 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 зареди ~/Library/LaunchAgents/environment.plist. Когато правя qmake --version сега, все още виждам QMake версия 2.01a Използване на Qt версия 4.8.7 в /usr/local/Cellar/qt/4.8.7/lib - какво правя погрешно? Аз съм на Yosemite 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 работи за Mojave - person Ivan Romanov; 13.11.2018

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

Очевидно няма да искате да правите това всеки път, когато влизате.

[Редактиране]: За да избегнете това, стартирайте AppleScript Editor, въведете команда като тази:

do shell script "launchctl setenv variablename value"

(Използвайте няколко реда, ако искате да зададете множество променливи)

Сега запазете (+s) като Файлов формат: Приложение. Накрая отворете System SettingsПотребители и групиЕлементи за влизане и добавете вашето ново приложение.

[Оригинален отговор]: За да заобиколите това място, всички променливи, които искате да дефинирате в кратък шел скрипт, след това погледнете това предишен отговор за това как да стартирате скрипт при влизане в MacOS. По този начин скриптът ще бъде извикан, когато потребителят влезе.

[Редактиране]: Нито едно от решенията не е перфектно, тъй като променливите ще бъдат зададени само за този конкретен потребител, но се надявам/предполагам, че това може да е всичко, от което се нуждаете.

Ако имате няколко потребители, можете ръчно да зададете Елемент за влизане за всеки от тях или да поставите копие на com.user.loginscript.plist във всеки от техните локални < em>Library/LaunchAgents директории, сочещи към един и същ скрипт на обвивката.

Разбира се, нито едно от тези решения не е толкова удобно, колкото /etc/launchd.conf.

[Допълнителна редакция]: Потребител по-долу споменава, че това не е проработило за него. Въпреки това тествах на множество машини Yosemite и работи за мен. Ако имате проблем, не забравяйте, че ще трябва да рестартирате приложенията, за да влезе в сила това. Освен това, ако зададете променливи в терминала чрез ~/.profile или ~/.bash_profile, те ще заменят нещата, зададени чрез launchctl setenv за < силни>приложения, стартирани от обвивката.

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 за цялата система за GUI приложения. - person TJ Luoma; 20.12.2014
comment
След като използвате един от гореспоменатите методи и рестартирате лаптопа си - Уверете се, че изрично отваряте отново приложенията (като iTerm, terminal, Eclipse, IDEA или каквото и да използвате). Ако не ги рестартирате изрично и ако по време на рестартирането на OSx квадратчето за отметка е поставено до Рестартиране на прозорци при повторно влизане (което е по подразбиране) - тези програми няма да прочетат новите променливи на средата. - person Ran; 15.03.2015
comment
1. launchctl setenv variablename valu и след това 2. рестартирайте shell - работи за мен - 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
PATH трябва да бъде зададен с файла /etc/paths. Просто добавете вашия персонализиран път в края на този файл. - person ursa; 28.10.2014
comment
Не съм толкова запознат с launchd, но не би ли било възможно да заредите тези Daemons при зареждане (т.е. преди влизане)? Това трябва да заобиколи всички проблеми, които споменавате. - 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
В моя въпрос Очертавам как да използвам горния подход за повторно използване на моите експорти на shell, за да имам само един истински източник за променливи на средата, т.е. в моя случай моята .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, но мисля, че същността тук е: поставете този plist в /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 каква част от този plist всъщност задава променлива на средата? - 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.

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

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 опит. Той обработва както командния ред, така и GUI приложения от един източник и работи с най-новата версия на 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
Имайте предвид, че не е нужно да излизате и да влизате отново. Просто използвайте командата източник, т.е. източник .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, the finder, emacs, xcode, cronjobs, launchd агенти, всяка IDE, браузъри за контрол на източника и т.н. и т.н. всички няма да имат bash като предшественик. Единственият процес, който може да ги обхваща последователно, е launchd. - person Ben Hyde; 15.03.2015