Das ist peinlich, aber nach vielen Jahren Vollzeitnutzung von POSIX-Systemen fällt es mir immer noch schwer herauszufinden, ob eine Shell-Anpassung in .bashrc
, .profile
oder woanders erfolgen sollte. Ganz zu schweigen von einigen betriebssystemspezifischen Konfigurationsdateien wie .pam_environment
.
Ja, ich weiß, wie man sich durch die Dokumentation wühlt und herausfindet, wann welche Datei geladen wird und wann nicht. Ich frage mich, ob irgendjemand schon einmal umfassende Richtlinien zusammengestellt hat, um zu entscheiden, in welche Datei eine bestimmte Art von Anpassung eingefügt werden soll.
Antwort1
Kurz zusammengefasst:
~/.bash_profile
sollte super einfach sein und nur laden.profile
und.bashrc
(in dieser Reihenfolge)~/.profile
enthält die Dinge, die NICHT speziell mit Bash zu tun haben, wie etwa Umgebungsvariablen (PATH
und ähnliches)~/.bashrc
hat alles, was Sie sich für eine interaktive Befehlszeile wünschen. Eingabeaufforderung,EDITOR
Variable, Bash-Aliase für meinen Gebrauch
Einige weitere Anmerkungen:
Alles, was für grafische Anwendungen ODER für sh (oder bash aufgerufen als ) verfügbar sein soll,
sh
MUSS in~/.profile
~/.bashrc
darf nichts ausgebenAlles, was nur für Login-Shells verfügbar sein soll, sollte in
~/.profile
Stellen Sie sicher, dass dies
~/.bash_login
nicht vorhanden ist.
Antwort2
In den letzten Jahren hatte ich viel Zeit zu verschwenden, alsohabenhabe das etwas länger als nur 10 Minuten recherchiert. Ich habe keine Ahnung, ob das das beste Layout ist, es ist nur eines, das in so ziemlich allen Fällen richtig funktioniert.
Die Anforderungen:
~/.profile
muss mit jedem /bin/sh kompatibel sein – dazu gehören Bash, Dash, Ksh und alles andere, was eine Distribution verwenden möchte.Umgebungsvariablen müssen in eine Datei eingefügt werden, die sowohl von Konsolenanmeldungen (d. h. einer „Login“-Shell) als auch von grafischen Anmeldungen (d. h. Anzeigemanagern wie GDM, LightDM oder LXDM) gelesen wird.
Es hat wenig Sinn,beide
~/.profile
und~/.bash_profile
. Wenn Letzteres fehlt, verwendet Bash gerne Ersteres und alle Bash-spezifischen Zeilen können mit einer Prüfung auf$BASH
oder geschützt werden$BASH_VERSION
.Der Unterschied zwischen
*profile
und*rc
besteht darin, dass Ersteres für „Login“-Shells verwendet wird und Letzteres jedes Mal, wenn Sie ein Terminalfenster öffnen. Bash verwendet im „Login“-Modus jedoch nicht als Quelle und muss dies~/.bashrc
daher manuell tun.~/.profile
DereinfachsteDie Konfiguration wäre:
Verfügen Sie über ein
~/.profile
, das alle Umgebungsvariablen (außer Bash-spezifischen) festlegt, möglicherweise eine oder zwei Zeilen druckt und dann die Quellen angibt,~/.bashrc
wenn es von Bash ausgeführt wird, und sich ansonsten an die Sh-kompatible Syntax hält.export TZ="Europa/Paris" export EDITOR="vim" wenn [ "$BASH" ]; dann . ~/.bashrc fi Betriebszeit
Haben Sie einen
~/.bashrc
, der jedes Shell-spezifische Setup durchführt, geschützt mit einer Prüfung fürinteraktiver Modusum zu vermeiden, dass Dinge wiesftp
bei Debian kaputt gehen (wo Bash mit der Option zum Laden auch für nicht-interaktive Shells kompiliert wird~/.bashrc
):[[ $- == *i* ]] || gibt 0 zurück PS1='\h \w \$ ' start() { sudo Dienst "$1" start; }
Allerdings besteht auch das Problem, dass bestimmte nicht interaktive Befehle (z. B. ssh <host> ls
) überspringen ~/.profile
, obwohl Umgebungsvariablen für sie sehr nützlich wären.
Bestimmte Distributionen (z. B. Debian) kompilieren ihre Bash mit der Option, Quellen
~/.bashrc
für solche nicht-interaktiven Logins zu verwenden. In diesem Fall fand ich es nützlich, alle Umgebungsvariablen (dieexport ...
Zeilen) in eine separate Datei zu verschieben~/.environ
und diese vonbeide.profile
und.bashrc
, mit einer Schutzvorrichtung, um es nicht zweimal zu tun:wenn ! [ "$PREFIX" ]; dann # oder $EDITOR, oder $TZ, oder ... . ~/.environ # im Allgemeinen jede Variable, die .environ selbst setzen würde fi
Leider habe ich für andere Distributionen (z. B. Arch) keine wirklich gute Lösung gefunden. Eine Möglichkeit besteht darin, das (standardmäßig aktivierte) PAM-Modul pam_env zu verwenden, indem man Folgendes einfügt
~/.pam_environment
:BASH_ENV=./.environ # kein Tippfehler; es muss ein Pfad sein, aber ~ funktioniert nicht
Dann natürlich die Aktualisierung
~/.environ
aufunset BASH_ENV
.
Fazit? Shells sind lästig. Umgebungsvariablen sind lästig. Distributionsspezifische Optionen zur Kompilierungszeit sind einimmensSchmerz im Arsch.
Antwort3
Guck dir das anausgezeichneter Blogbeitrag von ShreevatsaR. Hier ist ein Auszug, aber gehen Sie zum Blog-Beitrag, er enthält eine Erklärung für Begriffe wie „Login-Shell“, ein Flussdiagramm und eine ähnliche Tabelle für Zsh.
Für Bash funktionieren sie wie folgt. Lesen Sie die entsprechende Spalte nach unten. Führt A aus, dann B, dann C usw. B1, B2, B3 bedeutet, dass nur die erste der gefundenen Dateien ausgeführt wird.
Interaktive Anmeldung Interaktiv ohne Anmeldung Skript /etc/profile
A /etc/bash.bashrc
A ~/.bashrc
B ~/.bash_profile
B1 ~/.bash_login
B2 ~/.profile
B3 BASH_ENV
A ~/.bash_logout
C
Antwort4
Ich habe es aufgegeben, dieses Problem herauszufinden und habe ein Skript ( ~/.shell-setup
) erstellt, das ich von allen anderen als Quelle verwende.
Dieser Ansatz erfordert ~/.shell-setup
zwei Funktionen:
- Nur einmal ausführen, auch bei wiederholter Einspeisung (verwenden SieSchutzvorrichtungen einschließen)
- Erzeugen Sie keine unerwünschte Ausgabe (erkennen Sie, wenn die Ausgabe in Ordnung ist).
#1 ist ziemlich Standard, wird aber in Shell-Skripten vielleicht nicht oft verwendet.
#2 ist schwieriger. Folgendes verwende ich in Bash:
if [ "" == "$BASH_EXECUTION_STRING" -a "" == "$DESKTOP_SESSION" ]; then
echo "Hello user!" # ... etc
fi
Leider weiß ich nicht mehr, wie ich darauf gekommen bin und warumErkennen einer interaktiven Shellwar nicht ausreichend.