Sous Linux et, à ma connaissance, sur 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é va:
Lorsqu'un shell interactif qui n'est pas un shell de connexion est démarré, bash lit et exécute les commandes à partir de
/etc/bash.bashrc
et~/.bashrc
, si ces fichiers existent. Cela peut être inhibé en utilisant l'--norc
option.L'
--rcfile
option de fichier forcera bash à lire et à exécuter des commandes à partir du fichier au lieu de/etc/bash.bashrc
et~/.bashrc
.
Et pour les coquilles de connexion:
Lorsque bash est appelé en tant que shell de connexion interactif ou en tant que shell non interactif avec l'
--login
option, il commence par lire et exécuter 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 de la première qui existe et est lisible.Cette
--noprofile
option peut être utilisée au démarrage du shell pour empêcher ce comportement.
Sur Mac OS X, cependant, le shell par défaut ( ce qui est bash) a commencé dans le terminal par défaut (Terminal.app) en fait des sources ~/.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 un shell qui mentionnent des changements ~/.bashrc
vont échouer sous OSX ou vice versa ~/.profile
. Pourtant, si de nombreuses accusations peuvent être portées contre Apple, le recrutement 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 ont-ils changé le comportement de bash? Est-ce spécifique à Terminal.app ou est-il indépendant de l'émulateur de terminal?
Réponses:
La façon dont il est censé 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 manière dont vous arrivez à ce point sont d'une importance secondaire, mais si l'un des fichiers n'était pas exécuté, vous auriez un shell avec des paramètres incomplets.La raison pour laquelle les émulateurs de terminal sous Linux (et d’autres systèmes X) n’ont pas besoin de s’exécuter
.profile
eux-mêmes est qu’elle a normalement déjà été exécutée lorsque vous vous êtes connecté à X. Les paramètres.profile
sont supposés être du type pouvant être utilisé. hérité par les sous-processus, donc tant qu'il est exécuté une fois lorsque vous vous connectez (par exemple via.Xsession
), aucun sous-shell supplémentaire n'a besoin de le réexécuter.Comme l'explique la page wiki Debian liée par Alan Shutko:
Les mêmes règles sont également valables sous OSX, à une exception près: l'interface graphique OSX ne s'exécute pas
.profile
lorsque vous vous connectez, apparemment parce qu'elle possède sa propre méthode de chargement des paramètres globaux. Mais cela signifie qu’un émulateur de terminal sous OSX doit être exécuté.profile
(en indiquant au shell qu’il lance qu’il lance est un shell de connexion), sinon vous vous retrouveriez avec un shell potentiellement endommagé.Maintenant, une sorte de particularité idiote de bash, que ne partagent pas la plupart des autres shells, est qu'elle ne s'exécutera pas automatiquement
.bashrc
si elle est lancée en tant que shell de connexion. La solution standard consiste à inclure quelque chose comme les commandes suivantes.bash_profile
:Alternativement, il est possible de ne pas en avoir
.bash_profile
du tout et d'inclure simplement du code spécifique à Bash dans le.profile
fichier générique à exécuter.bashrc
si nécessaire.Si OSX par défaut
.bash_profile
ou.profile
ne le fait pas , c'est sans doute un bogue. Dans tous les cas, la solution appropriée consiste simplement à ajouter ces lignes.bash_profile
.Edit: Comme le notent les critiques , le shell par défaut sous 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 les deux
.profile
et.tcshrc
/.cshrc
, et n'a donc pas besoin de solutions de rechange comme le.bash_profile
truc. montré ci-dessus.Sur cette base, je suis sûr à 99% que OSX
.bash_profile
n’a pas fourni le paramètre par défaut approprié , car lorsqu’ils sont passés de tcsh à bash, les employés d’Apple n’ont tout simplement pas remarqué cette petite verrue dans le comportement de bash au démarrage. Avec tcsh, aucune de ces astuces n’était nécessaire: démarrer tcsh en tant que shell de connexion à partir d’un émulateur de terminal OSX, Just Plain Works, fait ce qu’il faut sans ces kluges.la source
.bashrc
non pertinent? Pourquoi ont-ils choisi de faire en sorte que tous les obus se connectent? Autant que je sache, seule votre dernière phrase parle de cela et seulement pour dire que c'est un bug..profile
lorsque l'utilisateur se connecte à l'interface graphique. Ils doivent donc l'exécuter ultérieurement pour obtenir des variables d'environnement telles que$PATH
, qui sont normalement définies dans.profile
, configurées correctement. . Le fait que, comme effet secondaire, cela.bashrc
ne cause pas de source est un bug; vous pouvez discuter du fait qu'il s'agisse d'un bogue dans bash ou dans OSX, mais cela ne change rien au fait que le comportement correct consiste à s'assurer que les variables d'environnement de.profile
et le paramètre de configuration de bash.bashrc
sont chargés..bashrc
source.profile
serait une mauvaise idée car cela provoquerait une nouvelle exécution de chaque sous-shell.profile
. Si rien d'autre, cela causerait des.profile
idiomes communs commeexport PATH = "$HOME/bin:$PATH"
garder des entrées redondantes avant les autres$PATH
. Avoir une.profile
source.bashrc
est beaucoup plus logique, mais seulement après avoir vérifié que le shell sous lequel il est exécuté est, en fait, bash. Avoir à la.bash_profile
fois la source.profile
et.bashrc
, comme je l’ai suggéré ci-dessus, l’OMI, l’option la plus judicieuse..profile
», alors que la réponse à « pourquoi ne pas la source.bashrc
de.profile
, alors? » est "parce que c'est un bug!" Sérieusement, cela ne peut éventuellement être une décision intentionnelle; c'est juste quelque chose qu'ils ont oublié, probablement parce que, dans l'écosystème Mac, les coquilles sont des citoyens de seconde classe que la plupart des utilisateurs ne sont pas supposés traiter. (Ps. Voir aussi la réponse du candidat pour une explication historique; il s'agit presque certainement d'une régression du passage de tcsh à bash.)La raison principale pour laquelle les applications de terminal X exécutent des shells autres que de connexion par défaut est qu’au début des temps, votre .Xsession aurait exécuté le fichier .profile pour configurer vos éléments de connexion initiaux. Puis, comme tout était déjà configuré, les applications de terminal n’avaient pas besoin de s’exécuter, elles pouvaient exécuter le fichier .bashrc. La discussion sur les raisons pour lesquelles cela est important est à l' adresse https://wiki.debian.org/DotFiles :
Sous OS X, les environnements utilisateur ne sont pas démarrés par une pile de scripts shell, et launchd ne source le fichier .profile à aucun moment. (C'est en quelque sorte une honte, car cela signifie que définir des variables d'environnement est bien plus ennuyeux, mais telle est la vie.) Puisqu'il ne le ferait pas, quand est-ce qu'il fonctionnerait .profile? Seulement si tu es entré? Cela semble un peu inutile, car de nombreuses boîtes ne seront jamais la cible de ssh. Autrement, les terminaux doivent exécuter des shells de connexion par défaut, afin que .profile soit exécuté de temps en temps.
Qu'en est-il de .bashrc, alors? Est-ce inutile? Non, il a toujours le but qu'il avait à l'époque du VT100. Il est utilisé chaque fois que vous ouvrez un shell autre que l'ouverture d'une fenêtre de terminal. Donc, si vous utilisez Emacs ou vi, ou si vous faites un utilisateur su.
la source
.profile
sources de Debian.bashrc
et non pas pourquoi OSX a décidé de faire en sorte que tous les shells se connectent par shells. En fait, vous répondez à une autre question , et merci! Cependant, votre réponse n’explique pas le choix OSX et la citation Debian n’a absolument aucune pertinence (dans la mesure où je peux en dire plus (laissez-moi savoir si je manque le point). La manière OSX rend.bashrc
etc inutile et ne rend.profile
pas plus utile.Je ne sais pas pourquoi ils l'auraient fait. Cependant, voici ma conjecture.
Pour commencer, il convient de noter que sur un système GNU / Linux, vous pouvez bien entendu passer à vt1, vt2, etc. Vous obtenez un shell de connexion à cet emplacement. Sur un système OS X, il n'y a pas d'équivalent. La seule façon d'accéder aux bases UNIX consiste à utiliser un émulateur de terminal ou un mode utilisateur unique (avertissement: je n'ai jamais utilisé le mode utilisateur unique; il s'agit d'un IIRC piloté par ligne de commande, mais je me trompe peut-être). Par conséquent, sous OS X, quelle que soit la valeur par défaut dans l'émulateur, il s'agit de la valeur par défaut pour l'ensemble du système.
Maintenant, pourquoi voudriez-vous que la valeur par défaut soit un shell de connexion? Il y a quelques raisons (lire: pas beaucoup) pour lesquelles je peux penser à faire cela.
tcsh
. C’est à peu près la plus approximative possible, mais il se peut quetcsh
normalement, quelque chose se passe lorsqu’il est exécuté en tant que shell de connexion et que le modèle historique reste bloqué. (J'en doute, cependant - peut-être qu'un des habitués les plus âgés pourrait nous le dire.)Honnêtement, j'utilise Darwin depuis environ 6 ans et je ne peux pas répondre correctement à cette question. Cela n'a pas vraiment de sens pour moi non plus.
Pour répondre à votre sous-question,
bash
n’est pas corrigé ou quoi que ce soit (du moins pour cela). L'émulateur de terminal par défaut exécute des shells de connexion par défaut, et probablement iTerm le copie.la source
.profile
et.tcshrc
/.cshrc
sans nécessiter de kluges comme celui que j'ai donné dans ma réponse. Compte tenu de cela, je soupçonne que ce comportement est une régression non corrigée causée par le passage de tcsh à bash..login
et.tcshrc
/.cshrc
? Cela n'aurait aucun sens pour tcsh de se procurer.profile
; il contient généralement des commandes avec unesh
syntaxe quitcsh
ne sera pas acceptée. Je n'ai pas macOS mais j'ai créé/bin/tcsh
mon shell de connexion sous Ubuntu 16.04..profile
ne provient pas. tcsh (1) ne mentionne pas ce fichier, pas plus que tcsh (1) .Ceci est une mise à jour du statut actuel: les réponses sont devenues obsolètes, de nouvelles versions de MacOSX ont été publiées et le comportement de connexion a changé.
Cette question a été posée et répondue en 2014. J'ai étudié le sujet pour tenter de créer un ensemble commun .bashrc & .bash_profile à utiliser sur différentes distributions Linux et BSD (comme ils les appellent, s'ils ne sont pas des distributions).
J'ai récemment acheté un Mac Mini usagé sur lequel Sierra est installé. J'ai donc maintenant des systèmes avec les versions 10.6, 10.10, 10.11 et 10.12. Bien que j'aie muni les plus anciens (en laissant des indices sur leur statut antérieur), l'installation de la version 10.12 de Sierra est intacte.
Résultats: Dans la version 10.12 de Sierra, AUCUN fichier .bashrc, .bash_profile ou .profile n'a été créé par défaut. Dans / etc, il y a bashrc, bashrc_Apple_Terminal et profile. Contenu de / etc / profile:
Contenu de / etc / bashrc:
Le script / etc / bashrc_Apple_Terminal définit la variable PROMPT_COMMAND et définit un mécanisme permettant de préserver l’état de la session pour chaque terminal; si l'application de terminal est fermée, l'état de la session précédente est restauré lorsque l'application est redémarrée. Sinon, presque rien ($ PS1 minimal) n'est défini dans / etc / bashrc, si bien que toute autre personnalisation (vraie $ PS1, alias, fonctions) sera définie dans les paramètres ~ / .bashrc et $ PATH dans .bash_profile (ou dans .profile , provenant de .bash_profile).
J'ai confirmé que iTerm2 se comporte de la même manière que l'application Terminal, à l'exception du fait que le comportement par défaut du démarrage d'une session de connexion est visible et peut être modifié.
Si vous exécutez une session de terminal XTerm X11 (maintenant XQuartz), vous verrez une session sans connexion, identique à celle d'un système Linux. .bash_profile (ou .profile) est ignoré et vous obtenez simplement .bashrc.
Et voici ma réponse:
Bien que l'application Terminal prétende être un xterm (TERM = xterm-256color), elle ne définit pas la variable $ DISPLAY sauf si X11 est installé. Nous assistons à une simulation d’un environnement X, mais pas tout à fait réelle. Si vous SSH dans un autre système avec le commutateur -X (activer le transfert X11), cela échouera car il n'y a pas de variable $ DISPLAY. Si vous avez installé X11, puis SSH sur un autre système, le transfert X11 aboutira.
Conclusion (et réponse courte): l'application Terminal n'est pas un véritable terminal X11 (ne définit pas $ DISPLAY); il se comporte beaucoup plus comme une connexion SSH qu'une session XTerm, en ce sens qu'il doit s'agir d'une session de connexion afin de définir les valeurs à partir de / etc / profile et ~ / .bash_profile ou ~ / .profile
la source
Les réponses ci - dessus expliquent la raison pour laquelle les shells interactifs sont des coquilles de connexion sur macOS par défaut: paramètres dans
/etc/profile
,~/.profile
sont hérités par un obus non-connexion sur les systèmes basés sur X, mais pas sur macOS . Ici, je voudrais vous rappeler que vous devez toujours utiliser le shell de connexion sur macOS en raison de l'existence depath_helper
:Si vous utilisez un shell autre que la connexion, certains chemins ne seront pas importés.
Je pense que c'est toujours une bonne idée pour les développeurs de mettre un fichier dans
/etc/paths.d
pour importer leurs valeurs de chemin, mais pas pour créer un lien symbolique entre les fichiers binaires appelables et les emplacements tels que/usr/bin
ou/bin
. (La valeur par défautPATH
est/usr/bin:/bin:/usr/sbin:/sbin
. Tout le monde n'utilise pas Homebrew ou MacPorts pour ajouter des valeurs personnaliséesPATH
. Il n'y a donc pas toujours de lieu sûr pour placer les liens symboliques des commandes appelables.)Voici un exemple de fichiers dans
/etc/paths.d
. Fondamentalement, vous mettez une valeur à chaque ligne.Référence:
man path_helper
la source