Встановлення змінних середовища через 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.