# 1.111.2

# Einstellen von Benutzer- und Systemumgebungsvariablen

Beschreibung: Prüfungskandidaten sollten in der Lage sein, globale und Benutzerprofile zu modifizieren. Dieses Lernziel beinhaltet das Setzen von Umgebungsvariablen, das Verwalten von skel Verzeichnissen für neue Benutzerkonten und das Setzen des Suchpfades auf die richtigen Verzeichnisse.

Die wichtigsten Dateien, Bezeichnungen und Anwendungen:

- env
- export
- set
- unset
- `/etc/profile`
- `/etc/skel`

### Profildateien

Wenn sich ein User an einem Linux-System anmeldet, sich also dort mit Usernamen und Passwort einloggt, so wird als erste Aktion, nach dem Login eine Shell gestartet. Welche Shell gestartet werden soll steht in dem jeweiligen Eintrag des Users in `/etc/passwd`. Jede Shell kann beim Start konfiguriert werden, das heißt, sie durchläuft mehrere Konfigurationsdateien, in denen bestimmte Umgebungsvariablen gesetzt werden können und evt. andere Programme aufgerufen werden, die im Hintergrund Arbeiten verrichten, die bei jedem Login erneut ausgeführt werden müssen.

Bei den Startdateien gibt es grundsätzlich zwei verschiedene Kategorien. Zum Einen, die Dateien, die bei jedem Login jedes Users ausgeführt werden und zum Anderen, die userbezogenen Dateien, in denen jeder User seine Einstellungen selbst treffen kann. Die systemweiten Startdateien liegen grundsätzlich in /etc, die userbezogenen grundsätzlich im Home-Verzeichnis des jeweiligen Users.

Linux/Unix kennt verschiedene Standard-Shells, die zum Teil unterschiedliche solche Startdateien benutzen. Im weiteren Verlauf dieser Darstellung werde ich mich auf die der Linux-Standardshell BASH reduzieren. Hier nur einmal kurz eine Auflistung verschiedener Startdateien:

Art | Bourne Again Shell | Korn Shell | TC-Shell
--- | --- | --- | ---
Systemweit | `/etc/profile` | `/etc/csh.cshrc /etc/csh.login`
Userbezogen | `~/.bash_profile ~/.bash_login` |  | `~/.tcshrc` oder `~/.cshrc` `~/.history ~/.login ~/.cshdirs`
`~/.profile`

Aus der Tabelle ist zu ersehen, daß die bash und die ksh zumindestens zwei Dateien gemeinsam benutzen, während die csh nur eigene Startdateien benutzt. Das liegt an der Tatsache, daß bash und ksh scriptkompatibel sind (also die selbe Syntax bei Shellscripts haben) während die csh eine völlig andere Syntax für ihre Scripts benutzt.

### Startdateien der Bourne Again Shell (bash)

Die Bourne Again Shell benutzt verschiedene Startdateien, die in unterschiedlichen Fällen abgearbeitet werden und in denen verschiedene Aufgaben erledigt werden können. Zunächst muß aber bei der Shell zwischen verschiedenen Kategorien unterschieden werden. Die erste grundsätzliche Unterscheidung liegt zwischen interaktiver Shell und nicht interaktiver Shell. Eine Shell ist immer dann eine interaktive Shell, wenn der User darin Kommandos eingeben kann. Das ist jedesmal der Fall, wenn

- ein User sich neu am System anmeldet,
- ein X-Term geöffnet wird,
- eine Shell eine andere Shell durch Programme wie su aufruft,
- eine Shell durch den User direkt aufgerufen wird.

Eine Shell ist eine nicht interaktive Shell immer dann, wenn z.B. eine Subshell aufgerufen wird, um ein Shellscript abzuarbeiten. Eine nicht-interaktive Shell arbeitet keine Startdateien ab.

Bei den interaktiven Shells muß zusätzlich noch zwischen einer Login-Shell und einer Nicht Login-Shell unterschieden werden. Die Shell ist dann eine Login-Shell, wenn sie direkt vom Login-Programm beim Anmelden eines Users gestartet wurde, oder wenn sie explizit mit dem Parameter `-l` aufgerufen wurde. Jede andere Shell, also wenn z.B. aus einem XTerm ein anderes Xterm aufgerufen wird, ist eine nicht Login-Shell.

Der wesentliche Unterschied zwischen Login-Shell und Nicht-Login-Shell besteht darin, daß bei einer Login-Shell davon ausgegangen werden muß, daß noch keinerlei Umgebungsvariablen gesetzt sind. Hier ist es also nötig, daß der gesammte Konfigurationsvorgang durchgearbeitet werden muß, um sicherzustellen, daß die Umgebung den Anforderungen entspricht. Eine Nicht-Login-Shell hingegen wurde ja durch eine Login-Shell aufgerufen, die ihrerseits wieder den Konfigurationsvorgang durchwandert hat. Ausgehend von der Forderung, daß alle wichtigen Umgebungsvariablen durch die export-Anweisung weitervererbt werden, muß diese Shell also nicht nochmal konfiguriert werden. Der Aufruf wird so wesentlich schneller.

#### Konfigurationsdateien der Loginshell

Eine Login-Shell arbeitet zuallererst immer die Datei /etc/profile ab. Diese Datei enthält alle wichtigen Konfigurationen, die für alle User des Systems gültig sein sollen. Hier werden insbesondere die folgenden Variablen gesetzt:

- PATH
  Der Suchpfad für ausführbare Dateien. Die Reihenfolge der genannten Verzeichnisse ist wichtig. Das erste gefundene Programm wird ausgeführt.
- MANPATH
  Der Pfad, in dem die verschiedenen Handbuch-Hierarchien zu finden sind. Auch hier ist die Reihenfolge wichtig. Liegen etwa die deutschen Handbuchverzeichnisse hier nach den englischen, dann werden sie nur angezeigt, wenn mit `man -a` alle Seiten angefordert werden würden.
- INFODIR bzw. INFOPATH
  Der Pfad zu den Info-Seiten.
- PAGER und EDITOR
  Die Standardprogramme zum Ansehen und Editieren von Textdateien (z.B. less und vi).
- PS1 und PS2
  Die Prompt-Einstellungen für den normalen und den Folgeprompt der Shell.

Daneben können hier weitere Variablen wie LS_OPTIONS oder LESSCHARSET gesetzt werden.

Auch Aliase und Shellfunktionen, die für alle User gelten sollen, werden in dieser Datei definiert. Eines ist aber für alle hier gesetzten Variablen, Funktionen und Aliase wichtig: Alle hier gesetzten Variablen, Aliase und Funktionen, die auch in später aufgerufenen Shells Geltung haben sollen, müssen mit der Anweisung `export` exportiert werden!

Absolut wichtig ist in /etc/profile die Angabe des initialen umask-Kommandos, das eine vernünftige Grundeinstellung für die Zugriffsmodi neu zu erstellender Dateien und Verzeichnisse setzt.

Des weiteren können hier noch Grenzwerte für die User gesetzt werden, was die Verwendung von Rechenzeit und Speicher angeht. Das wird durch Aufrufe des Programms ulimit erreicht.

Wenn die Datei /etc/profile abgearbeitet ist, werden noch die userspezifischen Konfigurationsdateien abgearbeitet. Hier stehen drei verschiedene Dateien zur Verfügung, von denen nur eine einzige wirklich abgearbeitet wird. Die drei Dateien liegen alle im Heimatverzeichnis des jeweiligen Users und heißen `.bash_profile .bash_login` und `.profile`. Die Shell entscheidet nach der folgenden Regel, welche dieser drei Dateien abgearbeitet wird:

      if [ -e ~/.bash_profile ]
      then
        . ~/.bash_profile
      elif [ -e ~/.bash_login ]
      then
        . ~/.bash_login
      elif [ -e ~/.profile ]
      then
        . ~/.profile
      fi

Oder - für Nicht-Bash-Programmierer:

Wenn im Heimatverzeichnis des Users die Datei .bash_profile existiert wird sie abgearbeitet.

Wenn diese Datei nicht existiert wird die Datei .bash_login im Heimatverzeichnis des Users gesucht und falls gefunden, abgearbeitet.

Wenn auch diese Datei nicht existiert, so wird im Heimatverzeichnis des Users die Datei .profile gesucht und falls gefunden abgearbeitet.

Diese drei Konfigurationsdateien bieten eigentlich jeweils die selben Möglichkeiten, wie die Einstellungen in /etc/profile, mit dem wesentlichen Unterschied, daß diese Einstellungen nur für den jeweiligen User gelten, in dessen Verzeichnis sich die Dateien befinden. Da immer nur eine dieser Dateien abgearbeitet wird, kann hier elegant jongliert werden. Ein paar Beispiele:

Will ein User experimentieren, so kann er alle Experimente in einer der beiden ersten Dateien machen, während er eine gut funktionierende dritte Datei besitzt. Falls etwas schiefgeht, muß er nur die ersten Dateien löschen und es wird wieder die dritte abgearbeitet.

Will ein Systemverwalter seinen Usern verbieten, Experimente oder eigene Einstellungen zu machen, muß er nur die Einstellungen in die erste abzuarbeitende Datei machen und dem User kein Schreibrecht darauf geben.

Neben diesen Startdateien kann auch noch eine Datei mit Namen .bash_logout existieren, die dann beim Logout abgearbeitet wird. Hier ist Platz für eventuell anstehende Aufräumarbeiten oder ähnliches.

#### Die Konfigurationsdatei der Nicht-Loginshell

Auch eine Nicht-Loginshell muß eventuell noch etwas konfiguriert werden. Das ist zwar nicht zwingend der Fall, insbesondere dann nicht, wenn die obigen Konfigurationsdateien der Loginshell alle wichtigen Einstellungen exportieren, aber die Shell kennt die Möglichkeit dazu. Allerdings ist diese Möglichkeit immer nur userbezogen.

Wenn im Verzeichnis eines Users die Datei .bashrc existiert, so wird sie von einer Nicht-Loginshell abgearbeitet, sobald diese Shell aufgerufen wird.

### Grundsätzliches zu Umgebungsvariablen

Jede Shell und natürlich auch unsere Standard-Shell bash kann Variablen definieren. Die Summe aller definierten Variablen nennen wir die Umgebung der Shell (engl. environment).

Shellvariablen werden einfach durch die Angabe

> Variablenname=Wert

definiert. Durch diese Definition steht uns die Variable mit dem gewählten Namen in dieser und nur dieser Shell zur Verfügung. Damit eine definierte Variable auch in Subshells zur Verfügung steht, die von unserer Shell geöffnet werden, muß die Variable exportiert werden. Das kann entweder im Nachhinein durch die Anweisung

> export Variablenname

oder schon während der Definition durch

> export Variablenname=Wert

geschehen. Erst jetzt werden solche Variablen auch in späteren Subshells zur Verfügung stehen. Allerdings stehen sie dort nur als Kopien der Variable der aufrufenden Shell zur Verfügung. Das hat zur Folge, daß die Variablen, die in der Subshell verändert werden, in der aufrufenden Shell unverändert bleiben.

Folgendes Beispiel mag das verdeutlichen:

`NAME=hans` |  | Eine Variable wird erzeugt
`export NAME` |  | Sie wird exportiert
`bash` |  | Eine Subshell wird geöffnet
`echo $NAME` |  | Wir überprüfen den Export
`hans` |  | Hat funktioniert
`NAME=otto` |  | Ein neuer Wert für die Variable
`echo $NAME` |  | Wir überprüfen den neuen Wert
`otto` |  | Hat funktioniert
`exit` |  | Subshell wird geschlossen
`echo $NAME` |  | Inhalt der Variable in der ersten Shell
`hans` |  | Ist immer noch der alte Wert.

Jede Shell hat ihren eigenen Umgebungsspeicher, in den zwar jeweils Kopien der exportierten Variablen abgelegt werden, der aber beim Beenden der Shell wieder gelöscht wird. So kann in keinem Fall eine geänderte Variable einer Subshell wieder der ursprünglichen Shell "reimportiert" werden.

Jedes Shellscript, das aufgerufen wird, wird in einer Subshell abgearbeitet. Variablen, die in diesem Script erzeugt oder verändert werden, sind nach Beendigung des Scripts (und damit der ausführenden Subshell) nicht mehr aktuell.

Damit es aber trotzdem möglich ist, Shellscripts zur Definition von Variablen heranzuziehen, gibt es die Möglichkeit ein Script in der ursprünglichen Shell auszuführen, statt eine Subshell zu öffnen. Zu diesem Zweck wird ein einfacher Punkt (.) mit anschließendem Leerzeichen vor der Nennung des Scriptnamens angefügt.

`meinscript` |  | meinscript wird von einer Subshell ausgeführt
`. meinscript` |  | meinscript wird von der ursprünglichen Shell ausgeführt.

Durch den Punkt wird unsere Shell also gezwungen, das Script selbst abzuarbeiten. Die Variablen, die innerhalb dieses Scripts definiert wurden, sind jetzt auch nach der Abarbeitung des Scriptes noch gültig.

Das klingt schön, hat aber einen bedeutenden Haken. Wenn innerhalb des Scrips ein `exit` vorkommt, normalerweise dazu benutzt, um das Script zu beenden, wird ja die Shell, die das Script ausführt, beendet. Wurde das Script jetzt mit vorgestelltem Punkt aufgerufen, also von unserer Loginshell selbst, dann wird das exit die LoginShell beenden! Wir müßten uns also erneut einloggen.

Scripts, die mit führendem Punkt aufgerufen werden sollen, sollten daher auf keinen Fall - auch nicht zur Fehlerbehandlung - ein `exit` benutzen.

Eine Liste aller Umgebungsvariablen, die in der aktuellen Shell bekannt sind (zusammen mit ihren Inhalten) wird durch das Shellkommando set ausgegeben.

Eine Variable kann durch den Befehl

      unset Variablenname

wieder aus dem Umgebungsspeicher entfernt werden.

Schließlich ist es noch möglich, einen Befehl in einer speziellen Umgebung auszuführen, die wir mit dem Befehl env erzwingen können.

### Das Verzeichnis /etc/skel

Wenn ein neuer User angelegt werden soll, dann hätte der Systemverwalter viel Arbeit damit, jedem neu anzulegenden User all diese persönlichen Konfigurationsdateien eigens zu erstellen und einzurichten. Damit diese Arbeit gar nicht erst anfällt, existiert das Verzeichnis /etc/skel. Es enthält alle wichtigen Konfigurationsdateien, die in einem Userverzeichnis existieren sollten, damit er vernünftig arbeiten kann.

Beim Anlegen eines neuen Users werden diese Konfigurationsdateien dann in das neu angelegte Userverzeichnis kopiert und dem neuen User übereignet. Das wird automatisch dann ausgeführt, wenn das useradd-Kommando mit der Option `-m` aufgerufen wurde.

Ein Systemverwalter kann also sozusagen einen Musteruser anlegen und alle nötigen Konfigurationsdateien dieses Musterusers in dieses Verzeichnis speichern. Jeder neu angelegte User wird dann exakt die Konfiguration des Musterusers bekommen.

Neben den oben besprochenen Konfigurationsdateien der Shells finden sich hier auch noch viele weiteren Dateien, deren Namen praktisch immer mit einem Punkt beginnt und somit von einem normalen `ls` Kommando nicht angezeigt wird. Diese Dateien sind Konfigurationsdateien für verschiedene Programme, die ein Normaluser ausführen können soll. Welche Dateien im Einzelnen hier zu finden sind, muß der Systemverwalter entscheiden. Ein paar Beispiele:

`.Xdefaults`
  Persönliche Resourcen für X-Clients. Hier kann das Verhalten und Aussehen verschiedener X-Clients eingestellt werden.
`.Xresources`
  Persönliche Resourcen für X-Clients. Hier kann das Verhalten und Aussehen verschiedener X-Clients eingestellt werden. Exakt die selbe Funktion wie .Xdefaults.
`.Xmodmap`
  Tastaturbelegung für X11. Spezielle Einstellungen, wie die Tasten belegt werden sollen.
`.bash_history`
  Eine leere Datei zur Aufnahme der bereits eingegebenen Befehle der Shell (Befehlswiederholung).
`.dayplan`
  Termine des Users für das Programm plan
`.dayplan.priv`
  Private Termine des Users, auch für plan
`.emacs`
  Persönliche Konfiguration für den Editor emacs
`.exrc`
  Persönliche Konfiguration für den Editor ex
`.vimrc`
  Persönliche Konfiguration für den Editor vim
`.gimprc`
  Persönliche Konfiguration für das Bildbearbeitungsprogramm gimp
`.xinitrc`
  Persönliche Konfiguration des Starts von X11
`.xfm`
  Verzeichnis mit Konfigurationsdateien des X-Filemanagers

Und viele anderen mehr...

Wenn es gewünscht ist, mehrere verschiedene Musteruser anzulegen, dann können neben dem skel-Verzeichnis noch weitere solcher Verzeichnisse angelegt werden (z.B. skel_verwaltung, skel_produktion) und beim Anlegen der jeweiligen User muß dann useradd mit dem Parameter -m -k Verzeichnis aufgerufen werden, wobei Verzeichnis das gewünschte Musterverzeichnis ist.