Моя оболочка - zsh
, а ОС - Ubuntu 13.04
Мне нужно добавить каталог в $ PATH, чтобы он работал в следующих местах:
gmrun
программа, запускаемая по ярлыку (в основном это «команда запуска» на alt + f2) Я добавил его в .profile
, и он работает для первых двух пунктов, но не последнее. Я знаю, что могу добавить его в .zshrc
, но в этом случае оно будет записано в местах буксировки (нарушает DRY), а в случае терминального внутри единства это будет два раза в $PATH
(я не не думаю, что это очень плохо, но это, по крайней мере, не красиво)
Если я добавлю его только к .zshrc
, это будет работать только для второго и третьего случаев (очевидно)
Что я могу сделать?
Этот ответ в основном основан на одном Eliah Kagan и содержит то, что я действительно сделал.
Я добавил к ~/.pam_environment
PATH DEFAULT=${PATH}:/home/riad/scripts
Но по крайней мере на моем ПК это не было проанализировано на tty1 (Ctrl+Alt+F1), входят в систему, но был проанализирован на графическом входе в систему. (Даже настройки локали, которые создаются единицей, не были работой в неграфическом входе в систему),
Причина состоит в том, что там следовал за строкой в pam конфигурационном файле для lightdm (/etc/pam.d/lightdm
) :
session required pam_env.so readenv=1 user_readenv=1 envfile=/etc/default/locale
Я добавил ту же строку к /etc/pam.d/login
между
@include common-session
и
@include common-password
.pam_environment
файл может, повредил Ваш вход в систему.Прежде всего, вы можете просто поставить свой .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.
Лучший способ - использовать ~/.pam_environment
. Например, чтобы добавить /opt/blah/bin
в конец вашего PATH
, вы должны поместить это в файл .pam_environment
в вашем домашнем каталоге:
PATH DEFAULT=${PATH}:/opt/blah/bin
Если вы хотите добавить что-то в PATH
для всех пользователей , используйте вместо этого /etc/environment
. Заблуждение, что /etc/environment
и ~/.pam_environment
не используют один и тот же синтаксис. Хотя ни один из них на самом деле не является сценарием, /etc/environment
выглядит как сценарий ( без каких-либо команд 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 < / kbd> + Alt kbd> + F1 kbd>) не устанавливает переменную окружения 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
(что является проблемой, с которой вы сталкиваетесь). Это также решает случайную проблему диспетчера дисплеев, не использующего этот файл, поскольку он инициализирует графический сеанс входа в систему (это проблема, с которой вы не сталкивались ).
Что если:
.pam_environment
(или для общесистемных переменных: /etc/environment
? Если вы не использовали zsh
, но вместо этого использовали bash
или другую более традиционную оболочку в стиле Борна, тогда вы могли бы просто установить переменные окружения в ~/.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
источник ~/.profile
(или какой-либо другой сценарий) при входе в систему, является ~/.zprofile
. Это соответствует ~/.profile
для более традиционных оболочек в стиле Борна. (Строго говоря, это $ZDOTDIR/.zprofile
, но $ZDOTDIR
обычно ~
.)
Вы бы добавили строку source $HOME/.profile
в этот файл.
Я подчеркиваю, однако, что если вам просто нужно выполнить простое присваивание переменным окружения (включая рекурсивное присваивание, когда переменным окружения присваивается выражение, содержащее себя и / или другие переменные окружения), вы должны просто использовать ~/.pam_environment
, как объяснено выше (или /etc/environment
для общесистемных переменных среды).