Разница между .bashrc и .bash_profile

449

В чем разница между .bashrcи .bash_profileи какой я должен использовать?

cfischer
источник
2
Смотрите также этот похожий вопрос на ubuntu.stackexchange.com/questions/1528/bashrc-or-bash-profile
Стефан Ласевский,
Если вы хотите получить более полное объяснение, которое также включает в себя .profile, взгляните на этот вопрос: superuser.com/questions/789448/…
Flimm
Этот ответ также охватывает некоторые аспекты stackoverflow.com/questions/415403/…
Сергей Воронежский

Ответы:

517

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

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

Вы можете вызвать оболочку напрямую в любое время, например, запустив эмулятор терминала в среде графического интерфейса. Если оболочка не является оболочкой входа, она не читается ~/.profile. Когда вы запускаете bash как интерактивную оболочку (то есть, чтобы не запускать скрипт), он читает ~/.bashrc(кроме случаев, когда он вызывается как оболочка входа в систему, тогда он читает только ~/.bash_profileили ~/.profile.

Следовательно:

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

  • ~/.bashrcэто место для размещения вещей, которые применяются только к самому bash, таких как определения псевдонимов и функций, параметры оболочки и настройки подсказок. (Вы также можете разместить здесь привязки клавиш, но для bash они обычно используются ~/.inputrc.)

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

    if [ -r ~/.profile ]; then . ~/.profile; fi
    case "$-" in *i*) if [ -r ~/.bashrc ]; then . ~/.bashrc; fi;; esac
    

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

Обратите внимание, что вы можете увидеть здесь и там рекомендации, чтобы либо помещать определения переменных среды, ~/.bashrcлибо всегда запускать оболочки входа в систему в терминалах. Оба плохие идеи. Наиболее распространенная проблема с любой из этих идей заключается в том, что переменные среды будут устанавливаться только в программах, запускаемых через терминал, а не в программах, запускаемых непосредственно с помощью значка, меню или сочетания клавиш.

¹ Для полноты, по запросу: если .bash_profileне существует, bash также пытается, .bash_loginпрежде чем вернуться к .profile. Не стесняйтесь забыть, что это существует.

жилль
источник
11
+1 за хороший пост. ТАКЖЕ спасибо за добавление раздела "вход в систему с графическим входом против оболочки входа в систему" ... У меня была проблема, когда я думал, что ~ / .profile ВСЕГДА будет выполняться для графического объекта / оболочки ... но он не выполняется, когда пользователь входит в систему через графический логин. Спасибо за разгадку этой тайны.
Тревор Бойд Смит
4
@ Жиль: Не могли бы вы объяснить более подробно, с примерами, почему запуск оболочки входа в систему в каждом терминале - плохая идея? Это только проблема с настольным Linux? (Я понимаю, что в OS X Terminal каждый раз запускается оболочка входа в систему, и я никогда не замечал каких-либо побочных эффектов (хотя я обычно использую iTerm). Но тогда я не могу думать о многих переменных среды, о которых бы я заботился за пределами терминал. (Может быть, HTTP_PROXY?))
иконоборчество
2
@Brandon Если вы запускаете оболочку входа в систему в каждом терминале, она будет переопределять переменные среды, предоставляемые средой. В повседневных ситуациях вы можете сойти с рук, но это рано или поздно укусит вас, когда вы захотите установить разные переменные в терминале (скажем, попробовать другую версию программы): запустить Оболочка входа переопределяет ваши локальные настройки.
Жиль
4
~/.bash_profileВместо этого можно использовать~/.profile~/.bashrc оператор , но его также необходимо включить, если оболочка является интерактивной. вводит в заблуждение, так как это ортогональные вопросы. Неважно, используете ли вы ~/.bash_profileили ~/.profileвы должны включить ~/.bashrcтот, который вы используете, если вы хотите, чтобы настройки оттуда вступили в силу в оболочке входа.
Петр Доброгост
3
@ Жиль: Конечно, но то, как формулировка предложения сформулирована в ответе, говорит о том, что необходимость включения ~/.bashrcимеет какое-то отношение к выбору, ~/.bash_profileа ~/.profileне к неправде. Если кто-то включает ~/.bashrcв сценарии любой вид источника во время входа в систему (здесь это либо ~/.bash_profileили ~/.profile), потому что он хочет, чтобы настройки ~/.bashrcприменялись к оболочке входа в систему так же, как они применяются к оболочке без входа в систему.
Петр Доброгост
53

Из этой короткой статьи

Согласно man-странице bash, .bash_profile выполняется для оболочек входа в систему, в то время как .bashrc выполняется для интерактивных оболочек без входа в систему.

Что такое оболочка для входа или не входа?

Когда вы входите в систему (например, введите имя пользователя и пароль) через консоль, либо физически сидите за компьютером при загрузке, либо удаленно через ssh: .bash_profile выполняется для настройки вещей до начальной командной строки.

Но, если вы уже вошли в систему и открыли новое окно терминала (xterm) внутри Gnome или KDE, то .bashrc выполняется перед командной строкой окна. .bashrc также запускается, когда вы запускаете новый экземпляр bash, набирая / bin / bash в терминале.

Jarvin
источник
12
Небольшие обновления: «Выполнено», вероятно, вводит в заблуждение термин, оба они получены. Исполняется звучит так, как будто он запускается как скрипт, fork / exec yadda yadda. Он запускается в контексте текущей оболочки. Более того, .bashrc запускается гораздо чаще. Он запускается при каждом запуске bash-скрипта, а также, если у вас нет файла .bash_profile. Кроме того, в зависимости от того, как вы настроили свои xterms, вы можете создать оболочку с исходным кодом .bash_profile
Rich Homolka
36

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

Чтобы поддержать это, оболочка создала файл .profileспециально для «оболочек входа в систему». Это сделало бы особенное, после настройки сеанса. Bash несколько расширил это, чтобы сначала посмотреть на .bash_profile, а затем на .profile, чтобы вы могли поместить туда только вещи bash (чтобы они не испортили оболочку Bourne и т. Д., Которые также рассматривали .profile). Другие оболочки, не входящие в систему, могут просто получить rc-файл .bashrc (или .kshrc и т. Д.).

Это немного анахронизм сейчас. Вы не входите в основную оболочку столько, сколько вы входите в менеджер окон графического интерфейса. Главное окно не отличается от любого другого окна.

Мое предложение - не беспокойтесь об этой разнице, она основана на более старом стиле использования Unix. Устранить разницу в ваших файлах. Все содержимое .bash_profile должно быть:

[ -f $HOME/.bashrc ] && . $HOME/.bashrc

И поместите все, что вы действительно хотите установить в .bashrc

Помните, что .bashrc поставляется для всех оболочек, интерактивных и неинтерактивных. Вы можете замкнуть источник для неинтерактивных оболочек, поместив этот код в верхнюю часть .bashrc:

[[ $- != *i* ]] && return

Рич Гомолка
источник
6
Это плохая идея, см. Мой ответ . В частности, переменные среды будут установлены только в программах, запускаемых через терминал, а не в программах, запускаемых непосредственно с помощью значка, меню или сочетания клавиш.
Жиль
4
@ Жиль, я не понимаю, почему ты так заявляешь. С помощью .$HOME/.bashrcRich, показанного выше, настройки .bashrcбудут доступны в оболочках входа в систему и, следовательно, в среде рабочего стола. Например, в моей системе Fedora gnome-sessionзапускается как -$SHELL -c gnome-session, так .profileи читается.
Микель
2
@PiotrDobrogost О, да, есть еще одна проблема с ответом Рича. Включение .bashrcin .profileобычно не работает, потому что .profileможет выполняться /bin/shи не bash (например, в Ubuntu для графического входа в систему по умолчанию), и эта оболочка может быть не интерактивной (например, для графического входа в систему).
Жиль
3
@Gilles re: «включая .bashrc в .profile» совсем не то, что было рекомендовано (на самом деле, наоборот). Либо ответ был отредактирован (так не кажется), либо ваши комментарии не соответствуют тому, что говорится.
Майкл
2
В общем, +1, но я бы добавил к рекомендации «короткое замыкание ... для неинтерактивных оболочек» («около вершины .bashrc: [[ $- != *i* ]] && return»); Мне нравится, что некоторые из моих команд .bashrcвыполняются даже для неинтерактивных оболочек, в частности для установки переменных env при выдаче ssh hostname {command}, чтобы удаленные команды выполнялись правильно (даже если оболочка не является интерактивной). Но другие настройки позже .bashrcследует игнорировать. Я обычно проверяю TERM = тупой и / или неустановленный, а затем выручаю рано.
Майкл
18

Взгляните на этот отличный пост в блоге 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      |           |      |
+----------------+-----------+-----------+------+
Флимм
источник
Вместо того, чтобы публиковать один и тот же ответ на несколько вопросов, предпочтительнее, если вы можете адаптировать свой ответ к конкретным потребностям задающего. Если ответ на оба вопроса одинаков, тогда вы должны опубликовать один ответ и проголосовать, чтобы закрыть остальные вопросы как дубликаты оригинала.
Мокубай
1
@Mokubai Другой вопрос уже помечен как дубликат этого.
Flimm
@ElipticalView: от набора ничего не делать, вы имеете в виду линию: [ -z "$PS1" ] && return? В таблице в моем ответе приведен список сценариев, запускаемых Bash, независимо от содержимого этих сценариев, если в самом сценарии есть строка [ -z "$PS1" ] && return, конечно, это вступит в силу, но я не думаю, что это должно означать, что я должен изменить Таблица.
Flimm
5

ЛУЧШИЙ КОММЕНТАРИЙ ДЛЯ ГЛАВЫ / ETC / PROFILE

Основываясь на великолепном ответе Flimm выше, я вставил этот новый комментарий во главе моего профиля Debian / etc / (вам может понадобиться настроить его для вашего дистрибутива.) :

# For BASH: Read down the appropriate column. Executes A, then B, then C, etc.
# The B1, B2, B3 means it executes only the first of those files found.  (A)
# or (B2) means it is normally sourced by (read by and included in) the
# primary file, in this case A or B2.
#
# +---------------------------------+-------+-----+------------+
# |                                 | Interactive | non-Inter. |
# +---------------------------------+-------+-----+------------+
# |                                 | login |    non-login     |
# +---------------------------------+-------+-----+------------+
# |                                 |       |     |            |
# |   ALL USERS:                    |       |     |            |
# +---------------------------------+-------+-----+------------+
# |BASH_ENV                         |       |     |     A      | not interactive or login
# |                                 |       |     |            |
# +---------------------------------+-------+-----+------------+
# |/etc/profile                     |   A   |     |            | set PATH & PS1, & call following:
# +---------------------------------+-------+-----+------------+
# |/etc/bash.bashrc                 |  (A)  |  A  |            | Better PS1 + command-not-found 
# +---------------------------------+-------+-----+------------+
# |/etc/profile.d/bash_completion.sh|  (A)  |     |            |
# +---------------------------------+-------+-----+------------+
# |/etc/profile.d/vte-2.91.sh       |  (A)  |     |            | Virt. Terminal Emulator
# |/etc/profile.d/vte.sh            |  (A)  |     |            |
# +---------------------------------+-------+-----+------------+
# |                                 |       |     |            |
# |   A SPECIFIC USER:              |       |     |            |
# +---------------------------------+-------+-----+------------+
# |~/.bash_profile    (bash only)   |   B1  |     |            | (doesn't currently exist) 
# +---------------------------------+-------+-----+------------+
# |~/.bash_login      (bash only)   |   B2  |     |            | (didn't exist) **
# +---------------------------------+-------+-----+------------+
# |~/.profile         (all shells)  |   B3  |     |            | (doesn't currently exist)
# +---------------------------------+-------+-----+------------+
# |~/.bashrc          (bash only)   |  (B2) |  B  |            | colorizes bash: su=red, other_users=green
# +---------------------------------+-------+-----+------------+
# |                                 |       |     |            |
# +---------------------------------+-------+-----+------------+
# |~/.bash_logout                   |    C  |     |            |
# +---------------------------------+-------+-----+------------+
#
# ** (sources !/.bashrc to colorize login, for when booting into non-gui)

И эта заметка в заголовке каждого из других файлов установки для ссылки на него:

# TIP: SEE TABLE in /etc/profile of BASH SETUP FILES AND THEIR LOAD SEQUENCE

Стоит отметить, что я думаю, что по умолчанию источники / etc / profile Debian (включают в себя) /etc/bash.bashrc (это когда /etc/bash.bashrc существует). Так что сценарии входа в систему читают оба файла / etc, а не входящие в систему - только bash.bashrc.

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

Эллиптический вид
источник
4

Логика конфигурации самого bash не очень сложна и объясняется в других ответах на этой странице, на сервере и во многих блогах. Проблема, однако, в том, что дистрибутивы Linux делают из bash , я имею в виду сложные и различные способы, которыми они конфигурируют bash по умолчанию. http://mywiki.wooledge.org/DotFiles кратко упоминает некоторые из этих причуд. Вот один пример трассировки в Fedora 29, который показывает, какие файлы являются источником, какие другие файлы и в каком порядке для очень простого сценария: удаленное соединение с ssh и затем запуск другого подоболочки:

ssh fedora29
 └─ -bash # login shell
      ├── /etc/profile
      |    ├─ /etc/profile.d/*.sh
      |    ├─ /etc/profile.d/sh.local
      |    └─ /etc/bashrc
      ├── ~/.bash_profile
      |    └─ ~/.bashrc
      |          └─ /etc/bashrc
      |
      |
      └─ $ bash  # non-login shell
            └─ ~/.bashrc
                 └─ /etc/bashrc
                       └─ /etc/profile.d/*.sh

Наиболее сложная логика Fedora находится в /etc/bashrc. Как видно выше, /etc/bashrcфайл, о котором сам bash не знает, я имею в виду не напрямую. /etc/bashrcТесты Fedora :

  • это происходит из оболочки входа в систему,
  • это происходит из интерактивной оболочки,
  • это уже было получено

... а затем делает совершенно разные вещи в зависимости от них.

Если вы думаете, что помните приведенный выше график, то это слишком плохо, потому что этого недостаточно: этот график просто описывает только один сценарий, при запуске неинтерактивных сценариев или запуске графического сеанса происходят немного другие вещи. Я опустил ~/.profile. Я опустил bash_completionсценарии. По причинам обратной совместимости, вызывая bash /bin/shвместо того, чтобы /bin/bashизменять его поведение. А как насчет зш и других оболочек? И, конечно, разные дистрибутивы Linux работают по-разному, например, Debian и Ubuntu поставляются с нестандартной версией bas h, она имеет специфичные для Debian настройки. В частности, он ищет необычный файл:/etc/bash.bashrc, Даже если вы придерживаетесь одного дистрибутива Linux, он, вероятно, со временем эволюционирует. Подождите: мы даже не коснулись macOS, FreeBSD, ... Наконец, давайте подумаем, если пользователи будут придерживаться еще более креативных способов, которыми их администраторы настраивали систему, которую они должны использовать.

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

Для последней забавы вот «исходный граф» для того же простого сценария на Clear Linux с июня 2019 года:

ssh clearlinux
 └─ -bash # login shell
      ├── /usr/share/defaults/etc/profile
      |    ├─ /usr/share/defaults/etc/profile.d/*
      |    ├─ /etc/profile.d/*
      |    └─ /etc/profile
      ├── ~/.bash_profile
      |
      |
      └─  $ bash   # non-login shell
           ├─ /usr/share/defaults/etc/bash.bashrc
           |      ├─ /usr/share/defaults/etc/profile
           |      |    ├─ /usr/share/defaults/etc/profile.d/*
           |      |    ├─ /etc/profile.d/*
           |      |    └─ /etc/profile
           |      └─ /etc/profile
           └─ ~/.bashrc
Марш
источник