Różnica między powłoką logowania a powłoką niezalogowaną?
318
Rozumiem podstawową różnicę między powłoką interaktywną a powłoką nieinteraktywną. Ale co dokładnie odróżnia powłokę logowania od powłoki niezalogowanej?
Czy możesz podać przykłady zastosowań interaktywnej powłoki bez logowania ?
Wydaje mi się, że pytanie jest lepiej sformułowane jako „ Dlaczego powinniśmy / powinniśmy dbać o to, aby odróżnić powłoki logowania i powłoki, które się nie logują?” Wiele miejsc w Internecie już mówi nam, jakie są różnice, jeśli chodzi o to, jakie pliki startowe czytają; ale żaden z nich nie wydaje się odpowiadać na „dlaczego” w zadowalający i przekonujący sposób. Przykładowe przypadki użycia, w których zdecydowanie nie chcesz jednego lub drugiego zachowania, byłyby świetne.
Powłoka logowania jest pierwszym procesem, który jest wykonywany w ramach identyfikatora użytkownika podczas logowania do sesji interaktywnej. Proces logowania mówi powłoce, aby zachowywała się jak powłoka logowania z konwencją: przekazanie argumentu 0, który jest zwykle nazwą pliku wykonywalnego powłoki, z -poprzedzającym znakiem (np. -bashPodczas gdy normalnie byłoby bash. Powłoki logowania zwykle czytają plik, który robi takie rzeczy jak ustawienie zmiennych środowiskowych: /etc/profilei ~/.profiledla tradycyjnego Bourne shell, ~/.bash_profiledodatkowo dla bash † , /etc/zprofilei ~/.zprofiledla zsh † , /etc/csh.logina ~/.logindla csh, etc.
Kiedy logujesz się na konsoli tekstowej, przez SSH lub za pomocą su -, otrzymujesz interaktywną powłokę logowania . Kiedy logujesz się w trybie graficznym (na X menedżerze wyświetlania ), nie dostajesz powłoki logowania, zamiast tego dostajesz menedżera sesji lub menedżera okien.
Rzadko uruchamia się nieinteraktywną powłokę logowania , ale niektóre ustawienia X robią to po zalogowaniu się za pomocą menedżera wyświetlania, aby zorganizować odczyt plików profilu. Inne ustawienia (zależy od dystrybucji i menedżera wyświetlania) czytają /etc/profilei ~/.profilejawnie lub nie czytają ich. Innym sposobem na uzyskanie nieinteraktywnej powłoki logowania jest zalogowanie zdalne za pomocą polecenia przekazanego przez standardowe wejście, które nie jest terminalem, np. ssh example.com <my-script-which-is-stored-locally(W przeciwieństwie do tego ssh example.com my-script-which-is-on-the-remote-machine, który uruchamia nieinteraktywną powłokę, która się nie loguje).
Kiedy uruchamiasz powłokę w terminalu w istniejącej sesji (screen, terminal X, bufor terminala Emacs, powłoka wewnątrz innej itp.), Otrzymujesz interaktywną powłokę , która nie jest zalogowana . Że powłoka może odczytać pliku konfiguracyjnego powłoki ( ~/.bashrcdla bash wywoływany jako bash, /etc/zshrca ~/.zshrcdla zsh, /etc/csh.cshrci ~/.cshrcdla csh, plik wskazywany przez ENVzmienną do muszli POSIX / XSI zgodnych takich jak deski rozdzielczej, ksh i bash przy wywołaniu jako sh, $ENVjeśli ustawiony i ~/.mkshrcdla mksh itp.).
Gdy powłoka uruchamia skrypt lub polecenie przekazane w wierszu poleceń, jest to nieinteraktywna powłoka , która nie loguje się . Takie powłoki działają cały czas: bardzo często zdarza się, że gdy program wywołuje inny program, tak naprawdę uruchamia mały skrypt w powłoce, aby wywołać ten inny program. W tym przypadku niektóre powłoki odczytują plik startowy (bash uruchamia plik wskazany przez BASH_ENVzmienną, działa zsh /etc/zshenvi ~/.zshenv), ale jest to ryzykowne: powłokę można wywoływać w różnych kontekstach, a nic nie można zrobić, co by nie złamać coś.
† Upraszczam trochę, zobacz szczegóły dotyczące krwawych szczegółów.
Czy możesz podać przykład działania bashjako nieinteraktywna powłoka logowania?
Piotr Dobrogost
13
@PiotrDobrogostecho $- | bash -lx
Gilles
1
Nie wiem, czy to prawda, ale chcę zauważyć, że kiedy otwieram nowy terminal (w systemie OSX przy użyciu ustawień domyślnych), otrzymuję powłokę logowania, mimo że nigdy nie wpisuję nazwy użytkownika ani hasła.
Kevin Wheeler
4
@KevinWheeler W systemie OSX domyślnie aplikacja terminalowa uruchamia powłokę logowania. (Jak wyjaśniam, program uruchamiający powłokę decyduje, czy powłoka działa jak powłoka logowania.) To nie jest normalny sposób wykonywania różnych czynności.
Gilles
2
@IAmJulianAcosta Jeśli FOOjest zmienną środowiskową (tzn. .profileZawiera export FOO=something), to jest dostępna dla wszystkich podprocesów, w tym foo.sh. Jeśli zmienisz .profilena, export FOO=something_elseto ./foo.shnadal będzie drukowany somethingdo następnego logowania.
Gilles
48
Aby stwierdzić, czy jesteś w powłoce logowania:
prompt> echo $0
-bash # "-" is the first character. Therefore, this is a login shell.
prompt> echo $0
bash # "-" is NOT the first character. This is NOT a login shell.
Ważne jest użycie powłoki logowania, aby wszelkie ustawienia w niej /home/user/.bash_profilezostały wykonane. Oto trochę więcej informacji, jeśli jesteś zainteresowany (z man bash)
„Gdy bash jest wywoływany jako interaktywna powłoka logowania lub jako nieinteraktywna powłoka z opcją --login, najpierw czyta i wykonuje polecenia z pliku / etc / profile, jeśli plik ten istnieje. Po odczytaniu 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. opcja --noprofile może być stosowany, gdy powłoka jest zaczął hamować ten problem.”
W powłoce logowania argv[0][0] == '-'. W ten sposób wie, że to powłoka logowania.
W niektórych sytuacjach zachowuje się inaczej w zależności od statusu „powłoki logowania”. Na przykład powłoka, która nie jest powłoką logowania, nie wykona polecenia „wylogowania”.
Zgodnie man bashz dodanym podkreśleniem: „Powłoka logowania to taka, której pierwszym znakiem argumentu zero jest - lub zaczyna się od opcji --login. ”
Wildcard
18
Powłoka uruchomiona w nowym terminalu w GUI byłaby interaktywną powłoką bez logowania. Byłby źródłem twojego .bashrc, ale nie na przykład twojego .profile.
Omówię świetną odpowiedź Gillesa w połączeniu z metodą Timothy'ego do sprawdzania typu powłoki logowania.
Jeśli chcesz zobaczyć rzeczy na własne oczy, wypróbuj poniższe fragmenty i scenariusze.
Sprawdzanie, czy powłoka jest (nie) interaktywna
if tty -s;then echo 'This is interactive shell.';else echo 'This is non-interactive shell.';fi
Sprawdzanie, czy powłoka jest (nie-) loginem
Jeśli wyjście echo $0zaczyna się od -, to jest to powłoka logowania ( echo $0przykład wyjścia:) -bash. W przeciwnym razie jest to powłoka niezalogowana ( echo $0przykład wyjściowy:) bash.
if echo $0 | grep -e ^\- 2>&1>/dev/null;then echo "This is login shell.";else echo "This is non-login shell.";fi;
Połączmy dwa powyższe razem, aby uzyskać obie informacje jednocześnie:
ssh ubuntu@34.247.105.87Welcome to Ubuntu16.04.5 LTS (GNU/Linux4.4.0-1083-aws x86_64)
ubuntu@ip-172-31-0-70:~$ THIS_SHELL_INTERACTIVE_TYPE='non-interactive';
ubuntu@ip-172-31-0-70:~$ THIS_SHELL_LOGIN_TYPE='non-login';
ubuntu@ip-172-31-0-70:~$ if tty -s;then THIS_SHELL_INTERACTIVE_TYPE='interactive';fi;
ubuntu@ip-172-31-0-70:~$ if echo $0 | grep -e ^\- 2>&1>/dev/null;then THIS_SHELL_LOGIN_TYPE='login';fi;
ubuntu@ip-172-31-0-70:~$ echo "$THIS_SHELL_INTERACTIVE_TYPE/$THIS_SHELL_LOGIN_TYPE"
interactive/login
Uruchamianie skryptu lub jawne wykonywanie za pomocą nowej powłoki
ubuntu@ip-172-31-0-70:~$ bash -c 'THIS_SHELL_INTERACTIVE_TYPE='non-interactive'; THIS_SHELL_LOGIN_TYPE='non-login'; if tty -s; then THIS_SHELL_INTERACTIVE_TYPE='interactive'; fi; if echo $0 | grep -e ^\- 2>&1>/dev/null; then THIS_SHELL_LOGIN_TYPE='login'; fi;
echo "$THIS_SHELL_INTERACTIVE_TYPE/$THIS_SHELL_LOGIN_TYPE"'
interactive/non-login
Zdalne uruchamianie lokalnego skryptu
ssh ubuntu@34.247.105.87< checkmy.sh
Pseudo-terminal will not be allocated because stdin is not a terminal.Welcome to Ubuntu16.04.5 LTS (GNU/Linux4.4.0-1083-aws x86_64)
non-interactive/login
Zdalne uruchomienie polecenia nad ssh
ssh ubuntu@34.247.105.87'THIS_SHELL_INTERACTIVE_TYPE='non-interactive'; THIS_SHELL_LOGIN_TYPE='non-login'; if tty -s; then THIS_SHELL_INTERACTIVE_TYPE='interactive'; fi; if echo $0 | grep -e ^\- 2>&1>/dev/null; then THIS_SHELL_LOGIN_TYPE='login'; fi; echo "$THIS_SHELL_INTERACTIVE_TYPE/$THIS_SHELL_LOGIN_TYPE"'
non-interactive/non-login
Uruchamianie polecenia ssh zdalnie za pomocą -tprzełącznika
Możesz jawnie zażądać interaktywnej powłoki, gdy chcesz uruchomić polecenie zdalnie przez ssh za pomocą -tprzełącznika.
ssh ubuntu@34.247.105.87-t 'THIS_SHELL_INTERACTIVE_TYPE='non-interactive'; THIS_SHELL_LOGIN_TYPE='non-login'; if tty -s; then THIS_SHELL_INTERACTIVE_TYPE='interactive'; fi; if echo $0 | grep -e ^\- 2>&1>/dev/null; then THIS_SHELL_LOGIN_TYPE='login'; fi; echo "$THIS_SHELL_INTERACTIVE_TYPE/$THIS_SHELL_LOGIN_TYPE"'
interactive/non-login
Uwaga: na ten temat, dlaczego zdalne uruchamianie polecenia nie ma tutajlogin shell więcej informacji .
Odpowiedzi:
Powłoka logowania jest pierwszym procesem, który jest wykonywany w ramach identyfikatora użytkownika podczas logowania do sesji interaktywnej. Proces logowania mówi powłoce, aby zachowywała się jak powłoka logowania z konwencją: przekazanie argumentu 0, który jest zwykle nazwą pliku wykonywalnego powłoki, z
-
poprzedzającym znakiem (np.-bash
Podczas gdy normalnie byłobybash
. Powłoki logowania zwykle czytają plik, który robi takie rzeczy jak ustawienie zmiennych środowiskowych:/etc/profile
i~/.profile
dla tradycyjnego Bourne shell,~/.bash_profile
dodatkowo dla bash † ,/etc/zprofile
i~/.zprofile
dla zsh † ,/etc/csh.login
a~/.login
dla csh, etc.Kiedy logujesz się na konsoli tekstowej, przez SSH lub za pomocą
su -
, otrzymujesz interaktywną powłokę logowania . Kiedy logujesz się w trybie graficznym (na X menedżerze wyświetlania ), nie dostajesz powłoki logowania, zamiast tego dostajesz menedżera sesji lub menedżera okien.Rzadko uruchamia się nieinteraktywną powłokę logowania , ale niektóre ustawienia X robią to po zalogowaniu się za pomocą menedżera wyświetlania, aby zorganizować odczyt plików profilu. Inne ustawienia (zależy od dystrybucji i menedżera wyświetlania) czytają
/etc/profile
i~/.profile
jawnie lub nie czytają ich. Innym sposobem na uzyskanie nieinteraktywnej powłoki logowania jest zalogowanie zdalne za pomocą polecenia przekazanego przez standardowe wejście, które nie jest terminalem, np.ssh example.com <my-script-which-is-stored-locally
(W przeciwieństwie do tegossh example.com my-script-which-is-on-the-remote-machine
, który uruchamia nieinteraktywną powłokę, która się nie loguje).Kiedy uruchamiasz powłokę w terminalu w istniejącej sesji (screen, terminal X, bufor terminala Emacs, powłoka wewnątrz innej itp.), Otrzymujesz interaktywną powłokę , która nie jest zalogowana . Że powłoka może odczytać pliku konfiguracyjnego powłoki (
~/.bashrc
dla bash wywoływany jakobash
,/etc/zshrc
a~/.zshrc
dla zsh,/etc/csh.cshrc
i~/.cshrc
dla csh, plik wskazywany przezENV
zmienną do muszli POSIX / XSI zgodnych takich jak deski rozdzielczej, ksh i bash przy wywołaniu jakosh
,$ENV
jeśli ustawiony i~/.mkshrc
dla mksh itp.).Gdy powłoka uruchamia skrypt lub polecenie przekazane w wierszu poleceń, jest to nieinteraktywna powłoka , która nie loguje się . Takie powłoki działają cały czas: bardzo często zdarza się, że gdy program wywołuje inny program, tak naprawdę uruchamia mały skrypt w powłoce, aby wywołać ten inny program. W tym przypadku niektóre powłoki odczytują plik startowy (bash uruchamia plik wskazany przez
BASH_ENV
zmienną, działa zsh/etc/zshenv
i~/.zshenv
), ale jest to ryzykowne: powłokę można wywoływać w różnych kontekstach, a nic nie można zrobić, co by nie złamać coś.† Upraszczam trochę, zobacz szczegóły dotyczące krwawych szczegółów.
źródło
bash
jako nieinteraktywna powłoka logowania?echo $- | bash -lx
FOO
jest zmienną środowiskową (tzn..profile
Zawieraexport FOO=something
), to jest dostępna dla wszystkich podprocesów, w tymfoo.sh
. Jeśli zmienisz.profile
na,export FOO=something_else
to./foo.sh
nadal będzie drukowanysomething
do następnego logowania.Aby stwierdzić, czy jesteś w powłoce logowania:
W Bash możesz także użyć
shopt login_shell
:(lub
on
w powłoce logowania).Informacje można znaleźć w
man bash
(Wyszukaj wywołanie). Oto fragment:Możesz to przetestować samodzielnie. Za każdym razem, gdy korzystasz z SSH, używasz powłoki logowania. Na przykład:
Ważne jest użycie powłoki logowania, aby wszelkie ustawienia w niej
/home/user/.bash_profile
zostały wykonane. Oto trochę więcej informacji, jeśli jesteś zainteresowany (zman bash
)źródło
W powłoce logowania
argv[0][0] == '-'
. W ten sposób wie, że to powłoka logowania.W niektórych sytuacjach zachowuje się inaczej w zależności od statusu „powłoki logowania”. Na przykład powłoka, która nie jest powłoką logowania, nie wykona polecenia „wylogowania”.
źródło
man bash
z dodanym podkreśleniem: „Powłoka logowania to taka, której pierwszym znakiem argumentu zero jest - lub zaczyna się od opcji --login. ”Powłoka uruchomiona w nowym terminalu w GUI byłaby interaktywną powłoką bez logowania. Byłby źródłem twojego .bashrc, ale nie na przykład twojego .profile.
źródło
Omówię świetną odpowiedź Gillesa w połączeniu z metodą Timothy'ego do sprawdzania typu powłoki logowania.
Jeśli chcesz zobaczyć rzeczy na własne oczy, wypróbuj poniższe fragmenty i scenariusze.
Sprawdzanie, czy powłoka jest (nie) interaktywna
Sprawdzanie, czy powłoka jest (nie-) loginem
Jeśli wyjście
echo $0
zaczyna się od-
, to jest to powłoka logowania (echo $0
przykład wyjścia:)-bash
. W przeciwnym razie jest to powłoka niezalogowana (echo $0
przykład wyjściowy:)bash
.Połączmy dwa powyższe razem, aby uzyskać obie informacje jednocześnie:
Scenariusze:
Typowa sesja SSH bez specjalnych opcji
Uruchamianie skryptu lub jawne wykonywanie za pomocą nowej powłoki
Zdalne uruchamianie lokalnego skryptu
Zdalne uruchomienie polecenia nad ssh
Uruchamianie polecenia ssh zdalnie za pomocą
-t
przełącznikaMożesz jawnie zażądać interaktywnej powłoki, gdy chcesz uruchomić polecenie zdalnie przez ssh za pomocą
-t
przełącznika.Uwaga: na ten temat, dlaczego zdalne uruchamianie polecenia nie ma tutaj
login shell
więcej informacji .źródło