Zmienne środowiskowe w bash_profile czy bashrc?

36

Znalazłem to pytanie [blog]: Różnica między .bashrc i .bash_profile jest bardzo przydatna, ale po zobaczeniu najczęściej głosowanej odpowiedzi (bardzo dobrze przy okazji) mam dalsze pytania. Pod koniec najczęściej głosowanej, poprawnej odpowiedzi widzę następujące oświadczenie:

Zauważ, że możesz zobaczyć tu i tam zalecenia, aby albo umieścić definicje zmiennych środowiskowych w ~ / .bashrc, albo zawsze uruchamiać powłoki logowania w terminalach. Oba są złymi pomysłami.

  1. Dlaczego to zły pomysł (nie próbuję walczyć, chcę tylko zrozumieć)?

  2. Jeśli chcę ustawić zmienną środowiskową i dodać ją do ŚCIEŻKI (na przykład JAVA_HOME), gdzie byłoby to najlepsze miejsce na wpis eksportu? w ~ / .bash_profile lub ~ / .bashrc ?

  3. Jeśli odpowiedź na pytanie nr 2 to ~ / .bash_profile , mam dwa kolejne pytania:

    3.1 Co byś umieścił w ~ / .bashrc ? tylko aliasy?

    3.2 Uważam, że w powłoce niezalogowanej plik ~ / .bash_profile nie jest „odbierany”. Jeśli eksport wpisu JAVA_HOME był w pliku bash_profile, czy byłbym w stanie wykonywać polecenia javac i java ? Czy znajdzie je na ŚCIEŻCE? Czy to jest powód, dla którego niektóre posty i fora sugerują ustawienie JAVA_HOME i podobnych na ~ / .bashrc ?

    Z góry dziękuję.

Viriato
źródło

Odpowiedzi:

26

W nowoczesnym systemie nie jest szczególnie często spotykane przypadki, w których ma to znaczenie, ale tak się dzieje. (W szczególności, jeśli korzystasz z operacji powłoki w vimtakiej formie :r !commandlub w !<motion>commandformie in-line .)

Co byś umieścił w ~ / .bashrc? tylko aliasy?

Wkładasz rzeczy ~/.bashrc, które nie byłyby automatycznie dziedziczone przez podpowłoki; oznacza to głównie aliasy i funkcje, chociaż czasami masz zmienne ustawienia, które nie powinny być widoczne poza powłoką (jest to bardzo rzadkie). Można argumentować, że należy je jakoś wyeksportować, ale różne próby eksperymentalne napotkały problemy ze zgodnością z próbą ukrycia ich w środowisku i zostały w większości porzucone.

Jeśli chcę ustawić zmienną środowiskową i dodać ją do ŚCIEŻKI (na przykład JAVA_HOME), gdzie byłoby to najlepsze miejsce na wpis eksportu? w ~ / .bash_profile lub ~ / .bashrc?

Wstawiasz ustawienia środowiska ~/.bash_profile, aby otrzymywały zdrowe ustawienia początkowe. Czasami będziesz chciał je zastąpić (często dzieje się tak w skomplikowanych środowiskach, takich jak Matlab lub Cadence); jeśli wprowadzisz ustawienia środowiska, ~/.bashrcwówczas powłoki uruchamiane z tych środowisk utracą możliwości dostosowywania środowiska, w wyniku czego rzeczy mogą nie działać poprawnie. Dotyczy to również sytuacji, gdy używasz pakietu takiego jak moduły , virtualenv , rvm itp. Do zarządzania wieloma środowiskami programistycznymi; wprowadzenie ustawień ~/.bashrcoznacza, że ​​nie możesz uruchomić żądanego środowiska z poziomu edytora, ale zamiast tego zostaniesz zmuszony do domyślnych ustawień systemu.

Uważam, że w powłoce niezalogowanej plik ~ / .bash_profile nie jest „odbierany”.

To jest poprawne; zwykle chcesz, aby początkowa powłoka była powłoką logowania, a wszelkie powłoki uruchomione pod tą powłoką nie były powłokami logowania. Jeśli początkowa powłoka nie jest powłoką logowania, nie będziesz mieć ustawień domyślnych PATHani różnych innych ustawień (w tym twojego JAVA_HOMEprzykładu).

Większość środowisk pulpitu uruchomionych z menedżerów ekranów (to znaczy zdecydowana większość graficznych loginów) nie konfiguruje środowiska logowania dla całego pulpitu, więc jesteś zmuszony uruchomić początkową powłokę w terminalach jako powłokę logowania. Powoduje to szereg problemów (zwłaszcza, że PATHi dostępne dla programów uruchamianych np. Z paneli nie jest poprawnie skonfigurowany, ponieważ panel nie jest terminalem i nie działał ~/.bash_profile), ale jest rozsądnym kompromisem, biorąc pod uwagę, że nie zawsze jest to możliwe do bezpiecznego uruchomienia ~/.bash_profilew środowisku nieinteraktywnym na początku sesji rozpoczętej przez menedżera wyświetlania, w zależności od jego zawartości. Czasami sugeruje się umieszczenie ustawień środowiska~/.bashrczamiast konfigurować powłokę logowania; jak wspomniano powyżej, działa to tak długo, jak długo nie musisz zastępować tego środowiska, i powoduje dziwne przerwy, gdy musisz to zrobić.

Niedawno pomogłem zdiagnozować taki problem w systemie OS X, w którym użytkownik, który wprowadził ustawienia, ~/.bashrca następnie zaczął używać, rvma Perlbrew zobaczył dziwne zachowanie, ponieważ środowiska skonfigurowane przez te dwie funkcje zostały „cofnięte” przez ~/.bashrcedytory wewnętrzne i sudo(które w systemie OS X , w przeciwieństwie do Linuksa, propaguje użytkownika, $HOMEaby ~/.bashrcbył uruchamiany przez powłokę root). Przed próbą użycia tych środowisk nie było problemu; kiedy zaczęli ich używać, byli zaskoczeni niespodziewaną utratą ustawień.

geekozaur
źródło
1
Myślę, że rozumiem, być może będę musiał przeczytać go więcej razy, aby go bardziej zinternalizować, ale podsumowuję następujące. W środowiskach korporacyjnych, aby mieć lepszą kontrolę nad dostosowanymi powłokami bez skutków ubocznych globalnej, najlepszą praktyką jest umieszczanie zmiennych środowiskowych w ~ / .bash_profile . W środowisku osobistym, takim jak Ubuntu lub Linux Mint, aby poprawnie ustawić PATH, powinienem ustawić go w ~ / .bashrc (lub nawet w / etc / profile ). Mam rację?
Viriato,
Ma to mniej wspólnego ze środowiskami korporacyjnymi niż z tym, czy jesteś tylko użytkownikiem czy programistą; systemy takie jak modulesi rvmsą narzędziami programistycznymi, podobnie jak Matlab i Cadence dla nieco innych definicji „programisty”. Proste rozwój również nie wymaga od nich, ale kiedy trzeba teście przeciwko wielu wersji Ruby, Perl lub Python wtedy naprawdę chcesz coś takiego rvm, perlbrewi virtualenv(odpowiednio) wokół, aby pomóc utrzymać to wszystko prosto.
geekozaur
2

szczerze mówiąc, w dzisiejszych czasach nie ma dużej różnicy, pomimo tego, co powiedział guru.

problemem jest to, że obecnie logujemy się graficznie, a nie za pomocą powłoki logowania. w przeszłości, my, użytkownicy unixowi, lubiliśmy widzieć krótki raport o tym, co dzieje się na serwerze natychmiast po zalogowaniu - wtedy uruchamiamy X z linii poleceń - raport ten często wymaga czasu (np. 10-20 sekund). a potem nie chcemy widzieć tego samego, kiedy zaczynamy np. xterm. stąd różnica.

obecnie nie sądzę, żeby to rozróżnienie było teraz ważne. myślę, że w dzisiejszych czasach, jeśli umieścisz bashrc w bash_profile, nikt nie może cię winić.

Uwaga: nie dotyczy to Macos X (każde uruchomione terminal.app jest powłoką logowania)

bubu
źródło
Nie jestem do końca pewien, czy w pełni rozumiem, ale w pracy, kiedy loguję się przez ssh, który jest powłoką logowania, wtedy bash_profile i bashrc są pozyskiwane, więc w tym przypadku nie ma to znaczenia. Ale jeśli zaloguję się graficznie (co to oznacza)? jak zalogować się do mojego osobistego ubuntu?
Viriato,
Zgadzam się z odpowiedzią @bubu tutaj - każda konfiguracja, w której ~/.bash_profilenie ma źródła, ~/.bashrcjest raczej trudna w obsłudze i pogarszająca się . Graficzne aplikacje terminalowe oznaczają, że łatwiej jest po prostu pobrać ~ / .bashrc i umieścić tam całą konfigurację.
RichVel
1

Cóż, jeśli chodzi o „Graficzne loginy”, zależy to od tego, jakiego * DM używasz ...

Z GDM (Gnome 3.18) mam to:

/ etc / gdm / Xsession

#!/bin/sh   <= *important*

...

# First read /etc/profile and .profile
test -f /etc/profile && . /etc/profile
test -f "$HOME/.profile" && . "$HOME/.profile"
# Second read /etc/xprofile and .xprofile for X specific setup
test -f /etc/xprofile && . /etc/xprofile
test -f "$HOME/.xprofile" && . "$HOME/.xprofile"

Więc ~ / .profile jest uzyskiwane podczas logowania przy użyciu / bin / sh, a nie / bin / bash

Istnieją dwa przypadki

  1. / bin / sh jest połączony z / bin / bash, ale działa w trybie „POSIX / Bourne”
  2. / bin / sh to / bin / dash (debian / ubuntu). Najszybszy, ale z mniejszą liczbą funkcji (obsługa ShellShock;) )

Zatem profil / bin / sh to ~ / .profile, a nie ~ / .bash_profile, ~ / .zprofile

Ten plik powinien być używany do ustawień „niezależnych od powłoki” , takich jak ścieżka i zmienne środowiskowe.

NO wykonywalny program do logowania-jedyne interakcji użytkownika powinno być, ale tutaj (sprawdzenie poczty, majątek, etc ...)

~ /.* rc są przeznaczone tylko do sesji „interaktywnych” (na przykład aliasy ...)

Istnieje różnica między bash i zsh dla interaktywnych powłok logowania

źródła bash tylko .bash_profile, podczas gdy źródła zsh w kolejności:

  1. ~ / .zprofile
  2. ~ / .zshrc
  3. ~ / zlogin (tutaj dostępne są aliasy zdefiniowane w ~ / .zshrc. w przypadku powłok „interaktywnych” + „login”)

Odpowiedzi na to, jak zrobić ~ / .bash_profile, tutaj:

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

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

Aby włączyć test (i profilowanie), możesz użyć tego

~ / .bash_profile:

#!/bin/bash

# ------------------------------------------------
export _DOT_BASH_PROFILE_0=`date  --rfc-3339=ns`
# ------------------------------------------------

if [ -f ~/.profile ] ; then
    . ~/.profile
fi

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

# ------------------------------------------------
export _DOT_BASH_PROFILE_1=`date  --rfc-3339=ns`
# ------------------------------------------------

~ / .zprofile:

#!/bin/zsh

# ------------------------------------------------
export _DOT_ZSH_PROFILE_0=`date  --rfc-3339=ns`
# ------------------------------------------------

if [ -f ~/.profile ] ; then
    . ~/.profile
fi

# no need to source, zsh already handle ~/.zshrc

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

# ------------------------------------------------
export _DOT_ZSH_PROFILE_1=`date  --rfc-3339=ns`
# ------------------------------------------------

następnie, aby przetestować:

chsh -s /bin/bash

ssh localhost
env

exit

ssh localhost env

ssh -t localhost bash -i -c env


chsh -s /bin/zsh

ssh localhost
env

exit

ssh localhost env

ssh -t localhost bash -i -c env

Tak więc RVM / virtualenv powinien przejść do ~ / .profile, IMHO

Ale to NIE DZIAŁA , czasami ...

Na przykład virualenvwrapper działa tylko wtedy, gdy powłoka z uruchomionym Xsession jest „oryginalną” wersją bash (eksportowanie BASH_VERSION)

Jeśli jesteś na desce rozdzielczej systemu, zmienna i praca ustawienie ścieżki, ale virualenvwrapper definicja funkcji nie działają, ponieważ skrypt nie jest zgodny z POSIX.

Skrypt nie podaje żadnego błędu, ale kończy się bez definicji „workon” .

Możesz więc ustawić dostępne środowisko w ~ / .profile , aby umożliwić prawidłowe wykonanie Pythona z klienta uruchomionego bezpośrednio z X:

export VIRTUAL_ENV="/home/mike/var/virtualenvs/myvirtualenv"
export PATH="$VIRTUAL_ENV/bin:$PATH"
unset PYTHON_HOME

https://gist.github.com/datagrok/2199506

https://www.bountysource.com/issues/9061991-setting-up-your-computer-virtualenvwrapper-linux-all

Ale dla virualenvwrapper masz dwie alternatywy:

  1. źródło w ~ / .bash_profile lub ~ / .zprofile (lub ~ / .zlogin), gdy terminal działa jako powłoka logowania
  2. dołącz skrypt do ~ / .bashrc lub ~ / zshrc

Oznacza to, że klienci X (na przykład emacs) powinni być uruchamiani z powłoki terminala, a nie z graficznej!

„Nie mogę uzyskać satysfakcji ...”

hute37
źródło
Kompletny inna historia pracuje usługi z Systemd kilka możliwych alternatyw: pisanie otoki skrypt, określić warunki, w „serwis” pliku definicji, wysypywania środowiska w „env” pliku, aby być pozyskiwane w powłoce macierzystej. Sprawa staje się trudniejsza z RVM / virtualenv ...
hute37