Zauważyłem, że kiedy uruchamiam polecenie bezpośrednio na hoście SSH przy użyciu ssh <host> <command>
składni, widzę dane wyjściowe ( .bashrc
ale) danych wyjściowych .bash_profile
(lub .profile
).
Na przykład, jeśli umieszczę następujące polecenie u góry obu plików,
echo ${BASH_SOURCE[0]}
i ręcznie źródła .bash_profile
(które źródła .bashrc
z kolei), zobaczę
$ . .bash_profile
.bash_profile
.bashrc
To jest to samo wyjście, które widzę, jeśli loguję się do tego komputera zdalnie przez SSH, używając ssh <host>
formularza polecenia. (A jeśli .bash_profile
tymczasowo schuję gdzie indziej, żadna z tych linii nie zostanie wyświetlona).
Jeśli jednak wykonam polecenie bezpośrednio na zdalnym komputerze w ssh <host> <command>
formie ssh
, wówczas dane wyjściowe wyglądają następująco:
$ ssh <host> echo foo
/home/rlue/.bashrc
foo
Rozumiem, że różnica między .bash_profile
i .bashrc
polega na tym, że ta pierwsza służy do powłok logowania, a druga do interaktywnych powłok bez logowania .
Doszedłem do następujących wniosków:
ssh <host>
tylko źródła.bash_profile
, podczas gdyssh <host> <command>
tylko źródła.bashrc
, co oznacza- ten pierwszy jest powłoką logowania, a drugi nie.
Czy te wnioski są prawidłowe? Dlaczego jest ssh <host> <command>
traktowany jako interaktywna powłoka bez logowania? Czy SSH nadal nie loguje się na zdalnym komputerze, aby wykonać polecenie?
.bashrc
? Ten plik nie powinien generować żadnych danych wyjściowych. Każde wyjście.bashrc
może zepsuć wszystkie narzędzia, używając ssh jako ich transportu..bashrc
wprowadzało błąd, podczas gdy podobne linie.bash_profile
nie. Skorzystałem z okazji, aby zbadać rozbieżność przed ustaleniem linii obrażających.Odpowiedzi:
OpenSSH (najprawdopodobniej to, co uruchamiasz) decyduje, czy utworzyć powłokę logowania, i robi to tylko wtedy, gdy nie uruchamiasz określonej komendy. Od
man ssh
:Jest to więc wybór implementacji dla serwera ssh, czy chce utworzyć powłokę logowania, czy nie, a jeśli wydasz polecenie uruchomienia, nie zrobi tego.
Chociaż
ssh
wykonuje logowanie, jeśli wykonujesz polecenie i kończysz działanie, jest to o wiele bardziej podobne do tworzenia powłoki tylko po to, aby uruchomić to polecenie, niż do uzyskiwania środowiska logowania. Wydaje się, biorąc pod uwagę, że ludzie piszący OpenSSH postanowili potraktować to jako takie zadanie.Tworzą nieinteraktywną powłokę niezalogowaną do wykonania polecenia, ponieważ taki jest duch uruchamiania polecenia w innym kontekście / powłoce. Zwykle jednak nieinteraktywne powłoki nie byłyby automatycznie źródłem,
~/.bashrc
co wyraźnie dzieje się tutaj.bash
próbuje nam pomóc tutaj. Z dokumentówźródło
ssh
nie wymaga logowania, implementatorzy najwyraźniej zdecydowali, że w pewnych okolicznościach, np. Prosząc go o wykonanie polecenia i zwrócenie nie potrzebują / nie korzystają z dodatkowych kroków wykonywanych przez powłokę logowania, więc pomijają to. Tak więc rzeczywiście istnieje powłoka, która jest uruchomiona, domyślam się, że głównie konfiguruje środowisko, a ponieważ powłoka nie zostanie udostępniona użytkownikowi, który się zalogował, traktują ją tak, jakby użytkownik właśnie uruchomił nową powłokę do uruchomienia tej powłoki poleceniessh <host> <command>
nie dziedziczy środowiska żadnej istniejącej powłoki logowania. Na przykład$ ssh <host> \$PATH
zwraca ścieżkę taką, jaka byłaby bez pozyskiwania.bash_profile
(lub.profile
niejako) ... W sensie praktycznym, dlaczego chcesz ominąć ten krok?PATH
in.profile
- nie jest to dokładnie ten rodzaj rzeczą, którą chciałby załadowany przed uruchomieniem dowolnego polecenia na zdalnym komputerze?Dlaczego takiego zachowania leży na niższym poziomie niż muszli:
ssh host
(the „login shell” case) wykorzystuje pseudoterminalu na zdalnym komputerze, do komunikowania się międzysshd
procesu serwera i powłoki; zamiast tegossh host command
używa potoków pomiędzysshd
icommand
. Pseudoterminy są niezbędne do interaktywnego korzystania z interpretera poleceń, takiego jak powłoka lub tryb „ odczytu-odczytu-wydruku ” języka skryptowego; wprowadzają szereg przyjaznych dla człowieka funkcji, takich jak możliwość cofania się nad literówkami. Ale mają one większy narzut i (w zależności od konfiguracji) nie pozwalają na przechodzenie dowolnych danych przez niezmodyfikowane, więc SSH unika ich używania, gdy interakcja nie będzie miała miejsca.Czasami heurystyczna komenda SSH / brak komendy źle to rozumie; można go zastąpić przełącznikami
-t
i-T
. Na przykład, aby zalogować się do zdalnego komputera i natychmiast ponownie dołączyć zawieszonąscreen
sesję, musisz to zrobićssh -t host screen -R
;ssh host screen -R
spowodujescreen
narzekanie na brak połączenia z terminalem. Nie mogę sobie wyobrazić sytuacji, w której naprawdę chciałbyś skorzystać-T
, ale ma miejsce, jeśli kiedykolwiek ją znajdziesz.źródło
Najpierw musisz zobaczyć różne typy, możesz przeczytać to:
/unix/170493/login-non-login-and-interactive-non-interactive-shells
Teraz, jeśli otworzysz bashrc, zobaczysz na początku:
Oznacza to, że w zależności od tego, w jaki sposób uzyskujesz dostęp do systemu, ten plik ładuje kod wewnątrz, czy nie.
źródło
.bashrc
może być napisane tak, aby nie być pozyskiwane, jeśli jest wywoływane w kontekście nieinteraktywnym ( tj. Jeśli nie ma „instrukcji szybkiej” /$PS1
zmiennej). Alessh <host> <command>
jest zdecydowanie nieinteraktywny ; to znaczy, że ma nie podnosić wiersz polecenia. Dlaczego więc OpenSSH miałby być zaprojektowany do tworzenia interaktywnego monitu bez logowania (takiego, który próbuje uzyskać źródło.bashrc
) dla tego pozornie nieinteraktywnego przypadku użycia?