¿Por qué la fuente Bash remota .bash_profile en lugar de .bashrc

24

Bash Manual dice:

Bash intenta determinar cuándo se ejecuta con su entrada estándar conectada a una conexión de red, como cuando lo ejecuta el demonio de shell remoto, generalmente rshd, o el demonio de shell seguro sshd. Si Bash determina que se está ejecutando de esta manera, lee y ejecuta comandos desde ~ / .bashrc, si ese archivo existe y es legible.

Esta fuente de Bash ~/.bashrc:

ssh user@host :

Pero esta fuente de Bash ~/.bash_profile:

ssh user@host

No veo una diferencia en estos dos comandos según la especificación. ¿No está stdin conectado a una conexión de red en ambos casos?

Cyker
fuente
2
Si bien no es lo que está preguntando, me gustaría señalar que se considera una buena práctica obtener .bashrc de .bash_profile . De esa manera, la configuración de .bashrc se aplicará independientemente de si bash se inicia como un shell de inicio de sesión o un shell sin inicio de sesión.
Ilmari Karonen

Respuestas:

44

Primero se lee un shell de inicio de sesión /etc/profiley luego ~/.bash_profile.

Un shell sin inicio de sesión lee desde /etc/bash.bashrcy luego ~/.bashrc.

¿Por qué es eso importante?

Debido a esta línea en man ssh:

Si se especifica el comando , se ejecuta en el host remoto en lugar de un shell de inicio de sesión.

En otras palabras, si el comando ssh solo tiene opciones (no un comando), como:

ssh user@host

Se iniciará un shell de inicio de sesión, se lee un shell de inicio de sesión ~/.bash_profile.

Un comando ssh que tiene un comando , como:

ssh user@host :

Donde está el comando :(o no hacer nada).
Será no abrir una shell de inicio de sesión, por lo tanto, ~/.bashrces lo que va a ser leído.


Remolino estándar

La conexión tty suministrada para / dev / stdin en la computadora remota puede ser un tty real o algo más.

Por:

$ 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

Que termina en un TTY (no una conexión de red) como lo ve el bash iniciado.

Para una conexión ssh con un comando:

$ 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 lista de TTY comienza igual, pero tenga en cuenta que / etc / profile no se obtuvo.

$ 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]

Lo que le dice al shell que la conexión es una tubería (no una conexión de red).

Entonces, en ambos casos de prueba, el shell no puede saber que la conexión es de una red y, por lo tanto, no lee ~/.bashrc(si solo hablamos de la conexión a una red). Se lee ~ / .bashrc, pero por una razón diferente.

sorontar
fuente
¿No calificaría también el caso sin argumentos que se ejecuta con su entrada estándar conectada a una conexión de red y, por lo tanto, ha ~/.bashrcleído?
Cyker
@Cyker Eso supone que el shell tendrá el stdin conectado a una red . Por qué asumes eso ? (Respuesta editada, por favor lea).
sorontar
La parte editada es interesante. Parece que ssh no se molesta con una pty cuando simplemente ejecuta un comando.
Cyker
8

Preguntas sobre el "por qué", no el "cómo", así que intentaré responder desde esa perspectiva. Lo siguiente será una buena razón de por qué las cosas sucedieron en el pasado para resultar en cómo suceden hoy.


La razón para tener dos archivos de inicio diferentes ("perfil" y "rc") es que en el pasado la forma común de trabajar en una máquina era:

  1. Inicie sesión desde algún tipo de terminal real u otra estación de trabajo y obtenga un shell de inicio de sesión . Este shell invocará /etc/profiley ~/.profileconfigurará el entorno para el usuario.

  2. Invoque el entorno en el que el usuario desea ingresar. Este entorno podría ser Xorg, pero en la mayoría de los casos era un multiplexor como la pantalla GNU.

  3. El entorno (por ejemplo, la pantalla GNU) invocaría shells adicionales (sin inicio de sesión) que heredan el entorno del shell de inicio de sesión principal.

Esa era la forma común de iniciar sesión en una máquina UNIX durante el tiempo en que cshy bashse estaban desarrollando. Por lo~/.profile tanto , se consideró un desperdicio leer de nuevo en los depósitos que heredaban el medio ambiente de todos modos.

bashluego se agregó ~/.bashrcpara una configuración adicional para estos shells sin inicio de sesión. csh(y tcsh) nunca agregó ningún tipo de archivo "rc" para shells sin inicio de sesión. Tenga en cuenta que csh/ tcshno son shells compatibles con el bourne shell (que es parte de POSIX) mientras lo bashsea. Otro shell compatible con bourne ksh, agregó una variable de entorno (llamada ENV) que, si se definiera, se usaría como un archivo de comandos de ejecución ("rc") para no iniciar sesión ksh.

Entonces, sí, las versiones más recientes de los bourne shells agregaron el archivo de configuración adicional como una conveniencia para los alias y otras opciones rápidas que estarían presentes dentro de los shells muxed por la pantalla GNU (o similar) pero no presentes en el shell que obtienes cuando ingresas por primera vez máquina.

Con el aumento de los administradores de pantallas gráficas (GDM), la diferenciación entre los archivos "perfil" y "rc" dejó de tener sentido porque el GDM tendría sus propios archivos de inicialización (por ejemplo, ~/.xinity ~/.xsession). Luego, los shells declarados desde el interior del GDM podrían ser shells de inicio de sesión o de no inicio de sesión, dependiendo de los caprichos de un usuario, y el caso en el que un shell de no inicio de sesión siempre tendría un padre que es un shell de inicio de sesión ya no es cierto.

Extra

Una de mis tablas favoritas sobre la comparación de archivos de inicio de shell muestra cómo los shells compatibles con bourne shell usan los profilearchivos mientras que otros shells no. Esto se debe a que en el pasado el shell inicial (el que inició el muxer) necesitaba ser un shell compatible con bourne.

grochmal
fuente