Выбор между .bashrc, .profile, .bash_profile и т. Д. [Дубликаты]

197

На этот вопрос уже есть ответ здесь:

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

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

AVDI
источник
6
этот вопрос не следует помечать как дубликат, так как .profile недоступен в добавленном вопросе.
Премрадж
Ответ
Premraj

Ответы:

222

TL; DR:

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

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

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

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

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

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

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

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

Дэн Рабиновиц
источник
3
+1, это позволяет ~/.profileправильно установить среду для таких сервисов, как GDM / LightDM / LXDM, которые явно запускают / bin / sh.
благодарность
12
Мои .bashrcвыводы довольно много вещей, вы можете прокомментировать это? В частности, где я должен поместить приветствие?
Калимо
14
@Calimo: Сделать вывод только в интерактивном режиме. Вы можете проверить это, используя [[ $- == *i* ]]поиск «i» в специальной $-переменной. Конечно, это важно только в первую очередь в системах, где bash компилируется для чтения .bashrcв неинтерактивном режиме. (То есть, Debian , но не Arch.) Но это частая причина загадочных сообщений об ошибках при попытке подключения с использованием sftpили scpпохожими инструментами.
Гравитация
4
Теперь я должен знать - почему .bash_login не должно существовать? Что оно делает?
tedder42
11
@ tedder42: делает так же, как .bash_profileи .profile. Но Bash читает только первый из трех. Значит, если есть .bash_login, то и то, .profileи другое .bash_profileбудет загадочно игнорироваться.
grawity
54

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

Требования:

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

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

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

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

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

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

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

    [[$ - == * i *]] || вернуть 0
    
    PS1 = '\ h \ w \ $'
    
    start () {sudo service "$ 1" start; }
    

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

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

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

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

    Тогда, конечно, обновление ~/.environдо unset BASH_ENV.


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

grawity
источник
2
+1 за последний пункт, но я предпочитаю источников .profileи .bashrcот .bash_profileи держать в .profileчистоте.
nyuszika7h
@ nyuszika7h: Мой .profile чистый , спасибо.
Гравитация
1
Обратите внимание на комментарий, каждый раз, когда вы открываете окно, для OSX
наоборот
1
« Бессмысленно иметь и то ~/.profileи другое ~/.bash_profile»: я не согласен. Смотрите ответ Дэна, почему.
rubenvb
@rubenvb Можете ли вы процитировать соответствующую часть? Я думаю, что хорошо иметь .profileи защищать только определенные bashчасти с помощью условных обозначений .
Кельвин
36

Взгляните на этот отличный пост в блоге 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      |           |      |
+----------------+-----------+-----------+------+
Флимм
источник
Это приятно. Важно отметить, что обычно /etc/profileзвонки /etc/bash.bashrcи ~/.profileзвонки ~.bashrc. Так эффективно, /etc/bash.bashrcи ~/.bashrcвыполняются для интерактивных входов в систему.
Висбуки
Обратите внимание, что некоторые дистрибутивы, похоже, переопределяют эту схему (со странными последствиями) - см., Например, мой отчет об ошибках в opensuse здесь: bugzilla.opensuse.org/show_bug.cgi?id=1078124
Christian Herenz
Btw. по крайней мере с bash ни один из этих файлов не выполняется, когда bash вызывается через/bin/sh
JepZ
@JepZ Вы правы, это то, что объясняет третий столбец «Сценарий».
Flimm
1
@Flimm Хорошо, столбец «Скрипт» описывает, что происходит, когда вы запускаете неинтерактивный скрипт через bash (например, / bin / bash). Однако, если вы запускаете скрипт с помощью sh (а / bin / sh является символической ссылкой на / bin / bash), ни один из вышеперечисленных не выполняется (даже не выполняется BASH_ENV). Соответствующий абзац справочной страницы bash можно найти, выполнив поиск If bash is invoked with the name sh.
JepZ
21

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

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

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

Механическая Рыба
источник
3
Наличие обоих .bash_profileи .profileнемного избыточно; вам нужно только последнее. Вы должны сделать это / bin / sh-proof, хотя: if [ "$BASH" ] && [ -r ~/.bashrc ]; then . ~/.bashrc; fiпоскольку есть программы (а именно gdm / lightdm), которые вручную получают файл из скрипта / bin / sh. Это также означает, что сохраняемая среда .bashrcбудет неэффективной. Пришлось -1, так как ваши «всеобъемлющие» рекомендации не будут работать на многих системах, как я несколько раз обнаружил на своем пути.
Гравитация
Нет проблем, я бы с радостью заплатил -1 за ответ, который не просто насмешливый «всеобъемлющий», и вы, безусловно, получили этот титул.
Механическая рыба
0

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

Этот подход требует ~/.shell-setupдвух функций:

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

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

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

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

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

ShadSterling
источник
-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безоговорочно. Пожалуйста, смотрите комментарии и другие ответы для получения дополнительной информации.

mattr-
источник
4
-1, НЕ источник .bashrcс .profile. Смотрите ответ @ DanRabinowitz.
nyuszika7h
По крайней мере, не безоговорочно.
nyuszika7h
[ -n "$BASH" -a -f ~/.bashrc ] && . ~/.bashrcбыл бы сладким вкладышем для .profile.
Джон У. С. Смит,
@ nyuszika7h, а почему бы и нет? Кажется, все предлагают это сделать.
Pacerier