Dlaczego zdalne Bash pobiera .bash_profile zamiast .bashrc

24

Bash Manual mówi:

Bash próbuje ustalić, kiedy jest uruchamiany ze standardowym wejściem podłączonym do połączenia sieciowego, tak jak w przypadku wykonania przez zdalny demon powłoki, zwykle rshd lub bezpieczny demon powłoki sshd. Jeśli Bash ustali, że jest uruchamiany w ten sposób, odczytuje i wykonuje polecenia z ~ / .bashrc, jeśli ten plik istnieje i można go odczytać.

Źródła tego Bash ~/.bashrc:

ssh user@host :

Ale źródła Bash ~/.bash_profile:

ssh user@host

Nie widzę różnicy w tych dwóch poleceniach zgodnie ze specyfikacją. Czy stdin nie jest podłączony do połączenia sieciowego w obu przypadkach?

Cyker
źródło
2
Chociaż nie o to pytasz, chciałbym zauważyć, że dobrą praktyką jest pozyskiwanie .bashrc z .bash_profile . W ten sposób ustawienia z .bashrc zostaną zastosowane niezależnie od tego, czy bash zostanie uruchomiony jako powłoka logowania czy powłoka niezalogowana.
Ilmari Karonen,

Odpowiedzi:

44

Powłoka logowania najpierw czyta, /etc/profilea następnie ~/.bash_profile.

Powłoka niezalogowana odczytuje /etc/bash.bashrcodtąd ~/.bashrc.

Dlaczego to takie ważne?

Z powodu tej linii w man ssh:

Jeśli podano polecenie, jest ono wykonywane na zdalnym hoście zamiast powłoki logowania.

Innymi słowy, jeśli polecenie ssh ma tylko opcje (nie polecenie), na przykład:

ssh user@host

Rozpocznie się powłoka logowania, czytana jest powłoka logowania ~/.bash_profile.

Polecenie ssh, które ma takie polecenie , jak:

ssh user@host :

Gdzie jest polecenie :(lub nic nie rób).
To będzie nie uruchomi powłokę logowania, więc ~/.bashrcto, co będzie czytać.


Zdalne wejście

Dostarczone połączenie tty dla / dev / stdin w komputerze zdalnym może być rzeczywistym tty lub czymś innym.

Dla:

$ ssh sorontar@localhost
/etc/profile sourced

$ ls -la /dev/stdin
lrwxrwxrwx 1 root root 15 Dec 24 03:35 /dev/stdin -> /proc/self/fd/0

$ ls -la /proc/self/fd/0
lrwx------ 1 sorontar sorontar 64 Dec 24 19:34 /proc/self/fd/0 -> /dev/pts/3

$ ls -la /dev/pts/3
crw--w---- 1 sorontar tty 136, 3 Dec 24 19:35 /dev/pts/3

Który kończy się na TTY (nie połączenie sieciowe), gdy widzi to uruchomiona bash.

W przypadku połączenia ssh z poleceniem:

$ ssh sorontar@localhost 'ls -la /dev/stdin'
sorontar@localhost's password: 
lrwxrwxrwx 1 root root 15 Dec 24 03:35 /dev/stdin -> /proc/self/fd/0

Lista TTY zaczyna się tak samo, ale pamiętaj, że nie podano źródła / etc / profile.

$ ssh sorontar@localhost 'ls -la /proc/self/fd/0'
sorontar@localhost's password:
lr-x------ 1 sorontar sorontar 64 Dec 24 19:39 /proc/self/fd/0 -> pipe:[6579259]

Co mówi powłoce, że połączenie jest potokiem (a nie połączeniem sieciowym).

Tak więc w obu przypadkach testowych powłoka nie może wiedzieć, że połączenie pochodzi z sieci i dlatego nie czyta ~/.bashrc(jeśli mówimy tylko o połączeniu z siecią). Czyta ~ / .bashrc, ale z innego powodu.

sorontar
źródło
Czy przypadek braku argumentu również nie kwalifikowałby się do uruchomienia ze standardowym wejściem podłączonym do połączenia sieciowego, a zatem zostałby ~/.bashrcodczytany?
Cyker
@Cyker Zakłada się, że powłoka będzie miała stdin połączenie z siecią . Dlaczego tak myślisz? (Odpowiedź zredagowana, proszę przeczytać).
sorontar
Edytowana część jest interesująca. Wygląda na to, że ssh nie przeszkadza pty podczas wykonywania polecenia.
Cyker,
8

Pytasz o „dlaczego”, a nie „jak”, więc postaram się odpowiedzieć z tej perspektywy. Poniżej przedstawione zostaną uzasadnione przyczyny, dla których w przeszłości wydarzyły się rzeczy, które doprowadziły do ​​tego, jak się dzisiaj dzieje.


Powodem posiadania dwóch różnych plików startowych („profil” i „rc”) jest to, że w przeszłości powszechnym sposobem pracy na komputerze było:

  1. Zaloguj się z jakiegoś prawdziwego terminala lub innej stacji roboczej i uzyskaj powłokę logowania . Ta powłoka będzie powoływać /etc/profilei ~/.profilei konfiguracja środowiska dla użytkownika.

  2. Wywołaj środowisko, do którego użytkownik chce wejść. Środowiskiem tym może być Xorg, ale w większości przypadków był to multiplekser, taki jak ekran GNU.

  3. Środowisko (np. Ekran GNU) wywoływałoby wówczas dodatkowe powłoki (niezalogowane), które dziedziczą środowisko po nadrzędnej powłoce logowania.

To była powszechnym sposobem logowania do systemu UNIX w czasie, gdy cshi bashbyły rozwijane. Dlatego uznano za niepotrzebne ~/.profileponowne czytanie w powłokach, które i tak dziedziczyły środowisko.

bashnastępnie dodano w ~/.bashrccelu dodatkowej konfiguracji dla tych powłok, które nie są zalogowane. csh(i tcsh) nigdy nie dodał żadnego pliku „rc” dla powłok nie zalogowanych. Zauważ, że csh/ tcshnie są powłokami kompatybilnymi z powłoką Bourne'a (która jest częścią POSIX), podczas gdy bashjest. Kolejna powłoka kompatybilna z Bourne ksh, dodała zmienną środowiskową (wywoływaną ENV), która, jeśli została zdefiniowana, byłaby używana jako plik komend uruchamiania („rc”) dla braku logowania ksh.

Więc tak, nowsze wersje powłok Bourne dodały dodatkowy plik konfiguracyjny jako wygodę dla aliasów i innych szybkich opcji, które byłyby obecne w powłokach zmiksowanych przez ekran GNU (lub podobny), ale nieobecne w powłoce, którą dostajesz, gdy po raz pierwszy wchodzisz do maszyna.

Wraz z pojawieniem się graficznych menedżerów wyświetlania (GDM) rozróżnienie między plikami „profilowymi” i plikami „rc” stało się bez znaczenia, ponieważ GDM miałby własne pliki inicjujące (np. ~/.xinitI ~/.xsession). Następnie powłoki podane z GDM mogą być powłokami do logowania lub bez logowania, w zależności od zachcianek użytkownika, a przypadek, w którym powłoka bez logowania zawsze miałaby rodzica, który jest powłoką do logowania, nie jest już prawdą.

Dodatkowy

Jedna z moich ulubionych tabel na temat porównania plików startowych powłoki pokazuje, w jaki sposób powłoki zgodne z powłoką Bourne'a używają profileplików, podczas gdy inne powłoki tego nie robią. Jest tak, ponieważ w przeszłości początkowa powłoka (ta, która uruchomiła multiplekser) musiała być powłoką kompatybilną z Bourne'em.

grochmal
źródło