Warum wird ~ / .bash_profile beim Öffnen eines Terminals nicht ermittelt?

175

Problem

Ich habe eine virtuelle Ubuntu 11.04-Maschine und wollte meine Java-Entwicklungsumgebung einrichten. Ich habe folgendes getan

  1. sudo apt-get install openjdk-6-jdk
  2. Die folgenden Einträge wurden zu ~ / .bash_profile hinzugefügt

    export JAVA_HOME=/usr/lib/jvm/java-6-openjdk
    
    export PATH=$PATH:$JAVA_HOME/bin
  3. Speichern Sie die Änderungen und beenden Sie das Programm

  4. Öffnen Sie erneut ein Terminal und geben Sie Folgendes ein

    echo $JAVA_HOME   (blank)
    echo $PATH        (displayed, but not the JAVA_HOME value)
  5. Es ist nichts passiert, als ob der Export von JAVA_HOME und seiner Hinzufügung zum PATH niemals durchgeführt worden wäre.

Lösung

Ich musste zu ~ / .bashrc gehen und den folgenden Eintrag gegen Ende der Datei hinzufügen

#Source bash_profile to set JAVA_HOME and add it to the PATH because for some reason is not being picked up
. ~/.bash_profile

Fragen

  1. Warum musste ich das tun? Ich dachte, bash_profile, bash_login oder profile in Abwesenheit dieser beiden werden zuerst vor bashrc ausgeführt.
  2. War in diesem Fall mein Terminal eine Nicht-Login- Shell?
  3. Wenn ja, warum führte su nach dem Terminal und dem Einfügen des Passworts kein Profil aus, bei dem ich auch die oben genannten Exporte eingestellt hatte?
Viriato
quelle

Antworten:

224

~/.bash_profilewird nur von bash bezogen, wenn es im interaktiven Anmeldemodus gestartet wird. Dies ist normalerweise nur der Fall, wenn Sie sich an der Konsole anmelden ( Ctrl+ Alt+ F1.. F6) oder eine Verbindung über ssh herstellen.

Wenn Sie sich grafisch anmelden, ~/.profilewird dies speziell von dem Skript ausgeführt, das die Gnome-Sitzung startet (oder von der Desktop-Umgebung, die Sie verwenden). Wird ~/.bash_profilealso überhaupt nicht bezogen, wenn Sie sich grafisch anmelden.

Wenn Sie ein Terminal öffnen, startet das Terminal die Bash im interaktiven Modus (ohne Anmeldung) ~/.bashrc.

Der richtige Ort, an dem Sie diese Umgebungsvariablen ablegen können, ist ~/.profile, und der Effekt sollte sich beim nächsten Anmelden bemerkbar machen.

Die Beschaffung ~/.bash_profilevon ~/.bashrcist die falsche Lösung. Es soll umgekehrt sein; ~/.bash_profilesollte Quelle ~/.bashrc.

In DotFiles finden Sie eine ausführlichere Erklärung, einschließlich einiger Informationen darüber , warum es so ist.

(Wenn Sie openjdk über apt installieren, sollten Symlinks vom Paket eingerichtet werden, damit Sie sie nicht wirklich einstellen JAVA_HOMEoder ändern müssen. PATH)

geirha
quelle
6
Ich habe festgestellt, dass beim Öffnen eines Terminals über die Seitenleiste in Ubuntu 12 die Datei ~ / .profile nicht geladen wird.
jcollum
3
@ jcollum Das ist gut. .profilesollte nur bezogen werden, wenn Sie sich einloggen.
geirha
2
Oh, ein Terminal zu öffnen ist nicht dasselbe wie sich einzuloggen ... Ich habe darüber nachgedacht, mich beim Terminal einzuloggen .
jcollum
2
Denken Sie daran, dass .profileBash ignoriert, wenn .bash_profilevorhanden. Siehe meine Antwort hier und man bashfür weitere Details.
Terdon
3
@terdon, ja, aber bash ist nicht beteiligt, wenn Sie sich grafisch anmelden .profile.
Geirha
48

Sie können überprüfen, ob Ihre Bash-Shell als Login-Shell gestartet wurde, indem Sie Folgendes ausführen:

shopt login_shell

Wenn die Antwort lautet, führen offSie keine Anmeldeshell aus.

Lesen Sie im Abschnitt zum Aufrufen des Bash-Handbuchs, wie Bash verschiedene Konfigurationsdateien liest (oder nicht liest).

Auszug aus man bash:

Wenn bash als interaktive Anmeldeshell oder als nicht interaktive Shell mit der --login Option aufgerufen wird , werden zuerst die Befehle aus der Datei gelesen und ausgeführt /etc/profile, sofern diese Datei vorhanden ist. Nachdem die Datei zu lesen, sucht er nach ~/.bash_profile, ~/.bash_loginund ~/.profilein dieser Reihenfolge, und liest und führt Befehle aus dem ersten , das existiert und lesbar ist .

suauf der anderen Seite startet eine Login-Shell auch nicht standardmäßig, Sie müssen sie dazu anweisen, indem Sie die --loginOption verwenden.

lgarzo
quelle
9
Vielen Dank für den Befehl shotp login_shell . Genial!!
Viriato
27

Ich denke, es ist erwähnenswert, dass Sie die Standardeinstellung von gnome-terminal ändern können, um eine Login-Shell (dh bash -l) zu verwenden, indem Sie die Profileinstellungen bearbeiten.

Gehen Sie zu Bearbeiten -> Profileinstellungen -> Titel und Befehl. Aktivieren Sie die Option "Befehl als Anmeldeshell ausführen"

Kisoku
quelle
1
Was sind die Nachteile dieser Einstellung?
Chrish
2
@chris Sie laden gerade Code ein wenig mehr als notwendig in vielen Fällen. Es spielt wahrscheinlich keine Rolle, ob Ihre ~/.bash_profileBewertung sehr schnell erfolgt, was wahrscheinlich der Fall ist. Eine gute Sache zu überprüfen ist, alle Anrufe zu anderen Prozessen zu vertreiben, die normalerweise ziemlich kostspielig sind.
Vaab
14

Wenn Sie ein Terminal öffnen oder ausführen, wird sudie Shell nicht als Anmeldeshell, sondern als normale interaktive Shell ausgeführt. So liest es sich ~/.bashrcaber nicht ~/.bash_profile. Sie können sumit der -lOption ausführen, dass Ihre Shell als Anmeldeshell ausgeführt wird.

Wenn Sie mit einer GUI arbeiten, wird die Shell normalerweise nie als Login-Shell ausgeführt ~/.bashrc.

Florian Diesch
quelle
1
Das habe ich getan und es hat funktioniert, aber überprüfen Sie, was der Typ unten sagt. Er schlägt vor, dass es eine schlechte Idee ist, es in bashrc und stattdessen im Profil abzulegen. .... Hey beides funktioniert, vielen Dank.
Viriato
4

TL; DR

Wird in der klassischen empfohlenen Ubuntu-Konfiguration ~/.bash_profilenur zu bestimmten Gelegenheiten ausgewertet. Und es macht Sinn.

Legen Sie Ihre Sachen in ~/.bashrc, es wird jedes Mal ausgewertet.

Ok, ich möchte verstehen, warum macht das Sinn?

Wichtige Punkte, um zu verstehen, was los ist:

  • Alle Prozesse müssen auf Linux und verwendet Umgebungsvariablen
  • Umgebungsvariablen werden vererbt
  • Daher reicht es aus, sie einmal auf den Vater Ihres gesamten Prozesses zu setzen (insbesondere, wenn dafür Rechenzeit erforderlich ist).
  • Der Vater Ihres gesamten Prozesses wird normalerweise gestartet, nachdem Sie sich auf Ihrem Gerät angemeldet haben (geben Sie Ihre Anmeldeinformationen ein).
  • Es gibt Dinge, die Sie möglicherweise nur einmal tun möchten, wenn Sie sich auf Ihrem Computer anmelden (z. B. nach neuen E-Mails suchen ...).

Die "Login" -Zeit beträgt also normalerweise:

  • Wenn Sie sich im Konsolenmodus anmelden (mit Strg-Alt F1) oder durch ssh, da die Shell der Vater aller Prozesse ist, wird Ihre geladen ~/.bash_profile.
  • Wenn Sie Ihre Sitzung im Grafikmodus öffnen, wird der erste Prozess ( gnome-sessionfür klassisches Ubuntu) für das Lesen zuständig sein
    .profile.

Ok, wo soll ich meine Sachen hinstellen?

Es ist ziemlich komplex, die ganze Geschichte ist hier . Aber hier ist ein Run-Down, der für Ubuntu-Benutzer ziemlich häufig ist. In Anbetracht dessen:

  • Sie verwenden bashShell,
  • Sie haben eine ~/.bash_profileund folgen der Empfehlung , das Laden von ~/.bashrcin Ihre zu addieren ~/.bash_profile, um mindestens eine Datei zu erhalten, die unabhängig vom Aufrufmechanismus ausgewertet wird .

Dies ist ein schneller Vorschlag, wo Dinge abgelegt werden sollen.

  • ~ / .bashrc ( Wird bei jeder Gelegenheit ausgewertet , vorausgesetzt, Sie folgen der Empfehlung)

    Für schnelle Auswertung Umgebungsvariablen und Code für Ihre Benutzer nur und bash-only - Befehlszeilenbenutzung (Aliase zum Beispiel). bashismus sind willkommen.

    Es wird auf sich selbst geladen auf:

    • Erstellen Sie in grafischen Sitzungen ein neues Shell-Fenster.
    • Berufung bash
    • screenneuer Bereich oder neuer Tab (nicht tmux!)
    • Jede Bash-Instanz in einem grafischen Konsolen-Client ( terminator/ gnome-terminal...), wenn Sie die Option "Befehl als Anmeldeshell ausführen" nicht aktivieren .

    Und es wird bei allen anderen Gelegenheiten dank der vorherigen Empfehlung geladen.

  • ~ / .bash_profile ( Wird nur bei bestimmten Gelegenheiten ausgewertet. )

    Für langsame Auswertung Umgebungsvariablen und Code für Ihre Benutzer nur und Konsole-Sitzung Prozesse. bashismus sind willkommen. Es wird geladen auf:

    • Konsolenanmeldung (Strg-Alt F1),
    • ssh meldet sich bei dieser Maschine an,
    • tmuxneues Fenster oder Fenster (Standardeinstellungen), (nicht screen!)
    • explizite aufrufe von bash -l,
    • Eine Bash-Instanz in einem grafischen Konsolen-Client ( terminator/ gnome-terminal...) nur, wenn Sie die Option "Befehl als Anmeldeshell ausführen" aktivieren.
  • ~ / .profile (Wird nur in einer grafischen Sitzung ausgewertet)

    Für Umgebungsvariablen mit langsamer Auswertung und ohne Bashismus für Ihre Nur-Benutzer- und alle grafischen Sitzungsprozesse . Es wird beim Anmelden in Ihrer grafischen Benutzeroberfläche geladen.

vaab
quelle
In den Fällen, in denen Bash eine Profildatei lädt, wird diese geladen, .profilewenn .bash_profilesie nicht vorhanden ist.
muru
Vielen Dank für die klare Erklärung. Es hilft Neulingen wie mir. Wenn ich in Mac Mojave Variablen in ~ / .bashrc setze und source mache und wenn ich es tue, envsehe ich nicht, dass env-Variablen gesetzt sind (ich habe versucht, iTerm zu schließen und erneut zu öffnen). Ich stelle jedoch fest, dass bei der Installation von Android Studio und anderen Apps alle diese Umgebungsvarianten aktiviert wurden /.bash_profile. Als ich es hinzufügte /.bash_profile, wirkte es wie ein Zauber. Warum ist das so?
sofs1