ZIV

  Linux-Einführung

Die Bash

 

WWU


Datei-Befehle  zurück vor Weitere Befehle

Die Bash (Bourne Again Shell)

Parametrierung

Man kann die bash seinen Bedürfnissen anpassen, indem man bash-Anweisungen in eine der folgenden Dateien stellt:


/etc/profile Beim Anmelden für systemweite Voreinstellungen automatisch ausgeführt.
$HOME/.profile Beim Anmelden für benutzereigene Voreinstellungen automatisch ausgeführt.
$HOME/.bashrc Beim Starten der Shell ausgeführt.
$HOME/.bash_logout Beim Abmelden automatisch ausgeführt.
HOME ist eine Shell-Variable, deren Wert $HOME der Pfad des HOME-Verzeichnisses ist. Meine .bashrc sieht so aus:
test -e ~/.alias && . ~/.alias
PS2=".. "
PS1='[\u@\h \w] \$ '
#
set -o emacs
set -o ignoreeof

Programmausführung

Die Hauptaufgabe der Shell besteht darin, Programme zu finden und auszuführen. Gefunden werden Programme, indem in allen Verzeichnissen, die in der Variablen $PATH stehen, nach ihnen gesucht wird.
===== ux02 (ost) /dfs/u/o/ost =====
  ost> echo $PATH
/usr/bin:/bin:/usr/bin:/usr/X11R6/bin:/dfs/a/urz/bin:/dfs/u/o/ost/bin
Ist ein Programm gefunden, so erstellt die bash eine Kopie von sich und ruft diese Kopie auf, um das gewünschte Programm  auszuführen. Am Ende des Programms beendet sich auch die Kopie. Das Original hat solange gewartet, sofern man nichts anderes gesagt hat. Dieses Modell der Programmausführung ist typisch für Unix-Systeme.

Durch which befehl oder type befehl kann man feststellen, wo ein Befehl steht.

Schreibweisen von Befehlen



Befehl Führe den Befehl aus und warte, bis er fertig ist
Befehl & Führe den Befehl im Hintergrund aus und warte nicht, sondern bitte um den nächsten Befehl
Befehl1 ; Befehl2 Befehlsfolge: Führe erst den Befehl1 und dann Befehl2 aus
(Befehl1 ; Befehl2) Beide Befehle werden als Gruppe in einer Shell-Kopie ausgeführt
Befehl1 | Befehl2 Ausgabeumleitung pipe: Die Ausgabe von Befehl1 wird die Eingabe von Befehl2. Beide Befehle arbeiten gleichzeitig
Befehl1 $(Befehl2) Die Ausgabe von Befehl2 wird zu Befehlsargumenten von Befehl1
Befehl1 && Befehl2 Befehl2 wird nur ausgeführt, wenn Befehl1 erfolgreich war 
Befehl1 || Befehl2 Befehl2 wird nur ausgeführt, wenn Befehl1 nicht erfolgreich war
pipes sind eine Besonderheit. Beide Programme laufen gleichzeitig. Das linke Ende der pipe schreibt Daten. Das rechte pipe-Ende wartet, bis es Daten lesen kann. Ist das linke Ende fertig, so wird dies dem rechten Ende als Signal mitgeteilt.

Beispiele

Wird ein Befehl im Hintergrund ausgeführt, so ist seine Ausgabe asynchron zu der weiterlaufenden bash. Die Reihefolge der Ausgabezeilen ist zufällig.
[mg@zivtux /var] $ ls -al & cat ~/.bashrc
insgesamt 12
drwxr-xr-x   20 root     root          423 Jun 20  2001 .
drwxr-xr-x   27 root     root          558 Jan 29 13:52 ..
drwxr-xr-x    6 root     root          132 Jun 20  2001 X11R6
drwxr-xr-x   17 root     root          418 Jun 21  2001 adm
drwxr-xr-x    5 root     root           96 Jun 20  2001 cache
drwxr-xr-x    2 root     root           35 Jun 20  2001 deliver
drwxrwxr-x    2 games    game           62 Jun 20  2001 games
test -e ~/.alias && . ~/.alias

PS2=".. "
# PS1='\[\][\u@\h \w] \[\] \n$ '
PS1='\n[\u@\h \w] \$ '
#
set -o emacs
set -o ignoreeof
drwx------    2 root     root           35 Jun 20  2001 iptraf
drwxr-xr-x   40 root     root          869 Mär  4 00:20 lib
drwxrwxr-x    3 root     uucp           57 Feb 27 16:19 lock
drwxr-xr-x    8 root     root         1056 Feb 28 00:17 log
lrwxrwxrwx    1 root     root           10 Mai  3  2001 mail -> spool/mail
drwxr-xr-x    3 named    root          139 Jun 20  2001 named
drwxr-xr-x    3 root     root           56 Jun 20  2001 opt
drwxr-xr-x    4 root     uucp          473 Feb 27 16:20 run
drwxr-xr-x   19 root     root          414 Jun 20  2001 spool
drwxr-xr-x    4 squid    root           76 Jun 20  2001 squid
drwxr-xr-x    5 root     root          100 Mai  3  2001 state
drwxrwxrwt    4 root     root           92 Mär  4 16:08 tmp
drwxr-xr-x    2 root     root           35 Sep 11 14:55 ucd-snmp
drwxr-xr-x    3 root     root          133 Jun 20  2001 yp
Eine in Klammern eingeschlossene Befehlsfolge ändert die Befehlsumgebung der aktuellen bash nicht. Achten Sie auf das jeweilige Arbeitsverzeichnis am Ende der Befehlsfolge!
[mg@zivtux ~ ] $ cd /var; ls
X11R6  cache    games   lib   log   named  run    squid  tmp       yp
adm    deliver  iptraf  lock  mail  opt    spool  state  ucd-snmp
[mg@zivtux /var ] $ cd
[mg@zivtux ~] $ (cd /var; ls)
X11R6  cache    games   lib   log   named  run    squid  tmp       yp
adm    deliver  iptraf  lock  mail  opt    spool  state  ucd-snmp

[mg@zivtux ~ ] $
Programme geben konventionsgemäß einen Return-Code zurück, aus dem man ablesen kann, ob ein Befehl erfolgreich war oder nicht. Dabei bedeutet ein Rückgabewert von Null, dass alles in Ordnung ablief. Diesen Rückgabewert machen sich die Operatoren && und || zu Nutze.

Achtung: Nicht alle Programme, am häufigsten die selbstgeschriebenen, beachten die Return-Code-Konvention.

Sind die Rückgabewerte allerdings aussagekräftig, so kann man sinnvolle Befehlsfolgen programmieren:

===== "stefan" as "stefan" (merlin) /home/stefan =====
stefan> ./configure && make all
Manchmal möchte man die Ausgabe eines Programmes als Argument für ein zweites Programm verwenden:
===== "stefan" as "stefan" (merlin) /home/stefan =====
stefan> echo "$(date) -- Platzverbrauch: $(du -ks .)"
Sun Sep 10 13:17:16 CEST 2000 -- Platzverbrauch: 263008 .
echo erwartet eine Zeichenkette, die es auf der Konsole ausgibt. Die Zeichenkette enthält zwei $(...)-Konstrukte. Die in Klammern stehenden Befehle werden ausgeführt und ihre Ausgabe in die Zeichenkette substituiert. date liefert eine Datums/Zeitangabe und du -ks . zählt, wieviel Platz das aktuelle Verzeichnis und seine Unterverzeichnisse in Anspruch nehmen.

Platzhalterzeichen in Dateinamen

Dateinamen können Platzhalterzeichen enthalten und bilden ein Dateinamen-Suchmuster. Dieses Muster wird vor der Befehlsausführung mit den vorhandenen Dateien verglichen (globbing). Die auf das Muster passenden Dateinamen werden zu Befehlsargumenten. Diesen Vorgang nennt man auch Parameter-Expansion.



Platzhalter Bedeutung
* Passt auf jede Zeichenfolge. Ein *, der als erstes Zeichen eines Dateisuchmusters steht, passt nicht auf Dateinamen, die mit einem Punkt beginnen
? Passt auf genau ein beliebiges Zeichen
[ xyz] Passt auf genau ein Zeichen aus der Menge der in eckigen Klammern eingeschlossenen Zeichen
[! xyz] Passt auf jedes Zeichen, das nicht in der Menge der in eckigen Klammern eingeschlossenen Zeichen ist
Hat man dummerweise Dateien angelegt, deren Namen Platzhalterzeichen enthalten, so kann man sie ansprechen, wenn man die besondere Wirkung der Platzhalterzeichen maskiert. Am einfachsten dadurch, dass man den Dateinamen in einfache Hochkommata einschließt.

Beispiele

echo ist ein bash-eigenes Kommando, mit dem die Wirkung der Platzhalterzeichen getestet werden kann:
===== "stefan" as "stefan" (merlin) /home/stefan/Linux =====
Linux> echo *
Hinweise.html Uebersicht.html V-04.09.2000.html V-05.09.2000.html V-06.09.2000.html V-07.09.2000.html V-07.09.2000.html~
===== "stefan" as "stefan" (merlin) /home/stefan/Linux =====
Linux> echo .*
. ..
===== "stefan" as "stefan" (merlin) /home/stefan/Linux =====
Linux> echo *.html
Hinweise.html Uebersicht.html V-04.09.2000.html V-05.09.2000.html V-06.09.2000.html V-07.09.2000.html 
===== "stefan" as "stefan" (merlin) /home/stefan/Linux =====
Linux> echo  [HU]*.html
Hinweise.html Uebersicht.html
===== "stefan" as "stefan" (merlin) /home/stefan/Linux =====
Linux>

Ein/Ausgabe-Kanäle

Jedes Programm kann davon ausgehen, drei Kanäle zur Ein/Ausgabe zur Verfügung zu haben.



Deskriptor Name Abkürzung Default
Standardeingabe stdin Tastatur
Standardausgabe stdout Bildschirm
Standardfehler stderr Bildschirm
Die voreingestellten Kanäle können umgeleitet werden:



Umleitung Bedeutung
<Datei Standardeingabe nach Datei umleiten
>Datei Standardausgabe nach Datei umleiten
2>Datei Standardfehler nach Datei umleiten
2>&1 Standardfehler auf den Deskriptor 1 (stdout) umleiten
>>Datei Standardausgabe nach Datei umleiten. Existiert Datei schon, so wird sie ergänzt und nicht überschrieben 
Befehl1 | Befehl2 pipe: Standardausgabe von Befehl1 auf die Standardeingabe von Befehl2 umleiten

Beispiele

wc (word count) ist ein Befehl, der in Pipes zum Zählen gelegen kommt. wc -l zählt die Eingabedatei-Zeilen.
[mg@zivtux ~] $ ls -l > ls.out

[mg@zivtux ~] $ ls -l ls.out
-rw-r-----    1 mg       u0rz          135 Mär  4 17:25 ls.out

[mg@zivtux ~] $ > LeereDatei

[mg@zivtux ~] $ ls -l LeereDatei
-rw-r-----    1 mg       u0rz            0 Mär  4 17:26 LeereDatei

[mg@zivtux ~] $ who | wc -l
      2

[mg@zivtux ~] $ echo "$(who | wc -l) Nutzer angemeldet."
      2 Nutzer angemeldet.

 Quoting, Maskieren

Bestimmte Zeichen haben für die bash eine besondere Bedeutung. Will man diese Zeichen in ihrer literalen Bedeutung nutzen, so muss man ihre spezielle Wirkung maskieren (quoting). Die bash kennt drei Formen des Maskierens:


" ... "  Mit Ausnahme des $ (Variablen- und Befehlssubstitution) und des \ sind alle Zeichen maskiert. 
' ... '  Alle Zeichen sind maskiert.
Das folgende Zeichen wird maskiert. Kann auch innerhalb doppelten Anführungszeichen verwendet werden.

Shell-Variablen

Die bash kennt eine Reihe Variablen, die das Verwalten der bash parametrisieren. set gibt Auskunft (Die Ausgabe ist stark gekürzt) :
===== "stefan" as "stefan" (merlin) /home/stefan/temp =====
temp> set
DISPLAY=:0
EDITOR=vi
HOME=/home/stefan
HOSTNAME=merlin
OLDPWD=/home/stefan
PATH=/usr/local/bin:/usr/bin:/usr/X11R6/bin:/bin:/opt/kde/bin:/usr/openwin/bin:.
PS1='===== "$USER" as "$EUSER" ($HOSTNAME) $PWD =====
${PWD##?*/}> '
PS2='> '
PWD=/home/stefan/temp
SHELL=/bin/bash
SHELLOPTS=braceexpand:hashall:histexpand:monitor:privileged:ignoreeof:interactive-comments:emacs
TERM=kvt
USER=stefan
Wie bash-Variablen verändert werden können, zeigt dieses Beispiel:
===== "stefan" as "stefan" (merlin) /home/stefan/temp =====
temp> echo $PATH
/usr/local/bin:/usr/bin:/usr/X11R6/bin:/bin:/opt/kde/bin:/usr/openwin/bin:.
===== "stefan" as "stefan" (merlin) /home/stefan/temp =====
temp> PATH=/home/stefan/bin:$PATH
===== "stefan" as "stefan" (merlin) /home/stefan/temp =====
temp> echo $PATH
/home/stefan/bin:/usr/local/bin:/usr/bin:/usr/X11R6/bin:/bin:/opt/kde/bin:/usr/openwin/bin:.

Der Prompt

Die Eingabeaufforderungen PS1 und PS2 können Platzhalter enthalten, in die jeweils der aktuelle Wert eingesetzt wird:


Platzhalter Bedeutung
\h
(Kurzer) Hostname
\n
Newlinezeichen
\t
Uhrzeit
\u
Benutzername
\w
Arbeitverzeichnis (lang)
\W
Arbeitsverzeichnis (kurz)
\$
# für den Superuser und  $ sonst 

Aliase

Ein Alias bietet die Möglichkeit, längere, häufig verwendete Befehle abzukürzen:

alias alias=ersetzungstext

Beispiel:

alias l='ls -aCF'
alias ll='ls -la'
alias lll='ls -latr'

Die "magische" Tab-Taste

In Microsoft-Produkten hieße sie wahrscheinlich "Do what I mean"-Taste und würde als jüngstes Beispiel künstlicher Intelligenz gefeiert. 8-)

In Wirklichkeit hilft sie beim Schreiben von Befehlen, indem sie, wenn möglich, den Befehl zu Ende schreibt. Sie weiß, wo syntaktisch ein Befehl oder ein Dateiname stehen könnte und gibt passende Vorschläge zur Vervollständigung.

Übungen

Das Skript /tmp/wild legt in Ihrem Arbeitsverzeichnis ein Unterverzeichnis wildcard mit einigen Dateien an.
Führen Sie das Skript aus und wechseln Sie in das Unterverzeichnis.
Geben Sie alle Dateinamen aus, die
  1.  mit "a" anfangen
  2.  nicht mit "a" anfangen
  3.  ein "a" enthalten
  4.  als zweites Zeichen ein "a" enthalten
  5.  mit "a" anfangen und als zweites Zeichen keinen Vokal enthalten
  6.  mit "a" anfangen und als zweites Zeichen einen Konsonanten enthalten
  7.  aus zwei Zeichen bestehen
  8.  Welcher Dateiname wird mit echo "\\*" bzw echo '\\*'  ausgegeben ?
  9.  Welcher Dateiname wird mit echo \\*  ausgegeben ? Warum ?


Vorlesungsübersicht zurück vor Weitere Befehle

Zentrum für Informationsverarbeitung / © Stefan Ost, Mathias Grote / Letzte Änderung:  23. August 2004