In Linux und meines Wissens nach allen Unix-Systemen führen Terminalemulatoren standardmäßig interaktive Shells ohne Anmeldung aus. Das bedeutet, dass die gestartete Shell für Bash:
Wenn eine interaktive Shell gestartet wird, die keine Login-Shell ist, liest bash Befehle aus /etc/bash.bashrc
und führt sie aus und ~/.bashrc
, falls diese Dateien vorhanden sind. Dies kann durch die Verwendung von --norc
verhindert werden Option.
Die --rcfile
Die file-Option zwingt Bash dazu, Befehle aus der Datei statt aus /etc/bash.bashrc
zu lesen und auszuführen und ~/.bashrc
.
Und für Login-Shells:
Wenn bash als interaktive Login-Shell oder als nicht interaktive Shell mit --login
aufgerufen wird Option liest es zuerst Befehle aus der Datei /etc/profile
und führt sie aus , wenn diese Datei existiert. Nach dem Lesen dieser Datei sucht es nach ~/.bash_profile
, ~/.bash_login
, und ~/.profile
, in dieser Reihenfolge, und liest und führt Befehle aus dem ersten Befehl aus, der vorhanden und lesbar ist.
Der --noprofile
Option kann verwendet werden, wenn die Shell gestartet wird, um dieses Verhalten zu verhindern.
Unter OSX liefert die Standard-Shell (die bash ist), die im Standard-Terminal (Terminal.app) gestartet wird, tatsächlich ~/.bash_profile
oder ~.profile
usw. Mit anderen Worten, es verhält sich wie eine Login-Shell.
Hauptfrage :Warum ist die standardmäßige interaktive Shell eine Login-Shell unter OSX? Warum hat sich OSX dafür entschieden? Das bedeutet, dass alle Anweisungen/Tutorials für Shell-basierte Dinge, die Änderungen in ~/.bashrc
erwähnen schlägt unter OSX fehl oder umgekehrt für ~/.profile
. Auch wenn viele Anschuldigungen gegen Apple erhoben werden können, gehört die Einstellung inkompetenter oder idiotischer Entwickler nicht dazu. Vermutlich hatten sie dafür einen guten Grund, warum also?
Unterfragen:Führt Terminal.app tatsächlich eine interaktive Login-Shell aus oder haben sie das Verhalten von bash geändert? Ist dies spezifisch für Terminal.app oder unabhängig vom Terminal-Emulator?
Akzeptierte Antwort:
So wie es angeblich ist Arbeit ist, dass an dem Punkt, an dem Sie einen Shell-Prompt erhalten, sowohl .profile
und .bashrc
gelaufen sind. Die genauen Details, wie Sie zu diesem Punkt gelangen, sind von untergeordneter Bedeutung, aber wenn eine der Dateien überhaupt nicht ausgeführt wird, haben Sie eine Shell mit unvollständigen Einstellungen.
Der Grund, warum Terminalemulatoren unter Linux (und anderen X-basierten Systemen) nicht benötigen um .profile
auszuführen selbst ist, dass es normalerweise bereits ausgeführt wurde, als Sie sich bei X angemeldet haben. Die Einstellungen in .profile
soll von der Art sein, die von Unterprozessen vererbt werden kann, solange sie einmal ausgeführt wird, wenn Sie sich anmelden (z. B. über .Xsession
), alle weiteren Subshells müssen es nicht erneut ausführen.
Wie die von Alan Shutko verlinkte Debian-Wiki-Seite erklärt:
„Warum ist .bashrc
eine separate Datei von .bash_profile
, dann? Dies geschieht hauptsächlich aus historischen Gründen, als Maschinen im Vergleich zu heutigen Workstations extrem langsam waren. Verarbeitung der Befehle in .profile
oder .bash_profile
könnte ziemlich lange dauern, besonders auf einer Maschine, auf der ein Großteil der Arbeit durch externe Befehle (Pre-Bash) erledigt werden musste. Daher werden die schwierigen anfänglichen Setup-Befehle, die Umgebungsvariablen erstellen, die an untergeordnete Prozesse weitergegeben werden können, in .bash_profile
eingefügt . Die vorübergehenden Einstellungen und Aliase, die nicht vererbt werden, werden in .bashrc
abgelegt damit sie von jeder Subshell neu gelesen werden können.“
Dieselben Regeln gelten auch für OSX, außer einer Sache – die OSX-GUI führt .profile
nicht aus wenn Sie sich anmelden, anscheinend weil es seine eigene Methode zum Laden globaler Einstellungen hat. Aber das bedeutet, dass ein Terminal-Emulator unter OSX es tut müssen .profile
ausführen (indem Sie der Shell, die sie startet, mitteilen, dass es sich um eine Login-Shell handelt), sonst würden Sie mit einer potenziell lahmgelegten Shell enden.
Nun, eine Art dumme Besonderheit von bash, die von den meisten anderen Shells nicht geteilt wird, ist, dass .bashrc
nicht automatisch ausgeführt wird wenn es als Login-Shell gestartet wird. Die Standardumgehung dafür besteht darin, so etwas wie die folgenden Befehle in .bash_profile
aufzunehmen :
[[ -e ~/.profile ]] && source ~/.profile # load generic profile settings
[[ -e ~/.bashrc ]] && source ~/.bashrc # load aliases etc.
Alternativ ist es möglich, kein .bash_profile
zu haben überhaupt, und fügen Sie einfach etwas Bash-spezifischen Code in das generische .profile
ein Datei zum Ausführen von .bashrc
bei Bedarf.
Wenn die OSX-Standardeinstellung .bash_profile
oder .profile
nicht tun, dann ist das wohl ein Fehler. In jedem Fall besteht die richtige Problemumgehung darin, diese Zeilen einfach zu .bash_profile
hinzuzufügen .
Bearbeiten: Wie strugee anmerkt, war die Standard-Shell auf OSX früher tcsh, deren Verhalten in dieser Hinsicht viel vernünftiger ist:Wenn sie als interaktive Login-Shell ausgeführt wird, liest tcsh automatisch sowohl .profile
und .tcshrc
/ .cshrc
, und benötigt daher keine Workarounds wie .bash_profile
Trick oben gezeigt.
Basierend darauf bin ich mir zu 99 % sicher, dass OSX kein geeignetes Standard-.bash_profile
bereitstellt liegt daran, dass die Leute bei Apple diese kleine Warze im Startverhalten von bash beim Wechsel von tcsh zu bash einfach nicht bemerkt haben. Mit tcsh waren solche Tricks nicht nötig – das Starten von tcsh als Login-Shell von einem OSX-Terminalemulator funktioniert einfach und macht das Richtige ohne solche Tricks.