GNU/Linux >> Tutoriels Linux >  >> Linux

Pourquoi les shells interactifs sur les shells de connexion Osx sont-ils par défaut ?

Sous Linux et, à ma connaissance, tous les systèmes Unix, les émulateurs de terminaux exécutent par défaut des shells interactifs sans connexion. Cela signifie que, pour bash, le shell démarré :

Lorsqu'un shell interactif qui n'est pas un shell de connexion est démarré, bash lit et exécute les commandes de /etc/bash.bashrc et ~/.bashrc , si ces fichiers existent. Cela peut être inhibé en utilisant le --norc option.

Le --rcfile L'option file forcera bash à lire et à exécuter les commandes du fichier au lieu de /etc/bash.bashrc et ~/.bashrc .

Et pour les shells de connexion :

Lorsque bash est appelé en tant que shell de connexion interactif ou en tant que shell non interactif avec le --login option, il lit et exécute d'abord les commandes du fichier /etc/profile , si ce fichier existe. Après avoir lu ce fichier, il recherche ~/.bash_profile , ~/.bash_login , et ~/.profile , dans cet ordre, et lit et exécute les commandes à partir de la première qui existe et est lisible.

Le --noprofile L'option peut être utilisée au démarrage du shell pour inhiber ce comportement.

Sur OSX, cependant, le shell par défaut (qui est bash) démarré dans le terminal par défaut (Terminal.app) source en fait ~/.bash_profile ou ~.profile etc. En d'autres termes, il agit comme un shell de connexion.

Question principale :Pourquoi le shell interactif par défaut est-il un shell de connexion sous OSX ? Pourquoi OSX a-t-il choisi de faire cela ? Cela signifie que toutes les instructions/tutoriels pour les choses basées sur le shell qui mentionnent de changer les choses dans ~/.bashrc échouera sur OSX ou vice versa pour ~/.profile . Pourtant, bien que de nombreuses accusations puissent être portées contre Apple, l'embauche de développeurs incompétents ou idiots n'en fait pas partie. Vraisemblablement, ils avaient une bonne raison pour cela, alors pourquoi ?

Sous-questions :Terminal.app exécute-t-il réellement un shell de connexion interactif ou a-t-il modifié le comportement de bash ? Est-ce spécifique à Terminal.app ou est-ce indépendant de l'émulateur de terminal ?

Réponse acceptée :

La façon dont c'est supposé le travail est que, au moment où vous obtenez une invite du shell, à la fois .profile et .bashrc ont été exécutés. Les détails spécifiques de la façon dont vous arrivez à ce point sont d'importance secondaire, mais si l'un des fichiers n'était pas exécuté du tout, vous auriez un shell avec des paramètres incomplets.

La raison pour laquelle les émulateurs de terminaux sous Linux (et d'autres systèmes basés sur X) n'ont pas besoin pour exécuter .profile eux-mêmes est qu'il aura normalement déjà été exécuté lorsque vous vous êtes connecté à X. Les paramètres dans .profile sont censés être du type qui peut être hérité par les sous-processus, donc tant qu'il est exécuté une fois lorsque vous vous connectez (par exemple via .Xsession ), les autres sous-shells n'ont pas besoin de le relancer.

Comme l'explique la page wiki Debian liée par Alan Shutko :

"Pourquoi .bashrc un fichier séparé de .bash_profile , alors? Cela se fait principalement pour des raisons historiques, lorsque les machines étaient extrêmement lentes par rapport aux postes de travail actuels. Traitement des commandes dans .profile ou .bash_profile pouvait prendre beaucoup de temps, surtout sur une machine où une grande partie du travail devait être effectuée par des commandes externes (pre-bash). Ainsi, les commandes de configuration initiales difficiles, qui créent des variables d'environnement pouvant être transmises aux processus enfants, sont placées dans .bash_profile . Les paramètres transitoires et les alias qui ne sont pas hérités sont placés dans .bashrc afin qu'ils puissent être relus par chaque sous-shell.”

Toutes les mêmes règles s'appliquent également à OSX, à une exception près :l'interface graphique OSX n'exécute pas .profile lorsque vous vous connectez, apparemment parce qu'il a sa propre méthode de chargement des paramètres globaux. Mais cela signifie qu'un émulateur de terminal sur OSX fait besoin d'exécuter .profile (en disant au shell qu'il lance qu'il s'agit d'un shell de connexion), sinon vous vous retrouveriez avec un shell potentiellement paralysé.

Connexe :Comment changer le shell cron (sh en bash) ?

Maintenant, une sorte de particularité idiote de bash, non partagée par la plupart des autres shells, est qu'il n'exécutera pas automatiquement .bashrc s'il est démarré en tant que shell de connexion. La solution standard pour cela consiste à inclure quelque chose comme les commandes suivantes dans .bash_profile :

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

Alternativement, il est possible de ne pas avoir de .bash_profile du tout, et incluez simplement du code spécifique à bash dans le générique .profile fichier pour exécuter .bashrc si nécessaire.

Si la valeur par défaut d'OSX .bash_profile ou .profile pas faites cela, alors c'est sans doute un bug. Dans tous les cas, la solution de contournement appropriée consiste simplement à ajouter ces lignes à .bash_profile .

Modifier : Comme le note strugee, le shell par défaut sur OSX était tcsh, dont le comportement est beaucoup plus sain à cet égard :lorsqu'il est exécuté en tant que shell de connexion interactif, tcsh lit automatiquement à la fois .profile et .tcshrc / .cshrc , et n'a donc pas besoin de solutions de contournement comme le .bash_profile astuce ci-dessus.

Sur cette base, je suis sûr à 99 % que l'échec d'OSX à fournir un .bash_profile par défaut approprié est parce que, lorsqu'ils sont passés de tcsh à bash, les gens d'Apple n'ont tout simplement pas remarqué cette petite verrue dans le comportement de démarrage de bash. Avec tcsh, aucune astuce de ce type n'était nécessaire - démarrer tcsh en tant que shell de connexion à partir d'un émulateur de terminal OSX Just Plain Works et fait ce qu'il faut sans de tels klugs.


Linux
  1. Différence entre le shell de connexion et le shell sans connexion ?

  2. Comment vérifier si un shell est connecté/interactif/batch ?

  3. Pourquoi Nullglob n'est-il pas par défaut ?

  4. Pourquoi un shell de connexion « sudo -i » casse-t-il un argument de chaîne de commande Here-doc ?

  5. Quelle est la commande *nix pour afficher le shell de connexion par défaut d'un utilisateur

Pourquoi le $shlvl commence-t-il au niveau 2 dans les shells sans connexion mais au niveau 1 dans les shells de connexion dans Rhel 7 ?

Pourquoi puis-je me connecter avec des mots de passe partiels ? ?

Comment changer (de manière permanente) le shell par défaut après la connexion à un Ttyn spécifique sous Linux ?

Qu'est-ce que le shell de connexion sous Linux ?

8 types de shells Linux

Pourquoi les fichiers .so sont-ils exécutables ?