1.1 Basics
Inhalt
- Die Shell
- Navigation und Commandline Programme
- Manipulation mit Dateien
- Suchen und Finden
- STDIN, STDOUT und andere Kanäle
- Der Pipeoperator
- Das env (Evnironment)
Die Shell
Die Shell ist ein Programm über welches der Benutzer mit dem System kommuniziert. Es nimmt Befehle an und führt die gewünschten Aktionen auf dem System aus. Genau gleich wie es verschiedene Linux Distributionen gibt, gibt es auch verschiedene Shells. Hier eine Auflistung der Populärsten mit ihrem initialen Releasedatum.
- sh, Bourne Shell, 1979
- bash, Bourne Again Shell, 1989
- ash, Almquist Shell, 1989
- zsh, Z Shell, 1990
- dash, Debian Almquist Shell, 1997
- fish, friendly interactive shell, 2005
Auf den allermeisten Linux system finden sich heutzutag bash
und sh
als
Standardshell vorinstalliert. Daher befasst sich dieses Lab auch
ausschliesslich mit der Bedienung dieser Beiden.
|
|
Ein Blick auf die Standardshell
Programme auf der Shell reden miteinander über die Kanäle “Standard Out” stdout
und “Standard In” stdin
.
Normalerweise schreibt ein Programm seinen Output nach stdout
und nimmt auf stdin
Input entgegen.
Diese Kanäle lassen sich über die Operatoren <,>,&,|
umbiegen. Doch dazu später mehr.
Alle Programme die dem POSIX Standard folgen kommen mit einer Hilfe Ausgabe.
Diese kann über die Parameter -h
oder --help
ausgegeben werden.
Navigation und Commandline Programme
Die eben kennengelernte Shell dient als Interface für die Bedienung einer Vielzahl von Programmen. Auch die Navigation in der Ordnerstruktur des Betriebsystems kann komplett über die Shell erfolgen. Folgende Werkzeuge werden dafür verwendet.
- ls,
list
, Zeige den Inhalt des aktuell gewählten Pfades an - cd,
change directory
, Springe zu einem beliebigen Pfad hin - pwd,
print working directory
, Zeige den kompletten Pfad an
Beispiel Navigation
|
|
Beispiel Navigation
In obigem Beispiel wird die Shell dazu verwenden in den Ordner dieses Labs zu springen und dessen Inhalt auszugeben. Das ~
ist dabei ein Shortcut und bezieht sich immer auf das Home Verzeichnis des aktuellen Nutzers.
Manipulation mit Dateien
Über die Shell können natürlich auch Dateien und Ordner erstellt, gelöscht und ausgegeben werden. Dafür dienen folgende Werkzeuge.
- touch, Erstelle eine Datei
- cat, Gib eine Datei aus
- cp, Kopiere eine Datei oder einen Order
- file, Zeige Metainformationen zu einer Datei
- mkdir, Erstelle einen Ordner
- rm, Lösche eine Datei oder einen Ordner
- mv, Verschiebe eine Datei oder einen Ordner
- less, Gib eine beliebige grosse Datei aus ohne mir das ganze System zu zerschiessen
Beispiel
|
|
Verwalten von Dateien mit der Shell
Hier wird die Shell dazu verwendet einen neuen Order im Homeverzeichnis des
Nutzers zu erstellen. Der Parameter -p
weist das Programm mkdir
dazu an
Unterordner die es noch nicht gibt gleich mit zu erstellen.
Das Programm file
wird dazu benutzt um den Typ des Inhalts der Datei zu prüfen.
Dann wird die Datei mit cat
ausgegeben und der Output mittels >
gleich dazu verwendet
eine neue Datei mit diesem Inhalt zu erstellen. Schlussendlich wird less
verwendet um die Datei bequem zu lesen. Das Programm kann mittels CTRL+C
verlassen werden.
|
|
Löschen von Dateien und Ordnern
In obigem Beispiel wird zuerst die eben erstellte Datei gelöscht, anschliessend
wird mittels cd ..
in den übergeordneten Ordner gesprungen und der
entsprechende Ordner, mit -r
(rekursiv) gelöscht. Der erste Schritt wäre nicht nötig gewesen, da
beim Löschen eines Ordners logischerweise auch der Inhalt flöten geht.
Suchen und Finden
Die suche von Dateien über die Shell ist effizient und schnell. Die Hauptarbeit
leistet hierbei das Programm find
. Find ermöglicht es sowohl nach Ordnern wie
auch Dateien an beliebigen Orten im System zu suchen. Die grundlegenden
Funktionen von find
sind schnell erklärt. Das erste Argument von
find
ist immer das Verzeichnis in welchem gesucht werden soll. Wird es
weggelassen sucht find
im aktuellen Verzeichnis. Mittels -type
lässt sich
der Typ der Suche festlegen, also beispielsweise Datei (-f
) oder Ordner (-d
).
Und über das Argument -name
kann der Name einer Datei spezifiziert werden.
Natürlich funktionieren beim Namen auch Platzhalter wie Wildcards. Es kann
beispielsweise mittels -name "*.txt"
nach allen Dateien mit der Endung .txt
gesucht werden.
|
|
Grundlegende Funktion von find
Weitere Standardprogramme
Hier werden weitere wichtige Werkzeuge genannt.
Deren Funktion und Details sollen von der lesenden Person über das Helpfile (-h
oder --help
) als Aufgabe erarbeitet werden.
- history
- tree
- wc
- nl
- sort
- uniq
STDIN, STDOUT und andere Kanäle
STDOUT
Wie bereits angesprochen verwendet jede Shell die Kanäle STDIN
und STDOUT
um den Input sowie Output von Programmen zu verwalten. In diesem Teil
untersuchen wir genauer was dabei passiert. Dazu betrachten wir folgendes
Beispiel.
|
|
Beispiel Umbiegen von STDOUT
Der >
Operator wurde in obigen Beispielen bereits einige Male verwendet.
Normalerweise gibt ein Programm seinen Output auf dem STDOUT
Kanal aus.
Dieser wird von der Shell direkt angezeigt. Bei diesem Operator handelt es sich
um einen Shortcut welcher den Output des Programms nun so umbiegt dass der Text
in einer Datei namens test.txt
landet. Die Datei wird neu erstellt falls sie noch nicht existiert.
Will man stattdessen einer Datei etwas hinzufügen ohne den Inhalt zu
überschreiben verwendet man >>
wie im folgenden Beispiel ersichtlich.
|
|
Beispiel Umbiegen von STDOUT mit append
STDIN
Um Programme mit Input zu füttern verwenet man den STDIN
Kanal. Betrachten
wir folgendes Beispiel für das Programm cat
.
|
|
Beispiel Umbiegen von STDIN
Erst legen wir eine Datei mit dem Namen hallo.txt und dem Inhalt “Hallo Puzzle”
an. Dann verwenden wir den <
Operator um den Inhalt der Datei über STDIN
an
das Programm cat
zu senden welches wiederum den Text ausgibt.
Gehen wir anhand des nächsten Beispiels nun einen Schritt weiter und verwenden die Ausgabe von cat
um eine
weitere Datei output.txt zu erstellen.
|
|
Beispiel Umbiegen von STDIN und Schreiben nach STDOUT
Nun landet der Text nicht in der Shell, sondern in der neuen Datei output.txt
STDERR
Ein weiterer Kanal der oft fürs Debugging verwendet wird ist STDERR
. In
diesem Kanal landen alle Fehlermeldungen. Bricht ein Programm mit einem
Fehlercode ab, so wird es seinen Output über diesen Kanal umschreiben, sofern
es dem POSIX Standard folgt. Die allermeisten Shells machen hier keine Ausnahme
und geben alles was in STDERR
landet direkt aus.
|
|
Beispiel STDERR
Wir versuchen per ls
Informationen über die nicht vorhandene Datei asdf
zu
betrachten, erhalten stattdessen einen Fehler da die Datei nicht existiert.
Bei der Ausgabe der Zustandsvariable $?
sehen wir einen Returncode mit dem
Wert 2. Was heisst das nun?
- Alle Programme die dem POSIX Standard folgen geben nach erfolgreicher Ausführung den Returncode 0 aus.
- Mittels
$?
lässt sich der Returncode des zuletzt ausgeführten Programmes anzeigen. - Jeder Returncode ungleich Null ist gemäss POSIX ein Fehler.
- In der entsprechenden Manpage des jeweiligen Programmes sind die Bedeutungen verschiedener Returncodes nachzuschlagen.
|
|
Auszug aus der Manpage von ls
In der Manpage finden wir heraus dass der Returncode 2 also ein Fehler mit der angegebenn Datei darstellt. In diesem Fall existiert diese einfach nicht. Nicht jeder Programm hat definierte Error Codes. Grundsätzlich ist alles was nicht Null ist aber ein Fehler.
Doch was wenn wir den Fehler nun loggen möchten ohne den kompletten Output des
Programmes inklusive STDOUT
in eine Datei zu schreiben? Wir möchten ja
schliesslich nur die Fehler sehen und nicht was das Programm sonst noch so tut.
Dazu können wir die Filedeskriptoren 0,1,2
verwenden welche zu den Kanälen
stdin,stdout,stderr
korrellieren. Möchten wir nur STDERR
in eine Datei
schreiben biegen wir also den Kanal mitdem Filedeskriptor 2 um.
|
|
Beispiel Umbiegen von STDERR in eine Datei
Dies wird beispielsweise auch oft verwendet wenn wir die Fehlermeldungen nicht
sehen möchten. Beispielsweise in Skripten oder Cronjobs wo diese sich störend
auf den Programmfluss auswirken würden. Unter Unix gibt es dafür das sogenannte Null
Device, oder auch /dev/null
. Alles was nach /dev/null
geschrieben wird wird
verworfen.
|
|
Beispiel Umbiegen von STDERR nach /dev/null
Die Fehlermeldungen von ls
werden in diesem Fall nun verworfen. Oft möchte man
sämtlichen Output eines Programmes nach /dev/null
umleiten. Dazu kann man
folgende Syntax verwenden.
|
|
Beispiel Umbiegen jeglichen Outputs nach /dev/null
Die Angabe 2>&1
weist die Shell dazu an den Kanal STDERR
nach STDOUT
umzuleiten. Da STDOUT
aber bereits nach /dev/null
umgeleitet ist wird
sämlticher Output im Null Device landen. Dieser Trick sollte man sich merken da
er oft verwendet wird!
Der Pipeoperator
Der |
Operator nennt sich Pipe. Mit ihm lässt sich ähnlich wie mit dem
>
Operator der Output eines Programmes umleiten. Möchte man den Output eines
Programmes als Input für ein Anderes verwenden verwendet man statt >
den Pipeoperator.
Ein oft verwendetes Beispiel ist das Folgende.
|
|
Beispiel zur Verwendung des Pipeoperators
Hier wird der Output des Programmes ls
als Input in das Textbetrachtungsprogramm less
geschickt. less
hat gegenüber der normalen Ausgabe den Vorteil dass man darin Suchen und auch Scrollen kann.
Später werden wir den Pipeoperator im Zusammenhang mit dem Programm grep
weiter verwenden um die Ausgabe von Programmen effizient nach beliebigen
Mustern zu durchsuchen.
Das env (Environment)
Das Environment besteht aus einer Vielzahl an Umgebungsvariablen. In ihnen sind Informationen zur aktuell verwendeten Umgebung enthalten. Alle Werte sind für die aktuelle Shell öffentlich. Das heisst jedes Programm das in dieser Shell ausgeführt wird, kann diese Werte lesen und nach belieben überschreiben.
|
|
Beispiel zur Ausgabe des lokalen env
Die Ausgabe wurde der Einfachheit halber auf einige essentielle Variablen gekürzt. Wir sehen also dass unter anderem der User spezifiziert wird. Dies ermöglicht es auch Shell Skripte benutzerunabhängig zu schreiben, wie in folgendem Beispiel ersichtlich wird.
|
|
Beispiel zur Verwendung von Umgebungsvariablen
Um auf den gespeicherten Wert einer Umgebungsvariablen zuzugreifen verwendet man den
$
Operator. Er ermöglicht es uns also in obigem Beispiel direkt in das
Downloads Verzeichnis des Nutzers zu Springen, ohne diesen explizit zu
deklarieren.
Die wahrscheinlich wichtigste Umgebungsvariable ist allerdiens die Pfadvariable
oder auch PATH
. Alle Ordner die in dieser Variable spezifiziert werden können
von der Shell aus ohne Angabe ihrer genauen Position ausgeführt werden.
|
|
Beispiel zur Verwendung der Pfadvariable
Mittels Aufruf des Programmes which
sehen wir den eigentlichen
Installationspfad von ls
. Nämlich das Verzeichnis /usr/bin/
.
Wir können das Programm aber von beliebigen Orten aus über die Shell aufrufen.
Dies ist nur möglich weil sich das Verzeichnis /usr/bin
in der Pfadvariable
befindet.
Möchte man einen eigenen Ordner zur Pfadvariable hinzufügen (um einfacher auf selbst geschriebene Skripte oder Programme zuzugreifen) kann man dies folgendermassen tun.
|
|
Beispiel zum Hinzufügen von Verzeichnisen zur Pfadvariable
In obigem Beispiel erweitern wir die Pfadvariable um das Nutzer Verzeichnis /home/$USER/bin
.
Natürlich müssen wir dabei aufpassen dass wir die Pfadvariable nicht komplett
überschreiben, sonst wirds mühsam Programme auszuführen. Dazu schreiben wir den
Wert der Pfadvariable neu, hängen aber hinten den aktuellen Wert wieder an.
Dadurch wird sichergestellt dass wir nichts verlieren.
Mit dem obigen Befehl wird die Pfadvariable in der aktuellen Shell neu gesetzt. Damit die Änderung auch bei neuen Shells oder nach einem Reboot noch vorhanden ist, kann die Datei ~/.bashrc
angepasst werden.