it-swarm.com.de

Warum wird / etc / profile für nicht angemeldete Shells nicht aufgerufen?

Anmelde- und Nicht-Anmelde-Shell definiert als:

su - $USER # will give you a login Shell
bash # will give you a non-login Shell

/ etc/profile wird nicht für nicht angemeldete Shells aufgerufen, z. B. wenn Sie konsole (kde) starten./etc/profile wird nur für Login-Shells aufgerufen.

Warum ist das so? Bitte erklären Sie, weil ich die Gründe dafür verstehen möchte.

49
James Mitch

/etc/profile wird nur für Login-Shells aufgerufen, da dies der spezifische Zweck ist.

Wenn ein Befehl für interaktive Shells ausgeführt werden soll, die nicht ​​Login-Shells sind, und Sie bash verwenden, geben Sie ihn in ~/.bashrc oder /etc/bash.bashrc ein.

Der Zweck der "Profil" -Dateien besteht darin, Befehle zu enthalten, die nur für Login-Shells ausgeführt werden sollten. Diese Dateien sind:

  • /etc/profile, wird von allen Bourne-kompatiblen Shells (einschließlich bash und dash ) ausgeführt, wenn sie als Anmeldeshell gestartet werden.

  • Skripte in /etc/profile.d.

    Dies gilt für Shells im Bourne-Stil, ist jedoch nicht in der Shell-Programmdatei selbst codiert. Befehle in /etc/profile rufen sie vielmehr auf. Auf meinem Ubuntu 12.04-System enthält /etc/profile beispielsweise folgende Zeilen:

    if [ -d /etc/profile.d ]; then
      for i in /etc/profile.d/*.sh; do
        if [ -r $i ]; then
          . $i
        fi
      done
      unset i
    fi
    
  • .profile im Home-Verzeichnis des Benutzers, das von Bourne-kompatiblen Shells ausgeführt wird, wenn es als Anmeldeshell gestartet wird (sofern es nicht überschrieben wird, siehe unten).

  • .bash_profile oder .bash_login im Benutzerverzeichnis. Diese werden von anderen Shells als bash ignoriert. Wenn jedoch .bash_profile vorhanden ist, wird es von bash anstelle von .profile ausgeführt. Wenn .bash_profile nicht existiert, aber .bash_login existiert, wird dies anstelle von .profile ausgeführt.

    (Es ist jedoch üblich, dass .bash_profile oder .bash_login, sofern vorhanden, so geschrieben werden, dass * .profile explizit aufgerufen wird.)

    Der Vorteil von Shell-spezifischen profile -Dateien besteht darin, dass sie Befehle oder Syntax enthalten können, die nur für diese Shell gültig sind. Beispielsweise kann ich den Bewertungsoperator [[ in .bash_profile/.bash_login verwenden, aber wenn ich ihn in .profile verwende und mich dann mit dash als meine Shell anmelde, schlägt dies fehl .

Was sollte in "Profil" -Dateien gehen

"profile" -Dateien sollten Befehle enthalten, die zu Beginn der Anmeldung nur einmal ausgeführt werden dürfen. (Dies schließt auch grafische Anmeldungen ein, da sie auch mit einer Anmeldeshell beginnen.) Wenn eine Shell interaktiv ist, ist der Benutzer, der sie ausführt, wahrscheinlich angemeldet, und daher hat sie wahrscheinlich einen Vorfahren (der sie gestartet hat oder was sie gestartet hat). oder fing damit an, etc.) das war eine Login-Shell.

Möglicherweise möchten Sie einen Befehl nur einmal ausführen, weil:

  1. es gibt keinen Grund, es mehr als einmal pro Anmeldung auszuführen, es wäre ineffizient, oder
  2. es würde zu einem unerwünschten Ergebnis führen, wenn es mehr als einmal pro Anmeldung ausgeführt würde.

Betrachten Sie als Beispiel für die zweite Situation, in der ein unerwünschtes Ergebnis auftreten würde, die folgenden Zeilen, die standardmäßig in ~/.profile jedes Benutzers angezeigt werden:

# set PATH so it includes user's private bin if it exists
if [ -d "$HOME/bin" ] ; then
    PATH="$HOME/bin:$PATH"
fi

Angenommen, Sie haben in SSH eine andere Shell ausgeführt (z. B. zsh ). Irgendwann wollten Sie vorübergehend zu bash zurückkehren, aber Ihre Umgebung beibehalten (also bash erneut ausführen, während Sie sich in zsh befinden) und Führen Sie dann ein Programm wie mc aus, das eine Shell als Teil ihrer Schnittstelle ausführt. Wenn bin in Ihrem Ausgangsordner vorhanden ist und Ihr Benutzername james lautet, lautet Ihr PATH in der innersten Shell etwa:

/home/james/bin:/home/james/bin:/home/james/bin:/home/james/bin:/usr/lib/lightdm/lightdm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games

Das ist ineffizient und (viel wichtiger) macht es schwierig, den Inhalt von PATH zu verstehen.

Dies ist jedoch keineswegs eine Katastrophe. Soweit ich das beurteilen kann, würde nichts Schlimmes passieren, wenn alle interaktiven Shell-bezogenen "Profil" -Dateien - in der Standardkonfiguration . Da der Zweck von "Profil" -Dateien darin besteht, Befehle zu enthalten, die nur einmal pro Anmeldung ausgeführt werden sollen , kann ein Benutzer oder Administrator einem Profil Befehle hinzufügen, die nur ausgeführt werden müssen , wenn eine Anmeldeshell gestartet wird.

Wo Befehle für jede auszuführende interaktive Shell abgelegt werden sollen

Wenn Sie bash verwenden, gibt es Dateien für Befehle, die in jeder interaktiven Shell ausgeführt werden sollen:

  • /etc/bash.bashrc
  • .bashrc im Home-Verzeichnis des Benutzers.

Dies wird am häufigsten für Befehle verwendet, die

  1. wirken sich nur auf die Umgebung der Shell aus, in der sie ausgeführt werden - nicht einmal auf Kinder-Shells, oder
  2. sollte laufen, auch wenn dies nicht die Login-Shell ist.

Beispielsweise sollte die Vervollständigung von Befehlszeilenregistern im Allgemeinen aktiviert sein, unabhängig davon, ob bash die Anmeldeshell war oder nicht. Das erscheint also in ~/.bashrc:

if [ -f /etc/bash_completion ] && ! shopt -oq posix; then
    . /etc/bash_completion
fi

Dort gelten 1 und 2 beide: Dies überträgt sich nicht auf andere in dieser Shell ausgeführte Shells, und die Tab-Vervollständigung sollte in bash funktionieren, auch wenn ich mich mit einer anderen Shell angemeldet habe.

Wo Befehle für Anmelde-Shells und interaktive Nicht-Anmelde-Shells abgelegt werden

Wenn Sie bash verwenden und möchten, dass ein Befehl in Anmelde-Shells und interaktiven Shells ausgeführt wird und keine Anmelde-Shells sind, ist es im Allgemeinen ausreichend, ihn in /etc/bash.bashrc oder ~/.bashrcabzulegen. Dies liegt daran, dass /etc/profile und ~/.profile sie standardmäßig explizit ausführen. Zum Beispiel hat ~/.profile:

# if running bash
if [ -n "$BASH_VERSION" ]; then
    # include .bashrc if it exists
    if [ -f "$HOME/.bashrc" ]; then
        . "$HOME/.bashrc"
    fi
fi

(Auf ähnliche Weise bezieht /etc/profile/etc/bash.bashrc für bash.)

Daher werden sowohl "profile" als auch "rc" -Dateien ausgeführt, wenn Sie eine interaktive bash-Shell starten (unabhängig davon, ob es sich um eine Login-Shell handelt oder nicht).

Wo Befehle in nicht interaktiven Shells ausgeführt werden sollen

Sie möchten wahrscheinlich keine Befehle für alle nicht interaktiven Shells angeben, die ausgeführt werden sollen. Sie werden jedes Mal ausgeführt, wenn ein Skript ausgeführt wird (vorausgesetzt, das Skript wird von der Shell ausgeführt, die Sie für die Ausführung konfiguriert haben).

Dies kann zu erheblichen Brüchen führen. Wenn Sie dies tun und auf dem System kein anderes Administratorkonto als das von Ihnen verwendete vorhanden ist, möchten Sie möglicherweise eines erstellen. das kann es einfacher machen, Fehler zu beheben.

In bash werden die "rc" -Dateien tatsächlich ausgeführt unabhängig davon, ob die Shell interaktiv ist oder nicht . Oben steht jedoch:

# If not running interactively, don't do anything
[ -z "$PS1" ] && return

Wenn Sie also Befehle benötigen, die auch in nicht interaktiven Shells wie denjenigen, die zum Ausführen von Skripten ausgeführt werden, automatisch ausgeführt werden, können Sie Ihre Befehle vor diesen Zeilen hinzufügen.

Starten einer Login-Shell

Beim Anmelden wird eine Anmeldeshell gestartet. Wenn eine danach gestartete Shell als Login-Shell fungieren soll, starten Sie sie mit dem Flag -l (steht fürl ogin ). Zum Beispiel:

Dies ist der beste Weg, um eine Login-Shell zu starten (ohne sich anzumelden), es sei denn, Sie möchten einen als einen anderen Benutzer starten. Dann benutze:

  • Sudo -i für root (verwenden Sie Sudo -s für eine nicht angemeldete, interaktive Root-Shell)
  • Sudo -u username -i für jeden Benutzer
  • su - username für Benutzer ohne root (verwenden Sie su username für eine nicht angemeldete, interaktive Root-Shell)

Was ist eine initial login-Shell?

Ein anfängliches Login Shell ist dasselbe wie ein Login Shell . Überall in dieser Antwort steht "login Shell", es könnte "inital login Shell" stehen (außer in diesem Abschnitt, der aufgehört hätte, Sinn zu machen).

Ein Grund für den Begriff initial login Shell ist, dass login Shell auch in einem anderen Sinne verwendet wird - um welches Programm als Shell zu identifizieren, die bei der Anmeldung ausgeführt wird. Dies ist der Sinn von login Shell , der verwendet wird, um Folgendes zu sagen:

  • " OpenBSD s Standard-Login-Shell ist ksh ; in Ubuntu ist es bash."
  • "Sie können ändern Ihre Login-Shell mit chsh ."

Weitere Lektüre

97
Eliah Kagan