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

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

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

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

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

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

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

5
задан 30 July 2013 в 20:55

3 ответа

Этот ответ в основном основан на одном 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 файл может, повредил Ваш вход в систему.

1
ответ дан 30 July 2013 в 20:55

Прежде всего, вы можете просто поставить свой .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.
0
ответ дан 30 July 2013 в 20:55

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

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

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

Setting Environment Переменные глобально (но не делайте этого, если вам не нужно)

Если вы хотите добавить что-то в 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 + 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 (что является проблемой, с которой вы сталкиваетесь). Это также решает случайную проблему диспетчера дисплеев, не использующего этот файл, поскольку он инициализирует графический сеанс входа в систему (это проблема, с которой вы не сталкивались ).

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

Что если:

  • вам нужно установить переменные окружения при входе в систему, основываясь на результатах тестов по сценарию? Или
  • вы просто не хотите использовать .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 для общесистемных переменных среды).

0
ответ дан 30 July 2013 в 20:55

Другие вопросы по тегам:

Похожие вопросы: