Rozumím základnímu rozdílu mezi interaktivním a neinteraktivním Shell. Ale co přesně odlišuje přihlašovací schránku od shellu bez přihlašování?
Můžete uvést příklady použití non-login interaktivní shellu?
Přihlašovací prostředí je první proces, který se provádí pod vaším uživatelským ID při přihlášení k interaktivní relaci. Proces přihlašování říká prostředí Shell, aby se chovalo jako přihlašovací prostředí s konvencí: předání argumentu 0, což je obvykle název spustitelného prostředí Shell, s -
vložen znak (např. -bash
vzhledem k tomu, že by to normálně bylo bash
. Přihlašovací skořápky obvykle čtou soubor, který provádí například nastavení proměnných prostředí: /etc/profile
a ~/.profile
pro tradiční Bourne Shell, ~/.bash_profile
navíc pro bash†, /etc/zprofile
a ~/.zprofile
pro zsh†, /etc/csh.login
a ~/.login
pro csh atd.
Když se přihlásíte na textové konzoli nebo prostřednictvím SSH nebo pomocí su -
, dostanete interaktivní přihlášení Shell. Když se přihlásíte v grafickém režimu (na správce zobrazení X ), nedostanete přihlašovací prostředí, ale dostanete správce relací nebo správce oken.
Spouštět neinteraktivní přihlášení Shell je vzácné, ale některá nastavení X to dělají, když se přihlásíte pomocí správce zobrazení, aby se zajistilo čtení souborů profilu. Další nastavení (záleží na distribuci a na správci zobrazení) přečtěte /etc/profile
a ~/.profile
explicitně nebo je nečtěte. Dalším způsobem, jak získat neinteraktivní přihlášení Shell, je vzdálené přihlášení pomocí příkazu procházejícího standardním vstupem, který není terminálem, např. ssh example.com <my-script-which-is-stored-locally
(naproti tomu ssh example.com my-script-which-is-on-the-remote-machine
, která spouští neaktivní prostředí bez přihlášení (Shell).
Když spustíte prostředí v terminálu v existující relaci (obrazovka, X terminál, vyrovnávací paměť Emacs terminálu, Shell uvnitř jiné atd.), Dostanete interaktivní, bez přihlášení Shell. Může Shell číst konfigurační soubor Shell (~/.bashrc
pro bash vyvolané jako bash
, /etc/zshrc
a ~/.zshrc
pro zsh, /etc/csh.cshrc
a ~/.cshrc
pro csh, soubor označený proměnnou ENV
pro shelly kompatibilní s POSIX/XSI, jako jsou pomlčka, ksh a bash, když je vyvolán jako sh
, $ENV
pokud je nastaveno a ~/.mkshrc
pro mksh atd.).
Když Shell spustí skript nebo příkaz předaný na jeho příkazovém řádku, jedná se o neinteraktivní, nepřihlašovací Shell. Takové skořápky běží po celou dobu: je velmi běžné, že když program volá jiný program, ve Shellu skutečně spustí malý skript, který vyvolá tento jiný program. Některé shelly v tomto případě načtou spouštěcí soubor (bash spustí soubor označený znakem BASH_ENV
variabilní, zsh běží /etc/zshenv
a ~/.zshenv
), ale to je riskantní: Shell se může dovolávat ve všech druzích kontextu, a je tu téměř cokoli, co můžete udělat, aby něco neporušilo.
† Trochu zjednodušuji, podívejte se do manuálu pro krvavé detaily.
Chcete-li zjistit, zda jste v přihlašovacím prostředí Shell:
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.
V Bash můžete také použít shopt login_Shell
:
Prompt> shopt login_Shell
login_Shell off
(nebo on
v přihlašovacím prostředí).
Informace naleznete v man bash
(hledejte Invocation). Zde je výňatek:
Přihlašovací prostředí je takové, jehož první znak nuly argumentu je - nebo ten začínající volbou --login.
Můžete to vyzkoušet sami. Kdykoli SSH, používáte přihlašovací Shell. Například:
Prompt> ssh [email protected]
[email protected]'s password:
Prompt> echo $0
-bash
Důležitost použití přihlašovacího prostředí je, že všechna nastavení v /home/user/.bash_profile
bude popraven. Tady je trochu více informací, pokud vás to zajímá (od man bash
)
"Když je bash vyvolán jako interaktivní přihlašovací prostředí nebo jako neinteraktivní prostředí s volbou --login, přečte a provede příkazy ze souboru/etc/profile, pokud tento soubor existuje. Po přečtení tohoto souboru hledá
~/.bash_profile
,~/.bash_login
, a~/.profile
v tomto pořadí a čte a provádí příkazy z prvního, který existuje a je čitelný. Volba --noprofile může být použita, když je Shell spuštěn, aby toto chování potlačil. "
V přihlašovacím prostředí Shell argv[0][0] == '-'
. Takto ví, že se jedná o přihlašovací schránku.
A pak se v některých situacích chová odlišně v závislosti na stavu „přihlašovací skořepiny“. Např. Shell, který není Shell pro přihlášení, by nevykonal příkaz „odhlášení“.
Shell zahájený v novém terminálu v GUI by byl interaktivním Shell bez přihlášení. Bylo by to zdrojem vašeho .bashrc, ale ne například vašeho .profilu.
Budu se zabývat skvělou odpovědí Gilles, v kombinaci s metodou Timothyho pro kontrolu typu přihlášení Shell.
Pokud chcete věci vidět sami, zkuste úryvky a scénáře níže.
Kontrola, zda je Shell (ne) interaktivní
if tty -s; then echo 'This is interactive Shell.'; else echo 'This is non-interactive Shell.'; fi
Kontrola, zda Shell je (ne) přihlašovací
Pokud výstup echo $0
začíná s -
, je to přihlašovací Shell (echo $0
příklad výstupu: -bash
). Jinak to není přihlášení Shell (echo $0
Příklad výstupu: bash
).
if echo $0 | grep -e ^\- 2>&1>/dev/null; then echo "This is login Shell."; else echo "This is non-login Shell."; fi;
Spojme obě výše uvedené dohromady a získáme obě informace najednou:
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 [email protected]
Welcome to Ubuntu 16.04.5 LTS (GNU/Linux 4.4.0-1083-aws x86_64)
[email protected]:~$ THIS_Shell_INTERACTIVE_TYPE='non-interactive';
[email protected]:~$ THIS_Shell_LOGIN_TYPE='non-login';
[email protected]:~$ if tty -s; then THIS_Shell_INTERACTIVE_TYPE='interactive'; fi;
[email protected]:~$ if echo $0 | grep -e ^\- 2>&1>/dev/null; then THIS_Shell_LOGIN_TYPE='login'; fi;
[email protected]:~$ echo "$THIS_Shell_INTERACTIVE_TYPE/$THIS_Shell_LOGIN_TYPE"
interactive/login
[email protected]:~$ 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 [email protected] < 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 [email protected] '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
přepínačMůžete explicitně požádat o interaktivní Shell, když chcete příkaz spustit vzdáleně přes ssh pomocí -t
přepínač.
ssh [email protected] -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
Poznámka: K tématu proč spuštění příkazu na dálku není login Shell
více informací zde .