En Linux y, que yo sepa, todos los sistemas Unix, emuladores de terminal ejecutan shells interactivos sin inicio de sesión de forma predeterminada. Esto significa que, para bash, el shell iniciado:
Cuando se inicia un shell interactivo que no es un shell de inicio de sesión, bash lee y ejecuta comandos desde
/etc/bash.bashrc
y~/.bashrc
, si existen estos archivos. Esto puede inhibirse mediante el uso de la--norc
opción.La
--rcfile
opción de archivo obligará a bash a leer y ejecutar comandos desde el archivo en lugar de/etc/bash.bashrc
y~/.bashrc
.
Y para los shells de inicio de sesión:
Cuando se invoca bash como un shell de inicio de sesión interactivo o como un shell no interactivo con la
--login
opción, primero lee y ejecuta comandos del archivo/etc/profile
, si ese archivo existe. Después de leer ese archivo, busca~/.bash_profile
,~/.bash_login
y~/.profile
, en ese orden, y lee y ejecuta órdenes desde el primero que existe y es legible.La
--noprofile
opción se puede usar cuando se inicia el shell para inhibir este comportamiento.
Sin embargo, en OSX, el shell predeterminado (que es bash) se inició en el terminal predeterminado (Terminal.app) en realidad fuentes ~/.bash_profile
o ~.profile
etc. En otras palabras, actúa como un shell de inicio de sesión.
Pregunta principal : ¿Por qué el shell interactivo predeterminado es un shell de inicio de sesión en OSX? ¿Por qué OSX eligió hacer esto? Esto significa que todas las instrucciones / tutoriales para cosas basadas en shell que mencionan cambios en las cosas ~/.bashrc
fallarán en OSX o viceversa ~/.profile
. Aún así, si bien muchas acusaciones pueden dirigirse a Apple, contratar desarrolladores incompetentes o idiotas no es una de ellas. Presumiblemente, tenían una buena razón para esto, entonces, ¿por qué?
Preguntas: ¿Terminal.app realmente ejecuta un shell de inicio de sesión interactivo o ha cambiado el comportamiento de bash? ¿Es esto específico para Terminal.app o es independiente del emulador de terminal?
Respuestas:
La forma en que se supone que el trabajo es que, en el momento en que obtener pronta una concha, tanto
.profile
y.bashrc
se han ejecutado. Los detalles específicos de cómo llegar a ese punto son de relevancia secundaria, pero si alguno de los archivos no se ejecuta en absoluto, tendría un shell con configuraciones incompletas.La razón por la que los emuladores de terminal en Linux (y otros sistemas basados en X) no necesitan ejecutarse
.profile
ellos mismos es que normalmente ya se habrán ejecutado cuando iniciaste sesión en X. Se.profile
supone que la configuración en es del tipo que puede ser heredado por subprocesos, por lo tanto, siempre y cuando se ejecute una vez cuando inicie sesión (por ejemplo, a través de.Xsession
), no será necesario volver a ejecutar más subcapas.Como explica la página wiki de Debian vinculada por Alan Shutko:
Las mismas reglas también se aplican a OSX, excepto por una cosa: la GUI de OSX no se ejecuta
.profile
al iniciar sesión, aparentemente porque tiene su propio método para cargar la configuración global. Pero eso significa que un emulador de terminal en OSX hace que tenga que ejecutar.profile
(contando la concha de su lanzamiento que es un intérprete de ingreso), de lo contrario acabaría con una cáscara potencialmente lisiado.Ahora, una especie de peculiaridad tonta de bash, no compartida por la mayoría de los otros shells, es que no se ejecutará automáticamente
.bashrc
si se inicia como un shell de inicio de sesión. La solución estándar para eso es incluir algo como los siguientes comandos en.bash_profile
:Alternativamente, es posible no tener ninguno
.bash_profile
, y solo incluir algún código específico de bash en el.profile
archivo genérico para ejecutar.bashrc
si es necesario.Si el OSX predeterminado
.bash_profile
o.profile
no hace esto, entonces eso podría decirse que es un error. En cualquier caso, la solución adecuada es simplemente agregar esas líneas.bash_profile
.Editar: como señala Strugee , el shell predeterminado en OSX solía ser tcsh, cuyo comportamiento es mucho más sensato a este respecto: cuando se ejecuta como un shell de inicio de sesión interactivo, tcsh lee automáticamente ambos
.profile
y.tcshrc
/.cshrc
, y por lo tanto no necesita soluciones alternativas como el.bash_profile
truco mostrado anteriormente.En base a esto, estoy 99% seguro de que la falla de OSX para proporcionar un valor predeterminado apropiado
.bash_profile
es porque, cuando cambiaron de tcsh a bash, la gente de Apple simplemente no notó esta pequeña verruga en el comportamiento de inicio de bash. Con tcsh, no se necesitaban tales trucos: iniciar tcsh como un shell de inicio de sesión desde un emulador de terminal OSX Just Plain Works y hace lo correcto sin tales problemas.fuente
.bashrc
irrelevante? ¿Por qué eligieron hacer que todos los shells inicien sesión? Por lo que puedo decir, solo su última oración aborda eso y solo para decir que es un error..profile
cuando el usuario inicia sesión en la GUI, por lo que debe ejecutarlo más tarde para obtener variables de entorno como$PATH
, que normalmente están configuradas.profile
, configuradas correctamente . El hecho de que, como efecto secundario, esto hace que.bashrc
no se origine es un error; puede discutir si se trata de un error en bash o en OSX, pero eso no cambia el hecho de que el comportamiento correcto sería garantizar que se carguen tanto las variables de entorno.profile
como la configuración de configuración de bash.bashrc
..bashrc
fuente.profile
sería una mala idea, ya que haría que cada subshell se volviera a ejecutar.profile
. Por lo menos, esto causaría.profile
modismos comunes comoexport PATH = "$HOME/bin:$PATH"
seguir anteponiendo entradas redundantes$PATH
. Tener.profile
fuente.bashrc
tiene mucho más sentido, pero solo después de verificar que el shell bajo el que se ejecuta es, de hecho, bash. Tener la.bash_profile
fuente de ambos.profile
y.bashrc
, como sugerí anteriormente, es, en mi opinión, la opción más sensata..profile
", mientras que la respuesta a "¿Por qué no la fuente.bashrc
de la.profile
, entonces?" es "porque es un error!" En serio, eso no puede ser una decisión intencional; es simplemente algo que pasaron por alto, presumiblemente porque, en el ecosistema de Mac, los shells son ciudadanos de segunda clase con los que la mayoría de los usuarios no deben lidiar. (Sal. Véase también la respuesta de Strugee para una explicación histórica; es casi seguro que es una regresión del cambio de tcsh a bash.)La razón principal por la que las aplicaciones de terminal X ejecutan shells sin inicio de sesión de forma predeterminada es que al principio de su tiempo, su .Xsession habría ejecutado el .profile para configurar sus elementos de inicio de sesión iniciales. Luego, dado que todo ya estaba configurado, las aplicaciones de terminal no necesitaban ejecutarlo, podían ejecutar el .bashrc. La discusión de por qué esto sería importante está en https://wiki.debian.org/DotFiles :
En OS X, los entornos de usuario no se inician con una pila de scripts de shell, y launchd no obtiene .profile en ningún momento. (Es una lástima, ya que significa que es mucho más molesto establecer variables de entorno, pero así es la vida). Dado que no es así, ¿cuándo se ejecutará .profile? ¿Solo si entraste? Eso parece un poco inútil, ya que muchas cajas nunca serán objetivos de ssh. También podría hacer que los terminales ejecuten shells de inicio de sesión de forma predeterminada, de modo que .profile se ejecute en algún momento.
¿Qué hay de .bashrc, entonces? ¿Es inútil? No. Todavía tiene el propósito que tenía en los días del VT100. Se usa para cualquier momento que abra un shell que no sea abrir una ventana de Terminal. Entonces, si sale de Emacs o vi, o si hace un usuario su.
fuente
.profile
fuentes de Debian.bashrc
, no por qué OSX decidió hacer que todos los shells inicien sesión por defecto. En realidad, estás respondiendo otra pregunta mía , ¡y gracias! Sin embargo, su respuesta no explica la elección de OSX y la cita de Debian es completamente irrelevante aquí hasta donde puedo decir (por favor avíseme si me estoy perdiendo el punto). La forma OSX hace que.bashrc
etc. sea inútil y no lo hace.profile
más útil.No sé por qué habrían hecho eso. Sin embargo, aquí está mi suposición.
Para empezar, vale la pena señalar que en un sistema GNU / Linux, por supuesto, puede cambiar a vt1, vt2, etc. Obtendrá un shell de inicio de sesión allí. En un sistema OS X, no hay equivalente. La única forma de acceder a las bases de UNIX es a través de un emulador de terminal o mediante el modo de usuario único (descargo de responsabilidad: en realidad nunca he usado el modo de usuario único; es IIRC impulsado por línea de comandos, pero puedo estar equivocado). Por lo tanto, en OS X, el valor predeterminado en el emulador es el predeterminado para todo el sistema.
Ahora, ¿por qué haría que el valor predeterminado sea un shell de inicio de sesión? Hay un par de razones (léase: no muchas) en las que puedo pensar para hacer esto.
tcsh
. Esto es una suposición tan descabellada como puede ser, pero puede ser quetcsh
normalmente hiciera algo cuando se ejecutaba como un shell de inicio de sesión y el patrón histórico se atascara. (Sin embargo, lo dudo, tal vez uno de los clientes habituales más antiguos podría decirnos).Honestamente, he estado usando Darwin durante ~ 6 años y no puedo responder esta pregunta correctamente. Realmente tampoco tiene sentido para mí.
Para responder a su pregunta,
bash
no está parcheado ni nada (al menos para esto). El emulador de terminal predeterminado ejecuta shells de inicio de sesión de forma predeterminada, y presumiblemente iTerm lo copia.fuente
.profile
y.tcshrc
/ o.cshrc
no requiere ningún tipo de kluges como el que di en mi respuesta. Dado eso, sospecho que este comportamiento es una regresión no fija causada por el cambio de tcsh a bash..login
y.tcshrc
/.cshrc
? No tendría sentido que tcsh se originara.profile
; Por lo general, contiene comandos consh
sintaxis quetcsh
no acepta. No tengo macOS pero hice/bin/tcsh
mi shell de inicio de sesión en Ubuntu 16.04..profile
No es de origen. tcsh (1) no menciona ese archivo, ni este tcsh (1) .Esta es una actualización del estado actual: las respuestas se han vuelto obsoletas a medida que se lanzan nuevas versiones de MacOSX y el comportamiento de inicio de sesión ha cambiado.
Esta pregunta fue formulada y respondida en 2014. He estado investigando el tema en un intento de crear un conjunto común .bashrc & .bash_profile para usar en diferentes distribuciones de Linux y BSD (como se llame si no son distribuciones).
Recientemente compré una Mac Mini usada con Sierra instalada, por lo que ahora tengo sistemas con 10.6, 10.10, 10.11 y 10.12. Aunque he manipulado a los más antiguos (dejando pistas sobre su estado anterior), la instalación de Sierra 10.12 no ha sido tocada.
Resultados: en 10.12 Sierra, NO hay .bashrc, .bash_profile o .profile predeterminados creados. En / etc, hay bashrc, bashrc_Apple_Terminal y profile. Contenido de / etc / profile:
Contenido de / etc / bashrc:
El script / etc / bashrc_Apple_Terminal establece la variable PROMPT_COMMAND y configura un mecanismo para preservar el estado de la sesión para cada terminal; si se cierra la aplicación de terminal, el estado de la sesión anterior se restaura cuando la aplicación se inicia nuevamente. De lo contrario, casi nada (mínimo $ PS1) se establece en / etc / bashrc, dejando cualquier otra personalización ($ PS1 real, alias, funciones) para configurar en ~ / .bashrc y $ PATH en .bash_profile (o en .profile , originado por .bash_profile).
He confirmado que iTerm2 se comporta de la misma manera que la aplicación Terminal, excepto que el comportamiento predeterminado de iniciar una sesión de inicio de sesión es visible y se puede editar.
Si ejecuta una sesión de terminal XTerm X11 (ahora XQuartz), verá una sesión sin inicio de sesión, igual que en un sistema Linux; .bash_profile (o .profile) se omite y solo obtiene .bashrc.
Y aquí está mi respuesta:
Aunque la aplicación Terminal afirma ser un xterm (TERM = xterm-256color), no establece la variable $ DISPLAY a menos que se instale X11. Estamos viendo una simulación de un entorno X, pero no completamente real. Si ingresa SSH a otro sistema con el interruptor -X (habilite el reenvío X11), fallará porque no hay una variable $ DISPLAY. Si ha instalado X11, luego SSH en otro sistema, el reenvío X11 tendrá éxito.
En pocas palabras (y respuesta breve): la aplicación Terminal no es una verdadera terminal X11 (no establece $ DISPLAY); se comporta mucho más como un inicio de sesión SSH que una sesión XTerm, ya que tiene que ser una sesión de inicio de sesión para establecer valores desde / etc / profile y ~ / .bash_profile o ~ / .profile
fuente
Las respuestas anteriores explicaron la razón por la cual los shells interactivos son shells de inicio de sesión en macOS de forma predeterminada: la configuración en
/etc/profile
,~/.profile
es heredada por un shell sin inicio de sesión en sistemas basados en X, pero no en macOS . Aquí quiero recordarle que siempre debe usar el shell de inicio de sesión en macOS debido a la existencia depath_helper
:Si está utilizando un shell sin inicio de sesión, algunas rutas no se importarán.
Creo que siempre es una buena idea que el desarrollador coloque un archivo
/etc/paths.d
para importar sus valores de ruta, pero no para vincular los archivos binarios invocables en ubicaciones como/usr/bin
o/bin
. (El valor predeterminadoPATH
es/usr/bin:/bin:/usr/sbin:/sbin
. No todos usan Homebrew o MacPorts agregando valores personalizadosPATH
. Por lo tanto, no siempre hay un lugar seguro para colocar los enlaces simbólicos de los comandos invocables).Aquí hay un ejemplo de archivos en
/etc/paths.d
. Básicamente estás poniendo un valor en cada línea.Referencia:
man path_helper
fuente