178

Это смущает, но после многих лет использования систем POSIX на полную ставку мне все еще трудно понять, стоит ли настраивать оболочку в .bashrc , .profile или где-то еще. Не говоря уже о некоторых специфичных для ОС конфигурационных файлах, таких как .pam_environment .

Да, я знаю, как разобраться в документации и узнать, когда каждый файл загружен или не загружен. Что мне интересно, так это то, что у кого-нибудь есть подробные рекомендации о том, как решить, в какой файл поместить данный тип настройки.

6 ответов6

200

TL; DR:

  • ~/.bash_profile должен быть очень простым и просто загружать .profile и .bashrc (в таком порядке)

  • ~/.profile есть вещи, НЕ связанные с bash, такие как переменные окружения (PATH и друзья)

  • ~/.bashrc содержит все, что вам нужно, в интерактивной командной строке. Командная строка, переменная EDITOR , псевдонимы bash для моего использования

Несколько других заметок:

  • Все, что должно быть доступно для графических приложений ИЛИ для sh (или bash, вызываемого как sh), ДОЛЖНО быть в ~/.profile

  • ~/.bashrc не должен ничего выводить

  • Все, что должно быть доступно только для оболочек входа, должно идти в ~/.profile

  • Убедитесь, что ~/.bash_login не существует.

49

За последние несколько лет, у меня было много времени , чтобы тратить, так что я исследовал это для немного больше , чем просто 10 минут. Я понятия не имею, если это лучший макет, он работает правильно почти во всех случаях.

Требования:

  • ~/.profile должен быть совместим с любым /bin /sh - это включает bash, dash, ksh, все, что дистрибутив может использовать.

  • Переменные среды должны быть помещены в файл, который читается как консольными именами входа (например, оболочкой «входа в систему»), так и графическими именами входа (то есть менеджерами отображения, такими как GDM, LightDM или LXDM).

  • Нет смысла иметь оба ~/.profile и ~/.bash_profile . Если последнее отсутствует, bash с радостью использует первое, и любые специфичные для bash строки могут быть защищены проверкой на $BASH или $BASH_VERSION .

  • Разделение между *profile и *rc состоит в том, что первый используется для оболочек 'login', а второй - каждый раз, когда вы открываете окно терминала. Тем не менее, bash в режиме 'login' не является источником ~/.bashrc , поэтому ~/.profile необходимо сделать это вручную.

Самая простая конфигурация будет:

  • Иметь ~/.profile который устанавливает все переменные окружения (кроме специфичных для bash), возможно, печатает одну или две строки, а затем исходники ~/.bashrc если они запускаются bash, в противном случае придерживайтесь sh-совместимого синтаксиса.

    export TZ = "Europe/Paris" export EDITOR = "vim" if ["$ BASH"]; затем . ~/.bashrc fi uptime
    
  • Иметь ~/.bashrc который выполняет любую специфическую для оболочки настройку, защищенную проверкой интерактивного режима, чтобы избежать взлома таких вещей, как sftp в Debian (где bash компилируется с возможностью загрузки ~/.bashrc даже для неинтерактивных оболочек):

    [[$ - == * i *]] || return 0 PS1 = '\h \w \$' start () {запуск службы sudo "$ 1"; }
    

Однако существует также проблема, заключающаяся в том, что некоторые неинтерактивные команды (например, ssh <host> ls) пропускают ~/.profile , но переменные окружения будут для них очень полезны.

  • Некоторые дистрибутивы (например, Debian) компилируют свой bash с опцией source ~/.bashrc для таких неинтерактивных входов в систему. В этом случае я счел полезным переместить все переменные среды (строки export ... ) в отдельный файл ~/.environ и получить его как из .profile и .bashrc с защитой, чтобы избежать делаем это дважды:

    если ! ["$ PREFIX"]; затем # или $ EDITOR, или $ TZ, или ...
        , ~/.environ # обычно любая переменная, которую сам .environ устанавливает в
    
  • К сожалению, для других дистрибутивов (например, Arch) я не нашел очень хорошего решения. Одна из возможностей - использовать (включенный по умолчанию) модуль PAM pam_env, поместив в ~/.pam_environment:

    BASH_ENV =./.environ # не опечатка; это должен быть путь, но ~ не сработает
    

    Затем, конечно, обновить ~/.environ чтобы unset BASH_ENV .


Заключение? Снаряды - это боль. Переменные среды - это боль. Определяемые распределением опции времени компиляции - огромная боль в заднице.

30

Взгляните на этот отличный пост в блоге ShreevatsaR. Вот выдержка, но перейдите к сообщению в блоге, она включает в себя объяснение таких терминов, как "оболочка входа", блок-схема и аналогичная таблица для Zsh.

Для Баша они работают следующим образом. Прочитайте соответствующий столбец. Выполняет A, затем B, затем C и т.д. B1, B2, B3 означают, что он выполняет только первый из найденных файлов.

+----------------+-----------+-----------+------+
|                |Interactive|Interactive|Script|
|                |login      |non-login  |      |
+----------------+-----------+-----------+------+
|/etc/profile    |   A       |           |      |
+----------------+-----------+-----------+------+
|/etc/bash.bashrc|           |    A      |      |
+----------------+-----------+-----------+------+
|~/.bashrc       |           |    B      |      |
+----------------+-----------+-----------+------+
|~/.bash_profile |   B1      |           |      |
+----------------+-----------+-----------+------+
|~/.bash_login   |   B2      |           |      |
+----------------+-----------+-----------+------+
|~/.profile      |   B3      |           |      |
+----------------+-----------+-----------+------+
|BASH_ENV        |           |           |  A   |
+----------------+-----------+-----------+------+
|                |           |           |      |
+----------------+-----------+-----------+------+
|                |           |           |      |
+----------------+-----------+-----------+------+
|~/.bash_logout  |    C      |           |      |
+----------------+-----------+-----------+------+
19

Я предлагаю вам свои "всеобъемлющие" рекомендации:

  • Сделайте .bash_profile и .profile загрузите .bashrc если он существует, используя, например, [ -r $HOME/.bashrc ] && source $HOME/.bashrc
  • Поместите все остальное в .bashrc .
  • Перестань беспокоиться.
  • Каждые четыре года или около того, проводите десять минут, исследуя этот самый вопрос, прежде чем сдаваться и возвращаться к "не беспокоиться".

РЕДАКТИРОВАТЬ: Добавил напугать кавычки на "всеобъемлющий" на тот случай, если кто-то соблазниться в это поверить. ;)

0

Я перестал пытаться выяснить это и создал один скрипт (~/.shell-setup), который я использую для всех остальных.

Этот подход требует, чтобы ~/.shell-setup имел две функции:

  1. Запускается только один раз, даже если он получен повторно (используйте Включить охрану)
  2. Не генерировать нежелательный вывод (определить, когда выход в порядке)

# 1 довольно стандартен, хотя, возможно, не используется в сценариях оболочки.

№2 сложнее. Вот что я использую в bash:

if [ "" == "$BASH_EXECUTION_STRING" -a "" == "$DESKTOP_SESSION" ]; then
    echo "Hello user!" # ... etc
fi

К сожалению, я не помню, как я придумал это, или почему обнаружения интерактивной оболочки было недостаточно.

-2

Поместите все в .bashrc а затем источник .bashrc из .profile

Со страницы руководства bash (на OS X 10.9):

Когда запускается интерактивная оболочка, которая не является оболочкой входа в систему, bash читает и выполняет команды из ~/.bashrc, если этот файл существует. Это может быть запрещено с помощью параметра --norc. Опция --rcfile file заставит bash читать и выполнять команды из файла вместо ~/.bashrc

Приведенный выше текст объясняет, почему все помещается в .bashrc . Однако, когда вы работаете с оболочкой входа в систему, поведение несколько иное. Опять цитата из справочной страницы:

Когда bash вызывается как интерактивная оболочка входа в систему или как неинтерактивная оболочка с параметром --login, она сначала читает и выполняет команды из файла /etc /profile, если этот файл существует. После прочтения этого файла он ищет ~ /.bash_profile, ~ /.bash_login и ~ /.profile в указанном порядке, а также читает и выполняет команды из первой, которая существует и доступна для чтения. Опция --noprofile может использоваться, когда оболочка запущена, чтобы запретить это поведение.

.profile читается для логинов, но .bashrc - нет. Дублировать все эти вещи в .bashrc - это плохо ™, поэтому нам нужно поместить их в .profile чтобы поведение оставалось последовательным.

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

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .