Різниця між .bashrc і .bash_profile


446

У чому різниця між .bashrcі від .bash_profileкого я повинен користуватися?


2
Дивіться також подібне запитання на ubuntu.stackexchange.com/questions/1528/bashrc-or-bash-profile
Стефан Ласєскі

Якщо ви хочете отримати більш повне пояснення, яке також стосується .profile, перегляньте це питання: superuser.com/questions/789448/…
Flimm

Ця відповідь охоплює також деякі аспекти stackoverflow.com/questions/415403/…
Сергій Воронезький,

Відповіді:


515

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

Баш - оболонка Борна. Він читає команди з того часу, ~/.bash_profileколи його викликають як оболонку входу, і якщо цього файлу не існує¹, він намагається читати ~/.profileзамість цього.

Ви можете викликати оболонку безпосередньо в будь-який час, наприклад, запустивши емулятор терміналу всередині GUI-середовища. Якщо оболонка не є оболонкою для входу, вона не читається ~/.profile. Коли ви запускаєте bash як інтерактивну оболонку (тобто не запускати скрипт), вона зчитується ~/.bashrc(за винятком випадків, коли викликається як оболонка для входу, тоді вона лише читає ~/.bash_profileабо ~/.profile.

Тому:

  • ~/.profile це місце, щоб розмістити речі, які стосуються всього вашого сеансу, такі як програми, які ви хочете запустити під час входу (але не графічні програми, вони переходять у інший файл) та визначення змінної середовища.

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

  • ~/.bash_profileможна використовувати замість ~/.profile, але він читається лише 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_loginперш ніж впасти назад .profile. Сміливо забудьте, що існує.


11
+1 за хороший пост. ТАКОЖ дякую, що ви додали розділ про "графічний вхід проти оболонки входу" ... У мене виникла проблема, коли я думав, що ~ / .profile ВЖЕ буде виконуватись для графічного / оболонки ... але він не виконується для того, коли користувач увійде в систему за допомогою графічного входу. Дякую, що розгадали цю таємницю.
Тревор Бойд Сміт

4
@Gilles: Чи можете ви пояснити більш детально, на прикладах, чому запуск оболонки для входу в кожен термінал є поганою ідеєю? Це лише проблема з настільним Linux? (Я вважаю, що на OS X Terminal кожного разу запускає оболонку входу, і я ніколи не помічав жодних побічних ефектів (хоча я зазвичай використовую iTerm). Але тоді я не можу придумати багато змінних оточуючих середовищ, про які я б хвилювався поза термінал. (Може бути, HTTP_PROXY?))
іконоборство

2
@Brandon Якщо ви запустите оболонку для входу в кожен термінал, це перекриє змінні середовища, що надаються середовищем. У повсякденних ситуаціях ви можете піти з цим, але він рано чи пізно прийде і вкусить вас, коли ви хочете встановити різні змінні в терміналі (скажімо, спробувати іншу версію програми): запуск оболонка входу замінить ваші локальні налаштування.
Жиль

4
Оператор ~/.bash_profileможна використовувати замість ~/.profile, але також потрібно включити, ~/.bashrcякщо оболонка інтерактивна. вводить в оману, оскільки це ортогональні питання. Незалежно від того , якщо ви використовуєте ~/.bash_profileабо ~/.profileви повинні включити ~/.bashrcв тій , який ви використовуєте , якщо ви хочете настройки звідти , щоб мати ефект в оболонках.
Пьотр Доброгост

3
@Gilles Звичайно, але спосіб формулювання речення у відповіді говорить про те, що необхідність включення ~/.bashrcмає щось спільне з вибором, ~/.bash_profileзамість ~/.profileякого не відповідає дійсності. Якщо хтось включає ~/.bashrcбудь-який тип сценарію, який отримується під час входу в систему (тут це або ~/.bash_profileабо ~/.profile), це тому, що він хоче, щоб установки ~/.bashrcбули застосовані до оболонки входу так само, як вони застосовуються до оболонки без входу.
Пьотр Доброгост

53

З цієї короткої статті

Згідно зі сторінкою bash man, .bash_profile виконується для оболонок входу, тоді як .bashrc виконується для інтерактивних оболонок без входу.

Що таке оболонка для входу або не вхід?

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

Але, якщо ви вже увійшли в свою машину і відкрили нове вікно терміналу (xterm) всередині Gnome або KDE, то .bashrc виконується перед командним вікном вікна. .bashrc також запускається при запуску нового екземпляра bash, ввівши / bin / bash в терміналі.


12
Невеликі оновлення: "Виконаний" - це, мабуть, трохи оманливий термін, вони обидва отримані. Виконані звуки, схожі на те, що він виконується як сценарій, fork / exec yadda yadda. Вона запускається в контексті поточної оболонки Більше того, що .bashrc запускається набагато частіше. Він запускається на кожному запуску сценарію bash, а також якщо у вас немає .bash_profile. Крім того, залежно від того, як ви налаштовуєте xterms, ви можете створити оболонку, яка джерела .bash_profile
Rich Homolka

36

Ще в старі часи, коли псевдоти не були псевдо, а насправді, добре набрали, а UNIXes були доступні модемами настільки повільно, що ви могли бачити друк кожного листа на екрані, ефективність була першорядною. Щоб дещо підвищити ефективність, у вас була концепція головного вікна входу та будь-яких інших вікон, якими ви працювали. У головному вікні ви хочете отримувати сповіщення про будь-яку нову пошту, можливо, запускати деякі інші програми у фоновому режимі.

Щоб підтримати це, оболонки виділяли файл .profileспеціально на "оболонках входу". Це зробило б спеціальну установку сеансу. Bash розширив це дещо, щоб подивитися на .bash_profile спочатку перед .profile, таким чином, ви можете помістити туди лише речі (щоб вони не накручували оболонку Борна тощо), які також дивилися на .profile). Інші оболонки, не вхідні в систему, просто будуть джерелом файлу rc, .bashrc (або .kshrc тощо).

Це трохи анахронізм зараз. Ви не входите в основну оболонку стільки, скільки входите в менеджер вікон gui. Немає головного вікна, відмінного від будь-якого іншого вікна.

Моя пропозиція - не турбуйтеся про цю різницю, вона заснована на старому стилі використання unix. Усуньте різницю у ваших файлах. Весь вміст .bash_profile повинен бути:

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

І поставте все, що ви насправді хочете встановити, у .bashrc

Пам'ятайте, що .bashrc розміщений для всіх оболонок, інтерактивних та неінтерактивних. Ви можете коротко замикати джерело пошуку неінтерактивних оболонок, помістивши цей код біля вершини .bashrc:

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


6
Це погана ідея, дивіться мою відповідь . Зокрема, ваші змінні середовища встановлюватимуться лише в програмах, запущених через термінал, а не в програмах, запущених безпосередньо із піктограмою чи меню або ярликом клавіатури.
Жиль

4
@Gilles Я не розумію, чому ти це стверджуєш. Оскільки, .$HOME/.bashrcяк показав Річ, вище, налаштування в .bashrcбуде доступна в оболонках для входу, а отже, і на робочому столі. Наприклад, у моїй системі Fedora gnome-sessionзапускається так -$SHELL -c gnome-session, .profileяк читається.
Мікель

2
@PiotrDobrogost О, так, є ще одна проблема з відповіддю Річа. У тому числі і .bashrcв .profileзазвичай не працює, тому що .profileможе бути виконана /bin/shі не Баш (наприклад , на Ubuntu для графічного входу в систему за замовчуванням), і ця оболонка не може бути інтерактивними (наприклад , для графічного входу в систему ).
Жиль

3
@ Gilles re: "включаючи .bashrc в .profile" - це зовсім не те, що було рекомендовано (навпаки, насправді). Або відповідь була відредагована (вона не виглядає так), або ваші коментарі не узгоджуються з тим, про що йдеться.
Майкл

2
Взагалі +1, але я додав би до рекомендації "коротке замикання ... для неінтерактивних оболонок" ("біля вершини .bashrc: [[ $- != *i* ]] && return"); Мені подобається, що деякі з моїх .bashrcвиконуються навіть для неінтерактивних оболонок, спеціально для встановлення env vars при видачі 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:? У таблиці моєї відповіді наведено список скриптів, керованих Башем, незалежно від вмісту скриптів, якщо у самого сценарію є рядок [ -z "$PS1" ] && return, звичайно, це вступить у силу, але я не думаю, що це повинно означати, що я повинен змінити стіл.
Flimm

5

Кращий коментар для керівника / ETC / ПРОФІЛЬ

Спираючись на чудову відповідь Flimm вище, я вписав цей новий коментар у голову мого Debian / etc / profile (можливо, вам знадобиться налаштувати його на ваш дистрибутив.) :

# 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 / профіль Debian за типовими джерелами (включає) /etc/bash.bashrc (саме тоді /etc/bash.bashrc існує). Тож сценарії входу читають обидва файли / etc, тоді як невхідні дані читають лише bash.bashrc.

Також слід зазначити, що /etc/bash.bashrc налаштований нічого не робити, коли він не працює інтерактивно. Тож ці два файли призначені лише для інтерактивних сценаріїв.


3

Логіка конфігурації 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зміни своєї поведінки. А що з zsh та іншими оболонками? І звичайно, різні дистрибутиви Linux роблять все по-різному, наприклад, Debian і Ubuntu поставляються з нестандартною версією bas h, він має специфічні для Debian настройки. Він особливо шукає незвичайний файл:/etc/bash.bashrc. Навіть якщо ви дотримуєтесь одного дистрибутива Linux, він, ймовірно, розвивається з часом. Зачекайте: ми навіть не торкалися macOS, FreeBSD, ... Нарешті, давайте подумаємо, що для користувачів дотримуються ще більш креативні способи, яким їх адміністратори налаштували систему, яку вони повинні використовувати.

Як демонструє нескінченний потік дискусій на цю тему, це втрачена причина. Поки ви просто хочете додати нові значення, деяких "проб і помилок", як правило, достатньо. Справжня забава починається, коли ви хочете змінити в одному (користувальницькому) файлі щось, що вже визначено в іншому (в / і т.д.). Тоді будьте готові витратити деякий час на розробку рішення, яке ніколи не буде портативним.

Для останнього задоволення ось "графік джерела" для того ж простого сценарію 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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.