Shell basics
In diesem Abschnitt lernen wir die Linux Shell, bzw. genauer, die bash kennen. Neben der bash gibt es auch noch andere Shells. Auf die verschiedenen grafischen Oberflächen (GUIs bzw. Desktop Environemts) gehen wir nur sehr kurz ein, weil sie einerseits leicht selbst angeeignet werden können und andererseits die Shell in jeder Distribution gleich funktioniert.
Keywords: bash, Aufbau von Shell Befehlen, Umgebungsvariablen, echo, alias, pwd, ls, cd, cp, mv, less, diff
Zum Umgang mit dem Terminal
Es gibt viele verschiedene Graphical User Interfaces (GUIs). Verschiedene Distributionen haben unterschiedliche Standard-GUIs eingestellt. Prinzipiell kann ich aber alle anderen auch immer nachinstallieren und zwischen diesen Umschalten. Generell sprechen wir hier von Desktop Environments. Die verwenden wir heute standardmäßig um mit dem System zu interagieren und unsere täglichen Arbeiten zu erledigen.
Einige Beispiele von Desktop Environments sind auf der Wikipedia Seite dazu (inklusive Screenshot-Gallerie) versammelt: https://en.wikipedia.org/wiki/Desktop_environment#Examples_of_desktop_environments
Die meisten gebräuchlichen Systemeinstellungen sind auch über diese grafische Oberfläche einstellbar. Allerdings schauen die Menüs und die jeweiligen Konfigurationstools je nach Desktop Environment unterschiedlich aus. Darunter liegen aber meist Befehle, die auch direkt per Shell ausgeführt werden können. Diese sind daher universeller und werden auch eher eingesetzt um im Web hilfreiche Infos zu verteilen und Fehlersuche zu betreiben. Wir arbeiten im Workshop auch deswegen vor allem mit der Shell. Konkret mit der bash. Während neben dem Desktop Environment (die quasi die grafische Shell ist) immer parallel auf den Konsolen 1-6 (Strg-Alt-F1...F6) eine bash (oder je nach Distro auch eine andere Shell waret), kann diese auch in der grafischen Umgebung gestartet werden - in den Programmmenüs meist als "Terminal", manchmal auch als "Konsole" zu finden. Auch hier gibt es unterschiedliche grafische Programme die dann eine der bekannten Shells starten. Z.B. gnome-terminal, xterm, ...
Die bash - was ist das?
Ein "interaktiver Kommandozeileninterpreter". ... hm, ok, dröseln wir das auf. Ein Kommandozeileninterpreter, was ist das? Ein Programm, das einzelne Kommandozeilen interpretiert und entsprechende Aktionen veranlässt (je nachdem, wie die Kommandozeile interpretiert wurde. Und was ist eine Kommandozeile? Eine Zeile die ein, oder vielleicht auch mehrere Kommandos beinhaltet, wobei diese Kommandos vielleicht auch Optionen und Parameter haben. Aber dazu später mehr. Und wieso ist dieser Kommandozeileninterpreter jetzt interaktiv? Weil er, sobald er gestartet wird, eine Prompt ausgibt (also eine Eingabeaufforderung), und wir dann einfach eine Kommandozeile eingeben können. Erst wenn wir diese Abschließen (z.B. durch Drücken der Eingabetaste), wird das Kommando interpretiertu und entsprechende Schritte gesetzt (z.B. Programme werden ausgefüht). Sobald diese Sequenz beendet ist, kommt wieder eine neue Prompt und wir können wieder ein Kommando eingeben. Ein nicht-interaktiver Kommandozeileninterpreter wäre also im Vergleich einer, dem ich nur irgendwie einen Haufen Kommandozeilen auf einmal geben kann (in Form eines Scripts) und der die dann alle automatisch hintereinander ausführt, ohne dass ich dazwischen eingreifen kann. Die bash kann genaugenommen beides. Die Interaktivität ist sozusagen ein Plus zum "normalen" Kommandozeileninterpreter.
In kurz, die bash ist eine Shell, die einfach auf Eingaben wartet und diese dann verarbeitet. Neben der bash gibt es auch noch andere Shells (z.B. dash, ksh, csh, zsh, ...). Diese unterscheiden sich manchmal mehr und manchmal weniger darin, wie sie Kommandos intepretieren und wie sie User-Input (auch shortcuts etc.) verarbeiten.
Einige praktische Shortcuts, die die Shell kennt:
Strg-Links
/Alt-b
: Cursor ein Wort nach linksStrg-Rechts
/Alt-f
: Cursor ein Wort nach rechtsStrg-a
/Strg-e
: Cursor zum Anfang/Ende der ZeileTab
: Befehl/Option vervollständigen (via bash-completion package)Strg-r
: Einen Befehl in der History suchen
Die bash kennt drei Typen von Befehlen (das sind die interpretierten Kommandos, bzw. Kommandozeilen)
- shell-interne: z.B.
echo
- diese sind in der shell integriert - alias - eigentlich auch shell-interner Befehl, um Synonyme anzulegen
- Programme (und (Shell-)Scripte), die irgendwo auf der Festplatte liegen
Befehle haben dabei üblicherweise einen Namen und eine meist einheitliche (aber manchmal doch unterscheidliche) Syntax, wie Optionen und Parameter an den Befehl übergeben werden. Außerdem verwenden sie Datenströme um Daten (Eingabe (stdin), Ausgabe (stdout) und Fehlermeldungen (stderr)) mit der Shell (oder anderen Teilen des Systems) auszutauschen. Diese Datenströme können auch umgeleitet werden, z.B. in Files, was manchmal ganz praktisch ist.
Auch jedes grafische Programm, das wir in unserer alltäglichen Arbeit von der grafischen Oberfläche aus benutzen ist auch nur ein Programm. Es kann somit wie jedes anderen Programm auch von der Shell ausgeführt werden. Probier es am besten gleich einmal aus und starte Firefox, Thunderbird & Co direkt von der Shell aus (starte dazu einfach ein Terminal-Programm, das in deiner Linux-Distribution verfügbar ist, unter Ubuntu ist das das gnome-terminal und unter Ubuntu MATE das mate-terminal):
$ firefox
$ thunderbird
$ gedit
$ libreoffice
Ein Tipp hier gleich vorab: wenn wir in der Shell Programme starten, dann wird die weitere Eingabe von der Shell an diese Programme weitergeleitet, bis die Programme beendet werden. Daher ist die Shell für uns bis dahin irgendwie "blockiert". Um das zu verhindern, können wir diese Programme von der Shell aus auch "in den Hintergrund" starten. Die Shell startet das Programm dann zwar als eigenen child process, nimmt sich aber die Kontrolle über Eingabe via Tastatur gleich wieder zurück. So kann dann auch während die grafischen Progrmme laufen auf der selben Shell weitergearbeitet werden. Das funktioniert ganz einfach indem wir an einen Shell-Befehl am Ende ein &
anhängen. Probieren wirs:
$ gedit &
[1] 2038
$
Was bringt es aber nun grafische Programme direkt von der Shell zu starten? Ein gutes daran ist jedenfalls, dass auch die Ausgabe der gestarteten Programme auf der Shell passiert. So bekommen wir manchmal Fehlermeldungen oder Warnungen mit, die wir nie mitbekommen, wenn wir die Programme nur von unserer grafischen Umgebung aus starten. Manchmal sind diese Ausgaben eher unverständlich und können uns auch egal sein, weil eh alles funktioniert. Manchmal finden wir aber so wertvolle Hinweise zur Fehlerbehebung.
Ein paar weitere spannende Programme, die wir im Alltag oft nutzen, die wir aber auch von der Shell starten können sind (nicht alle sind schon in jeder Distribution standardmäßig installiert und unterschiedliche Desktop Environments bringen oft auch unterschiedliche Programme für die jeweiligen Aufgaben mit sich):
eog
zum Betrachten von Bilderevince
zum Betrachten von PDFsmplayer
zum Abspielen von Audio- und Videodatengimp
für die Bildbearbeitung
Bei manchen dieser Progrmamen macht es wenig Sinn sie ohne weitere Argumente zu starten, oft wollen wir zumindest einen Dateinamen mit angeben. Schauen wir uns also an, wie Shell-Befehle generell aufgebaut werden.
Aufbau eines Befehls
$ commandname [OPTIONS] [ARGUMENTS] ...
Optionen werden oft als short options "-o" oder alternativ manchmal auch als long options "--long-opt" angeführt. Diese können auch Paramenter haben, z.B. "-o 5" oder "--long-opt=5". Die Argumente sind einfach bestimmte allgemeine Parameter, die dem Programm übergeben werden, z.B. ein Dateiname, oder auch einfach ein beliebiger Text-String, je nachdem was was Programm macht.
Ein Beispiel:
echo Hallo
echo "ich bin ein text-string"
echo ich bin viele text-strings
echo -n "Oh, hier fängt keine neue Zeile an"
echo -e "Oh, hier fängt\n eine neue Zeile an"
Noch ein Beispiel:
ls
ls -l
ls -l -h
ls -l -h
ls -l -h --full-time
ls -l -h --full-time --color=auto
ls -l -h --full-time --color=auto /etc
Eine tolle Website, die hier erwähnt werden muss ist http://explainshell.com. Dort können Shell-Befehle eingegeben werden und die Website erklärt die einzelnen Bestandteile des Befehls bzw. der Befehlsfolge, die eingegeben wurde.
Umgebungsvariablen
... sind Variablen, die im Hintergrund gesetzt werden und auf die die Shell, aber auch die von ihre gestarteten Programme zugreifen können.
Wichtig z.B. ist die PATH
Variable. In dieser werden alle Verzeichnisse gespeichert in der die Shell nach ausführbaren Programmen suchen soll. Alle Umgebungsvariablen können mit dem Befehl env
angezeigt werden. env
kann auch verwendet werden um Programme in einer veränderten Umgebung zu starten. Mit export
können neue Umgebungsvariablen der bestehenden Umgebung hinzugefügt werden (für diese eine Sitzung der Shell - sie gehen also nach dem Schließen der Shell wieder verloren). Die bash
liest beim Start standardmäßig die Konfigurationsdateien /etc/profile
, ~/.profile
sowie /etc/bashrc
und ~/.bashrc
ein. So können auch Umgebungsvariable und allgemeine Einstellungen bereits für jeden Start der bash
vorgenommen werden.
Lassen wir uns also einmal mit env
alle gesetzten Umgebungsvariablen ausgeben (hier wird nur ein Teil des Outputs dargestellt):
$ env
MANPATH=/usr/local/man:/usr/local/share/man:/usr/share/man
SHELL=/bin/bash
TERM=xterm-256color
USER=workshop
USERNAME=workshop
MAIL=/var/mail/workshop
PATH=/home/workshop/bin:/home/workshop/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
PWD=/home/workshop
LANG=en_UK.UTF-8
HOME=/home/workshop
LANGUAGE=en_UK
LOGNAME=workshop
Wenn wir in der Shell nun einzelne dieser Variablen nutzen wollen, so müssen wir ihnen nur ein $
voranstellen. Wenn wir also nur den aktuellen PATH ausgeben wollen oder nur das SHELL Programm in dem wir uns befinden, so können wir das wie folgt tun:
$ echo $PATH
/home/workshop/bin:/home/workshop/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
$ echo $SHELL
/bin/bash
Ein praktisches Kommando ist auch noch which
. Mit diesem können wir herausfinden wo das Programm das wir aufrufen überhaupt liegt bzw. welche ausführbare Datei in welchem Pfad hier überhaupt ausgeführt wird.
$ which firefox
/usr/bin/firefox
Das Progamm firefox
liegt also im Pfad /usr/bin/firefox
. Würden wir nun ein anderes Programm auch firefox
nennen und dieses aber im Verzeichnis /home/workshop/bin
ablegen (wenn wir als Userin workshop
eingeloggt sind), dann würde wenn wir
$ firefox
eintippen dieses neue firefox
ausgeführt werden, weil in der Umgebungsvariable PATH
das Verzeichnis /home/workshop/bin
vor dem /usr/bin
angeführt wird.
Mehr zur Bash im Web
Ein paar hilfreiche Links, um sich mit der Linux-Shell anzufreunden (wie immer gibts aber hundertausend hilfreiche Seiten im Netz und jede* kommt mit einer anderen Erklärung unter Umständen auch wieder besser zurecht - wenn ihr hilfreiche Infos habt, einfach hier dazuposten):
- http://unixmages.com/
- http://www.osdata.com//programming/shell/unixbook.pdf
- http://www.mat.univie.ac.at/~praxis/sosem16/vorlesung.html (Vorlesungsunterlagen zum Umgang mit Linux; auch mit vielen hiflreichen Tips zur bash)
Nun aber mal genug mit Hintergrundwissen und ab in die Praxis.
Commands zum Ausprobieren
Mit man programmname
kann mensch sich eine Beschreibung des jeweiligen Programms ausgeben lassen. "man" steht dabei für "manual".
Damit nicht dauernd "man" geschrieben werden muss, kann ein Alias gesetzt werden.
Z.B. so:
alias ?="man"
Das Fragezeichen ersetzt dann man. Anstatt "man programmname", kann jetzt "? programmname" geschrieben werden.
Mit diesem alias-Befehl kann allerhand ersetzt werden. Z.B. auch so was:
alias bussi="echo bussi zurück!"
Jetzt kann ich "bussi" ins Terminal schreiben (mit Enter bestätigen) und bekomm ein "bussi zurück".
Mit dem Alias-Befehl, kann mensch sich aber auch Ärger machen. Z.B. könnte ich den Befehl "rmdir" ("remove directory") mit dem ich ein Verzeichnis lösche, mit dem Alias "cd" belegen. "cd" ist der Name eines Befehls den es schon gibt und den ich oft brauche - "cd" steht für ("change directory") mit dem ich das Verzeichnis wechsle.
# Achtung, für folgenden Befehl zu erst Beschreibung dazu lesen,
# außer du weißt schon was du tust
alias cd="rmdir"
bedeutet also dann, dass wenn immer ich z.B. "cd /irgendeines/meiner/Verzeichnisse" tippe um ins Verzeichnis zu wechseln, ich nicht dorthin wechsle, sondern das Verzeichnis lösche. ...
Im nächsten Abschnitt schauen wir uns an, wie wir uns eigentlich in der Shell bewegen. Beziehungsweise müssten wir genau genommen eher sagen, wie wir uns im Filesystem bewegen und wie wir das in der Shell tun können.