Linux-Grundlagen
Version 0.8
Axel Pemmann, 2019-10-21
In den folgenden Kapiteln sollen wichtige Grundkonzepte vorgestellt werden, die vor allem die Bedienung des Systems betreffen. Ziel ist, sich im jeweiligen Kontext sicher bewegen zu können. Die Vorstellung der Konzepte ist mehr oder weniger kurz und prägnant gehalten und erhebt keinen Anspruch auf Vollständigkeit. Insbesondere fehlen die Themen Hardware/Kernel sowie Netzwerk- und Servertechnik. Im Zusammenhang mit den hier beschriebenen Beispielen ist es aber möglich, sich einen Überblick zu verschaffen und solide Grundkenntnisse und Fertigkeiten aufzubauen, die als Ausgangspunkt für eigenes weiterforschen dienlich sein mögen. Jedem Grundkonzept wurde ein Kapitel gewidmet, wobei die gewählte Reihenfolge den Einstieg in die gesamte Problematik unterstützen soll.
Linux ist eine spannende Plattform für technisch interessierte und sicherheitsbewusste Menschen. Der Begriff „Linux“ steht genaugenommen nur für die Hauptkomponente eines Betriebssystems: den Kernel. Hören wir Namen wie z.B. Ubuntu, Debian oder openSUSE, handelt es sich um ein Fertigprodukt, eine Distribution. Seine Wurzeln hat Linux in Unix, was als altgestandenes Multitaskting- und Multiusersystem eine stabile Basis darstellt. Den Unix-Stammbaum, in dem seit dem Jahre 1991 auch Linux eine Rolle spielt, kann man unter https://www.levenez.com/unix/ finden.
1. Distributionen
An dieser Stelle möchte ich einen kleinen Überblick über Distributionen geben, die ich persönlich favorisiere. Es gibt natürlich viele weitere, die je nach Zielstellung ebenfalls empfehlenswert sind.
Name |
Einsatzgebiet |
Besonderheiten |
---|---|---|
Alpine Linux |
Container, IoT, Server, Desktop |
leichtgewichtig (musl libc), sehr sicher, flexibel, unabhängige Entwicklung |
Debian |
Server, Desktop, … |
komfortable Paketverwaltung, tausende Apps, viele Derivate (z.B. Ubuntu, Devuan) |
Gentoo |
Server, Desktop, … |
Software wird aus dem Quellcode kompiliert, sehr flexibel, vorgefertigte Profile |
GuixSD |
Server, Desktop, … |
freies GNU-System mit Libre-Kernel, um den deklarativen Paketmanager Nix gebaut |
KaOS |
Desktop (KDE), QT-Anwendungen |
innovativ, inspiriert von Arch Linux, eigene Paketrepos, Qualität vor Quantität |
RedHat |
Server, Desktop, … |
kommerzielle Distri, Stabilität hat höchste Priorität, freies Derivat: CentOS |
Slackware |
Server, Desktop, … |
älteste Distri, KISS-Prinzip, hält an UNIX-Philosophie fest, viele Derivate |
SliTaz |
Rettungssystem, PXE-boot, Desk. |
kleinste Distribution mit vollständiger grafischer Oberfläche |
SuSE |
Server, Desktop, … |
kommerzielle Distri, flachere Lernkurve dank YaST, freie Derivat: openSUSE |
Tiny Core |
Rettungssystem, PXE-boot, Desk. |
sehr kleine, spartanische Distribution mit minimaler grafischer Oberfläche |
Distro-Links, Arch Linux
Hier ein paar Links zu diesen Distributionen:
Was die Rolling Release Distribution Arch Linux und ihre Derivate betrifft, beschreibt Mythbusting Arch Linux sehr treffend: Experimentierfreudigen kann diese Distribution eine Bereicherung sein, für Einsteiger ist sie allerdings weniger ratsam, weil unauflösbare Paketabhängigkeiten schnell zu einem defekten System führen können. Wie auch immer: das Arch Linux Wiki ist eine Quelle vieler wertvoller Informationen. In Arch Linux mit Feinschliff, wird Manjaro Linux vorgestellt. Diese Distribution versucht die Problemtik mit den Paketabhängigkeiten auszubügeln, in dem in separaten Repositories Snapshots von funktionierenden Paketzuständen vorgehalten werden.
2. Benutzerschnittstellen
An erster Stelle soll das Konzept der Schnittstellen, die für eine sinnvolle Mensch/Maschine-Interaktion erforderlich sind, beschrieben werden. Es haben sich über die Jahre hinweg zwei behaupten können: die von der Lernkurve her sehr steile Kommandozeile und das angenehmere, grafische X-Window-System.
Kommandozeile
Die Unix-Shell stellt die uralte Kommandozeilenschnittstelle dar, die auch heute noch ihren Charme besitzt. Sie ist sehr effizient und ressourcenfreundlich. Eine Shell dient als Interpreter von eingegebenen Kommandozeilen.
Prompt
Das beginnt schon damit, dass sie sich um den Eingabeprompt kümmert, der mittels der Variable „PS1“ im einfachsten Falle wie folgt umgestaltet werden kann:
tux@deb:~$
tux@deb:~$ PS1="Give me input> "
PS1="Give me input> "
Give me input>
Give me input> date
Mi 13. Apr 15:47:36 CEST 2022
Give me input>
Give me input> cal
April 2022
Mo Di Mi Do Fr Sa So
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30
Give me input>
Give me input> # Ein Doppelkreuz leitet Kommentarzeilen ein...
Give me input>
Um den alten Prompt wiederzubekommen, ist es das Einfachste, sich mit exit
oder logout
aus- und wieder einzuloggen.
HINWEIS: Sollte das Kommando cal
nicht gefunden werden, so kann es unter Debian/Ubuntu als root mittels apt install ncal
nachinstalliert werden.
Suchpfad
Weiterhin ist die Shell behilflich, den Ort ausfindig zu machen, wo das Kommando ‚date‘ im Dateisystem liegt. Dadurch brauchen wir nur das Kommando selber einzugeben und müssen den exakten Pfad nicht kennen:
tux@deb:~$ date
Mo 16. Okt 8:08:26 CEST 2017
tux@deb:~$
Die Shell hat in diesem Moment einen Suchpfad durchstöbern müssen, d.h. an bekannten Orten nachsehen müssen, ob dort das gewünschte Kommandos zu finden ist:
tux@deb:~$ echo $PATH
/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games
tux@deb:~$
Das Hilfswerkzeug ‚which‘ kann uns dabei Auskunft geben, wo ‚date‘ nun genau gefunden wurde:
tux@deb:~$ which date
/bin/date
tux@deb:~$
Interpreter
Weiterhin muss unsere Standard-Shell namens „Bash“ die Kommandozeile in einzelne, sinnvolle Bestandteile zerlegen, wobei Leerzeichen und Tabulatorschritte als Trenner der einzelnen Teile herangezogen werden. Will man sie aber als Teil des Dateinamens verwenden, müssen sie zum Beispiel mit einem Backslash - der in Unix kein Verzeichnistrenner ist - maskiert werden:
tux@deb:~$ mkdir Eigene\ Dateien
Eine weitere interessante Aufgabenstellung, welche die Interpreterrolle unserer Bash verdeutlicht, ist die Ergänzung von Dateinamen durch Platzhalter (auch Joker, Wildcards, = Dateinamensexpansion):
tux@deb:~$ ls -l /etc/host*
-rw-r--r-- 1 root root 9 Aug 7 2006 /etc/host.conf
-rw-r--r-- 1 root root 5 Mai 15 19:13 /etc/hostname
-rw-r--r-- 1 root root 197 Mai 15 19:13 /etc/hosts
-rw-r--r-- 1 root root 411 Apr 2 22:29 /etc/hosts.allow
-rw-r--r-- 1 root root 711 Apr 2 22:29 /etc/hosts.deny
Wir weisen damit die Bash an, zuerst alle Dateinamen, die mit ‚host‘ beginnen und unterhalb von ‚/etc‘ liegen, zu finden, vorzumerken und erst bei der Ausführung dem Kommando ls -l
als Parameterliste zu übergeben („ls -l“: Inhalt auflisten, Ausgabe in Langform).
Pipelines
Zum on-the-fly Weiterverarbeiten von Datenströmen werden sehr gern Pipes eingesetzt.
Das Kürzel für Pipes ist lediglich ein einzelnes Bar-Zeichen (‚|‘), mit Hilfe dessen angedeutet wird, dass die Ausgabe des einen Kommandos zur Eingabe des nächsten wird. Dabei gibt es den Begriff „First-In-First-Out“, was einen gar nicht so selbstverständlichen Mechanismus beschreibt, den Standardoutput (stdout) des vorhergehenden Kommandos via Rohrleitung zum Standardinput (stdin) des nachfolgenden Kommandos zu machen:
tux@deb:~$ command1 | command2 | command3
Dazu ein Beispiel, was als weiteres Kommando „head“ einbezieht, das per Default die ersten 10 Zeilen einer Datei ausgeben würde, hier aber mit der Option -n 1
nur die erste Zeile auf stdout schickt:
tux@deb:~$ cal | head -n 1
April 2022
tux@deb:~$
Beim Durchreichen der Daten tritt jetzt allerdings ein Problem auf: Zwischenergebnisse gehen verloren! Im Beispiel von eben ist uns ja nur die erste Zeile „April 2022“ erhalten geblieben. Wie kann man nun auf alles, was vor dem Filtern war, zurückgreifen? Es muss ein T-Stück (engl: ‚tee‘) eingebaut werden, welches das Zwischenergebnis vor der Weiterverarbeitung in eine Datei schreibt; hier soll sie ‚kalender-april.txt‘ heißen:
tux@deb:~$ cal | tee kalender-april.txt | head -n 1
April 2022
tux@deb:~$
Weiter unten lernen wir das Kommando „cat“ kennen; mit cat kalender-april.txt
können wir auf das Zwischenergebnis zugreifen.
Siehe dazu https://de.wikipedia.org/wiki/Tee_%28Unix%29 - dort liest man auch über die für uns wichtige Option ‚-a‘ (append): „Mit -a wird an die angegebene Datei angehängt (anstatt eine neue leere Datei zu eröffnen).“
Umleitungen
Die Shell unterhält standardmäßig drei Kanäle; stdin für die Eingabe („Ein Kommando liest von der Tastatur“), stdout für normale, fehlerfreie Ausgaben und stderr für fehlerhafte Ausgaben (Error). Die beiden letzteren Kanäle sind per Default so verdrahtet, dass sie ihre Meldungen an die selbe Stelle senden: ins Terminal des angemeldeten Benutzers. Die folgende Tabelle gibt einen Überblick über wichtige Eigenschaften:
Kanal stdin: |
Dateideskriptor: 0 |
Umleitungs-Kürzel: < |
anhängende Arbeitsweise als Here-Dokument |
Kanal stdout: |
Dateideskriptor: 1 |
Umleitungs-Kürzel: > |
anhängende Arbeitsweise: >> |
Kanal stderr: |
Dateideskriptor: 2 |
Umleitungs-Kürzel: 2> |
anhängende Arbeitsweise: 2>> |
ANMERKUNG: Den Dateidekriptor kann man weglassen, wenn das Kürzel eine eindeutige Interpretation durch die „Pfeilrichtung“ zulässt, ansonsten muss die Ziffer angegeben werden. Bei stderr muss sie immer mit notiert werden.
Siehe dazu auch http://www.netzmafia.de/skripten/unix/unix2.html
Hierzu ein paar praktische Einsatzbeispiele:
Beispiel Eingabeumleitung (stdin):
In der Datei ‚kontakte‘ liegen die Buchstaben in Klein- und Großschreibung wild gemischt vor. Es soll nun alles in Kleinbuchstaben umgewandelt werden:
tux@deb:~$ tr '[:upper:]' '[:lower:]' < kontakte | nl 1 müller 2 meier 3 schulze tux@deb:~$
Beispiel Ausgabeumleitung (stdout):
Ein Überblick über die aktuelle Speicherplatzbelegung wird in die Datei ‚disk-free_humanreadeable.txt‘ umgeleitet:
tux@deb:~$ df -h / > disk-free_humanreadeable.txt
Beispiel Ausgabefehlerumleitung (stderr):
Falls eine der drei Dateien in unserer Distribution nicht in dieser Form existiert, soll die diesbezügliche Fehlermeldung in der Datei ‚error.txt‘ abgelegt werden:
tux@deb:~$ cat /etc/HOSTNAME /etc/hostname /etc/hosts 2> error.txt
Standardkanäle verbinden
Die drei Standard-Datenströme unserer Shell lassen sich nicht nur umleiten, sie können auch miteinander verbunden werden. Genauer gesagt wird der Inhalt des einen Kanals in einen anderen kopiert. Dazu dient das Kaufmanns-Und (‘&‘).
Beispiele für die Kombination von Ausgabeumleitung, Fehlerausgabeumleitung und Kanalverbindung:
a) Beim Archivieren via Cron-Job soll jegliche Ausgabe unterdrückt werden, damit nicht fälschlicherweise E-Mails vom Cron-Daemon versendet werden:
tux@deb:~$ tar czf /root/etc-$(date +%F).tar.gz > /dev/null 2>&1
b) Für typische Aufgaben wie das Kompilieren von Anwendungen soll jeglicher Output, unter anderem eben auch Fehlermeldungen abgespeichert werden:
tux@deb:~$ make > my-important-file.log 2>&1
Komfort
Nicht zuletzt bietet die bash-Shell Features an, um den Benutzer bei der Arbeit zu unterstützen. Es handelt sich um die folgenden Komfortfunktionen
History (Cursortasten nach oben/unten,
history
,history 20
)Autovervollständigung mit der Tabulatortaste (Ergänzung von Kommandozeilen)
Kommandozeileneditor (bereits eingegebene Kommandozeilen können editiert werden)
Aliase (= Kürzel für Kommandozeilen, z.B.
alias l='ls -ltrc'
)
X-Window-System
Als X-Window-System bezeichnet man ein GUI-System, das man als eine Art „grafischen Aufsatz“ auf das kommandozeilenbasierte Grundsystem verstehen kann. Es ist netzwerkfähig und besteht aus folgenden grundlegenden Komponenten:
X-Server (= Treiber für das Grafiksystem, Hardwareabstraktion auf der Grafikkarte, Darstellung von Pixelbildern)
X-Clients (= Grafikanwendungen und Komponenten des X-Window-Systems, senden ihre Pixelbilder zum X-Server), sie unterteilen sich in:
Window-Manager (Fensterrahmen und -buttons zeichnen)
Typische X-Anwendungen wie xterm, firefox, Office-Programme…
Display-Manager (grafischer Login-Manager für komfortables Anmelden von Nutzern)
Desktop (z.B. LXDE, XFCE, GNOME, KDE), Kennzeichen: Integriert sind passende Windowmanager und Zubehörprogramme; einheitliches Look & Feel
Siehe auch https://www.itwissen.info/X-Window-X-window-XDOT-11.html
3. Hilfe und Dokumentation
Die (De-)Motivation ist gewaltig: Es gibt viel zu lesen! Und das Ganze funktioniert in der Not auch ohne Internet. Es existieren drei offizielle, große Hilfesysteme:
man-Pages (Manual-Seiten, die zu fast jedem Kommando mit ausgeliefert werden
info-Pages (ähnlich wie man-Pages, allerdings hypertextartig formatiert)
HOWTOs (Anleitungen und Tutorials, wie bestimmte Ausgabenstellungen praktisch realisiert werden können)
Zusätzlich werden unter ‚/usr/share/doc‘ „example“-Configs und weitere Dokumentation u.a. vom Quelltext-Ursprung abgelegt.
man-Pages benutzen
Manual-Pages sind Kurzbeschreibungen von Kommandos und Dateien, denen oft Beispiele fehlen (Von Programmierern für Programmierer!), weswegen man dann eben auch noch weitere HOWTOs und Anleitungen benötigt. Die eckigen Klammern (‘[ … ]‘) in der Syntax-Beschreibung sind in aller Regel NICHT als zu notierende Zeichen zu verstehen, sie wollen lediglich andeuten, dass etwas optional ist.
Aufruf, Navigation, Suchen und Beenden
Aufruf: man <KOMMADO/LIBRARY/KONFIGDATEI>
Navigation (gemäß less-Pager):
Cursortasten, Enter, Leertaste
F (forward), B (backward)
G (go to the end), g (go to the begin)
Suchen:
Vorwärts (nach unten): /SUCHMUSTER, Weitersuchen: n (next), Rückwärts nach oben suchen: N (Next)
Rückwärts (nach oben): ?SUCHMUSTER, Weitersuchen: n (next), Rückwärts nach unten suchen: N (Next)
Beenden: q (quit)
Unterteilung in thematische Abschnitte
Die man-Pages werden in sogenannten Abschnitten kategorisiert, siehe ‚man man‘, z.B.
Abschnitt 1: Programme für Benutzer (unter /bin oder /usr/bin oder /usr/local/bin)
Abschnitt 4: Spezielle Dateien (Gerätedateien, siehe man 4 null)
Abschnitt 5: Dateiformate und Konventionen (z.B. Aufbau der Datei /etc/fstab: ‚man 5 fstab‘)
Abschnitt 6: Spiele (z.B.: ‚man 6 fiberlamp‘)
Abschnitt 8: Programme für root (unter /sbin oder /usr/sbin oder /usr/local/sbin)
Tipps für die praktische Arbeit
Es gibt mit ‚-a‘ eine sehr wichtige Option, die alle man-Pages zu einem Kommando oder einer Datei zur Anzeige bringen kann. Ansonsten wird nur die als erstes vorgefundene Seite geöffnet! Mit dieser Option werden aber oft noch weitere Seiten gefunden und zum Lesen vorgeschlagen. Die folgenden Kommandozeilen können als Praxisbeispiel dienen:
man -a mount
man -a crontab ### Hier werden nacheinander die Seiten der Abschnitte 1 und 5 geöffnet.
Eine schnelle Suche im Beschreibungstext des Pages ist mit
apropos SUCHMUSTER
man -k SUCHMUSTER
möglich. Hierbei wird innerhalb der Man-Page nach ‚NAME‘ bzw. ‚BEZEICHNUNG‘ gesucht. Siehe auch ‚whatis <KOMMANDO>‘.
Außerdem spielt hier auch das Kommando ‚whereis‘ eine Rolle, es gibt mehrere Dinge aus:
tux@deb:~$ whatis whereis
whereis (1) - locate the binary, source, and manual page files for a command
tux@deb:~$
4. Textarbeit
Pager
Das Ziel ist hier lediglich, Textdateien seitenweise lesen zu können, wobei auch Suchfunktionen möglich sind. Hierfür gibt es prinzipiell zwei Werkzeuge:
more (= einfaches Leseprogramm, um bildschirmausschnittsweise blättern zu können)
Navigation:
Enter: Eine Zeile nach unten
Leertaste: Einen Bildschirmausschnitt nach unten
STRG - B: bildschirmausschnittsweise nach oben blättern (Backward)
Suchen:
Vorwärts (nach unten): /SUCHMUSTER, Weitersuchen: n (next)
Beenden: q (quit), nur erforderlich, wenn man den Pager vorzeitig verlassen möchte
less (= umfangreicheres Leseprogramm, u.a. der Pager für man-Pages, Komfortfunktionen beim Bildschirmausschnittsblättern in rückwärtige Leserichtung)
Navigation:
Cursortasten, Enter, Leertaste
F (forward), B (backward)
G (go to the end), g (go to the begin)
Suchen:
Vorwärts (nach unten): /SUCHMUSTER, Weitersuchen: n (next), Rückwärts nach oben suchen: N (Next)
Rückwärts (nach oben): ?SUCHMUSTER, Weitersuchen: n (next), Rückwärts nach unten suchen: N (Next)
Beenden: q (quit)
Das verblüffende Motto: Less is more.
Editor vim
Der Linux-Standardeditor ist der vi (visual editor‘). Er steht in
einer verbesserten Version als vim (vi improved) zur Verfügung. Bei
Debian muss diese erweitere Variante zuerst mit apt-get install vim
installiert werden.
Dieser textbasierte Editor arbeitet mit folgenden drei Haupt-Modi:
COMMAND = Standard- bzw Startmodus (dahin zurückkehren mit
ESC
), hier werden Befehle zur Navigation oder zum Kopieren, Ausschneiden und Löschen erteilt.INSERT = Schreibmodus (in diesen Modus kommt man mit
i
,o
,a
oderA
)EXECUTE = Aktionsmodus (in diesen Modus kommt man mit einem
:
)Hier speichert und verlässt man den Editor z.B. mit
:wq
Weitere wichtige Kürzel sind
:w
,ZZ
,:q!
,:wq!
sowie:e datei
Navigation:
Ersatz der Cursortasten: h, j, k, l
Einen Bildschirmausschnitt nach unten (forward) blättern: STRG + f
Einen Bildschirmausschnitt nach unten (backward) blättern: STRG + b
Ganze Zeilen bearbeiten
dd - (delete) - eine ganze Zeile in den Löschpuffer (= Ausschneiden)
yy - (yank) - eine ganze Zeile in den Kopierpuffer legen
p - (paste) - Pufferinhalt eine Zeile darunter einfügen
HINWEIS: Dabei können den Befehlen ein Zahl für den Wiederholungsfaktor vorangestellt werden
Siehe auch http://pemmann.de/doc/Linux/kleine-kommandoreferenz.pdf
Textfilter
Einfache Filter
Die folgenden Werkzeuge stellen nur eine kleine Auswahl dar. Sie zeichnen sich in vielen alltäglichen Aufgabenstellungen durch hohen Nutzwert aus. Diese Tools können direkt mit Dateien umgehen, lassen sich aber auch in Zeichenströmen via Umlenkungen und Pipes einsetzen.
cat
- eine oder mehrere Dateien ausgeben (catenate = verketten)head
- nur die ersten Zeilen einer oder mehrerer Dateien ausgebentail
- nur die letzten Zeilen einer oder mehrerer Dateien ausgebensort
- eine Datei sortierenwc
- Zeichen, Wörter und Zeilen zählen (word count)
Gehen wir nun, was diese 5 wichtigen Werkzeug betrifft, ins Detail:
cat - Datei ausgeben, auch mehrere nacheinander verkettend, Praxisbeispiele:
Eine Datei auf Standardoutput ausgeben:
cat /etc/hosts
Mehrere Dateien auf Standardoutput ausgeben:
cat /etc/hostname /etc/hosts.*
head / tail - Nur eine gewisse Zahl von Zeilen ausgeben:
head (per Default die ersten 10 Zeilen ausgeben), wichtige Option:
-n <NUMBERS>
oder-<NUMBERS>
tail (per Default die letzten 10 Zeilen ausgeben)
Wichtige Optionen:
Zeilenzahl:
-n <NUMBERS>
oder-<NUMBERS>
- Folge dem Inputstrom (Monitoring)
-f
oder--follow
Bsp.:tail -f /var/log/messages
Im Praxistest:
tux@deb:~$ head -n 3 /etc/hosts /etc/services ==> /etc/hosts <== 127.0.0.1 localhost 127.0.1.1 deb.dom1.test deb ::1 localhost ip6-localhost ip6-loopback ==> /etc/services <== # Full data: /usr/share/iana-etc/port-numbers.iana tcpmux 1/tcp tux@deb:~$
sort - sortieren von Zeilen in Textdateien, Praxisbeispiele:
Verzeichnisgrößen berechnen (-n = numerisch):
du -s /usr/* | sort -n
Top Ten der großen Verzeichnisse (-r = reverse):
du -s /usr/share/* | sort -nr | head
Bequemer, weil „human“ readeable (-h):
du -sh /usr/* | sort -h
Sortierte Ausgabe in selbe Datei wieder zurückschreiben (-o = output file):
sort myfile.txt -o myfile.txt
- ACHTUNG, so geht es nicht (DATENVERLUST!):
sort myfile.txt > myfile.txt
(Zuerst wird wegen der Umleitung ein Filehandle eingerichtet,dann die Datei geleert (mit „>>“ würde append durchgeführt) und zum Schluss die leere Datei sortiert.) Ignorieren des Case-Sensivität: Option -i
wc - Wörter, Zeichen und Zeilen zählen (word count):
Ein Praxisbeispiel:
tux@deb:~$ wc -l /etc/hosts 12 /etc/hosts tux@deb:~$Wichtige Optionen:
Lines:
-l
oder--lines
Words:
-w
oder--words
Characters:
-m
oder--chars
Filter mit Regex
Mit Hilfe sogenannter regulärer Ausdrücke lassen sich Textdateien oder -ströme sehr zielgerichtet nach bestimmten Mustern durchsuchen. Damit lässt sich die Inhaltssuche (engl. Search File Content) sehr effizient gestalten.
Viele Tools wie auch der vorgestellte Editor vim beherrschen Regular Expressions. Das ist eine komplette, universelle Filtersprache für die Volltextsuche in Dateien oder Datenströmen, Aber bitte nicht mit Dateijokern wie *
und ?
verwechseln, diese Zeichen haben hier eine andere Bedeutung!
Für den Anfang sollte man sich die folgenden regulären Ausdrücke einprägen:
Zeilenanfang (Caret / Dach):
^
Zeilenende (Dollar):
$
Wortanfang:
\<
Wortende:
\>
EIN beliebiges Zeichen (ein einzelner Punkt):
.
Das davor stehende Zeichen beliebig oft mal (Wiederholungsfaktor; ein Stern):
*
Zum Vergleich: Den bekannten Dateijoker *
müssen wir hier mit Hilfe von Punkt und Stern realisieren: .*
Kommen wir nun zu Anwendungsbeispielen. Zuerst werden wir uns dem Standardkommando ‚grep‘ widmen, danach weiteren Werkzeugen, die reguläre Ausdrücke beherrschen.
Kommando ‚grep‘ (Abkürzung für „globally search a regular expression and print“)
Zuerst einmal sollen wichtige Optionen für ‚grep‘ genannt werden:
-i
- Ignoriere Groß- und Kleinschreibung
-v
- inVertiere die Ergebnisse (negieren)
-r
- Rekursiv arbeiten (Verzeichnisse samt Inhalt durchsuchen)
-E
- Extended Arbeitsweise aktivieren (= egrep)
-F
- Fixed-Strings-Arbeitsweise aktivieren (= fgrep)
-c
- Counting: Zählt nur die Übereinstimmungen (gibt nur eine Zahl aus)
-n
- Number of Line: Die betreffende Zeilennummer mit ausgeben
-l
- Liste nur die Dateinamen auf, nicht den gefundenen Inhalt
-H
- Liste die Dateinamen und den gefundenen Inhalt auf, ideal für eine kleine Suchmaschine:find /etc -type f -exec grep -iH --color linus {} \;
Hier nun ein paar Beispiele zu ‚grep‘:
Zeilenanfang: Zuerst wollen wir nach bestimmten Zeichen am Zeilenanfang fahnden:
grep -v '^#' <DATEI>
Die Option
-v
invertiert dabei das Ergebnis: zeige NICHT diejenigen Zeilen an, die mit einem Hash Tag (= Kommentarzeilen) beginnen:tux@deb:~$ grep -v ^# /etc/fstab /dev/sda1 / ext4 defaults 0 1 /dev/sda2 /home ext4 defaults 0 2 /dev/sda3 /tmp ext4 defaults 0 2 /dev/sda5 /var ext4 defaults 0 2 /dev/sda6 none swap sw 0 0 /dev/sr0 /media/cdrom0 udf,iso9660 user,noauto 0 0 tux@deb:~$
Zeilenende: Nun fahnden wir nach Zeichen, die am Zeilenende stehen:
tux@deb:~$ cat /etc/hosts 127.0.0.1 localhost 127.0.1.1 jessie.dom.site jessie # The following lines are desirable for IPv6 capable hosts ::1 localhost ip6-localhost ip6-loopback ff02::1 ip6-allnodes ff02::2 ip6-allrouters tux@deb:~$Zeige nur die Zeilen, die auf den Buchstaben
t
enden:tux@deb:~$ cat /etc/hosts | grep t$ 127.0.0.1 localhost tux@deb:~$
In Kombination: Leerzeilen finden (Zeilenanfang und -ende fallen zusammen)
tux@deb:~$ grep -v ^# /etc/hosts | grep -v ^$ 127.0.0.1 localhost 127.0.1.1 jessie.dom.site jessie ::1 localhost ip6-localhost ip6-loopback ff02::1 ip6-allnodes ff02::2 ip6-allrouters 192.168.2.2 cent6.dom.site cent6 tux@deb:~$Und so macht man es auch mit großen Config-Files, die man aufs wesentliche reduzieren möchte (Damit realisieren wir übrigens eine logisch UND-Verknüpfung):
tux@deb:~$ grep -v ^# /etc/hosts | grep -v ^$ > hosts
Wortanfang und -ende
tux@deb:~$ grep '\<localhost\>' hosts 127.0.0.1 localhost ::1 localhost ip6-localhost ip6-loopback tux@deb:~$
Weitere Werkzeuge zur Suche mit regulären Ausdrücken
egrep
(odergrep -E
, = extended grep, beherrscht weitere reguläre Ausdrücke)
sed
(stream editor, Syntax für Suchen und Ersetzen:sed [-i] 's/ALT/NEU/g' datei
)
vim
(visual editor, Syntax für Suchen und Ersetzen::1,$s/ALT/NEU/g
)Beispiel zu ``egrep``: Wollen wir alternativ z.B. Car oder Auto in einer Datei finden, benutzen wir am besten für diese logisch-ODER-Verknüpfung das Extended grep. Wir erzeugen die Datei ‚mobilität.txt‘ hierbei mit Hilfe eines sogenannten here-Dokumentes (zwei „kleiner-als-Zeichen“ für die Input-Umleitung, der eigentliche Text wird zwischen die beiden Textanker ‚EOF‘ geschrieben):
root@deb:~# cat > mobilität.txt <<EOF Ein Car ist ein Mobil, das wir auch Auto nennen. Fahrradfahren ist freilich umweltfreundlicher. EOF root@deb:~# root@deb:~# grep -E -i 'car|auto' mobilität.txt Ein Car ist ein Mobil, das wir auch Auto nennen. root@deb:~#Apropos logische Verknüpfungen: Lässt sich auch logisch-UND realisieren? Ja, hierfür brauchen wir aber zwei grep-Aufrufe, die wir mittels Pipe verbinden: Zuerst filtern wir z.B. alle Gerätedateien aus der /etc/fstab heraus, danach folgt ein weiteres Filter, das nur ext-Dateisysteme berücksichtigt:
root@deb:~# grep '^/dev' /etc/fstab | fgrep ext /dev/store01/www /srv/www ext3 defaults 0 2 root@deb:~#Beispiel zum Kommando „sed“: Mit folgender Zeile wird on-the-fly die im Heimatverzeichnis von Debian-basierten Distributionen liegende Datei ‚.bashrc‘ editiert; und zwar wird damit die Zeile ‚#force_color_prompt=yes‘ aktiv gesetzt. Die zweite Zeile liest die Änderung dann nur noch ein, so dass der farbige Prompt sofort sichtbar wird:
tux@deb:~$ sed -i 's/^#force/force/' ~/.bashrc tux@deb:~$ source ~/.bashrcANMERKUNG: In der grep-Familie tanzt das Kommando
fgrep
(odergrep -F
, das „f“ bedeutet fixed Strings) aus der Reihe! Das Textfilter IGNORIERT reguläre Ausdrücke. Das kann sehr nützlich sein, z.B. wenn vermieden werden soll, dass der Punkt als „ein beliebiges Zeichen“ interpretiert wird. Dazu ein Beispiel: Der Punkt ist hier ein ganz normales Zeichen ohne Sonderbedeutung, das bedeutet, dass im speziellen Fall nur die Datei ‚grub.cfg‘ angezeigt wird und nicht die Dateien ‚syslinuxcfg.mod‘ und ‚legacycfg.mod‘, wie es ‚grep‘ tun würde:root@deb:~# find /boot/ | fgrep .cfg /boot/grub/grub.cfg root@deb:~#
5. Dateisystem
Die alte Philosophie „Alles ist eine Datei“ (siehe https://de.wikipedia.org/wiki/Unix-Philosophie#Alles_ist_eine_Datei), setzte eine erste objektorientierte Betrachtungsweise um. Die Windows-typische Dreiteilung „Laufwerk - Ordner - Datei“ gibt es hier nicht. Für den Umstieg auf Linux müssen wir zuerst einmal klären, wo wir unsere Daten wiederfinden können:
Verwendungszweck |
Windows |
Linux |
---|---|---|
Nutzerdaten |
c:\Users |
/home |
Programme/Anwendungen |
c:\Program Files |
/usr |
Betriebssystem |
c:\WINDOWS |
Rest von / |
Achtung: Es gibt keine Laufwerks-Buchstaben! Das ist zwar erst einmal ungewöhnlich, hat aber mehrere Vorteile. So können sie sich beim Hinzufügen eines Datenträgers nicht verschieben, außerdem existiert dadurch ein systemweit einheitlicher Namensraum unterhalb der einen Systemwurzel („/“).
Zur Kontrolle der Dateisysteme und Partitionierung können folgende Kommandos eingesetzt werden:
|
Anzeigen, was aktuell gemountet ist |
|
Nur physische Geräte anzeigen, keine virtuellen Dateisysteme (das Caret-Zeichen |
|
Gesamtüberblick der Festplattenbelegung (disk free) |
|
Speicherverbrauch eines bestimmten Verzeichnisses (disk usage) |
|
Liste Block Devices auf, auch USB-Hotpluggeräte ausgeben |
|
Auflisten der Block Devices unter Angabe der UUIDs |
|
Detaillierte Informationen für Partitionen (nur als root möglich) |
Umgang mit Dateien und Verzeichnissen
Um einen ersten Eindruck über das Dateimanagement zu erhalten und sich ausprobieren zu können, werden an dieser Stelle ein paar lebenswichtige Kommandos vorgestellt. ACHTUNG: Unix-artige Dateisysteme sind case-sensitiv, d.h. es wird zwischen Groß- und Kleinschreibung unterschieden!
Verzeichnisarbeit:
cd (change directory)
z.B.:
cd /usr/share/doc
; mitcd
können wir wieder ins Heimatverzeichnis zurückwechselnls -l (list directory content, mit ‚-l‘ in langer (long) / detailierter Form)
z.B.:
ls -l /etc/host*
mkdir (make directory)
z.B.:
mkdir /tmp/Übung1 /tmp/Übung2
rmdir (remove directory, das Verzeichnis muss allerdings leer sein)
z.B.:
rmdir /tmp/Übung1
rm -r (remove files, recursiv; d.h. es werden auch Verzeichnisse samt Inhalt gelöscht!!)
z.B.:
rm -r /tmp/Übung2
Dateiarbeit:
touch DATEI (Zeitstempel ändern bzw. leere Datei erzeugen)
z.B.:
touch /tmp/datei-01
echo „Mit Inhalt.“ > DATEI (eine Datei mit Inhalt erzeugen)
z.B.:
echo "Dies ist der Inhalt." > /tmp/datei-02
cp [-r] QUELLE ZIEL (= Kopieren; wenn QUELLE ein Verzeichnis ist, wird die Option ‚-r‘ (rekursiv) benötigt)
z.B.:
cp /tmp/datei-01 /tmp/file-01
odercp -r ~/Downloads /tmp
mv QUELLE ZIEL (= Umbenennen bzw. Verschieben; die Option ‚-r‘ existiert hier nicht)
z.B.:
mv /tmp/datei-02 /tmp/file-02
rm DATEI (eine einzelne Datei löschen)
z.B.:
rm /tmp/file-01
Partitionierung
Zuerst einmal müssen wir hier den Begriff „Formatierung“ einstreuen, der in der Unix-Welt allgemeiner verwendet wird.
Es lassen sich nämlich drei Arten der Formatierung unterscheiden:
Low-Level (nur noch bei Disketten möglich):
fdformat /dev/fd0
Partitionierung:
fdisk /dev/sdb
High-Level = Aufbringen eines Dateisystemes:
mkfs.ext2 /dev/fd0
Die Low Level Formatierung, auch physische Formatierung genannt, wird heutzutage nur noch bei Disketten durchgeführt. Hierbei werden Spuren und Sektoren des Datenträgers neu geschrieben. Dazu setzt man gemäß obigen Beispiel das Kommando fdformat
ein.
Die Partitionierung ist bei dieser Betrachtungsweise die zweite Art der Formatierung. Hierbei wird ein Datenträger in kleinere Unterbereiche aufgeteilt.
Wichtige Partitionierungstools sind:
fdisk (mächtiges Werkzeug mit textbasierten Menüs)
cfdisk (einfacheres Werkzeug mit Cursor-Steuerung)
parted (neues Werkzeug insbesondere auch für große Festplatten mit GPT, textbasiert)
gparted (neues Werkzeug insbesondere auch für große Festplatten mit GPT, GUI-basiert)
gdisk (neues Werkzeug, was das alte MBR-Format ins neue GPT-Format konvertieren kann)
Ein neu eingebaute Festplatte würde dann z.B. als zweites Device auftauchen und so partitioniert werden können:
root@deb:~# cfdisk /dev/sdb
Syncing disks.
root@deb:~#
Dabei werden folgende Eingaben gemacht:
Enter (gpt)
Enter (Size übernehmen oder andere Größe angeben)
Cursor nach rechts auf [ Write ], => „yes“
Cursor [ Quit ]
Dateisysteme erzeugen und einhängen
Das Aufbringen des Dateisytems, wie es in der Unix-Welt so schön heißt (= die dritte Art der Formatierung), ist schnell gemacht:
root@deb:~# mkfs.ext4 /dev/sdb1
mke2fs 1.43.4 (31-Jan-2017)
Ein Dateisystems mit 2096891 (4k) Blöcken und 524288 Inodes wird erzeugt.
UUID des Dateisystems: 58000698-6d3d-4bc5-9f0f-3714046ebc0b
Superblock-Sicherungskopien gespeichert in den Blöcken:
32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632
beim Anfordern von Speicher für die Gruppentabellen: erledigt
Inode-Tabellen werden geschrieben: erledigt
Das Journal (16384 Blöcke) wird angelegt: erledigt
Die Superblöcke und die Informationen über die Dateisystemnutzung werden
geschrieben: erledigt
root@deb:~#
Zum einbinden/mounten (= Zuordnung phys. Gerät => log. Mountpunkt/-verzeichnis) legen wir ein leeres Verzeichnis namens ‚/d:‘ an (um es Windows nachzutun) und machen darin das neue Gerät verfügbar:
root@deb:~# mkdir /d:
root@deb:~# mount /dev/sdb1 /d:
Zur Kontrolle geben wir folgendes ein:
root@deb:~# df -h
Dateisystem Größe Benutzt Verf. Verw% Eingehängt auf
udev 488M 0 488M 0% /dev
tmpfs 100M 2,0M 98M 2% /run
/dev/sda1 48G 2,1G 44G 5% /
tmpfs 499M 0 499M 0% /dev/shm
tmpfs 5,0M 0 5,0M 0% /run/lock
tmpfs 499M 0 499M 0% /sys/fs/cgroup
tmpfs 100M 0 100M 0% /run/user/1000
/dev/sdb1 7,9G 36M 7,4G 1% /d:
root@deb:~#
root@deb:~# ls -la /d:
insgesamt 24
drwxr-xr-x 3 root root 4096 Okt 18 12:57 .
drwxr-xr-x 23 root root 4096 Okt 18 12:59 ..
drwx------ 2 root root 16384 Okt 18 12:57 lost+found
root@deb:~#
Das neue Volume ist natürlich leer, nur das für ext-Dateisysteme typische Verzeichnis ‚lost+found‘ ist zu sehen.
ACHTUNG: Der Vorgang des Einbindens des Devices in den Dateibaum ist nur von temporärer Natur! Wenn es nach einem Neustart des Systems automatisch eingehängt werden soll, muss das in der Datei ‚/etc/fstab‘ konfiguriert werden:
root@deb:~# # Vorsichtshalber das Überschreiben verhindern, nur Anhängen ist erlaubt:
root@deb:~# set -o noclobber
root@deb:~#
root@deb:~# # Anhängen einer Zeile an die Datei 'fstab':
root@deb:~# echo '/dev/sdb1 /d: ext4 defaults 0 2' >> /etc/fstab
Überblick Mount-Mechanismus
- /etc/fstab
legt fest, welche Ressourcen wie zu mounten sind
- /etc/mtab
listet auf, welche Ressourcen aktuell gemountet sind
Relevante man-Pages
In erster Linie sind die man-Pages von mount und fstab von Bedeutung. Weitere Man-Pages sind bei Bedarf für die verwendeten Dateisysteme zu konsultieren (siehe Abschnit Beispiele).
Die Datei /etc/fstab
Aufbau der Datei
Die Datei ist in Tabellenform organisiert:
- Eine Zeile
beschreibt jeweils das Einhängen einer Ressource.
- Sechs Spalten
beschreiben die Details für das Einhängen einer Ressource:
Ressource (z.B. /dev/fd0 oder 192.168.23.200:/home/pub)
Mountpunkt (z.B. /media/cdrom oder /media/pub)
Dateisystemtyp (z.B. auto für Autoerkennung oder nfs)
Verschiedene Optionen (z.B. noauto, user oder für NFS sinnvoll: bg,soft)
Datensicherung mit dump vornehmen? Eine Null steht für nein. Eine Eins für ja.
Reihenfolge der Datenkonsistenz-Prüfung beim booten? Eine Null steht für keine Prüfung. Eine Eins für ja, als erstes zu prüfen (Wurzelpartition). Eine Zwei für ja, später prüfen (Nicht-Wurzelpartition).
Findet das System in den Spalten fünf und sechs keine Einträge, gilt als Voreinstellung Null.
HINWEIS: Bei Systemd-Distributionen gibt es Mount-Units, die entweder dynamisch aus der althergebrachten /etc/fstab mittels systemd-fstab-generator erzeugt werden oder aber ganz ohne fstab-Datei als eigenständige Unit vorliegen. Einen Überblick aller existierenden Mount-Units erhält man mittels: systemctl -t mount
Beispiele
Wurzel-Partition mit ext4 und Standard-Optionen in Spalte 4 (defaults):
/dev/sda2 / ext4 defaults 0 1
Normale Diskette, zu den Optionen noauto,user,sync siehe man mount:
/dev/sr0 /media/cdrom auto noauto,user,sync 0 0
Mit mount /media/cdrom kann nun jedermann eine Diskette einhängen und später mit umount /media/cdrom wieder aus dem Dateisystem entfernen. Die Option sync soll veranlassen, dass Änderungen sofort auf das Medium geschrieben werden.
NFS-Freigabe (Network File System, Unix-Standard), zu den Optionen soft,bg siehe spezielles Manual man nfs:
192.168.23.200:/home/pub /media/pub nfs soft,bg 0 0
Samba-Freigabe (SMB = Server Message Block Protocol, Windows-Standard), zu den Optionen username,password siehe spezielles Manual man smbfs:
//192.168.23.200/doc /media/doc smbfs username=tux,password=x 0 0
Virtuelle Dateisysteme
- Ein wichtiges virtuelles Dateisystem ist das unter /proc eingehangene, das für jeden laufenden Prozess einen Verzeichnis-Eintrag führt sowie Hardwareinformationen, z.B. über die CPU, liefert:
cat /proc/cpuinfo
- Seit Kernelversion 2.6.x gibt es unter /sys ein weiteres virtuelles Dateisystem, in dem sich vor allem Informationen über Hardware und ihre Einstellungen befinden. Hiermit lassen wir uns z.B. die aktuelle CPU-Frequenz anzeigen:
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq
- Für automatische Mountvorgänge (USB-Sticks u.ä.) wird in neueren Distributionen UDEV verwendet. Mit Hilfe von Rules (Regeln) können Mountpunkte und Aktionen an persönliche Erfordernisse angepasst werden. Dem Udev-Dienst dient dabei das Verzeichnis /dev als Mountpunkt, in dem dann die neuen Gerätedateien als Zeiger auf die Datenträger automatisch erscheinen. Siehe dazu:
Verzeichnisbaum
Der Verzeichnis- oder Dateibaum ist Ergebnis von Bestrebungen in der Entwicklung des Unix-Betriebssystems. Unter https://de.wikipedia.org/wiki/Filesystem_Hierarchy_Standard lesen wir dazu: „Er soll die Interoperabilität von Computerprogrammen fördern, indem er die Lage von Verzeichnissen und Dateien vorhersehbar macht.“
Außerdem wollte man verschiedene Szenarien unterscheiden können, was dann 3 unterschiedlich tiefe Ebenen ergibt:
Booten in den Recovery-Modus (Single User) - Verzeichnisse: /bin, /sbin
Booten in den normalen Multiuser-Modus - Verzeichnisse: /usr/bin, /usr/sbin
Bereitstellung von Zusatzprogrammen/-Scripts - Verzeichnisse: /usr/local/bin, /usr/local/sbin
Siehe auch:
Dateirechte
Auf dem Fundament eines stabilen, Unix-artigen Dateisystems wie ‚ext4‘ wird das alte, grundlegende Multiuser-Konzept auf einfache und sichere Weise umgesetzt:
1. Besitz: Ein Dateisystemobjekt (Datei, Verzeichnis) kann einem Besitzer (User) sowie einer Gruppe (Group) zugeordnet werden. Das Kommando dafür ist ‚chown‘ (CHange OWNer).
-> Im Beispiel:
chown -R max:users /home/max
Das Ergebnis mittels
ls -ld /home/max
kontrolliert, sieht so aus:
drwxr-xr-x 6 max users 4096 Jan 1 19:11 /home/max
2. Rechtemodus: Ein Dateisystemobjekt (Datei, Verzeichnis) kann für den Besitzer (User), die Gruppe (Group) oder den Rest der Welt (Others) die Rechte Read (Oktalwert 4), Write (Oktalwert 2) oder eXecute (Oktalwert 1) erhalten. Die Oktalwerte werden für User, Group und Others jeweils getrennt zusammenaddiert und dann einfach nur noch hintereinander notiert. Das Kommando dafür ist ‚chmod‘ (CHange MODus), mit
chmod 700 /home/max
kann ein Nutzer beispielsweise sein Heimatverzeichnis vor neugierigen Blicken schützen.Das Ergebnis mittels
ls -ld /home/max
kontrolliert, sieht nunmehr so aus:
drwx------ 6 max users 4096 Jan 1 19:11 /home/max
Weiterhin verfügen ext-Dateisysteme über erweiterte Dateiattribute, mit denen sich z.B. Dateien immunisieren lassen (read only auch für ‚root‘) sowie Access Control Lists (File ACLs).
6. Systemstart und Prozessverwaltung
Ein typischer Ablauf eines Bootvorgangs gestaltet sich folgendermaßen:
Power-Knopf drücken (ATX-Formfaktor, Stromsparfunktionen via Taster => Netzteil)
Start-OS „BIOS“, Power On Self Test (POST) => www.grundlagen-computer.de
Auf der Festplatte wird MBR gesucht (512 Byte Bootcode, 64 Byte Partitionstabelle)
Den gesamten MBR sichern:
dd if=/dev/sda of=mbr.bin count=1 bs=512
Nur den Bootcode sichern:
dd if=/dev/sda of=bootcode.bin count=1 bs=440
Bootloader lädt den Kernel in den RAM
Kernel startet den ersten Prozess mit der PID 1 (init / systemd)
Bereitstellen von Dateisystem und User-Login
Bootloader
Bootloader werden vor allem in der x86-Intel-Welt benötigt. So etwas hat beispielsweise die SPARC-Hardwareplattform nicht nötig. Hier startet ein komfortables Boot-ROM das Betriebssystem.
Wir aber benötigen in der Regel eine solche Komponente. Sie muss den Kernel in den Arbeitsspeicher laden, der dann von dort aus die ersten richtigen Prozesse starten kann, was schließlich in den User-Login mündet.
In der Open-Source-Welt gibt es viele verschiedene Bootloader. Historisch gesehen hat der „Linux Loader“ (LILO) eine wichtige Rolle gespielt. Nachteilig ist bei ihm vor allem, dass die Konfigurationsdatei unter /etc liegt (/etc/lilo.conf), was mit sich bringt, dass mit Kernel-Updates immer auch der MBR neu geschrieben werden muss. Denn das Verzeichnis /etc kann mitsamt der Wurzelpartition (‚/‘) unter Umständen sehr weit ‚hinten‘ liegen und wird dann auch erst zu einem späteren Zeitpunkt gemountet. Womit die Konfigurationsdatei im frühen Bootstadium nicht verfügbar ist!
Heute wird per Default der Bootloader „Grand Unified Boot Loader“ (GRUB) eingesetzt. Seine Konfigurationsdatei liegt woanders, nämlich unter /boot (/boot/grub/grub.cfg). Da dieses Verzeichnis im Bootprozess sehr früh ansprechbar sein muss (Dort liegt ja auch der Linux-Kernel!), ist das Überschreiben des MBRs bei regulären Updates nicht mehr erforderlich.
Interessant ist auch die Frage, wohin der Bootloader installiert werden sollte - vor allem bei der Installation des Linux-Betriebssystems. Dieser Ort ist in aller Regel der MBR der ersten Festplatte. Bei SATA-Laufwerken ist dies „sda“ (Gerätedatei: /dev/sda).
Init-System
Nachdem der Kernel in den RAM gebracht wurde, können weitere Prozesse gestartet werden. In der Regel übernimmt das Starten und Stoppen der verschiedensten Dienste eine zentrale Kontrollinstanz, die sicherstellt, dass die richtige Reihenfolge beachtet wird. So z.B. Log-Dienst starten, -> Netzwerk initialisieren, -> Firwallregeln setzen, -> Netzwerkservices bereitstellen. Und natürlich kümmert sie sich auch um das geordnete, saubere Stoppen der Dienste.
Dienste (engl. services) werden in der Unix-Welt gern als DAEMON bezeichnet, was eine Abkürzung ist für Disks And Extensions MONitor und für einen guten, dienstbaren Geist steht. Grundlegende Aufgaben sind das Bereitstellen lokaler Konsolen- oder grafischer Logins sowie von Netzwerkdiensten.
Ein Init-System ist nicht zwingend erforderlich, beispielsweise kann der ssh-Daemon im Notfall folgendermaßen an den Start gebracht werden:
mkdir /run/sshd && /usr/sbin/sshd
Wer der allererste, im laufenden System messbare Prozess ist, lässt sich hier sehr schön an der Prozess-ID 1 erkennen:
root@deb:~# pstree -pn | head
systemd(1)-+-systemd-journal(304)
|-blkmapd(318)
|-lvmetad(321)
|-systemd-udevd(330)
|-rpc.idmapd(653)
|-rpcbind(654)
|-systemd-timesyn(657)---{systemd-timesyn}(761)
|-rpc.mountd(756)
|-irqbalance(765)
|-freshclam(767)
root@deb:~#
Bei vielen Linux-Distributionen (wie auch schon unter Debian 9) ist dies inzwischen ‚systemd‘. Historisch gesehen spielt aber ‚sysVinit‘ immer noch eine gewisse Rolle. In diesem Falle steht hinter der Prozess-ID 1 der Dienst ‚init‘ (Programm ‚/sbin/init‘), der sich über die Datei /etc/inittab und mit Hilfe von Init-Skripten sowie Runlevel-Links konfigurieren lässt.
Services mit Systemd verwalten
Wir haben weiter oben bereits gesehen, dass hier Systemd als Init-Daemon regiert (pstree -pn
).
Zuerst fragen wir nach der Anzahl aller vorhanden Service-Units und suchen dann nach ‚ssh‘:
[root@hostX]# systemctl list-unit-files | wc -l
233
[root@hostX]#
[root@hostX]# systemctl list-unit-files | grep -i ssh
ssh.service enabled enabled
ssh@.service static -
sshd.service alias -
ssh.socket disabled enabled
rescue-ssh.target static -
[root@hostX]# ## >> Mehrere Units für einen Dienst! Die eigentliche Unit ist "ssh.service".
Auf diesem minimalen Debian 11 System hatten wir bereits bei der Installation (tasksel
) das Paket „openssh-server“ ausgewählt. Bezüglich dessen sollen zuerst einmal Infos eingeholt werden:
[root@hostX]# systemctl status ssh
● ssh.service - OpenBSD Secure Shell server
Loaded: loaded (/lib/systemd/system/ssh.service; enabled; vendor preset: enabled)
Active: active (running) since Thu 2022-04-14 16:05:24 CEST; 4 days ago
Docs: man:sshd(8)
man:sshd_config(5)
Process: 392 ExecStartPre=/usr/sbin/sshd -t (code=exited, status=0/SUCCESS)
Main PID: 441 (sshd)
Tasks: 1 (limit: 1868)
Memory: 5.6M
CPU: 1.453s
CGroup: /system.slice/ssh.service
└─441 sshd: /usr/sbin/sshd -D [listener] 0 of 10-100 startups
Apr 14 16:05:22 dbuster systemd[1]: Starting OpenBSD Secure Shell server...
Apr 14 16:05:24 dbuster sshd[441]: Server listening on 0.0.0.0 port 22.
Apr 14 16:05:24 dbuster sshd[441]: Server listening on :: port 22.
Apr 14 16:05:24 dbuster systemd[1]: Started OpenBSD Secure Shell server.
Apr 19 08:08:42 dbuster sshd[473]: Accepted password for tux from 192.168.2.107 port 50092 ssh2
Apr 19 08:08:42 dbuster sshd[473]: pam_unix(sshd:session): session opened for user tux(uid=1000) by (uid=0)
Apr 19 09:19:38 dbuster sshd[813]: Accepted password for tux from 192.168.2.107 port 50247 ssh2
Apr 19 09:19:38 dbuster sshd[813]: pam_unix(sshd:session): session opened for user tux(uid=1000) by (uid=0)
Apr 19 09:19:39 dbuster sshd[815]: Accepted password for tux from 192.168.2.107 port 50248 ssh2
Apr 19 09:19:39 dbuster sshd[815]: pam_unix(sshd:session): session opened for user tux(uid=1000) by (uid=0)
[root@hostX]#
[root@hostX]# ## Oder kürzer:
[root@hostX]# systemctl is-enabled ssh
enabled
[root@hostX]# systemctl is-active ssh
active
[root@hostX]# ## >> Damit haben wir erstens Gewissheit, dass er beim Booten automatisch gestartet wird,
[root@hostX]# ## und sehen zweitens, dass er läuft.
Debian ist schön bequem, was das automatische Konfigurieren angeht; bei RedHat/SuSE werden neu installierte Services dagegen nicht automatisch gestartet, dort also nicht vergessen, „enable“ und „start“ auszuführen:
[root@hostX]# systemctl enable ssh
Synchronizing state of ssh.service with SysV service script with /lib/systemd/systemd-sysv-install.
Executing: /lib/systemd/systemd-sysv-install enable ssh
[root@hostX]#
[root@hostX]# systemctl start ssh
[root@hostX]#
Zusammenfassend hier ein paar wichtige systemctl-Aktionen:
Autostart:
enable
oderdisable
Live-Running:
start
,stop
,restart
oderreload
(je nach Unit leicht unterschiedlich)
Um in den sogenannten Single-User-Modus (= abgesicherter Modus) hineinfahren zu können, benutzen wir hier nicht so sehr die alten Runlevel, sondern eher fein unterteilte Targets:
[root@hostX]# runlevel
N 5
[root@hostX]# ## >> Das bedeutet: (N)o other runlevel before, - jetzt befindet sich das System
[root@hostX]# ## im Level 5, wo viele Dienste laufen (Multiuser mit Netzwerk und grafischer Oberfläche)
[root@hostX]#
[root@hostX]# ## Bei Systemd-Distributionen gibt es sehr viele "targets":
[root@hostX]# systemctl isolate rescue.target
-- nach kurzer Wartezeit kommt die folgende Fehlermeldung --
[root@hostX]# client_loop: send disconnect: Broken pipe
tux@alp ~$
tux@alp ~$ ## >> Richtig: der ssh-Client hat einen Timeout erlitten!
An der Maschine nun selber einfach mittels systemctl default
in den Standard-Modus fahren, was hier leider kein Netzwerk zurückbringt! Wir
müssen daher als root systemctl isolate runlevel6.target
ausführen…
Oder kürzer:
init 6
systemctl reboot
Bei Systemd-Distribution gibt es außerdem einen integrierten Log-Dienst „journald“, der via journalctl
gesteuert werden kann; die Option -f
(follow) gestattet das Logbuch offen zu halten und neuen Zeilen zu folgen:
[root@hostX]# journalctl -f
-- Journal begins at Wed 2022-04-13 09:02:58 CEST. --
Apr 19 12:15:57 dbuster systemd[447]: Reached target Basic System.
Apr 19 12:15:57 dbuster systemd[1]: Started User Manager for UID 1000.
Apr 19 12:15:57 dbuster systemd[1]: Started Session 1 of user tux.
Apr 19 12:15:57 dbuster systemd[447]: Reached target Main User Target.
Apr 19 12:15:57 dbuster systemd[447]: Startup finished in 92ms.
Apr 19 12:16:16 dbuster su[462]: (to root) tux on pts/0
Apr 19 12:16:16 dbuster su[462]: pam_unix(su-l:session): session opened for user root(uid=0) by tux(uid=1000)
Apr 19 12:17:01 dbuster CRON[468]: pam_unix(cron:session): session opened for user root(uid=0) by (uid=0)
Apr 19 12:17:01 dbuster CRON[469]: (root) CMD ( cd / && run-parts --report /etc/cron.hourly)
Apr 19 12:17:01 dbuster CRON[468]: pam_unix(cron:session): session closed for user root
^C
[root@hostX]# ## >> Zum Beenden des Monitorings STRG-C drücken.
[root@hostX]#
[root@hostX]# ## Auch nützlich: alle Nachrichten bezüglich der ssh-Unit ausgeben ( nur die letzten 10 Zeilen):
[root@hostX]# journalctl -u ssh | tail
Apr 19 12:10:59 dbuster systemd[1]: Stopping OpenBSD Secure Shell server...
Apr 19 12:10:59 dbuster systemd[1]: ssh.service: Succeeded.
Apr 19 12:10:59 dbuster systemd[1]: Stopped OpenBSD Secure Shell server.
-- Boot a6e5d9680f4e4234ab34518a66ee17d4 --
Apr 19 12:13:48 dbuster systemd[1]: Starting OpenBSD Secure Shell server...
Apr 19 12:13:48 dbuster sshd[397]: Server listening on 0.0.0.0 port 22.
Apr 19 12:13:48 dbuster sshd[397]: Server listening on :: port 22.
Apr 19 12:13:48 dbuster systemd[1]: Started OpenBSD Secure Shell server.
Apr 19 12:15:57 dbuster sshd[444]: Accepted password for tux from 192.168.2.107 port 50470 ssh2
Apr 19 12:15:57 dbuster sshd[444]: pam_unix(sshd:session): session opened for user tux(uid=1000) by (uid=0)
[root@hostX]#
Siehe dazu auch:
Prozessverwaltung
Eine wichtige Aufgabe in einem Multiusersystem ist die Überwachung und Manipulation von Prozessen. Ein Prozess ist ein Programm im Abarbeitung – es kommt also der Zeitfaktor hinzu. Ein Daemon (Service, Dienst) startet zur Erfüllung seiner Aufgaben häufig mehrere Prozesse gleichzeitig.
Wichtige Werkzeuge zur Prozessüberwachung und -manipulation sind:
ps
- Process Snapshot, ohne Option werden nur die Prozesse der aktuellen Shellumgebung angezeigt. Alle auflisten:ps aux
. Weil das meist zu viel produziert, kann man das Ergebnis mit dem Pager ‚more‘ betrachten:ps aux | more
pstree
- Prozesse in Baumform ausgebenkill <PID>
- Prozess beenden, z.B.kill 2918
killall <NAME>
- Alle gleichnamigen Prozesse beenden, z.B.killall firefox-esr
xkill
- Ein Fenster des X-Window-Systems mit einfachem Linksklick gewaltsam beendentop
- Prozesse in einem sich selbst aktualisierenden Live-Monitor präsentieren und manipulieren („top“ = die größten Ressourcenverbraucher zuerst)
Der Prozessmonitor ‚top‘ lässt sich interaktiv bedienen. Hier ein paar elementare Möglichkeiten zu seiner Steuerung:
Taste
q
- quitTaste
1
- alle Prozessoren (CPU-Cores) anzeigenTaste
u <USERNAME>
- Nach einem Nutzer filternTaste
r
- Renice von Prozessen durchführen (Nice-Wert nachträglich ändern)Taste
k
- Killen von Prozessen (PID und Signalnummer angeben)
Praxisbeispiel: Ein Programm frisst so viel Ressourcen, dass das System langsam wird (Out of Memory-Killer = OOM-Killer)
Firefox mit laufenden Flash-Plugins an den Start bringen, Last verursachen
Den „Taskmanager“ starten:
top
Die vorgeschlagene PID übernehmen oder anpassen, Taste ‚k‘ (kill) drücken
Die vorgeschlagene Signalnummer (15) übernehmen oder anpassen, eine ‚9‘ macht ein Clean up des Programmes unmöglich (SIGKILL)!
Beobachten, ob der Systemzustand wieder in Ordnung ist
Beenden des Prozessverwaltungstools mit ‚q‘
7. Benutzer-/Gruppen-Verwaltung
Da Linux als Unix-Ableger ein typisches Multiuser- und Multitaskting-Betriebssystem darstellt, gibt es natürlich eine ausgefeilte, strapazierfähige Benutzer- und Gruppenverwaltung. Der administrative User ‚root‘ spielt dabei eine Sonderrolle. Wichtig sind insbesondere die klassischen Datenbankdateien, die im Plaintextformat vorliegen. Und natürlich werden wir uns verschiedene Werkzeuge ansehen.
Root werden
Achtung: Der administrative (Super-)User namens ‚root‘ unterliegt keinen Beschränkungen! Es sollte sich nicht direkt auf der grafischen Oberfläche einloggen. Ausgehend von einem normalen Useraccount mutiert man in der Regel mit dem Kommando:
/bin/su -
zum allmächtigen Admin. Der Bindestrich ist von Bedeutung (= Kürzel für ‚-l‘); damit verhält sich die neue Benutzerumgebung wie bei einem richtigen Login. Unter Ubuntu und ähnlichen Distributionen besitzt der Superuser kein Passwort, hier verwenden wir das Kommando ‚sudo‘:
/usr/bin/sudo -i
Die Option ‚-i‘ steht für „interactive“, womit auch hier eine dauerhafte root-Shell gegeben ist und nicht immer das Kommando ‚sudo‘ vorangestellt werden muss.
In beiden Fällen wurde der absolute Pfad zum Kommando mit angegeben, was in Multiusersystemen aus Sicherheitsgründen ratsam ist. Ansonsten genügt auch die Kurzform ‚su -‘ bzw. ‚sudo -i‘.
Gruppenkonzept
Es gibt zwei Gruppenarten, die erste ist zwingend erforderlich, weil neu zu erzeugende Dateien immer einer bestimmten Gruppe zugeordnet werden müssen:
a) Primäre Gruppe: Im Wesentlichen wird darüber festgelegt, welcher Gruppe neue Dateien angehören. Eine entsprechende Kommandozeile, die beim Hinzufügen eines Nutzers die Gruppe ‚users‘ zuordnet, könnte so aussehen: useradd -m -s /bin/bash -g users friedrich
b) Sekundäre Gruppen: Soll Nutzern höhere Rechte eingeräumt werden, um z.B. Gerätedateien nutzen zu können (Gruppe ‚audio‘, ‚video‘) oder automatisches Mounten zu erlauben (Gruppe ‚plugdev‘), müssen sie oft noch weiteren Gruppen angehören.
Hinweis: Moderne Distributionen wie SUSE-Linux setzen verstärkt auf POSIX-ACLS (= Unix-basierte Access Control Lists), daher werden den Benutzern dort keine sekundäre Gruppen mehr zugewiesen.
Datenbank-Dateien
a) Benutzer-Definitionen und ihre Passwort- und Kontoalterungsinformationen:
/etc/passwd (für jedermann lesbar)
/etc/shadow (steht im Schatten der ‚passwd‘, ist NICHT für jedermann lesbar, denn hier stehen heutzutage die Passwörter drin, außerdem finden sich hier Informationen über die Passwort- und Kontogültigkeit)
b) Gruppen-Definitionen und eventuelle Gruppenpasswörter:
/etc/group (für jedermann lesbar)
/etc/gshadow (steht im Schatten der ‚group‘, ist NICHT für jedermann lesbar, denn hier stehen heutzutage die Gruppen-Passwörter drin)
Werkzeuge
Zum Anlegen von Benutzern und Gruppen verwendet man useradd
, passwd
und groupadd
.
Kommando ‚useradd‘: mit ‚-D‘ werden zuerst einmal Default-Einstellungen ausgegeben: z.B. $HOME, $SHELL, primäre Gruppe, die beim Neuanlegen von Benutzern verwendet werden soll, dabei wird die folgende Datei abgearbeitet: ‚/etc/default/useradd‘. Führt man das Kommando dann wie im folgenden Beispiel gezeigt aus, wird ein Eintrag in Form einer Textzeile jeweilig zu den Dateien /etc/passwd, /etc/shadow, /etc/group und evl. /etc/gshadow hinzugefügt.
Kommando ‚passwd‘: Erzeugen und ändern von Passwörtern, die in der Datei /etc/shadow landen.
Kommando ‚groupadd‘: Im Beispiel soll eine Gruppe namens ‚verwaltung‘ angelegt werden:
groupadd verwaltung
Voreinstelungen: Neben der Datei ‚/etc/default/useradd‘, gibt es noch eine weitere, die sich um Defaults kümmert, die Datei ‚/etc/login.defs‘. Sie beinhaltet vor allem die Account-Alterungseinstellungen.
Einen beispielhaften Benutzer mit Heimatverzeichnis anlegen (‚-m‘ = make home directory), wobei ihm als Login-Shell die Bash zugewiesen werden soll (‚-s‘ = shell):
root@deb:~# useradd -m -s /bin/bash max
root@deb:~# passwd max
Geben Sie ein neues UNIX-Passwort ein:
Geben Sie das neue UNIX-Passwort erneut ein:
passwd: Passwort erfolgreich geändert
root@deb:~#
Wir kontrollieren das Ergebnis mit dem Textfilter ‚tail‘, was mit ‚-n1‘ lediglich die letzte Zeile dieser 4 Dateien ausgibt:
root@deb:/etc# tail -n 1 passwd shadow group gshadow
==> passwd <==
max:x:2009:2009::/home/max:/bin/bash
==> shadow <==
max:$6$OjxHwbEI$OtrjdN46X8cNIuQi/945bQWVDMOHPvLsX1/x9IVCSsG.nFEN84vAPLAlHCkivtE94lMdF4uWTvTehT.6Rtb6c/:17556:0:99999:7:::
==> group <==
max:x:2009:
==> gshadow <==
max:!::
root@deb:/etc#
8. Software, Applications
Das Installieren und Aktualisieren von Software ist unter Linux prinzipiell nicht sehr schwierig, da sich ja der Distributor um die Erstellung und Bereitstellung von Binärpaketen kümmert. Daher kommt man meist recht schnell in den Genuss von Updates und Hotfixes. Allerdings handhabt es jede Distribution ein wenig anders, weshalb wir hier nur die Paketverwaltung typischer Debian-basierter Distributionen umreißen wollen.
Erwähnt sei allerdings noch an dieser Stelle, dass es auch quelltextbasierte Distributionen wie ‚Gentoo‘ gibt, die keine fertigen Binärpakete anbieten. Dort wird fast alles just-in-time kompiliert, was natürlich deutlich mehr Zeit beansprucht.
Paketverwaltung unter Debian
Anders als unter Windows werden in der UNIX-Welt zentrale Repositories angezapft (= „App Store“-Prinzip, ein guter Open Source Appstore für Android ist https://f-droid.org). Unter Debian werden die Quellen in der Datei ‚/etc/apt/sources.list‘ hinterlegt. Bei Release 9 (Codename „stretch“) sind das im wesentlichen diese 3 Zeilen (je nach gewählen Mirror unterscheiden sich die verwendeten Server und Pfade):
deb http://ftp.tu-chemnitz.de/pub/linux/debian/debian/ stretch main
deb http://security.debian.org/ stretch/updates main
deb http://ftp.tu-chemnitz.de/pub/linux/debian/debian/ stretch-updates main
Diese externen Quellen können nur von Frontends wie ‚synaptic‘ (Graphical User Interface) und den apt-Tools (pseudo Graphical User Interface) genutzt werden. Das im Hintergrund werkelnde Backend ‚dpkg‘ ist nicht netzwerkfähig. Aber man kann damit viele Detailaufgaben erledigen. So lässt sich mit dpkg -l | more
die Liste aller installierter Debian-Pakete durchforsten.
Zur Verdeutlichung, wie die klassischen apt-Tools eingesetzt werden, hier zwei typische Szenarien:
a) Systemupdate durchführen
root@deb:~# ### Softwarelisten refreshen:
root@deb:~# apt-get update
root@deb:~# ### Software aktualisieren:
root@deb:~# apt-get upgrade
b) Ein Paket suchen und installieren
root@deb:~# ### Falls heute nicht bereits durchgeführt, Softwarelisten refreshen:
root@deb:~# apt-get update
root@deb:~# ### Software suchen:
root@deb:~# apt-cache search mindmap
root@deb:~# ### Software installieren (eine gute, javabasierte Mindmap-Anwendung):
root@deb:~# apt-get install freemind
Unter RedHat, CentOS, Fedora und SuSE-Linux läuft es ganz ähnlich, siehe dazu die Vergleichstablle unter http://danilodellaquila.com/en/blog/linux-package-management-cheatsheet
Portable-Apps, neue Wege
Die aus der Windows-Welt bekannten Portable-Apps gibt es hier natürlich auch. Allerdings ist es nicht ganz so einfach damit. Dazu ein paar Anregungen:
Relativ leicht lassen sich javabasierte Anwendungen an den Start bringen (‚java -jar myapp.jar‘).
Ähnlich ist es mit Python-Programmen, der Interpreter ist oft schon vorinstalliert.
Es gibt fertige Gesamtpakete, die lediglich heruntergeladen und mit Hilfe von
chmod +x my-program.AppImage
ausführbar gemacht werden müssen. So z.B. ein Malprogramm für Illustrationen, was unter https://bintray.com/package/files/probono/AppImages/AzPainter zu finden ist.Aber auch auf liebgewonnene, native Windows-Programme muss man nicht verzichten. Die Chancen stehen für manche Anwendungen gut, dass sie mit Hilfe von ‚wine‘ ausgeführt werden können. Siehe dazu https://appdb.winehq.org/
Parallel dazu wird versucht, ein flexibles Containerformat für Anwendungen zu etablieren. Ubuntu versucht sich an ‚snap‘, aus dem Desktop-Projekt von Gnome ist ‚flatpack‘ hervorgegangen. Mehr Informationen dazu sind unter https://www.devpy.me/snapcraft-appimage-flatpak/ zu finden.