Różnica między .bashrc i .bash_profile

450

Jaka jest różnica między .bashrci .bash_profilea których jeden należy użyć?

cfischer
źródło
2
Zobacz także podobne pytanie na ubuntu.stackexchange.com/questions/1528/bashrc-or-bash-profile
Stefan Lasiewski
Jeśli chcesz uzyskać pełniejsze wyjaśnienie, które obejmuje również .profile, spójrz na to pytanie: superuser.com/questions/789448/…
Flimm
Ta odpowiedź obejmuje również niektóre aspekty stackoverflow.com/questions/415403/…
Sergey Voronezhskiy

Odpowiedzi:

518

Tradycyjnie, gdy logujesz się do systemu uniksowego, system uruchamia jeden program dla ciebie. Ten program jest powłoką, tj. Programem przeznaczonym do uruchamiania innych programów. To powłoka wiersza poleceń: uruchamiasz inny program, wpisując jego nazwę. Domyślna powłoka, powłoka Bourne'a, odczytuje polecenia z ~/.profilemomentu jej wywołania jako powłoki logowania.

Bash to skorupa przypominająca Bourne'a. Odczytuje polecenia z ~/.bash_profilemomentu wywołania jako powłoki logowania, a jeśli ten plik nie istnieje¹, ~/.profilezamiast tego próbuje odczytać .

Możesz wywołać powłokę bezpośrednio w dowolnym momencie, na przykład uruchamiając emulator terminala w środowisku GUI. Jeśli powłoka nie jest powłoką logowania, nie czyta ~/.profile. Kiedy zaczynasz bash jako interaktywną powłokę (tj. Nie uruchamiać skryptu), czyta ~/.bashrc(z wyjątkiem gdy jest wywoływany jako powłoka logowania, wtedy tylko czyta ~/.bash_profilelub ~/.profile.

W związku z tym:

  • ~/.profile to miejsce, w którym można umieścić rzeczy, które dotyczą całej sesji, takie jak programy, które chcesz uruchomić po zalogowaniu (ale nie programy graficzne, przechodzą do innego pliku) oraz definicje zmiennych środowiskowych.

  • ~/.bashrcjest miejscem do umieszczania rzeczy, które dotyczą tylko samego basha, takich jak aliasy i definicje funkcji, opcje powłoki i ustawienia zachęty. (Możesz także umieścić tam przypisania klawiszy, ale zwykle używa się ich do bash ~/.inputrc).

  • ~/.bash_profilemoże być użyte zamiast ~/.profile, ale jest odczytywane tylko przez bash, a nie przez żadną inną powłokę. (Jest to głównie problem, jeśli chcesz, aby pliki inicjujące działały na wielu komputerach, a twoja powłoka logowania nie jest bash na wszystkich z nich.) Jest to logiczne miejsce do włączenia, ~/.bashrcjeśli powłoka jest interaktywna. Polecam następujące treści w ~/.bash_profile:

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

W nowoczesnych jednorożcach występuje dodatkowa komplikacja związana z ~/.profile. Jeśli zalogujesz się w środowisku graficznym (to znaczy, jeśli program, w którym wpisujesz hasło, działa w trybie graficznym), nie otrzymasz automatycznie powłoki logowania, która czyta ~/.profile. W zależności od graficznego programu logowania, menedżera okien lub środowiska pulpitu, które uruchamiasz później, oraz od tego, jak twoja dystrybucja skonfigurowała te programy, ~/.profilemożesz, ale nie musisz, odczytać. Jeśli tak nie jest, zwykle jest inne miejsce, w którym można zdefiniować zmienne środowiskowe i programy, które mają być uruchamiane po zalogowaniu, ale niestety nie ma standardowej lokalizacji.

Zauważ, że możesz zobaczyć tu i tam zalecenia, aby albo umieścić definicje zmiennych środowiskowych, ~/.bashrcalbo zawsze uruchamiać powłoki logowania w terminalach. Oba są złymi pomysłami. Najczęstszym problemem związanym z którymkolwiek z tych pomysłów jest to, że zmienne środowiskowe będą ustawione tylko w programach uruchamianych przez terminal, a nie w programach uruchamianych bezpośrednio za pomocą ikony lub menu lub skrótu klawiaturowego.

¹ Dla kompletności, na żądanie: jeśli .bash_profilenie istnieje, bash próbuje również .bash_loginprzed powrotem do .profile. Zapomnij, że istnieje.

Gilles
źródło
11
+1 za dobry post. RÓWNIEŻ dziękuję za dodanie sekcji o „logowaniu graficznym vs powłoce logowania” ... Miałem problem, w którym myślałem, że ~ / .profile ZAWSZE uruchomi się dla grafiki / powłoki ... ale nie wykonuje się, gdy użytkownik się loguje poprzez logowanie graficzne. Dziękujemy za rozwiązanie tej tajemnicy.
Trevor Boyd Smith
4
@Gilles: Czy możesz wyjaśnić bardziej szczegółowo, z przykładami, dlaczego uruchamianie powłoki logowania w każdym terminalu jest złym pomysłem? Czy to tylko problem z komputerowym Linuksem? (Rozumiem, że na OS X Terminal uruchamia powłokę logowania za każdym razem i nigdy nie zauważyłem żadnych efektów ubocznych (chociaż zwykle używam iTerm). Ale wtedy nie mogę wymyślić wielu zmiennych środowiskowych, na których mi zależy poza terminal. (Może HTTP_PROXY?))
iconoclast
2
@Brandon Jeśli uruchomisz powłokę logowania na każdym terminalu, zastąpi to zmienne środowiskowe dostarczone przez środowisko. W codziennych sytuacjach możesz sobie z tym poradzić, ale prędzej czy później przyjdzie cię ugryźć, gdy chcesz skonfigurować różne zmienne w terminalu (powiedzmy, aby wypróbować inną wersję programu): uruchamianie powłoka logowania zastąpiłaby twoje ustawienia lokalne.
Gilles
4
~/.bash_profileZamiast tego można użyć~/.profile~/.bashrc instrukcji , ale należy ją również uwzględnić, jeśli powłoka jest interaktywna. wprowadza w błąd, ponieważ są to kwestie ortogonalne. Bez względu na to, czy używasz, ~/.bash_profileczy ~/.profilemusisz dołączyć ~/.bashrcdo tego, którego używasz, jeśli chcesz, aby stamtąd ustawienia miały wpływ na powłokę logowania.
Piotr Dobrogost
3
@Gilles Oczywiście, ale sposób, w jaki zdanie zostało sformułowane w odpowiedzi, sugeruje, że potrzeba uwzględnienia ~/.bashrcma coś wspólnego z wyborem ~/.bash_profilezamiast tego, ~/.profileco nie jest prawdą. Jeśli ktoś włącza ~/.bashrcdowolny skrypt w czasie logowania (tutaj albo ~/.bash_profilealbo ~/.profile), to dlatego, że chce, aby ustawienia ~/.bashrcbyły stosowane do powłoki logowania w taki sam sposób, jak są one stosowane do powłoki niezalogowanej.
Piotr Dobrogost
53

Z tego krótkiego artykułu

Według strony podręcznika bash, .bash_profile jest wykonywany dla powłok logowania, podczas gdy .bashrc jest wykonywany dla interaktywnych powłok bez logowania.

Co to jest powłoka do logowania lub bez logowania?

Podczas logowania (np. Wpisz nazwę użytkownika i hasło) za pomocą konsoli, albo fizycznie siedząc przy komputerze podczas uruchamiania, albo zdalnie przez ssh: wykonywany jest profil .bash_profile w celu skonfigurowania rzeczy przed pierwszym wierszem poleceń.

Ale jeśli już zalogowałeś się do komputera i otworzyłeś nowe okno terminala (xterm) w Gnome lub KDE, wtedy .bashrc jest wykonywany przed wierszem poleceń okna. .bashrc jest także uruchamiany, gdy uruchamiasz nową instancję bash, wpisując / bin / bash w terminalu.

Jarvin
źródło
12
Nieznaczne aktualizacje: „Wykonane” jest prawdopodobnie nieco mylącym terminem, oba pochodzą. Wykonane dźwięki brzmią tak, jakby były uruchamiane jako skrypt, fork / exec yadda yadda. Jest uruchamiany w kontekście bieżącej powłoki. Co ważniejsze. .Bashrc jest uruchamiany znacznie częściej. Jest uruchamiany przy każdym uruchomieniu skryptu bash, a także, jeśli nie masz pliku .bash_profile. Ponadto, w zależności jak skonfigurować xtermach, można tworzyć powłokę, że źródła bash_profile
Rich Homolka
36

W dawnych czasach, gdy pseudo-tty nie były pseudo, a właściwie pisane, a UNIXy były dostępne przez modemy tak wolno, że można było zobaczyć każdą literę drukowaną na ekranie, wydajność była najważniejsza. Aby nieco zwiększyć wydajność, masz pojęcie głównego okna logowania i wszystkich innych okien, w których faktycznie działałeś. W głównym oknie chcesz otrzymywać powiadomienia o każdej nowej poczcie, ewentualnie uruchom inne programy w tle.

Aby to obsłużyć, powłoki pozyskały plik .profilespecjalnie na „powłoki logowania”. To zrobiłoby specjalne, po skonfigurowaniu sesji. Bash rozszerzył to nieco, aby najpierw spojrzeć na .bash_profile przed .profile, w ten sposób można umieścić tam tylko rzeczy (aby nie spieprzyły powłoki Bourne'a itp., Które również patrzyły na .profile). Inne powłoki, niezalogowane, po prostu źródło pliku rc, .bashrc (lub .kshrc itp.).

To jest teraz trochę anachronizm. Nie logujesz się do głównej powłoki tak bardzo, jak logujesz się do menedżera okien GUI. Nie ma innego okna głównego niż inne.

Moja sugestia - nie martw się o tę różnicę, jest ona oparta na starszym stylu korzystania z unixa. Wyeliminuj różnicę w swoich plikach. Cała zawartość pliku .bash_profile powinna wynosić:

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

I umieść wszystko, co naprawdę chcesz ustawić w .bashrc

Pamiętaj, że .bashrc jest pozyskiwany dla wszystkich powłok, interaktywnych i nieinteraktywnych. Możesz zewrzeć źródła dla nieinteraktywnych powłok umieszczając ten kod w górnej części .bashrc:

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

Rich Homolka
źródło
6
To zły pomysł, patrz moja odpowiedź . W szczególności zmienne środowiskowe będą ustawiane tylko w programach uruchamianych przez terminal, a nie w programach uruchamianych bezpośrednio za pomocą ikony lub menu lub skrótu klawiaturowego.
Gilles
4
@Gilles Nie rozumiem, dlaczego tak twierdzisz. Dzięki, .$HOME/.bashrcjak pokazano powyżej, ustawienia .bashrcbędą dostępne w powłokach logowania, a więc również w środowisku pulpitu. Na przykład w moim systemie Fedora gnome-sessionjest uruchamiany tak -$SHELL -c gnome-session, jak .profileczytany.
Mikel
2
@PiotrDobrogost O tak, jest inny problem z odpowiedzią Richa. Wpisywanie .bashrcw .profilezwykle nie działa, ponieważ .profilemoże być wykonywane przez /bin/shi nie bash (np. Na Ubuntu dla domyślnego logowania graficznego), a ta powłoka może nie być interaktywna (np. Dla graficznego logowania).
Gilles
3
@Gilles re: „włączenie .bashrc w .profile” wcale nie jest zalecane (wręcz przeciwnie). Albo odpowiedź została zredagowana (tak się nie wydaje), albo twoje komentarze nie zgadzają się z tym, co zostało powiedziane.
Michael
2
Ogólnie +1, ale dodałbym do zalecenia „zwarcie ... dla nieinteraktywnych powłok” („u góry .bashrc: [[ $- != *i* ]] && return”); Podoba mi się, aby niektóre z nich .bashrcbyły wykonywane nawet w przypadku powłok nieinteraktywnych, a zwłaszcza w celu ustawienia zmiennych env podczas wydawania ssh hostname {command}, aby zdalne polecenia były poprawnie wykonywane (nawet jeśli powłoka nie jest interaktywna). Ale inne ustawienia później .bashrcnależy zignorować. Zazwyczaj sprawdzam, czy TERM = głupi i / lub nieuzbrojony, a potem ratuję się wcześnie.
Michael
18

Obejrzyj ten znakomity post na blogu autorstwa ShreevatsaR . Oto wyciąg, ale przejdź do postu na blogu, zawiera wyjaśnienie terminów takich jak „powłoka logowania”, schemat blokowy i podobna tabela dla Zsh.

W przypadku Bash działają one w następujący sposób. Przeczytaj odpowiednią kolumnę. Wykonuje A, następnie B, a następnie C itd. B1, B2, B3 oznacza, że ​​wykonuje tylko pierwszy ze znalezionych plików.

+----------------+-----------+-----------+------+
|                |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      |           |      |
+----------------+-----------+-----------+------+
Flimm
źródło
Zamiast zamieszczać tę samą odpowiedź na wiele pytań, najlepiej jest dostosować odpowiedź do konkretnych potrzeb pytającego. Jeśli odpowiedź jest identyczna dla obu pytań, powinieneś opublikować jedną odpowiedź i głosować, aby zamknąć pozostałe pytania jako duplikaty oryginału.
Mokubai
1
@Mokubai Drugie pytanie zostało już oznaczone jako duplikat tego pytania.
Flimm
@ElipticalView: przez zestaw zrobić nic, jesteś powołując się na linii: [ -z "$PS1" ] && return? Tabela w mojej odpowiedzi podaje listę skryptów uruchamianych przez Basha, niezależnie od zawartości skryptów, jeśli sam skrypt ma linię [ -z "$PS1" ] && return, to oczywiście by to zadziałało, ale nie sądzę, że powinno to oznaczać, że powinienem zmienić stół.
Flimm
5

LEPSZY KOMENTARZ DLA GŁOWICY / ETC / PROFILU

Opierając się na powyższej świetnej odpowiedzi Flimma, umieściłem ten nowy komentarz na początku mojego profilu Debian / etc / (może być konieczne dostosowanie go do dystrybucji) .

# 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)

I ta uwaga na początku każdego innego pliku instalacyjnego, aby się do niego odwołać:

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

Warto zauważyć, że myślę, że domyślnie źródła / etc / profil Debiana (zawiera) /etc/bash.bashrc (wtedy, gdy istnieje /etc/bash.bashrc). Więc skrypty logowania odczytują oba pliki / etc, podczas gdy non-login czyta tylko bash.bashrc.

Warto również zauważyć, że /etc/bash.bashrc jest ustawiony tak, aby nic nie robić, gdy nie jest uruchamiany interaktywnie. Te dwa pliki są tylko dla interaktywnych skryptów.

Widok eliptyczny
źródło
4

Logika konfiguracji samego basha nie jest szalenie skomplikowana i wyjaśniona w innych odpowiedziach na tej stronie, na temat błędu serwera i wielu blogów. Problemem jest jednak to, co dystrybucje Linuksa tworzą bash , mam na myśli złożoną i różne sposoby domyślnej konfiguracji bash. http://mywiki.wooledge.org/DotFiles krótko wspomina niektóre z tych dziwactw. Oto jeden przykładowy ślad na Fedorze 29, który pokazuje, które źródło plików, które inne pliki i w jakiej kolejności w bardzo prostym scenariuszu: zdalne połączenie z ssh, a następnie uruchomienie innej podpowłoki:

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

Najbardziej złożona logika Fedory /etc/bashrc. Jak widać powyżej, /etc/bashrcplik bash sam nie wie o tym, że nie bezpośrednio. /etc/bashrcTesty Fedory, czy:

  • jest pozyskiwany z powłoki logowania,
  • jest pozyskiwany przez interaktywną powłokę,
  • zostało już pozyskane

... a następnie robi zupełnie różne rzeczy w zależności od nich.

Jeśli uważasz, że możesz zapamiętać powyższy wykres, to szkoda, ponieważ nie jest prawie wystarczający: ten wykres opisuje tylko jeden scenariusz, podczas uruchamiania nieinteraktywnych skryptów lub uruchamiania sesji graficznej dzieją się nieco inne rzeczy. Mam pominięta ~/.profile. Pominąłem bash_completionskrypty. Ze względu na kompatybilność wsteczną wywołanie bash as /bin/shzamiast /bin/bashzmiany jego zachowania. Co z Zsh i innymi powłokami? I oczywiście różne dystrybucje Linuksa robią to inaczej, na przykład Debian i Ubuntu są dostarczane z niestandardową wersją bas h, mają specyficzne dla Debiana modyfikacje. W szczególności szuka nietypowego pliku:/etc/bash.bashrc. Nawet jeśli trzymasz się jednej dystrybucji Linuksa, prawdopodobnie ewoluuje ona z czasem. Czekaj: nawet nie dotknęliśmy macOS, FreeBSD, ... Wreszcie, pomyślmy o użytkownikach, którzy utknęli w jeszcze bardziej kreatywnych sposobach, w jakie ich administratorzy skonfigurowali system, z którego muszą korzystać.

Jak pokazuje niekończący się strumień dyskusji na ten temat, jest to przegrana sprawa. Tak długo, jak chcesz tylko dodać nowe wartości, niektóre „próby i błędy” wydają się wystarczające. Prawdziwa zabawa zaczyna się, gdy chcesz zmodyfikować w jednym pliku (użytkownika) coś już zdefiniowane w innym (w / etc). Przygotuj się na poświęcenie czasu na opracowanie rozwiązania, które nigdy nie będzie przenośne.

Dla odrobiny zabawy oto „wykres źródłowy” dla tego samego, prostego scenariusza na Clear Linux z czerwca 2019 r .:

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
Marsz
źródło