Shells: Tutorial


* Einf├╝hrung * Installation * Paketmanager * Grundlagen * Shells * Entwicklung * KDE * Skriptsprachen * AWK * PHP * Perl * Apache * Veranstaltungen * Schulungen * B├╝cher * Netzwerk * OpenOffice * OpenSource * Samba

Shells


© <a href="http://www.fotolia.de/p/29003">Ljupco Smokovski</a> - FOTOLIA
Home
Erste Schritte mit der Bourne-Shell
Dateien zeilenweise zusammenf├╝gen
Head or Tail
Schleifen und Z├Ąhlen
Shell-Variablen
Pipes
Sortieren von Daten
Wer sucht der findet!
Praktische Shell-Skripte
Rechtschreibung
Schleifen und elegant Z├Ąhlen
Texte formatieren mit fmt und fold
Umlenkung der Ein- und der Ausgaben
Klammer-Erweiterung
Verkn├╝pfen von Textdateien mittels Schl├╝sselfeldern
Mit freundlicher Unterstützung von:

Linux-Kurse und Seminare Linux Kurse
Veranstalter des
Linux-Tag
am Bodensee
2007 und 2008

Kontakt
Haftung
Impressum
Problem Hilfe Startseite


Shell-Variablen


Es lohnt sich hier weiterzulesen, denn auch wenn Sie schon alles über Variablen in der Bash-Shell zu wissen glauben, finden Sie hier sicherlich "Neues". So wie zum Beispiel die elegante Übergabe von Umgebungsvariablen bei Skript- oder Kommandoaufrufen.

Auch in der Bash-Shell, wie in jeder Skript- bzw. Programmiersprache, gibt es Variablen. Aber die Variablen der Bash-Shell kennen keinen Typ, oder anders ausgedrückt nur einen Typ und der heißt String. Ein solcher String kann aber falls nötig als Integer interpretiert werden.

Shell-Variablen werden per Konvention meistens groß geschrieben, wird aber nicht durch die Syntax der Bash-Shell verlangt.

Einer Variablen wird ein Wert zugewiesen, indem der Variablenname auf die linke Seite eines Gleichheitszeichens gestellt wird, während auf der rechten Seite der zuzuweisende Wert steht.

Beispiele:
  • is="is not"
  • b=$a
  • zahl=42
Im zweiten Beispiel sieht man, dass eine Variable nur im definierenden Fall (auf der linken Seite) ohne Dollarzeichen geschrieben wird. Bei jedem benutzenden Vorkommen einer Variablen muss dem Variablennamen ein Dollarzeichen vorangestellt werden.
Warum das so sein muss, sieht man am besten, wenn man sich eine echo-Anweisung ansieht:
echo Windows is great
gemeint ist aber in sicherlich vielen Fällen
echo Windows $is great
Im letzten Fall würde $is durch seinen Wert ersetzt werden, und man erhält die für Linux-Freunde und OpenSource-Anhänger angenehmere Ausgabe "Windows is not great"

Arithmetische Ausdrücke in der Bash

Kaum ein Skript kommt ohne einen arithmetischen Ausdruck aus. Wie wir gesehen haben können wir Variablen numerische Werte zuweisen, also beispielsweise
a=5
b=7
Was passiert aber, wenn wir diese in einen Ausdruck der Form
c=$a+$b
packen, wie dies in vielen Programmiersprachen möglich ist?

Ganz einfach: Es wird der String "5+7" ausgegeben und nicht, wie man gehofft hat, der Wert 12.
Ausdrücke werden in der Shell ausgewertet, wenn sie innerhalb von eckigen Klammern mit vorangestelltem Dollarzeichen stehen $[...], also in unserem Fall:
echo $[$a+$b]

Die bisher besprochenen Variablen sind nur innerhalb der Shell gültig, in der sie eingeführt wurden. Wird die Shell verlassen oder wird eine Untershell gestartet, sind sie nicht mehr bekannt.

Umgebungs-Variablen

Was man unter Umgebungsvariablen (Environment variable) versteht, scheint nicht eindeutig in der Literatur zu sein. Manche verstehen und bezeichnen damit alle Shell-Variablen. Meistens versteht man bei Shells aber darunter globale Variablen, die auch noch nach dem Verlassen der aktuellen Shell und in Untershells ihre Gültigkeit und ihren Wert behalten. Andersherum können diese Variablen ihren Wert auch von Eltern-Prozessen geerbt haben. Man kann jede Variable zu einer solchen Umgebungsvariablen machen, indem man sie exportiert.

Exportieren einer Variablen ist entweder direkt bei der Wertzuweisung an die Variablen möglich
export a="Eine Variable, die exportiert wird."
oder wenn vor dem Aufruf einer Untershell oder vor dem Verlassen der Shell ein export mit dem Variablennamen erfolgt, also
export a
Die Umgebungsvariablen werden meist bereits beim Eintritt in die Shell automatisch gesetzt. Dies geschieht automatisch für alle Benutzer in der Datei /etc/bash.bashrc (bei Red Hat) oder /etc/bashrc (SuSE, Fedora, Mandriva und andere). Individuell kann ein Nutzer Umgebungsvariablen im eigenen Homeverzeichnis in de Dateie ~/.profile  (alternativ in der Datei ~/.bashrc) setzen.

Nun zeigen wir Ihnen einen besonderen Trick, den sie in kaum einem Buch oder Dokumentation über Bash-Shells finden, obwohl dieser Trick einem das Leben sehr erleichtern kann. Stellen Sie sich folgende Aufgabe vor: Sie wollen ein Skript FOO aufrufen und müssen dazu eine (oder mehrere) Umgebungsvariable (z.B. VAR1 auf den Wert 47, und VAR2 auf den Wert 11) ändern. Im eigentlichen Skript soll aber diese Umgebungsvariable ihren alten Wert behalten.
Man könnte es wie folgt tun


help1=$VAR1
help2=$VAR2
export VAR1=47
export VAR2=11
TestAusgabe.sh
export VAR1=$help1
export VAR2=$help2
 
Ganz elegant geht es jedoch wie folgt:


VAR1=47 VAR2=11 TestAusgabe.sh
 
Das Skript TestAusgabe.sh könnte dazu wie folgt aussehen:


#!/bin/bash
echo $VAR1$VAR2

Dazu noch eine kleine praktische Anwendung: Mit dem Kommando date kann man sich das aktuelle Datum mit Uhrzeit usw. ausgeben lassen.
Ruft man date aber wie folgt auf
TZ=GMT date
erhält man die aktuelle Uhrzeit in Greenwich Mean Time (GMT), natürlich ohne dass die Rechnerzeit damit umgestellt wird.

Löschen von Umgebungsvariablen

Manchmal ist es nötig, eine Umgebungsvariable zu löschen. Man muss hier zwei Möglichkeiten unterscheiden.
  1. Man möchte eine Variable komplett entfernen, dh. sie soll nachher weder als lokale noch als globale Variable weiter existieren.
    In diesem Fall muss man die Variable mit unset <Variablenname> bzw "unset -v <Variablenname>" entfernen.
  2. Möchte man eine Variable nur aus der Liste der zu exportierenden Variablen entfernen, so geht dies mit dem Befehl "export -n <Variablenname>"

Bash-Konfigurationsdateien

Wie bereits im letzten Abschnitt angeklungen gibt es verschiedene Konfigurationsdateien für Bash. Die folgende Tabelle stellt eine systematische Übersicht dar:

Datei
Beschreibung
Optional
/etc/profile
Eine systemweite Initialisierungs-Datei, die bei jedem Login automatisch ausgeführt wird.
obligatorisch
/etc/bashrc
Eine systemweite Initialisierungsdatei, die allerdings innerhalb der ~/.bashrc geladen werden kann. Sie muss vorhanden sein, muss aber nicht geladen werden.
Auszug aus ~/.bashrc:

# Source global definitions
if [ -f /etc/bashrc ]; then
        . /etc/bashrc
fi
obligatorisch
~/.bash_profile
Falls diese Datei existiert, wird sie automatisch während des Logins nach /etc/profile ausgeführt.
optional
~/.bash_login
Falls ~/.bash_profile nicht existiert, wird diese Datei automatisch während des Logins ausgeführt.
optional
~/.profile
Wenn weder ~/.bash_profile noch ~/.bash_login existieren wird diese Datei automatisch während des Login ausgeführt.
Die letzten drei Dateien werden im Prinzip nach der folgenden Bash-Anweisung abgearbeitet:
  if [ -e ~/.bash_profile ] 
then
. ~/.bash_profile
elif [ -e ~/.bash_login ]
then
. ~/.bash_login
elif [ -e ~/.profile ]
then
. ~/.profile
fi
optional
~/.bashrc
Diese Datei wird immer mit dem Start einer Shell automatisch ausgeführt, egal ob es sich um eine Login-Shell handelt oder nicht.
optional
~/.bash_logout
Diese Datei wird automatisch beim ausloggen ausgeführt.
optional
~/.inputrc
Diese Datei enthält, wenn vorhanden, zusätzliche Tastaturbelegungen und Variablen, die Tastaturbelegungen beeinflussen. Standardmäßig verhält sich die Bash wie der Emacs.
optional

Wann diese Dateien ausgeführt werden hängt unter anderem davon ab, um es sich bei der gestarteten Shell um eine Login-Shell (z.B. Textkonsole) oder um eine Nicht-Login-Shell handelt (z.B. konsole, wenn sie nicht mit "konsole -ls" aufgerufen wird). Bei einer Nicht-Login-Shell wird nur die Datei ~/.bashrc eingelesen, während eine Login-Shell /etc/profile, ~/.bash_profile, ~/.bash_login (siehe oben) startet.

Anzeige der Environment-Variablen

Es stellt sich die Frage, wie man sich definierte Variablen und ihre zugehörigen Werte anschauen kann. Außerdem möchte man häufig gerne nur eine Liste der Variablen sehen, die exportiert wurden.

Die Lösung dieser  Problemstellungen liegt in den beiden Kommandos set und env.

Ruft man set ohne jeden Parameter oder Option auf, so liefert das Kommando alle Variablen und Funktionsdefinitionen der aktuellen Shell und zwar in jeder Ausgabezeile ein Paar der Form
<Variablenname>=<Wert>

Der Befehl env hingegen liefert eine Liste aller Variablen, die exportiert worden sind und deshalb auch in einer Untershell (subshell) sichtbar sind. Eine Alternative zum 'env' stellt übrigens auch der Befehl "export -p" dar.

Besondere Shell-Variablen

Eingabe-Prompt

Der Eingabe-Prompt, auch Prompt-Sequenz genannt, dient dazu dem Benutzer zu signalisieren, dass die Eingabe einer weiteren Kommandozeile möglich ist.
Ein Eingabeprompt endet immer mit einem bestimmten Zeichen z.B. "~" oder ">". Im Falle des Superusers endet sie meist mit einem Rautenzeichen "#", damit man sofort merkt, dass man als Superuser eingeloggt ist.
Vor dem letzten Prompt-Zeichen können andere Informationen, so wie beispielsweise Rechnername, Verzeichnisname, Pfad, Datum und so weiter stehen.
Das Aussehen der Shell-Eingabeaufforderung wird durch die Umgebungsvariable PS1 bestimmt. PS1 steht übrigens für "Prompt String 1".

Anpassen des Eingabe-Promptes an eigene Bedürfnisse

Der Eingabe-Prompt in der Bash-Shell kann je nach Distribution unterschiedlich sein.  Häufig ähnelt er jedoch folgender Einstellung:

PS1='[\u@\h \W]\$ '
Man beachte, dass hinter dem Dollarzeichen sich ein Leerzeichen befindet. Dadurch werden Eingaben in der Kommandozeile besser lesbar, da die Eingabe vom Prompt mit einem Blank getrennt ist. Obige Einstellung druckt in geschweifter Klammer zuerst den Benutzername (\u), dann hinter dem @-Zeichen den Rechnernamen und dann getrennt durch ein Leerzeichen das aktuelle Verzeichnis (nur base directory) aber keine übergeordneten Verzeichnisse.

Möchte man seinen Eingabeprompt dauerhaft ändern, so definiert man ihn am besten in der Datei ~/.profile neu. Die Defaultkonfiguration von PS1 erfolgt für alle Benutzer in /etc/bashrc.bash   emacs

Häufige in Prompts verwendete Abkürzungen:

Variable
Bedeutung
\u
Benutzername
\h
Hostname
\w
Aktuelles Verzeichnis in Langform, also z.B. /home/freddy/beispiele
\W
Aktuelles Verzeichnis aber nur das letzte Unterverzeichnis ohne die übergeordneten Verzeichnisse, d.h. nur das Verzeichnis "beispiele" aus dem Beispiel der vorigen Zeile
\d
Datum
\A
Uhrzeit
\D
zur Konfiguration eines beliebigen Datum und Uhrzeitstrings. Allerdings wird \D immer von einem Format-String gefolgt:
Beispiel:
PS1='[\u@\h \D{%d.%m.%Y, %H:%M:%S}]\$ '
liefert folgenden Eingabeprompt:
[bernd@localhost 16.04.2008, 18:26:56]$
\v
Versionsnummer der Bash-Shell in der Form <Hauptversionsnummer>.<Nebenversionsnummer> (major release und minor release)
\V
Versionsnummer der Bash-Shell in der Form <Hauptversionsnummer>.<Nebenversionsnummer>.<Revisionsnummer>
$SHLVL
Shell Level. Ruft man innerhalb einer Shell wieder eine Shell auf, erhöht sich der Shell-Level um 1.
Beispiel:
[bernd@localhost 2]$ export PS1='[\u@\h $SHLVL]\$ '
[bernd@localhost 2]$ bash
[bernd@localhost 3]$ export PS1='[\u@\h $SHLVL]\$ '
[bernd@localhost 3]$ bash
[bernd@localhost 4]$  
\l
base pty
$PWD
aktuelles Arbeitsverzeichnis
Im Unterschied zu "\w" benutzt $PWD keine abgekürzten Schreibweisen. Das Homeverzeichnnis wird beispielsweise von \w als "~" und von $PWD immer als /home/<username> ausgegeben.
\?
Der Exit-Status der letzten Anweisung
\!
Nummer in der History des letzten Befehls
\j
Anzahl der noch in der Shell aktiven Hintergrundjobs
\n
Erzeugt eine neue Zeile. Dies ist eine elegante Möglichkeit viele nützliche Informationen in einen Shell-Prompt zu packen und gleichzeitig in einer relativ kurzen Zeile mit der Eingabe zu beginnen:


Auch farbige Eingabeprompts sind möglich:

export PS1='\[\033[1;34m\][\u@\h SH-Lev:$SHLVL \D{%H:%M} jobs:\j c:\! \w]\n\$\[\033[0m\] '
Der obige Prompt liefert folgende Ausgabe:
[bernd@localhost SH-Lev:4 20:36 jobs:0 c:1001 ~/bashcb]
$

Vernachlässigte Prompts

In den meisten Büchern über Linux und sogar spezieller Literatur über Shells feht häufig der Hinweis auf die drei anden Eingabeprompts und ihre zugehörigen Umgebungsvariablen, d.h. PS2, PS3 und PS4. Sie werden wie folgt verwendet:

Prompt-Umgebungsvariable
Funktion
PS1
der Default-Prompt, der sogenannte Zweitprompt (engl. "secondary prompt").
PS2
wird bei Eingaben benutzt, die über mehrere Zeilen gehen. Also wenn die Shell zur Ausführung eines Kommandos weitere Informationen benötigt, die in weiteren Zeilen eingegeben werden.
PS3
Auswahl-Prompt
PS4
HIerbei handelt es sich um den xtrace-Prompt (debugging). Der Default-Wert ist  das Plus-Zeichen "+".

Die Funktionsweise des Auswahlprompts versteht am am besten in folgendem Bash-Beispielprogramm:

#!/bin/bash
PS3="Ihre Wahl:"
OPTIONS="Hello Quit"
select opt in $OPTIONS; do

if [ "$opt" = "Quit" ]; then
    echo Ciao
    exit
elif [ "$opt" = "Hello" ]; then
    echo Hello World
else
    echo Diese Auswahl kenn ich nicht!
fi
done

Ein Aufruf liefert zum Beispiel folgenden interaktiven Beispieldialog:

[freddy@localhost tests]$ ./sel.sh
1) Hello
2) Quit
Ihre Wahl:1
Hello World
Ihre Wahl:3
Diese Auswahl kenn ich nicht!
Ihre Wahl:2
Ciao


 







© Copyright 2007 - 2010, Bernd Klein mit freundlicher Unterst├╝tzung von Bodenseo, Linux-Kurse und Schulungen,
Foto linke Seite (Mann mit Strick und Colt): Foto: ┬ę Ljupco Smokovski, fotolia 984022