GNU/Linux >> Znalost Linux >  >> Linux

Proč jsou ve výchozím nastavení interaktivní shelly na přihlašovacích shellech Osx?

V Linuxu a, pokud je mi známo, ve všech unixových systémech emulátory terminálu standardně spouštějí interaktivní shelly bez přihlášení. To znamená, že pro bash bude spuštěný shell:

Když je spuštěn interaktivní shell, který není přihlašovacím shellem, bash čte a provádí příkazy z /etc/bash.bashrc a ~/.bashrc , pokud tyto soubory existují. Tomu lze zabránit pomocí --norc možnost.

--rcfile file option donutí bash číst a provádět příkazy ze souboru namísto /etc/bash.bashrc a ~/.bashrc .

A pro přihlašovací shelly:

Když je bash vyvolán jako interaktivní přihlašovací shell nebo jako neinteraktivní shell s --login nejprve nač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 od prvního, který existuje a je čitelný.

--noprofile Tato možnost může být použita při spuštění shellu k potlačení tohoto chování.

V OSX však výchozí shell (což je bash) spuštěný ve výchozím terminálu (Terminal.app) ve skutečnosti zdroje ~/.bash_profile nebo ~.profile atd. Jinými slovy, funguje jako přihlašovací shell.

Hlavní otázka :Proč je výchozí interaktivní shell přihlašovací shell v OSX? Proč se OSX rozhodl udělat toto? To znamená, že všechny instrukce/tutoriály pro věci založené na shellu, které zmiňují změny v ~/.bashrc selže v OSX nebo naopak pro ~/.profile . Přestože na Apple lze vznést mnoho obvinění, najímání nekompetentních nebo idiotských vývojářů mezi ně nepatří. Pravděpodobně k tomu měli dobrý důvod, tak proč?

Dílčí otázky:Spouští Terminal.app skutečně interaktivní přihlašovací shell nebo změnili chování bash? Je to specifické pro Terminal.app nebo je to nezávislé na emulátoru terminálu?

Přijatá odpověď:

Tak, jak se to předpokládá práce spočívá v tom, že v okamžiku, kdy dostanete výzvu shellu, obě .profile a .bashrc byly spuštěny. Konkrétní podrobnosti o tom, jak se k tomuto bodu dostanete, jsou druhotné, ale pokud by se některý ze souborů vůbec nespustil, měli byste shell s neúplným nastavením.

Důvod, proč emulátory terminálu na Linuxu (a dalších systémech založených na X) nepotřebují spustit .profile samy o sobě je, že to bude normálně spuštěno již při přihlášení do X. Nastavení v .profile předpokládá se, že jde o druh, který mohou podprocesy zdědit, pokud se tedy spustí jednou, když se přihlásíte (např. přes .Xsession ), žádné další podskořápky jej nemusí spouštět znovu.

Jak vysvětluje wiki stránka Debianu, na kterou odkazoval Alan Shutko:

"Proč je .bashrc." samostatný soubor z .bash_profile , pak? Děje se tak z většinou historických důvodů, kdy byly stroje ve srovnání s dnešními pracovními stanicemi extrémně pomalé. Zpracování příkazů v .profile nebo .bash_profile může trvat poměrně dlouho, zvláště na stroji, kde mnoho práce muselo být provedeno externími příkazy (pre-bash). Takže obtížné příkazy počátečního nastavení, které vytvářejí proměnné prostředí, které lze předat podřízeným procesům, jsou vloženy do .bash_profile . Přechodná nastavení a aliasy, které nejsou zděděny, jsou vloženy do .bashrc aby je mohla znovu číst každá podslupka.“

Všechna stejná pravidla platí i pro OSX, až na jednu věc – OSX GUI nespouští .profile když se přihlásíte, zřejmě proto, že má svůj vlastní způsob načítání globálních nastavení. To ale znamená, že emulátor terminálu na OSX dělá je třeba spustit .profile (sdělením shellu, že se spouští, že je to přihlašovací shell), jinak byste skončili s potenciálně zmrzačeným shellem.

Související:Jak změnit cron shell (sh na bash)?

Nyní je jakousi hloupou zvláštností bash, kterou většina ostatních shellů nesdílí, že automaticky nespustí .bashrc pokud je spuštěn jako přihlašovací shell. Standardním řešením je zahrnout něco jako následující příkazy do .bash_profile :

[[ -e ~/.profile ]] && source ~/.profile    # load generic profile settings
[[ -e ~/.bashrc  ]] && source ~/.bashrc     # load aliases etc.

Případně je možné mít žádný .bash_profile vůbec a stačí zahrnout nějaký kód specifický pro bash do obecného .profile soubor ke spuštění .bashrc v případě potřeby.

Pokud je výchozí OSX .bash_profile nebo .profile není udělejte to, pak je to pravděpodobně chyba. V každém případě je správným řešením jednoduše přidat tyto řádky do .bash_profile .

Upravit: Jak poznamenává strugee, výchozí shell na OSX býval tcsh, jehož chování je v tomto ohledu mnohem rozumnější:když je spuštěn jako interaktivní přihlašovací shell, tcsh automaticky čte oba .profile a .tcshrc / .cshrc , a proto nepotřebuje žádná řešení jako .bash_profile trik zobrazený výše.

Na základě toho jsem si na 99 % jistý, že selhání systému OSX poskytnout odpovídající výchozí .bash_profile je to proto, že když přešli z tcsh na bash, lidé z Apple si jednoduše nevšimli této malé bradavice při spouštění bash. S tcsh nebyly žádné takové triky potřeba – spouštění tcsh jako přihlašovacího shellu z emulátoru terminálu OSX Just Plain Works a dělá správnou věc bez takových zbytečností.


Linux
  1. Rozdíl mezi přihlašovacím prostředím a nepřihlašovacím prostředím?

  2. Jak zkontrolovat, zda je Shell přihlašovací/interaktivní/dávkový?

  3. Procesy v relaci v interaktivním prostředí versus ve skriptu?

  1. Jak změnit (trvale) výchozí prostředí po přihlášení na konkrétním Ttynu v Linuxu?

  2. Co je příkaz *nix pro zobrazení výchozího přihlašovacího prostředí uživatele

  3. Změna výchozího prostředí v Linuxu

  1. Proč Bashrc kontroluje, zda je aktuální shell interaktivní?

  2. Proč není Nullglob výchozí?

  3. Proč jsou soubory .so spustitelné?