Pourquoi la source Bash distante .bash_profile au lieu de .bashrc

24

Le manuel de Bash dit:

Bash tente de déterminer quand il est exécuté avec son entrée standard connectée à une connexion réseau, comme lorsqu'il est exécuté par le démon shell distant, généralement rshd, ou le démon shell sécurisé sshd. Si Bash détermine qu'il est exécuté de cette manière, il lit et exécute les commandes à partir de ~ / .bashrc, si ce fichier existe et est lisible.

Ce Bash sources ~/.bashrc:

ssh user@host :

Mais ce Bash sources ~/.bash_profile:

ssh user@host

Je ne vois pas de différence dans ces deux commandes selon la spécification. Stdin n'est-il pas connecté à une connexion réseau dans les deux cas?

Cyker
la source
2
Bien que ce ne soit pas ce que vous demandez, je voudrais noter qu'il est considéré comme une bonne pratique de source de .bashrc à partir de .bash_profile . De cette façon, les paramètres de .bashrc seront appliqués, que bash soit démarré en tant que shell de connexion ou non.
Ilmari Karonen du

Réponses:

44

Un shell de connexion lit d'abord /etc/profile, puis ~/.bash_profile.

Un shell sans connexion lit à partir de /etc/bash.bashrcpuis ~/.bashrc.

Pourquoi est-ce important?

En raison de cette ligne dans man ssh:

Si la commande est spécifiée, elle est exécutée sur l'hôte distant au lieu d'un shell de connexion.

En d'autres termes, si la commande ssh n'a que des options (pas une commande), comme:

ssh user@host

Il va commencer un shell de connexion, un shell de connexion lit ~/.bash_profile.

Une commande ssh qui a une commande , comme:

ssh user@host :

Où se trouve la commande :(ou ne rien faire).
Il ne démarrera pas un shell de connexion, c'est donc ~/.bashrcce qui sera lu.


Stdin à distance

La connexion tty fournie pour / dev / stdin sur l'ordinateur distant peut être un tty réel ou autre chose.

Pour:

$ ssh sorontar@localhost
/etc/profile sourced

$ ls -la /dev/stdin
lrwxrwxrwx 1 root root 15 Dec 24 03:35 /dev/stdin -> /proc/self/fd/0

$ ls -la /proc/self/fd/0
lrwx------ 1 sorontar sorontar 64 Dec 24 19:34 /proc/self/fd/0 -> /dev/pts/3

$ ls -la /dev/pts/3
crw--w---- 1 sorontar tty 136, 3 Dec 24 19:35 /dev/pts/3

Ce qui se termine par un ATS (pas une connexion réseau) comme le bash démarré le voit.

Pour une connexion ssh avec une commande:

$ ssh sorontar@localhost 'ls -la /dev/stdin'
sorontar@localhost's password: 
lrwxrwxrwx 1 root root 15 Dec 24 03:35 /dev/stdin -> /proc/self/fd/0

La liste des ATS commence de la même manière, mais notez que / etc / profile n'a pas été fourni.

$ ssh sorontar@localhost 'ls -la /proc/self/fd/0'
sorontar@localhost's password:
lr-x------ 1 sorontar sorontar 64 Dec 24 19:39 /proc/self/fd/0 -> pipe:[6579259]

Ce qui indique au shell que la connexion est un canal (pas une connexion réseau).

Ainsi, dans les deux cas de test, le shell est incapable de savoir que la connexion provient d'un réseau et ne lit donc pas ~/.bashrc(si nous parlons uniquement de la connexion à un réseau). Il lit ~ / .bashrc, mais pour une raison différente.

Sorontar
la source
Le cas sans argument ne serait-il pas également admissible à être exécuté avec son entrée standard connectée à une connexion réseau et donc à avoir ~/.bashrclu?
Cyker
@Cyker Cela suppose que le shell sera stdin connecté à un réseau . Pourquoi supposez-vous cela? (Réponse modifiée, veuillez lire).
sorontar
La partie éditée est intéressante. On dirait que ssh ne dérange pas avec un pty lors de l'exécution d'une commande.
Cyker
8

Vous posez des questions sur le «pourquoi» et non sur le «comment», je vais donc essayer de répondre dans cette perspective. Ce qui suit sera une bonne partie de la raison pour laquelle les choses se sont passées dans le passé pour aboutir à comment elles se produisent aujourd'hui.


La raison d'avoir deux fichiers de démarrage différents ("profil" et "rc") est que dans le passé, la manière courante de travailler sur une machine était:

  1. Connectez-vous à partir d'une sorte de terminal réel ou d'un autre poste de travail et obtenez un shell de connexion . Ce shell invoquera /etc/profileet ~/.profileconfigurera l'environnement pour l'utilisateur.

  2. Appelez l'environnement dans lequel l'utilisateur souhaite entrer. Cet environnement pourrait être Xorg, mais dans la plupart des cas, il s'agissait d'un multiplexeur tel que l'écran GNU.

  3. L'environnement (par exemple, l'écran GNU) invoquerait alors des shells supplémentaires (sans connexion) qui héritent de l'environnement du shell de connexion parent.

C'était la manière courante de se connecter à une machine UNIX à l'époque cshet en bashcours de développement. Par conséquent , il a été jugé inutile de lire à ~/.profilenouveau dans les coquilles qui héritaient l'environnement de toute façon.

bashpuis ajouté ~/.bashrcpour une configuration supplémentaire pour ces shells sans connexion. csh(et tcsh) n'a jamais ajouté de fichier "rc" pour les shells sans connexion. Notez que csh/ tcshne sont pas des shells compatibles avec le bourne shell (qui fait partie de POSIX) tandis que l' bashest. Un autre shell compatible bourne ksh, a ajouté une variable d'environnement (appelée ENV) qui, si elle était définie, serait utilisée comme fichier de commandes d'exécution ("rc") pour la non-connexion ksh.

Alors oui, les nouvelles versions des shells bourne ont ajouté le fichier de configuration supplémentaire pour des alias et d'autres options rapides qui seraient présentes à l'intérieur des shells muxed par GNU screen (ou similaire) mais pas présentes dans le shell que vous obtenez lorsque vous entrez pour la première fois dans le machine.

Avec l'augmentation des gestionnaires d'affichage graphique (GDM), la différenciation entre les fichiers "profil" et les fichiers "rc" est devenue sans signification parce que le GDM aurait ses propres fichiers d'initialisation (par exemple ~/.xinitet ~/.xsession). Ensuite, les shells indiqués depuis l'intérieur du GDM peuvent être des shells de connexion ou de non-connexion en fonction des caprices d'un utilisateur, et le cas dans lequel un shell non-connexion aurait toujours un parent qui est un shell de connexion n'est plus vrai.

Supplémentaire

Un de mes tableaux préférés sur la comparaison des fichiers de démarrage du shell montre comment les shells compatibles avec le shell bourne utilisent les profilefichiers alors que les autres shells ne le font pas. En effet, dans le passé, le shell initial (celui qui a démarré le multiplexeur) devait être un shell compatible bourne.

grochmal
la source