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

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:

  1. 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:~$
  1. 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
  1. 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 oder A)

  • 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 ausgeben

  • tail - nur die letzten Zeilen einer oder mehrerer Dateien ausgeben

  • sort - eine Datei sortieren

  • wc - 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.

  1. 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‘:

  1. 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:~$
  1. 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:~$
  1. 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
  1. Wortanfang und -ende

tux@deb:~$ grep '\<localhost\>' hosts
127.0.0.1        localhost
::1     localhost ip6-localhost ip6-loopback
tux@deb:~$
  1. Weitere Werkzeuge zur Suche mit regulären Ausdrücken

  • egrep (oder grep -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 ~/.bashrc

ANMERKUNG: In der grep-Familie tanzt das Kommando fgrep (oder grep -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:

mount

Anzeigen, was aktuell gemountet ist

mount | grep ^/dev

Nur physische Geräte anzeigen, keine virtuellen Dateisysteme (das Caret-Zeichen ^ bedeutet: Zeilenanfang, d.h. die Zeile muss mit dem Muster „/dev“ beginnen)

df -h

Gesamtüberblick der Festplattenbelegung (disk free)

du -sh /usr

Speicherverbrauch eines bestimmten Verzeichnisses (disk usage)

lsblk

Liste Block Devices auf, auch USB-Hotpluggeräte ausgeben

blkid

Auflisten der Block Devices unter Angabe der UUIDs

fdisk -l

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!

  1. Verzeichnisarbeit:

  • cd (change directory)

    • z.B.: cd /usr/share/doc; mit cd können wir wieder ins Heimatverzeichnis zurückwechseln

  • ls -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

  1. 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 oder cp -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:

  1. Low-Level (nur noch bei Disketten möglich): fdformat /dev/fd0

  2. Partitionierung: fdisk /dev/sdb

  3. 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

Die Kommandos mount und umount leisten die eigentliche Arbeit, wenn Dateisysteme oder Netzwerkressourcen transparent in den Linux-Verzeichnisbaum einzuhängen sind.
Um aber Partitionen beim Booten automatisch in den Baum einzuhängen (wie z.B. die Wurzelpartition!) oder um festzulegen, dass normale Benutzer eine Ressource bei Bedarf einbinden dürfen, sind zwei Dateien von Belang:
/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

Abkürzung: FSTAB = FileSystem TABle (Dateisystemtabelle)
Diese einfache Textdatei spielt eine sehr wichtige Rolle, sie ordnet Gerätedateien oder Netzwerkfreigaben leeren Verzeichnissen, den Mountpunkten zu. Nach erfolgreichem Mountvorgang sind diese Mountpunkt-Verzeichnisse nicht mehr leer; in ihnen befindet sich dann der Inhalt z.B. einer Diskette, die mit Hilfe einer Gerätedatei /dev/fd0 (floopy disk0) angesprochen wird.
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:

  1. Ressource (z.B. /dev/fd0 oder 192.168.23.200:/home/pub)

  2. Mountpunkt (z.B. /media/cdrom oder /media/pub)

  3. Dateisystemtyp (z.B. auto für Autoerkennung oder nfs)

  4. Verschiedene Optionen (z.B. noauto, user oder für NFS sinnvoll: bg,soft)

  5. Datensicherung mit dump vornehmen? Eine Null steht für nein. Eine Eins für ja.

  6. 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

…benötigen keinen Festplattenplatz. Sie benutzen den Arbeitsspeicher, um die Kommunikation zwischen dem Kernel selbst und dem sogenannten Userspace (Benutzer-Bereich des Kernels = Schnittstelle nach außen) zu ermöglichen.
Aus einer Vielzahl hier eine Auswahl:
  • 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:

  1. Booten in den Recovery-Modus (Single User) - Verzeichnisse: /bin, /sbin

  2. Booten in den normalen Multiuser-Modus - Verzeichnisse: /usr/bin, /usr/sbin

  3. 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:

  1. Power-Knopf drücken (ATX-Formfaktor, Stromsparfunktionen via Taster => Netzteil)

  2. Start-OS „BIOS“, Power On Self Test (POST) => www.grundlagen-computer.de

  3. Auf der Festplatte wird MBR gesucht (512 Byte Bootcode, 64 Byte Partitionstabelle)

  4. Bootloader lädt den Kernel in den RAM

  5. Kernel startet den ersten Prozess mit der PID 1 (init / systemd)

  6. 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 oder disable

  • Live-Running: start, stop, restart oder reload (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 ausgeben

  • kill <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 beenden

  • top - 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:

  1. Taste q - quit

  2. Taste 1 - alle Prozessoren (CPU-Cores) anzeigen

  3. Taste u <USERNAME> - Nach einem Nutzer filtern

  4. Taste r - Renice von Prozessen durchführen (Nice-Wert nachträglich ändern)

  5. 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:

  1. Relativ leicht lassen sich javabasierte Anwendungen an den Start bringen (‚java -jar myapp.jar‘).

  2. Ähnlich ist es mit Python-Programmen, der Interpreter ist oft schon vorinstalliert.

  3. 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.

  4. 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.