Добавить каталоги в $ PATH, не повторяя себя

5

Моя оболочка zsh , а ОС - Ubuntu 13.04

Мне нужно добавить каталог в $ PATH, чтобы он работал в следующих местах:

  • В графической среде (Unity) (например, при запуске приложений, gmrun программа, выполняемая ярлыком (в основном это как «Команда запуска» на alt + f2)
  • В терминале в Unity
  • В терминале на Ctrl + Alt + F1

Я добавил его в .profile , и он работает для первых двух точек, но не для последнего. Я знаю, что могу добавить его в .zshrc , но в этом случае он будет записан в местах буксировки (нарушает DRY), а в случае терминала внутри единицы он будет два раза в $PATH (я не думаю, что это очень плохо, но это по крайней мере не очень)

Если я добавлю его только в .zshrc , он работает только для второго и третьего случаев (очевидно)

Что я могу сделать?

    
задан RiaD 30.07.2013 в 18:07
источник

3 ответа

1

Этот ответ, в основном, основан на одном из них Элиа Кагана и содержит то, что я действительно сделал.

Я добавил к ~/.pam_environment

PATH DEFAULT=${PATH}:/home/riad/scripts

Но, по крайней мере, на моем ПК он не разбирался в tty1 ( Ctrl + Alt + F1 )), но был разобран на графическом входе , (Даже настройки языкового стандарта, созданные единством, не работали в неграфическом входе в систему)

Причина в том, что для файла lightdm ( /etc/pam.d/lightdm ) была следующая строка в файле конфигурации pam:

session required        pam_env.so readenv=1 user_readenv=1 envfile=/etc/default/locale

Я добавил ту же строку в /etc/pam.d/login между

@include common-session

и

@include common-password

Будьте осторожны! Файл Bad .pam_environment может нарушить ваш логин.

    
ответ дан RiaD 01.08.2013 в 06:18
источник
4

Настройка переменной среды для всех логинов (независимо от типа)

Лучший способ - использовать ~/.pam_environment . Например, чтобы добавить /opt/blah/bin до конца PATH , вы поместите это в файл .pam_environment в вашем домашнем каталоге:

PATH DEFAULT=${PATH}:/opt/blah/bin

Установка переменных среды Глобально (но не делайте этого, если вам не нужно)

Если вы хотите добавить что-то в PATH для всех пользователей , вместо этого используйте /etc/environment . Смутно, /etc/environment и ~/.pam_environment не используют один и тот же синтаксис. Хотя ни один из них не является скриптом, /etc/environment выглядит как скрипт ( without для любых команд export ). Итак, если вы хотите добавить /opt/blah/bin к концу PATH всех, а строка PATH в /etc/environment начиналась как

PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games"

, то вы измените его на:

PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/opt/blah/bin"

Анализ

Большинство оболочек в стиле Бурна, включая bash , будут источником ~/.profile , когда они будут запущены в качестве оболочки входа. zsh - необычное исключение; он будет делать это только в том случае, если он вызывается с именем одной из традиционных оболочек в стиле Бурна. То есть, если вы назовите zsh именем sh или ksh (чаще всего достигается путем создания символической ссылки на zsh с одним из этих имен), она будет вести себя как их и источник ~/.profile (если это оболочка входа). В противном случае это не произойдет. (Источник: man zsh .)

Вот почему zsh в сеансе виртуальной консоли (например, вы переходите к Ctrl + Alt + F1 ) не устанавливает переменную среды PATH из ~/.profile . Это оболочка входа, но zsh является специальной; он не ведет себя как традиционные оболочки в стиле Бурна, если он не притворяется одним.

Почему в zsh , запущенном в окне терминала, есть переменные среды, установленные в ~/.profile ? Поскольку они уже были установлены на вашем графическом сеансе, прежде чем вы запустили терминал . Когда вы входите в систему графически, диспетчер отображения (который предоставляет графический экран входа в систему и управляет графическими сеансами), действует как оболочка входа . Обычно это источник ~/.profile (хотя он не гарантирован , что он это сделает, а иногда кто-то меняет среду рабочего стола только для того, чтобы найти, что ~/.profile больше не используется при графическом входе в систему).

В текстовых виртуальных консолях ничего нет, что делает ~/.profile недоступным. Например, если ваша оболочка была bash вместо zsh , и вы вошли в систему на виртуальной консоли, ~/.profile будет отправлено. Проблема заключается в том, что, в отличие от надежного поведения традиционной оболочки в стиле Бурна, а также не столь же надёжного поведения диспетчера дисплея, запускающего графический сеанс входа в систему, zsh не отправляет ~/.profile , когда это ваша оболочка входа.

Аналогично, если переменные окружения заданы в ~/.profile , если вы должны были удаленно войти в систему (например, включив SSH и зарегистрировавшись таким образом), ~/.profile не будет отправлено.

Это относится и к глобальному файлу /etc/profile , кстати. Если вы установите глобальные переменные окружения там, вы будете испытывать то же поведение, что видите переменные среды среды для своего пользователя в ~/.profile .

Решение при условии, что вам не нужно писать скриптовый тест для определения содержимого переменных среды , заключается в установке пользовательских переменных среды в ~/.pam_environment и в системном масштабе (т.е. , для всех пользователей) переменные среды в /etc/environment .

Когда вы это сделаете, PAM (в частности, pam_env.so ) устанавливает переменные при входе в систему, в основном для каждого типа входа, и делает это до оболочка входа (например, zsh , bash для большинства пользователей) или элемент, похожий на логин (например, диспетчер отображения), содержит свои собственные файлы конфигурации входа. Это обычно рекомендуемый способ установки переменных среды в Ubuntu в наши дни .

Этот способ решает проблему некоторых оболочек входа, которые не всегда используют ~/.profile и /etc/profile (что является проблемой, с которой вы столкнулись). Он также решает случайную проблему диспетчера дисплея, не используя этот файл, поскольку он инициализирует графический сеанс входа в систему (это проблема, с которой вы сталкиваетесь not ).

Альтернативы

Что делать, если:

  • вам нужно установить переменные среды при входе в систему, основываясь на результатах тестовых тестов? Или
  • вы просто не хотите использовать .pam_environment (или для системных переменных, /etc/environment ?

Если вы не использовали zsh , но вместо этого использовали bash или другую более традиционную оболочку стиля Bourne, тогда вы можете просто установить переменные среды в ~/.profile (или /etc/profile для системных переменных). Иногда есть конфигурация, где это не устанавливает их для графических сеансов входа в систему, но обычно это работает.

Установка этих параметров в ~/.bashrc не будет работать для этой цели . По сути, только bash сообщает об этом файле, поэтому он не будет работать, когда zsh является вашей оболочкой входа в систему, а также когда диспетчер отображения действует как ваша оболочка входа. (Другими словами, в вашей ситуации, которая никогда не будет работать вообще.)

Таким образом, если вам нужен сценарий, который используется для всех типов входа, а ~/.profile используется для ваших графических сеансов, вы можете просто:

  • измените конфигурацию zsh на источник ~/.profile , или
  • настройте конфигурацию zsh и ~/.profile - третий, общий файл. (Это может быть даже добавлено в отдельный файл конфигурации для графических сеансов, например, .xsession , если это оказалось чтобы это было необходимо позже.)

Из этих двух вариантов второй лучше, если вы не прочитали содержимое ~ / .profile and made sure they--and the contents of any script sourced from .profile --won't cause problems if sourced by zsh '. (Обычно этого не должно быть, но вы никогда не знаете.)

Лучший конфигурационный файл для модификации, чтобы zsh source ~/.profile (или какой-либо другой скрипт) при входе в систему был ~/.zprofile . Это соответствует ~/.profile для более традиционных оболочек в стиле Бурна. (Строго говоря, это $ZDOTDIR/.zprofile , но $ZDOTDIR обычно ~ .)

Вы добавили бы строку source $HOME/.profile к этому файлу.

Я подчеркиваю, однако, что если просто нужно выполнить простое присвоение переменных среды (включая рекурсивное присваивание, где переменным окружения присваивается выражение, содержащее сам и / или другие переменные среды), нужно просто использовать ~/.pam_environment , как описано выше (или /etc/environment для системных переменных среды).

    
ответ дан Eliah Kagan 30.07.2013 в 19:02
1

Прежде всего, вы можете просто указать свой .profile в вашем файле .zshrc.

Кроме того, поскольку вы используете zsh, вы можете добавить следующее в свой .zshrc:

typeset -U path

# If you want it at the front of your path
path=({/custom/path/bin "${path[@]}")

# If you want it at the end of your path
path+=(/custom/path/bin)

Как это работает:

В zsh переменная $PATH привязана к переменной $path ; $path - массив, а $PATH - это скаляр с элементами $path , соединенными : (идентичными ${(j|:|)path} ). typeset -U path делает элементы массива path (и, следовательно, $PATH ) уникальными.

   typeset [ {+|-}AEFHUafghklprtuxmz ] [ -LRZi [ n ]] [ name[=value] ... ]
   typeset -T [ {+|-}Urux ] [ -LRZ [ n ]] SCALAR[=value] array [ sep ]
          Set or display attributes and values for shell parameters.
          (...)
          -U     For  arrays  (but  not for associative arrays), keep only
                 the first occurrence of each duplicated value.  This  may
                 also  be  set for colon-separated special parameters like
                 PATH or FIGNORE, etc.  This flag has a different  meaning
                 when used with -f; see below.
    
ответ дан Kevin 30.07.2013 в 18:56