Auswahl zwischen .bashrc, .profile, .bash_profile usw. [duplizieren]

197

Diese Frage hat hier bereits eine Antwort:

Das ist peinlich, aber nach vielen Jahren der POSIX - Systemen voll in Betrieb nehmen , ich habe noch eine harte Zeit , herauszufinden , ob eine Shell - Anpassung in gehen sollte .bashrc, .profileoder irgendwo anders. Ganz zu schweigen von einigen betriebssystemspezifischen Konfigurationsdateien wie .pam_environment.

Ja, ich kann durch die Dokumentation rätseln und lernen, wann jede Datei geladen ist oder nicht. Ich frage mich, ob jemand umfassende Richtlinien zusammengestellt hat, um zu entscheiden, in welche Datei eine bestimmte Art von Anpassung eingefügt werden soll.

Avdi
quelle
6
Diese Frage sollte nicht als Duplikat markiert werden. Der Grund dafür ist, dass .profile in der hinzugefügten Frage nicht verfügbar ist.
Premraj
Antwort
Premraj,

Antworten:

222

TL; DR:

  • ~/.bash_profilesollte super einfach sein und nur laden .profileund .bashrc(in dieser Reihenfolge)

  • ~/.profileHat das Zeug NICHT speziell mit Bash zu tun, wie Umgebungsvariablen ( PATHund Freunde)

  • ~/.bashrchat alles, was Sie an einer interaktiven Befehlszeile wollen. Eingabeaufforderung, EDITORVariable, Bash-Aliase für meine Verwendung

Ein paar andere Anmerkungen:

  • Alles, was für grafische Anwendungen verfügbar sein oder als sh (oder bash aufgerufen werden soll sh), MUSS enthalten sein~/.profile

  • ~/.bashrc darf nichts ausgeben

  • Alles, was nur für Login-Shells verfügbar sein sollte, sollte rein ~/.profile

  • Stellen Sie sicher, dass ~/.bash_logindas nicht vorhanden ist.

Dan Rabinowitz
quelle
3
+1, dies ermöglicht ~/.profiledie korrekte Einstellung der Umgebung für Dienste wie GDM / LightDM / LXDM, die explizit / bin / sh ausführen.
Grawity
12
Meine .bashrcAusgaben ziemlich viel Zeug, kannst du das kommentieren? Wo soll ich die Begrüßungsausgabe platzieren?
Calimo
14
@Calimo: Legt fest, dass nur Inhalte im interaktiven Modus ausgegeben werden. Sie können es testen, indem Sie [[ $- == *i* ]]in der speziellen $-Variablen nach 'i' suchen . Auf Systemen, auf denen bash kompiliert wurde, um .bashrcim nicht interaktiven Modus zu lesen, ist dies natürlich nur von Bedeutung . (Das heißt, Debian , aber nicht Arch.) Aber es ist eine häufige Ursache für mysteriöse Fehlermeldungen bei der Verwendung zu versuchen , eine Verbindung sftpoder scpoder ähnliche Werkzeuge.
Grawity
4
Jetzt muss ich wissen, warum .bash_login nicht existieren sollte. Was tut es?
Tedder42
11
@ tedder42: Es macht das gleiche wie .bash_profileund .profile. Aber bash liest nur den ersten von drei. Das heißt, wenn Sie eine haben .bash_login, dann werden beide .profileund .bash_profileauf mysteriöse Weise ignoriert.
Grawity
54

In den letzten Jahren hatte ich viel Zeit zu verschwenden und habe dies für etwas mehr als nur 10 Minuten recherchiert. Ich habe keine Ahnung, ob dies das beste Layout ist, es ist nur eines, das in fast allen Fällen richtig funktioniert.

Die Anforderungen:

  • ~/.profile muss mit jedem / bin / sh kompatibel sein - dies schließt bash, dash, ksh und alles andere ein, was eine Distribution sonst noch verwenden möchte.

  • Umgebungsvariablen müssen in einer Datei abgelegt werden, die sowohl von Konsolenanmeldungen (dh einer 'Login'-Shell) als auch von grafischen Anmeldungen (dh Display-Managern wie GDM, LightDM oder LXDM) gelesen wird.

  • Es gibt sehr wenig Sinn, die beide ~/.profile und ~/.bash_profile. Wenn letzteres fehlt, verwendet bash gerne das erstere, und alle bashspezifischen Zeilen können mit einem Check für $BASHoder geschützt werden $BASH_VERSION.

  • Die Trennung zwischen *profileund *rcbesteht darin, dass ersteres für 'Login'-Shells verwendet wird und letzteres jedes Mal, wenn Sie ein Terminalfenster öffnen. Bash im Anmeldemodus wird jedoch nicht als Quelle verwendet ~/.bashrcund muss daher ~/.profilemanuell ausgeführt werden.

Die einfachste Konfiguration wäre:

  • Haben Sie ein ~/.profile, das alle Umgebungsvariablen (außer bash-spezifischen) festlegt, vielleicht ein oder zwei Zeilen ausgibt, dann Quellen, ~/.bashrcwenn es von bash ausgeführt wird, und ansonsten die sh-kompatible Syntax beibehalten.

    export TZ = "Europa / Paris"
    export EDITOR = "vim"
    if ["$ BASH"]; dann
        . ~ / .bashrc
    fi
    Betriebszeit
    
  • Haben Sie eine ~/.bashrc, die alle Shell-spezifischen Setups ausführt, mit einer Prüfung für den interaktiven Modus , um zu vermeiden, dass Dinge wie sftpunter Debian beschädigt werden (wobei Bash mit der Option kompiliert wird, ~/.bashrcauch für nicht interaktive Shells zu laden ):

    [[$ - == * i *]] || 0 zurückgeben
    
    PS1 = '\ h \ w \ $'
    
    start () {sudo service "$ 1" start; }
    

Es gibt jedoch auch das Problem, dass bestimmte nicht interaktive Befehle (z. B. ssh <host> ls) übersprungen werden ~/.profile, aber Umgebungsvariablen für sie sehr nützlich wären.

  • Bestimmte Distributionen (z. B. Debian) kompilieren ihre Bash mit der Option, Quellen ~/.bashrcfür solche nicht interaktiven Logins anzugeben. In diesem Fall hat es sich als nützlich erwiesen, alle Umgebungsvariablen (die export ...Zeilen) in eine separate Datei zu verschieben ~/.environund aus beiden Quellen .profileund .bashrcmit einem Schutz zu extrahieren, um zu vermeiden, dass dies zweimal geschieht:

    wenn ! ["$ PREFIX"]; dann    # oder $ EDITOR oder TZ $, oder ... 
        . ~ / .environ            # im Allgemeinen jede Variable, die .environ selbst festlegen würde
    fi
    
  • Leider habe ich für andere Distributionen (zB Arch) keine sehr gute Lösung gefunden. Eine Möglichkeit besteht darin, das (standardmäßig aktivierte) PAM-Modul pam_env zu verwenden, indem Sie Folgendes eingeben ~/.pam_environment:

    BASH_ENV =. /. Environ         # kein Tippfehler; Es muss ein Pfad sein, aber ~ wird nicht funktionieren
    

    Dann natürlich aktualisieren ~/.environauf unset BASH_ENV.


Fazit? Muscheln sind ein Schmerz. Umgebungsvariablen sind ein Schmerz. Distributionsspezifische Optionen zur Kompilierungszeit sind ein großes Ärgernis.

Grawity
quelle
2
+1 für den letzten Absatz, aber ich bevorzuge Sourcing .profileund .bashrcvon .bash_profileund .profilesauber zu halten .
Nyuszika7h
@ nyuszika7h: Meine .profile ist sauber , danke.
Grawity
1
Notieren Sie sich den Kommentar erneut jedes Mal , wenn ein Fenster geöffnet ist umgekehrt für OSX
Mark
1
"Es hat wenig Sinn, beides zu haben ~/.profileund ~/.bash_profile": Ich bin anderer Meinung. Siehe Dans Antwort für das Warum.
Rubenvb
@rubenvb Kannst du das relevante Teil zitieren? Ich finde es in Ordnung, nur einen zu haben .profileund die bash-spezifischen Teile mit Auflagen zu bewachen .
Kelvin
36

Schauen Sie sich diesen ausgezeichneten Blog-Beitrag von ShreevatsaR an . Hier ist ein Auszug, aber gehen Sie zum Blog-Beitrag, der eine Erklärung für Begriffe wie "Login-Shell", ein Flussdiagramm und eine ähnliche Tabelle für Zsh enthält.

Für Bash arbeiten sie wie folgt. Lesen Sie die entsprechende Spalte. Führt A, dann B, dann C usw. aus. B1, B2, B3 bedeutet, dass nur die erste der gefundenen Dateien ausgeführt wird.

+----------------+-----------+-----------+------+
|                |Interactive|Interactive|Script|
|                |login      |non-login  |      |
+----------------+-----------+-----------+------+
|/etc/profile    |   A       |           |      |
+----------------+-----------+-----------+------+
|/etc/bash.bashrc|           |    A      |      |
+----------------+-----------+-----------+------+
|~/.bashrc       |           |    B      |      |
+----------------+-----------+-----------+------+
|~/.bash_profile |   B1      |           |      |
+----------------+-----------+-----------+------+
|~/.bash_login   |   B2      |           |      |
+----------------+-----------+-----------+------+
|~/.profile      |   B3      |           |      |
+----------------+-----------+-----------+------+
|BASH_ENV        |           |           |  A   |
+----------------+-----------+-----------+------+
|                |           |           |      |
+----------------+-----------+-----------+------+
|                |           |           |      |
+----------------+-----------+-----------+------+
|~/.bash_logout  |    C      |           |      |
+----------------+-----------+-----------+------+
Flimm
quelle
Das ist nett. Es ist wichtig zu beachten, dass in der Regel /etc/profileAnrufe /etc/bash.bashrcund ~/.profileAnrufe ~.bashrc. So effektiv /etc/bash.bashrcund ~/.bashrcwerden auch für Interactive Logins ausgeführt.
wisbucky
Beachten Sie, dass einige Distributionen scheinen diese Regelung außer Kraft zu setzen (mit seltsamen Folgen) - siehe zum Beispiel meines bugreport opensuse hier: bugzilla.opensuse.org/show_bug.cgi?id=1078124
Christian Herenz
Btw. Zumindest mit Bash wird keine dieser Dateien ausgeführt, wenn die Bash über/bin/sh
JepZ
@JepZ Du hast recht, das wird in der dritten Spalte "Skript" erklärt.
Flimm
1
@Flimm Nun, die Spalte 'Script' beschreibt, was passiert, wenn Sie ein nicht interaktives Script über Bash starten (zB / bin / bash). Wenn Sie jedoch ein Skript über sh starten (und / bin / sh ein Symlink zu / bin / bash ist), wird keine der oben genannten Aktionen ausgeführt (nicht einmal BASH_ENV). Der zugehörige Absatz der Bash-Manpage kann durch Suchen nach gefunden werden If bash is invoked with the name sh.
JepZ
21

Ich biete Ihnen meine "umfassenden" Richtlinien an:

  • Machen Sie .bash_profileund .profileladen .bashrcSie, wenn es existiert, mit z [ -r $HOME/.bashrc ] && source $HOME/.bashrc
  • Alles andere reinstecken .bashrc.
  • Hör auf dir Sorgen zu machen.
  • Erforschen Sie diese Frage ungefähr alle vier Jahre zehn Minuten lang, bevor Sie aufgeben und sich wieder "keine Sorgen machen".

BEARBEITEN: Erschreckende Anführungszeichen zu "umfassend" hinzugefügt, nur für den Fall, dass jemand versucht ist, es zu glauben. ;)

Mechanischer Fisch
quelle
3
Beides zu haben .bash_profileund .profileist ein bisschen überflüssig; du brauchst nur letzteres. Sie müssen es jedoch / bin / sh-proof machen, if [ "$BASH" ] && [ -r ~/.bashrc ]; then . ~/.bashrc; fida es Programme (nämlich gdm / lightdm) gibt, die die Datei manuell aus einem / bin / sh-Skript beziehen. Dies bedeutet auch, dass die Umgebung, in .bashrcder wir uns befinden, unwirksam wäre. Musste -1, da deine "umfassenden" Richtlinien auf vielen Systemen nicht funktionieren, wie ich mehrmals auf die harte Tour herausgefunden hatte.
Grawity
Kein Problem, ich bezahle gerne eine -1 für eine Antwort, die nicht nur "umfassend" ist, und Sie haben sich diesen Titel mit Sicherheit verdient.
Mechanical Fish
0

Ich habe es aufgegeben, dies herauszufinden und ein Skript ( ~/.shell-setup) erstellt, das ich von allen anderen Quellen beziehe.

Dieser Ansatz erfordert ~/.shell-setupzwei Funktionen:

  1. Nur einmal ausführen, auch bei wiederholtem Bezug ( Include-Guards verwenden )
  2. Keine unerwünschte Ausgabe erzeugen (erkennen, wenn die Ausgabe in Ordnung ist)

# 1 ist ein ziemlich normaler Standard, obwohl er in Shell-Skripten möglicherweise nicht häufig verwendet wird.

# 2 ist schwieriger. Folgendes verwende ich in bash:

if [ "" == "$BASH_EXECUTION_STRING" -a "" == "$DESKTOP_SESSION" ]; then
    echo "Hello user!" # ... etc
fi

Leider kann ich mich nicht erinnern, wie ich darauf gekommen bin oder warum das Erkennen einer interaktiven Shell nicht ausreichte.

ShadSterling
quelle
-2

Setzen Sie alles in .bashrcund dann Quelle .bashrcaus.profile

Von der Bash-Manpage (unter OS X 10.9):

Wenn eine interaktive Shell gestartet wird, die keine Anmeldeshell ist, liest bash Befehle von ~ / .bashrc und führt sie aus, sofern diese Datei vorhanden ist. Dies kann mit der Option --norc verhindert werden. Die Option --rcfile file erzwingt, dass Bash anstelle von ~ / .bashrc Befehle aus der Datei liest und ausführt

Der obige Text ist, warum alles eingegeben wird .bashrc. Es gibt jedoch ein etwas anderes Verhalten, wenn Sie mit einer Anmeldeshell arbeiten. Nochmals ein Zitat aus der Manpage:

Wenn bash als interaktive Anmeldeshell oder als nicht interaktive Shell mit der Option --login aufgerufen wird, werden zuerst Befehle aus der Datei / etc / profile gelesen und ausgeführt, sofern diese Datei vorhanden ist. Nach dem Lesen dieser Datei sucht sie in dieser Reihenfolge nach ~ / .bash_profile, ~ / .bash_login und ~ / .profile und liest und führt Befehle von der ersten Datei aus, die vorhanden und lesbar ist. Die Option --noprofile kann verwendet werden, wenn die Shell gestartet wird, um dieses Verhalten zu unterbinden.

.profilewird für Login-Shells gelesen, ist es aber .bashrcnicht. Das Duplizieren all dieser Inhalte .bashrcist schlecht, so dass wir sie als Quelle verwenden .profilemüssen, damit das Verhalten konsistent bleibt.

Sie möchten jedoch nicht unbedingt .bashrcvon .profilebeziehen. Weitere Informationen finden Sie in den Kommentaren und anderen Antworten.

Matratze
quelle
4
-1, KEINE Quelle .bashrcvon .profile. Siehe @ DanRabinowitz Antwort.
Nyuszika7h
Zumindest nicht unbedingt.
Nyuszika7h
[ -n "$BASH" -a -f ~/.bashrc ] && . ~/.bashrcwäre ein süßer oneliner für .profile.
John WH Smith
@ Nyuszika7h, warum nicht? Jeder scheint dies zu empfehlen.
Pacerier