Dlaczego ~ / .bash_profile nie jest pozyskiwany podczas otwierania terminala?

175

Problem

Mam maszynę wirtualną Ubuntu 11.04 i chciałem skonfigurować środowisko programistyczne Java. Zrobiłem w następujący sposób

  1. sudo apt-get install openjdk-6-jdk
  2. Dodano następujące wpisy do ~ / .bash_profile

    export JAVA_HOME=/usr/lib/jvm/java-6-openjdk
    
    export PATH=$PATH:$JAVA_HOME/bin
    
  3. Zapisz zmiany i wyjdź

  4. Ponownie otwórz terminal i wpisz następujące polecenie

    echo $JAVA_HOME   (blank)
    echo $PATH        (displayed, but not the JAVA_HOME value)
    
  5. Nic się nie stało, tak jakby eksport JAVA_HOME i jego dodatku do ŚCIEŻKI nie został nigdy wykonany.

Rozwiązanie

Musiałem przejść do ~ / .bashrc i dodać następujący wpis na końcu pliku

#Source bash_profile to set JAVA_HOME and add it to the PATH because for some reason is not being picked up
. ~/.bash_profile

pytania

  1. Dlaczego musiałem to zrobić? Myślałem, że bash_profile, bash_login lub profil w przypadku braku tych dwóch zostaną najpierw wykonane przed bashrc.
  2. Czy w tym przypadku moja Terminal A non-login shell?
  3. Jeśli tak, to dlaczego wykonując su po terminalu i wprowadzając hasło, nie wykonał on profilu, w którym również ustawiłem wyżej wymienione eksporty?
Viriato
źródło

Odpowiedzi:

223

~/.bash_profilejest pozyskiwany wyłącznie przez bash, gdy jest uruchamiany w trybie interaktywnego logowania. Zwykle dzieje się tak tylko wtedy, gdy logujesz się na konsoli ( Ctrl+ Alt+ F1.. F6) lub łączysz się przez ssh.

Gdy logujesz się graficznie, ~/.profilebędzie on pochodzić ze skryptu, który uruchamia sesję gnome (lub dowolnego używanego środowiska pulpitu). W ~/.bash_profileogóle nie jest pozyskiwany, gdy logujesz się graficznie.

Gdy otworzysz terminal, terminal rozpocznie bash w trybie interaktywnym (bez logowania), co oznacza, że ​​będzie źródłem ~/.bashrc.

Odpowiednie miejsce na umieszczenie tych zmiennych środowiskowych jest ~/.profile, a efekt powinien być widoczny przy następnym logowaniu.

Pozyskiwanie ~/.bash_profilez ~/.bashrcjest złym rozwiązaniem. Powinno być na odwrót; ~/.bash_profilepowinien źródło ~/.bashrc.

Zobacz DotFiles, aby uzyskać dokładniejsze wyjaśnienie, w tym historię tego, jak to jest.

(Na marginesie, podczas instalowania openjdk za pośrednictwem apt, dowiązania symboliczne powinny być konfigurowane przez pakiet, aby tak naprawdę nie trzeba było ustawiać JAVA_HOMEani zmieniać PATH)

geirha
źródło
6
Przekonałem się, że podczas otwierania terminala z paska bocznego w Ubuntu 12 plik ~ / .profile nie jest ładowany.
jcollum
3
@jcollum To dobrze. .profilenależy pozyskiwać tylko po zalogowaniu.
geirha
2
och, otwarcie terminala to nie to samo, co logowanie ... Myślałem o zalogowaniu się do terminala .
jcollum
2
Pamiętaj, że .profileignorowane przez bash, jeśli .bash_profileistnieje. Zobacz moją odpowiedź tutaj i man bashpo więcej szczegółów.
terdon
3
@terdon, tak, ale bash nie bierze udziału w logowaniu graficznym, więc idzie od razu .profile.
geirha
48

Możesz sprawdzić, czy twoja powłoka Bash jest uruchomiona jako powłoka logowania, uruchamiając:

shopt login_shell

Jeśli odpowiedź brzmi: offnie korzystasz z powłoki logowania.

Przeczytaj sekcję wywołania instrukcji Bash dotyczącą sposobu, w jaki Bash czyta (lub nie czyta) różne pliki konfiguracyjne.

Fragment man bash:

Kiedy bash jest wywoływany jako interaktywna powłoka logowania lub jako nieinteraktywna powłoka z --login opcją, najpierw czyta i wykonuje polecenia z pliku /etc/profile, jeśli plik istnieje. Po przeczytaniu tego pliku, szuka ~/.bash_profile, ~/.bash_logini ~/.profile, w tej kolejności, a odczytuje i wykonuje polecenia z pierwszego, który istnieje i jest czytelny.

suz drugiej strony również domyślnie nie uruchamia powłoki logowania, musisz to powiedzieć, używając --loginopcji.

lgarzo
źródło
9
Bardzo dziękuję za shotp login_shell polecenie. Niesamowite!!
Viriato,
27

Myślę, że warto wspomnieć, że możesz zmienić domyślny terminal gnome, aby używać powłoki logowania (tj. Bash -l), edytując preferencje profilu.

przejdź do Edycja -> Preferencje profilu -> zakładka Tytuł i polecenie zaznacz opcję „Uruchom polecenie jako powłokę logowania”

kisoku
źródło
1
Jakie są wady włączenia tego ustawienia?
chrish
2
@ Chris, ładujesz kod nieco więcej kodu niż to konieczne w wielu przypadkach. Prawdopodobnie nie ma znaczenia, czy Twoja ~/.bash_profileocena jest bardzo szybka, co prawdopodobnie ma miejsce. Dobrą rzeczą do sprawdzenia jest wygaszanie wszelkich połączeń z innymi procesami, które zwykle są dość kosztowne.
vaab
14

Jeśli otworzysz terminal lub uruchomisz supowłokę, powłoka nie zostanie wykonana jako powłoka logowania, ale jako zwykła powłoka interaktywna. Więc czyta, ~/.bashrcale nie ~/.bash_profile. Możesz uruchomić suz -lopcją, aby uruchomić powłokę jako powłokę logowania.

Kiedy pracujesz z GUI, powłoka zwykle nigdy nie działa jako powłoka logowania, więc zazwyczaj wszystko jest w porządku ~/.bashrc.

Florian Diesch
źródło
1
Właśnie to zrobiłem i zadziałało, ale sprawdź, co mówi facet na dole, sugeruje, że złym pomysłem jest umieszczenie go w bashrc i umieszczenie go w profilu. .... Hej, obie strony działają, wielkie dzięki.
Viriato,
4

TL; DR

W klasycznej zalecanej konfiguracji ubuntu ~/.bash_profilejest oceniany tylko w określonych przypadkach. I to ma sens.

Włóż swoje rzeczy ~/.bashrc, będą oceniane za każdym razem.

Ok, chcę zrozumieć, dlaczego to ma sens?

Kluczowe punkty, aby zrozumieć, co się dzieje:

  • wszystkie procesy w systemie Linux mają i wykorzystują zmienne środowiskowe
  • zmienne środowiskowe są dziedziczone
  • wystarczy więc jednorazowe ustawienie ich na ojca całego procesu (szczególnie jeśli wymaga to trochę czasu obliczeniowego).
  • ojciec wszystkich procesów jest zwykle uruchamiany po zalogowaniu się na urządzeniu (podaj swoje dane uwierzytelniające).
  • są rzeczy, które możesz zrobić tylko raz, gdy logujesz się na swoim komputerze (na przykład sprawdź, czy jest nowa poczta ...).

Czas „logowania” zazwyczaj wynosi:

  • W trybie konsoli, gdy się zalogujesz (przy pomocy Ctrl-Alt F1) lub poprzez ssh, ponieważ powłoka będzie ojcem całego procesu, załaduje twój ~/.bash_profile.
  • W trybie graficznym, po otwarciu sesji, pierwszy proces ( gnome-sessiondla klasycznego Ubuntu) będzie odpowiedzialny za czytanie
    .profile.

Ok, więc gdzie położyć moje rzeczy?

Jest to dość skomplikowane, pełna historia jest tutaj . Ale tutaj jest zaniedbanie, które jest dość powszechne dla użytkowników Ubuntu. Biorąc pod uwagę, że:

  • używasz bashpowłoki,
  • masz ~/.bash_profilei postępuj zgodnie z zaleceniami, aby dodać ładowanie ~/.bashrcw swoim ~/.bash_profile, aby uzyskać co najmniej jeden plik, który zostanie oceniony bez względu na mechanizm wywoływania .

To szybka sugestia, gdzie umieścić rzeczy.

  • ~ / .bashrc (Pobiera oceniane za każdym razem , pod warunkiem przestrzegania zaleceń)

    Dla szybkiej oceny zmiennej środowiskowej i kodu dla użytkownika tylko i bash tylko użycia wiersza polecenia (aliasy na przykład). bashism są mile widziane.

    Ładuje się na:

    • utwórz nowe okno / panel powłoki w sesjach graficznych.
    • powołanie bash
    • screennowy panel lub karta. (nie tmux!)
    • dowolna instancja bash w graficznym kliencie konsoli ( terminator/ gnome-terminal...), jeśli nie zaznaczysz opcji „uruchom polecenie jako powłoka logowania”.

    I zostanie załadowany na wszystkie inne okazje dzięki wcześniejszej rekomendacji.

  • ~ / .bash_profile (Pobiera oceniany tylko przy konkretnej okazji )

    Na zwolnionym oceny zmiennej środowiskowej i kodu dla użytkownika tylko i konsola-sesyjnych procesów. bashism są mile widziane. Jest ładowany na:

    • logowanie do konsoli (Ctrl-Alt F1),
    • ssh loguje się do tego komputera,
    • tmuxnowe okienko lub okna (ustawienia domyślne), (nie screen!)
    • wyraźne wezwania bash -l,
    • dowolna instancja bash w graficznym kliencie konsoli ( terminator/ gnome-terminal...) tylko jeśli zaznaczysz opcję „uruchom polecenie jako powłoka logowania”.
  • ~ / .profile (Pobiera oceniane tylko w sesji graficznej)

    Dla zmiennych środowiskowych powolnych i bez bashizmu dla procesów użytkownika i wszystkich sesji graficznych . Zostaje załadowany po zalogowaniu w graficznym interfejsie użytkownika.

Vaab
źródło
W przypadkach, gdy bash ładuje plik profilu, ładuje się, .profilejeśli .bash_profilenie istnieje.
muru
Dziękuję bardzo za jasne wyjaśnienie. pomaga początkującym jak ja. W Mac Mojave, jeśli wstawię zmienne do ~ / .bashrc i zrobię source, a jeśli nie env, nie zobaczę ustawionych zmiennych env (próbowałem zamknąć iTerm i ponownie otworzyć). Ale zauważam, że kiedy zainstalowałem Android studio i inne aplikacje, wszystkie te zmienne środowiskowe zostały włączone /.bash_profile. Więc kiedy dodałem /.bash_profileto działało jak urok. Dlaczego?
sofs1