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 ?
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 ?
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łoby bash
. 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 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 ( ~/.bashrc
dla bash wywoływany jako bash
, /etc/zshrc
a ~/.zshrc
dla zsh, /etc/csh.cshrc
i ~/.cshrc
dla csh, plik wskazywany przez ENV
zmienną do muszli POSIX / XSI zgodnych takich jak deski rozdzielczej, ksh i bash przy wywołaniu jako sh
, $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.
bash
jako nieinteraktywna powłoka logowania?
echo $- | bash -lx
FOO
jest zmienną środowiskową (tzn. .profile
Zawiera export FOO=something
), to jest dostępna dla wszystkich podprocesów, w tym foo.sh
. Jeśli zmienisz .profile
na, export FOO=something_else
to ./foo.sh
nadal będzie drukowany something
do następnego logowania.
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.
W Bash możesz także użyć shopt login_shell
:
prompt> shopt login_shell
login_shell off
(lub on
w powłoce logowania).
Informacje można znaleźć w man bash
(Wyszukaj wywołanie). Oto fragment:
Powłoka logowania to taka, której pierwszym znakiem argumentu zero jest - lub rozpoczęty z opcją --login.
Możesz to przetestować samodzielnie. Za każdym razem, gdy korzystasz z SSH, używasz powłoki logowania. Na przykład:
prompt> ssh user@localhost
user@localhost's password:
prompt> echo $0
-bash
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 (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_login
i~/.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”.
man bash
z dodanym podkreśleniem: „Powłoka logowania to taka, której pierwszym znakiem argumentu zero jest - lub zaczyna się od opcji --login. ”
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 $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
.
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:
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"
ssh ubuntu@34.247.105.87
Welcome to Ubuntu 16.04.5 LTS (GNU/Linux 4.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
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
ssh ubuntu@34.247.105.87 < checkmy.sh
Pseudo-terminal will not be allocated because stdin is not a terminal.
Welcome to Ubuntu 16.04.5 LTS (GNU/Linux 4.4.0-1083-aws x86_64)
non-interactive/login
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
-t
przełącznikaMożesz jawnie zażądać interaktywnej powłoki, gdy chcesz uruchomić polecenie zdalnie przez ssh za pomocą -t
przełą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 .