Встановлення змінних середовища через startd.conf більше не працює в OS X Yosemite / El Capitan / macOS Sierra / Mojave?


190

Схоже, launchd.confце не завантажує мій змінний середовища. Хтось ще помітив це?

Чи є інше рішення для постійного встановлення змінних середовища?


Це працює і стає доступним у додатку, але не в терміналі
Чанг Чжао

Відповіді:


159

Створіть 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негайно запустити його.

[Редагувати]

Це ж рішення працює і в Ель-Капітан.

Xcode 7.0+ не за замовчуванням оцінює змінні середовища. Стару поведінку можна включити за допомогою цієї команди:

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

[Редагувати]

Існує пара ситуацій, коли це не зовсім працює. Якщо комп'ютер перезапущено і вибрано "Повторно відкрити вікна при вході в систему", повторно відкриті вікна можуть не бачити змінних (можливо, вони відкриваються до запуску агента). Крім того, якщо ви увійдете через ssh, змінні не будуть встановлені (тому вам потрібно буде встановити їх у ~ / .bash_profile). Нарешті, це, здається, не працює для PATH на Ель-Капітан та Сьєрра. Це потрібно встановити через "startctl config user path ..." та в / etc / paths.


20
Не потрібно перезавантажувати! Ви можете зробити "startctl start environment.plist" та перезапустити додаток, який вам потрібен, щоб отримати нові env vars;)
hasvn

1
Це не буде працювати зі змінною PATH для мене. Отже, крім цього підходу для встановлення інших змінних, я встановлюю змінну PATH у своєму ~ / .bash_profile. Це може не спрацювати для кожного випадку, але поки що у мене немає проблеми.
djule5

6
З'ясував це: Щоб працювати без перезавантаження, це має бути "launchctl load environment.plist", а не запуск
Дейв Хартнолл

2
Ага, так. Нічого подібного до незрозумілого налаштування конфігурації, яке з’являється рівно 9 разів у всьому Інтернеті (Google UseSanitizedBuildSystemEnvironment).
Охад Шнайдер

2
Працює і на Сьєррі
Швоук

64

[ Оригінальна відповідь ]: Ви все одно launchctl setenv variablename valueможете встановити змінну так, щоб її забрали всі програми (графічні програми, запущені через док-станцію або прожектор, на додаток до запущених через термінал).

Очевидно, що ви не хочете робити цього кожного разу, коли будете входити в систему.

[ Редагувати ]: Щоб уникнути цього, запустіть AppleScript Editor, введіть таку команду:

do shell script "launchctl setenv variablename value"

(Використовуйте кілька рядків, якщо ви хочете встановити кілька змінних)

Тепер збережіть ( + s) як формат файлу: додаток . Нарешті відкрийте System SettingsКористувачі та групиЕлементи входу та додайте нову заявку.

[ Оригінальна відповідь ]: щоб обійти навколо цього місця всі змінні, які ви хочете визначити у сценарії короткої оболонки, а потім ознайомтеся з цією попередньою відповіддю про те, як запустити скрипт під час входу в MacOS . Таким чином сценарій буде викликаний, коли користувач увійде в систему.

[ Редагувати ]: Жодне рішення не є ідеальним, оскільки змінні встановлюватимуться лише для цього конкретного користувача, але я сподіваюся, що це може бути все, що вам потрібно.

Якщо у вас є кілька користувачів, ви можете вручну встановити елемент входу для кожного з них або помістити копію com.user.loginscript.plist у кожну їх локальну бібліотеку / LaunchAgents каталог « , вказуючи на той самий скрипт оболонки.

Звичайно, жоден із цих обхідних шляхів не є таким зручним, як /etc/launchd.conf .

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


5
Наскільки я можу сказати, один із недоліків цієї методики полягає в тому, що змінна (и) не буде встановлена ​​для будь-яких інших програм, запущених під час входу. Так, наприклад, якщо ви відкриєте Terminal, змінна буде встановлена, але якщо ви вийдете з системи і знову
ввімкнете її,

Я спробував це рішення, і для мене це не вийшло. Але я спеціально очікую, що мій Java IDE (IntelliJ) підбере мої модифікації шляху, і це не так. З терміналу все працює чудово. Це може бути помилка в IntelliJ. Досі неприємно, що Apple видалила цю функціональність. Я подзвонив Apple, і вони не були дуже корисними
Джейсон

Це працює для мене, але чи знаєте ви, що робити, щоб додати змінні середовища до sudo?
etiennenoel

2
Це буде працювати загалом, проте є помилка в Yosemite (10.10.0 та 10.10.1 принаймні), де встановлення $ PATH не працює таким чином. Apple знає про помилку. Наразі (станом на 10.10.1) невідомий спосіб встановити загальносистемний $ PATH для додатків GUI.
TJ Luoma

3
Після використання одного з перерахованих вище способів та перезавантаження ноутбука. Переконайтеся, що ви явно перезапустите додатки (наприклад, iTerm, термінал, Eclipse, IDEA або все, що ви використовуєте). Якщо ви явно не перезапускаєте їх, а якщо під час перезавантаження OSx, то прапорець встановлено прапорець "Перезавантажити вікна при вході в систему назад" (що за замовчуванням) - ці програми не будуть читати нові змінні середовища.
Ран

21

Можна встановити змінні середовища на 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 реєструються паралельно з обробкою "повторно відкритої черги".

Але насправді я перезавантажую систему лише кілька разів на рік (на великих оновленнях), тому це не велика справа.


Чудова ідея. Я спробував це, і він працює для більшості змінних середовища (як JAVA_HOME), але не для PATHзмінної (див. Моє запитання на запитання різних ).
halloleo

4
PATH слід встановити з файлом / etc / paths. Просто додайте свій власний шлях до кінця цього файлу.
ursa

Я не такий знайомий launchd, але чи не вдалося б завантажити цих демонів під час завантаження (тобто перед входом)? Це повинно обійти всі згадані вами проблеми.
Егон

Я люблю підхід вище, але маю дивну проблему управління. Після перезавантаження генет VARNAME повертає мені потрібне значення, але echo $ VARNAME нічого не повертає. Що може бути причиною цього? Я опублікував це на stackoverflow.com/questions/27045137/… і сподіваюся, що хтось тут має ідею
ctp

Переконайтесь, що дозволи файлу / etc / environment є описаними вище.
imanuelcostigan

6

Цитується з

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

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

Рішення:

Введіть код у /Library/LaunchDaemons/com.apple.launchd.limit.plistbash-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

1
Чи можете ви пояснити це трохи більше? Я не бачу, як "Вирішити питання" стосується початкової проблеми!
Нік H247

Не OP, але я думаю, що суть у цьому: введіть цей список /Library/LaunchDaemonsі замість того, launchctlщоб казати виконувати limitкоманду, скажіть йому, щоб запустити setenvкоманду PATHі рядок шляху як аргументи. launchdслід підбирати його автоматично під час запуску та отримувати щось самомодифіковане майже негайно.
Лаїрд Нельсон

5
XML неповно копіюється. У рядку <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
доктрипу

6
@aax Яка частина цього списку фактично встановлює змінну середовища?
HairOfTheDog

3

Ось команди відновити стару поведінку:

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

Перевірено на Ель-Капітан.


2

Що для мене спрацювало (надихнувшись від дякової подяки):

Вставте це в /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
  • Перезавантажте систему та перевірте, чи працює вона, використовуючи ліміт запуску команд

Я сподіваюся, що це вам допомогло.


10
Що це рішення має відношення до встановлення змінних середовища?
HairOfTheDog

2

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

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

Я відповів на подібне запитання тут, де ви знайдете більше.


-3

Рішення полягає в тому, щоб додати свою змінну до /etc/profile. Тоді все працює як очікувалося! Звичайно, ВИ ТАКОЙ СПОСІБНО це зробити як користувач root з sudo nano / etc / profile. Якщо ви редагуєте його будь-яким іншим способом, система скаржиться на пошкоджений / etc / profile, навіть якщо ви зміните дозволи на root.


7
Додавання змінних середовища до профілю дуже поступається, оскільки впливає лише на процеси оболонки.
UloPe

-5

Я додав змінні в ~ / .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

Зауважте, що вам не потрібно виходити та повертатися назад. Просто використовуйте команду source, тобто source .bash_profile.
Майкл

2
Також проблема цього методу полягає в тому, що вам все одно доведеться відкривати термінал, перш ніж змінні середовища стануть доступними. Краще робити те, що є в першій відповіді, щоб вони були доступні, не відкриваючи термінал.
Майкл

1
Це не працює в додатках, завантажених через SpotLight. stackoverflow.com/questions/135688/…
Расіка Перера

1
Використання bash-конфігураційних файлів має обмежену допомогу, оскільки передбачає, що ви завжди отримали bash як предка процесу, оточуючи ваше намагання впливати. Прожектор, шукач, emacs, xcode, cronjobs, запускаючі агенти, будь-яка IDE, браузери з управління джерелами тощо, і т. Д. Всі не будуть мати башти як предка. Єдиний процес, який може послідовно їх охоплювати, - це запущений.
Бен Гайд
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.