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. .. highlight:: shell-session 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: - `Alpine Linux `_ - `Debian-Paketsuche `_ - `Devuan-Derivat "Refracta" `_ - `GuixSD `_ - `KaOS `_ - `CentOS `_ - `SliTaz `_ - `openSUSE `_ - `Tiny Core Linux `_ 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: a) 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:~$ b) 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 c) 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 ` * 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 '. 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:~$ .. LINUX-Konzepte II .. ################# .. Version 0.8 .. Axel Pemmann, 2019-10-21 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 `` oder ``-`` - tail (per Default die letzten 10 Zeilen ausgeben) - Wichtige Optionen: - Zeilenzahl: ``-n `` oder ``-`` - | 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': a) Zeilenanfang: Zuerst wollen wir nach bestimmten Zeichen am Zeilenanfang fahnden: ``grep -v '^#' `` 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:~$ b) 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:~$ c) 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 d) Wortanfang und -ende :: tux@deb:~$ grep '\' hosts 127.0.0.1 localhost ::1 localhost ip6-localhost ip6-loopback tux@deb:~$ 2. **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 < 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 = **F**\ ile\ **S**\ ystem **TAB**\ le (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* (**f**\ loopy **d**\ isk\ **0**) 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: #. 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): .. container:: myverbatim ``/dev/sda2 / ext4 defaults 0 1`` **Normale Diskette**, zu den Optionen *noauto,user,sync* siehe *man mount*: .. container:: myverbatim ``/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*: .. container:: myverbatim ``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*: .. container:: myverbatim ``//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: | http://de.wikipedia.org/wiki/Udev | http://de.wikipedia.org/wiki/Ger%C3%A4tenamen_unter_Linux 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: a) Booten in den Recovery-Modus (Single User) - Verzeichnisse: **/bin, /sbin** b) Booten in den normalen Multiuser-Modus - Verzeichnisse: **/usr/bin, /usr/sbin** c) Bereitstellung von Zusatzprogrammen/-Scripts - Verzeichnisse: **/usr/local/bin, /usr/local/sbin** Siehe auch: - http://www.linux-praxis.de/linux1/spaziergang.html - http://www.pc-erfahrung.de/nebenrubriken/sonstiges/linux-fhs.html 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) - Siehe https://de.wikipedia.org/wiki/Master_Boot_Record - 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`` 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: .. highlight:: bash :: 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: .. highlight:: shell-session :: 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': .. highlight:: shell-session :: [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: .. highlight:: shell-session :: [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: .. highlight:: shell-session :: [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: .. highlight:: shell-session :: [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`` (*f*\ollow) gestattet das Logbuch offen zu halten und neuen Zeilen zu folgen: .. highlight:: shell-session :: [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: - https://blog.desdelinux.net/de/systemd-versus-sysvinit-systemd-shim/ - https://www.su4me.de/lin_init.html 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 `` - Prozess beenden, z.B. ``kill 2918`` - ``killall `` - 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: a) Taste ``q`` - quit b) Taste ``1`` - alle Prozessoren (CPU-Cores) anzeigen c) Taste ``u `` - Nach einem Nutzer filtern d) Taste ``r`` - Renice von Prozessen durchführen (Nice-Wert nachträglich ändern) e) 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: a) Relativ leicht lassen sich javabasierte Anwendungen an den Start bringen ('java -jar myapp.jar'). b) Ähnlich ist es mit Python-Programmen, der Interpreter ist oft schon vorinstalliert. c) 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. d) 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.