LPIC-1_Notizen_Gesamt
---

<u>LPIC-1 Gesamtnotizen (sortiert nach Prüfungsthemen)</u>



Übersicht: Stufen der LPIC-1 Prüfung


* LPIC-1 : Besteht aus zwei Prüfungen: 101-500 und 102-500
* Exam 101-500
* 101 : System Architecture
* 102 : Linux Installation and Package Management
* 103 : GNU and Unix Commands
* 104 : Devices, Linux Filesystems, Filesystem Hierarchy Standard
* Exam 102-500
* 105 : Shells, Scripting and Data Management
* 106 : User Interfaces and Desktops
* 107 : Administrative Tasks
* 108 : Essential System Services
* 109 : Networking Fundamentals
* 110 : Security

---

Exam 101-500



101 – System Architecture



101.1 Determine and configure hardware settings


* Hardware-Uhr (Firmware-Uhr) : Linux hat im Kernel eine eigene Uhr ; die Systemzeit wird beim Hochfahren aus der Firmware-Uhr ermittelt
* Firmware : muss die Boot-Platte kennen ; legt die Bootreihenfolge fest (z.B. CD, Netzwerk oder bestimmte Platte zuerst)
* Einschalten des Rechners: als erstes wird die Firmware aktiv
* Kernel : wird beim Hochfahren des Systems gestartet ; wenn z.B. die Shell auf die Platte schreiben will, nutzt sie dafür die Unterstützung des Kernels (System Call) ; Anwendungssoftware liegt oberhalb des Kernels

* Schichtenmodell : User Mode (keine privilegierten Prozesse) und Kernel Mode (kontrollierte, privilegierte Berechtigungen)
* Aufbau von oben nach unten: Linux-Anwendung -> Standard Library -> System Calls -> Linux-Kernel -> Hardware

* BIOS : alt ; wird eher noch in VMs verwendet
* UEFI : moderner, unterstützt größere Platten

* uname : Gibt das System wie "Linux" aus
* uname -r : laufende Kernel Version, z.B. "6.14.0.36-generic"
* uname -a : alle Infos zum laufenden Kernel

* lspci : listet PCI Bus Geräte auf
* lspci -v : Verbose
* lspci -t : Tree
* lspci -tv : Verbunden (Tree + Verbose)
* lspci -n : Geräte ID
* lspci -s 00:03.0 -v : schränkt den Befehl auf bestimmten Treiber ein
* lspci -s 00:03.0 -k : zeigt Kernel Modul
* lspci -s 00:03.0 -n : zeigt direkt Geräte ID
* zeigt: Geräte ID, Interrupt IP, Geräte ID
* IRQ 16 : Interrupt Request Que
* Kernel Modul e1000 : Beispiel für ein verwendetes Kernel Modul (Netzwerk)

* lsusb : listet am USB Bus angeschlossene Geräte auf
* lsusb -v | less : Infos zeilenweise ausgeben
* lsusb -v > i : Ausgabe in Datei "i" schreiben
* 4 USB Typen: OHCI 1.0, UHCI 1.1, EHCI 2.0, xHCI 3.1

* modinfo : Infos zum Treiber/Kernelmodul
* modinfo ehci-pci : Beispiel
* modinfo e1000 : Infos zum Kernel Modul
* liegt unter /lib/modules/Kernel.../ethernet/intel/e1000.ko.zst (ko = Kernel Objekt, komprimiert als zst)
* modinfo hv_utils | head : anzeigen, ähnlich wie lsmod

* lsmod : Zeigt (aktuell) geladene Kernel Module an
* Ausgabe zeigt Zahlen wie "1 2 1 0" ; wenn 0 steht, ist das Modul nicht in Benutzung
* lsmod | head : geladene Module auflisten (wichtig für LPIC-1 Prüfung)
* lsmod | grep hv_ : zeigt alles mit "hv_"

* insmod : lädt Module in den laufenden Kernel (Abhängigkeiten werden geprüft, aber nicht gelöst)

* rmmod : entfernt (remove) Kernel Module
* sudo rmmod hv_utils : entfernt ein Kernel Modul ; wenn es in Benutzung ist, kommt eine Meldung

* modprobe : Kombination aus insmod und rmmod ; erkennt und löst Abhängigkeiten automatisch auf
* Moderne Versionen können Kernelmodule einfügen und entladen
* sudo modprobe hv_utils : lädt Modul (wie insmod), Abhängigkeiten werden automatisch aufgelöst

* ls /lib/modules : Alle Kernel Versionen anzeigen
* ls -l /proc/modules : 0 Bytes, da dies zur Laufzeit direkt im Kernel/Arbeitsspeicher stattfindet, keine echte Datei ist

* /proc : bildet Parameter des Kernels ab (virtuelles Verzeichnis)
* liegt im Arbeitsspeicher, nicht auf der Festplatte
* Normaler Benutzer kann Werte lesen, aber nicht jeder User kann schreiben
* Einige Bereiche können geändert werden
* ls -l /proc/Interrupts : Interrupts anzeigen (IRQ 16 = Interrupt Request Line/Query, einem Treiber zugeordnet)
* cat /proc/ioports : Eingabe- und Ausgabegeräte
* cat /proc/sys/kernel/Version : Kernel Version anzeigen
* man proc : Infos
* df -T /proc : zeigt für /proc den Dateisystem-Typ "proc" an ; bestätigt, dass es sich um ein virtuelles Pseudo-Dateisystem für Prozess-/Kernelinformationen handelt (kein echtes Dateisystem auf einer Platte)

* /sys : virtuelles Dateiverzeichnis (sysfs), neben /proc
* df /sys : speichert Infos über den Kernel
* ls /sys
* tree /sys | less
* Beispiele: cpu0, cpu1
* sysfs = virtuelles Dateisystem für Treiber

* hald : Hardware Abstraction Layer Daemon ; informierte den dbus Daemon über Hotplug Geräte (wird aktuell nicht mehr verwendet)
* udev : Nachfolger von hald ; Gerätemanager, erstellt Geräteverzeichnis in /dev
* Driver : z.B. verweist usbhid auf ein Kernel Modul
* udisks : Dienst, der auf udev aufbaut ; sorgt dafür, dass z.B. ein USB-Stick automatisch partitioniert und ohne Root-Rechte gemountet werden kann
* /dev : Verzeichnis vom Typ tmpfs bzw. devtmpfs
ls /dev/fs : * ist Platzhalter für die Suche
* Platten beginnen mit /dev/sd

* cd /etc/modprobe.d : Verzeichnis für Modul-Konfiguration
* blacklist.conf : Kernel Module blacklisten (beim nächsten Start nicht laden) (für LPIC-1: wissen, dass es das gibt)

/boot : z.B. ls -l 36* zeigt config-6.13.0.36-generic (Kernel Parameter)
* Kernel besteht aus zwei Teilen: statischer Kernel + Module

101.2 Boot the system


* Boot Reihenfolge: BIOS -> Bootloader -> Kernel -> Initsystem
* Speicherort: Die initiale RAMdisk liegt als fertige Datei in /boot (z. B. /boot/initrd.img-[Kernelversion] oder /boot/initramfs-[Kernelversion].img).
* Ablauf: Der Bootloader lädt den Kernel (in Read-Only) und diese RAMdisk-Datei in den RAM.
* Phase 1: Der Kernel entpackt die RAMdisk im Arbeitsspeicher und führt dort das Skript /init aus (lädt Treiber, mountet die echte Festplatte).
* Phase 2: Das System wechselt zur echten Festplatte. Der Kernel startet dort /sbin/init (Prozess-ID 1: systemd oder sysvinit).

* dd : DiskDump - Convert and write a File
* dd if=/dev/sda of=mbr.bin bs=512 count=1 : liest die ersten 512 Bytes (MBR)
* if = Input File
* count = angeben, sonst liest er bis zum Ende der Platte
* bs = 512 Bytes lesen
* /dev/sda wichtig, damit von der ganzen Platte gelesen wird, nicht nur Partition 1 z.B. /dev/sda1

* od -cb mbr.bin : Oktal Dump ; lässt man "-b" weg, wird nur binär angezeigt ; "c" = Character = ASCII-Zeichen ausgeben
* hd : Hex Dump
* od -h mbr.bin | head : liest auch Hex
* im Hexdump z.B. "G R U B" auslesbar
* MBR = die ersten 512 Bytes, egal ob Windows oder Linux
* nur im MBR die ersten 512 Bytes ; bei UEFI scheinbar nicht
* Partitionstabelle steht am Ende des MBR (0x1BE bis 0x1FE / Signatur 55aa)

* ls /boot/efi : prüfen, ob UEFI-basiertes System vorhanden ist
* sudo ls -lR /boot/efi : "R" = Recursive ; zeigt z.B. EFI/Boot/... und EFI/ubuntu/...

* UEFI Secure Boot :
* verhindert, dass Rootkits geladen werden
* unter Linux mühsam, man muss sicherstellen, dass UEFI gültige Treiber hat
* Firmware überprüft, ob das zu startende Programm (Bootloader) eine gültige digitale Signatur besitzt
* der Bootloader prüft dann, ob der zu ladende Kernel die korrekten digitalen Signaturen enthält
* für LPIC-1 wichtig: wissen, dass es das gibt und wie man es ein-/ausschaltet

* GRUB : Grand Unified Bootloader ; wird von der Firmware gestartet (für LPIC-1 nur GRUB wichtig)
* (!) "GNU GRUB" : ist die offizielle/vollständige Bezeichnung und meint heute praktisch immer GRUB 2 (nicht mehr GRUB Legacy)
* GRUB Legacy
* Konfigurationsdatei: /boot/grub/menu.lst
* stage1 : erste Phase, liegt im MBR (/boot/grub/stage1)
* stage 1,5 : liegt in /boot/grub ; enthält Routinen (z.B. e2fs_stage1_5), damit der Bootloader weiß, wie er auf reiserfs/xfs-Dateisysteme zugreift
* wenn Dateien in GRUB Boot defekt sind: Prompt erhalten, "c" eingeben -> grub-Shell ; Möglichkeit zu booten, wenn das System nicht mehr funktioniert
* wichtig: bei "kernel" muss der Kernel gesetzt werden, z.B. grub> kernel /boot/vmlinuz...-generic root=/dev/sda1
* GRUB 2 : ist üblich
* Konfigurationsdatei: /boot/grub/grub.cfg
* insmod : lädt bestimmte Module (Verstehen wichtig, nicht genau wissen)
* menuentry : wichtig, das ist der Startpunkt
* grub-mkconfig : ermittelt, welche Kernel es gibt, und trägt sie in die Konfig ein
* sudo grub-mkconfig -o mygrub : Beispiel
* /etc/default/grub : Konfigurationsdatei, wo Einstellungen vorgenommen werden ; sollte man immer editieren, wenn man etwas ändern möchte
* GRUB_DEFAULT = 0 : lädt den ersten Menu Entry
* /etc/grub.d : enthält zusätzliche Verzeichnisse, hier kann man Dinge konfigurieren, z.B. os-prober, wenn noch ein Windows hinterlegt werden soll
* diff grubcfg mygrub : Befehl, um zwei Dateien zu vergleichen
* update-grub : muss ausgeführt werden, damit grub.cfg überschrieben/aktualisiert wird ; erstellt die Bootloader-Datei neu ; man ändert die generierte Datei nicht manuell, sondern die Konfig-Datei (z.B. /etc/default/grub) und lässt sie neu erzeugen
* Bei RedHat-basierten Systemen heißt es grub2, bei Ubuntu grub
* grub-install /dev/sdc : Bootloader auf die 3. Festplatte ("c") installieren ; bei RedHat: grub2-install
* grub-install --root-directory=/custom-grub /dev/sda : installiert GRUB nicht in /boot/grub (Default), sondern relativ zu einem alternativen Wurzelverzeichnis, hier also unter /custom-grub/boot/grub
* (!) Bei der GRUB-Installation wird immer die ganze Platte angegeben (z.B. /dev/sda), keine einzelne Partition
* /boot/grub/i386-pc/lvm.mod : Beispiel für ein Modul innerhalb des GRUB-2-Verzeichnisses
* Änderung der Grub-Konfigurationsdatei (grub.cfg) selbst: keine weitere Aktion nötig, gilt für Legacy und GRUB 2 gleichermaßen
* Unterschied GRUB Legacy vs. GRUB 2: Partitionsnummerierung beginnt bei GRUB Legacy bei 0, bei GRUB 2 bei 1
* In der EFI System Partition liegt der "first stage boot loader"

* GRUB-Beispielablauf (root/kernel/initrd):
* root (hd0,1) : sda2 -> hd0: erste Festplatte (a in sda), 1: zweite Partition (2 in sda2), da GRUB ab Null zählt
* ls (hd0,gpt2)
* set root=(hd0,sda2)
* linux /boot/vmlinuz-7.0.0-28-generic root=/dev/sda2 : lädt den Kernel ; Parameter, wo das echte Betriebssystem liegt ; mögliche Parameter: ro = read only beim Prüfen der Festplatte, quiet = versteckt Textmeldungen ; Remote Desktop beginnt ist oft sda2
* initrd /boot/initrd.img : lädt ein temporäres Dateisystem (initramfs) in den Arbeitsspeicher, damit der Kernel die nötigen Treiber findet ; initialisiert die RAMdisk
* linux (der Kernel) steuert Hardware und verwaltet Prozesse
* initrd (die RAM Disk) lädt Treiber für Festplatte und Dateisysteme
* vmlinuz und initrd gehören zusammen: vmlinuz ist die Core-Engine, initrd ist das Paket mit den Boot-Treibern
* Eingabe "normal" beendet den GRUB-Modus
* Boot-Konfigurationsdatei liegt immer in /boot/grub

* Kernelparameter übergeben (Boot beeinflussen):
* e : im Bootmenü drücken, um Änderungen vorzunehmen
* Strg-X : setzt Boot-Vorgang fort
* Beispiel: init=/bin/bash (normalerweise wird /sbin/init gestartet)
* Beispiel: Linux /boot/vmlinuz-generic root=UUID=78... ro init=/bin/bash
* lädt bis in die Bash ; es wird eine Low-Level-Bash schreibgeschützt geladen
* mount -o remount,rw / : um das Verzeichnis schreibbar zu laden
* exec /sbin/init : Default-Datei, wie beim Hochfahren gestartet wird ; ersetzt die Shell durch /sbin/init, System fährt wieder hoch (wird gemacht, um Änderungen/Korrekturen am System vorzunehmen)
* in /boot/grub/grub.cfg kann als Boot-Parameter auch 1 übergeben werden, um in den Rescue Modus zu gelangen
* single : Boot-Parameter, startet das System im Single-User-Modus (vergleichbar mit init=1 / rescue.target)
* Wechsel der Root-Partition über GRUB, z.B. root=/dev/sda2 : gibt an, von welcher Partition das System bootet

* vmlinuz-7.0.0-29-generic : Beispiel für einen Kernel-Dateinamen ; das "z" am Ende von "vmlinuz" steht dafür, dass der Kernel komprimiert (gzip) vorliegt

* /proc/sys/kernel/modprobe : Beispieldatei unterhalb von /proc/sys/kernel/, dort stehen verschiedene System-/Kernel-Infos und -Parameter

* cat /proc/cmdline : Enthält Infos, wie die aktuellen Kernel Parameter/der Kernel gebootet wurde (wichtig für LPIC-1)
* man bootparam : Infoseite, welche Parameter für den Boot wichtig sind
* ls -l /sbin/init : wird als erstes geladen, um das System zu starten ; kann überschrieben werden

* Recovery Kernel: beim Grub-Modus kann Recovery Boot verwendet werden -> hier kann root mit einer root-Shell gestartet werden
* rescue.target : wird beim "c" in der Boot-Reihenfolge erreicht

* Kernel-Bestandteile (grob) : RAM-Disk (initrd/initramfs), Kernel selbst, Symboltabelle, Kernel-Parameter
* (!) Hängt initramfs beim Systemstart bzw. gibt es dabei Fehler, lohnt sich ein Blick in /var/log nach entsprechenden Fehlermeldungen

* Initiale RAM-Disk:
* df : zeigt initrd
* Bootloader lädt Kernel in den Speicher (RAM)
* Aufgabe: sicherstellen, dass auf das Root-Verzeichnis zugegriffen werden kann und die Module vorhanden sind
* apropos ramfs : Manual-Seiten anhand des Strings anzeigen
* Befehle unterscheiden sich zwischen Debian und RedHat:
* Debian: mkinitramfs
* RedHat: dracut (neuer)

* quiet : Kernel-/Bootparameter, der die meisten Boot-Meldungen beim Start unterdrückt (Antwort auf die vorher offene Frage, siehe /proc/cmdline)

* Firmware sucht die 1. Stufe des Bootloaders im MBR, nicht in /boot/grub
* /boot : Änderungen greifen direkt beim nächsten Neustart
* /etc/default/grub : Änderungen hier müssen erst per Befehl (z.B. update-grub) nach /boot übernommen werden

101.3 Change runlevels/boot targets and shutdown or reboot system


* 3 Initialisierungsprozesse: SysVinit, Upstart, systemd
* Upstart : Systeminitialisierungsvariante (nur wissen, dass es sie gibt)

* SysVinit (V = 5):
* /sbin/init : startet Prozess ID 1
* Runlevel: Single User/Rescue Mode, Desktop oder Multiuser
* ps -p 1 : zeigt an, was gestartet wurde
* /etc/inittab : gibt es nur bei SysVinit (nicht mehr vorhanden, wenn systemd vorhanden)
* Beispiel (Devuan6): id:2:initdefault: (Default Runlevel hier 2, kein Kernelparameter)
* führt Skripte aus wie 10:0:wait:/etc/init.d/rc 0
* [STRG]+[ALT]+[ENTF] : bei SysVinit wird dieses Tastenkürzel über einen eigenen Eintrag in /etc/inittab gesteuert (klassisch: ca::ctrlaltdel:/sbin/shutdown -t3 -r now) ; bei systemd übernimmt stattdessen die Unit ctrl-alt-del.target diese Funktion
* /etc/init.d : hier stehen Systemdienste-Skripte ; moderne Systeme pflegen dies aus Kompatibilitätsgründen mit
* man telinit / man init : telinit ist alt, init die moderne Form ; sind Synonym, wechseln den Runlevel
* init 0, init 1, init 6 : Runlevel wechseln ; init 6 entspricht Neustart, genau wie reboot
* sudo telinit 6 : Boot/Neustart
* sudo ./ssh status (in /etc/init.d) : früherer Weg (SysVinit)

* (!) Runlevel 0 und 6 dürfen niemals als Default-Runlevel gesetzt werden : z.B. nicht als "initdefault" in /etc/inittab ; da 0 = Herunterfahren und 6 = Neustart, das System also sofort wieder herunterfahren bzw. neu starten würde

* Runlevel-Bedeutung:
* Runlevel 0 : Halt / System herunterfahren (poweroff.target)
* Runlevel 1 : Single User/Rescue Mode (rescue.target)
* Runlevel 2,3,4 : Multiuser ; bei SysVinit je nach Distribution leicht unterschiedlich (z.B. mit/ohne Netzwerk), bei systemd alle drei auf multi-user.target gemappt
* Runlevel 5 : grafische Oberfläche (graphical.target)
* Runlevel 6 : Neustart / Reboot (reboot.target)

* systemd :
* verwaltet "Units" (Dienste, die verwaltet werden)
* z.B. kann sshd eine .service- oder .socket-Unit sein
* man systemd.unit
* 5 wichtige Unit-Typen bei systemd, u.a. service.service
* Zielzustände nennt man "Targets"
* systemctl status cups : ruft Infos zum Dienst ab
* systemctl status : schauen, welche Dienste starten
* systemctl get-default : gibt z.B. graphical.target aus
* systemctl isolate multi-user.target : wechselt in eine andere Umgebung/Runlevel
* systemctl isolate graphical.target : Beispiel Wechsel des Runlevel zu grafisch
* sudo systemctl set-default rescue.target : Beispiel Default-Target setzen
* ls -l /sbin/init : zeigt z.B. /sbin/init -> ../lib/systemd/systemd

* runlevel : zeigt vorherigen und aktuellen Runlevel an
* Parameter: [Vorheriger Runlevel] [Aktueller Runlevel] ; "N" = None
* man runlevel : alle Runlevel anzeigen

* pstree -d | less : Prozessbaum anzeigen
* pstree | less : zeigt laufende Prozesse baumartig
* ps -A : alle laufenden Prozesse

* journalctl : gibt es nur bei systemd, liest das Systemprotokoll
* journalctl -e : springt direkt ans Ende
* journalctl -k : nur Kernel-Meldungen
* journalctl -ke : Kernel-Meldungen am Ende
* journalctl -b : Meldungen seit dem aktuellen Boot
* journalctl --list-boots : IDX der aufgelisteten Boots
* journalctl -b -6 : bestimmten Boot-Index ansehen
* journalctl --since=10:00 : Meldungen ab Uhrzeit
* journalctl --since=10:00 --until=10:30 : Meldungen in Zeitfenster (Shift+G springt ans Ende)

* man dmesg : zeigt Infos des Kernel Ring Buffers an
* sudo dmesg | less
* sudo dmesg -T | less : zeigt Zeiten an
* dmesg -H : "--human" ; Ausgabe im "human readable"-Format (Achtung: großes "-H", nicht zu verwechseln mit "-h"/"--help")

* shutdown -r +15 : fährt System in 15 Minuten neu hoch (Reboot) ; Minutenangabe möglich, Default ist 1 Minute
* shutdown -r now : entspricht shutdown -r +0, also sofortiger Neustart (keine Wartezeit)
* shutdown -c : bricht einen laufenden Shutdown ab (canceling the shutdown)
* shutdown -h : Halt
* shutdown -rf now : Achtung, alter Befehl ; die Option "-f" gibt es in aktuellen Versionen nicht mehr
* ps ef | grep shut : Beispiel, um laufenden Shutdown-Prozess zu finden

* halt : bewirkt ein sofortiges Shutdown des Systems
* which halt poweroff reboot : zeigt die Pfade der Befehle an
* ls -l $(which halt poweroff reboot) : zeigt, dass halt, poweroff und reboot alle auf systemctl verweisen (symbolische Links)
* systemctl poweroff : fährt ein systemd-System sauber (kontrolliert) herunter

* sudo sysctl -a | less : zeigt Kernel-Parameter an (kein LPIC-1-Thema)

* pidof bash : zeigt die PID von bash an
* kill -HUP <PID> : HUP = Hang Up Signal ; wird an die angegebene Prozess-ID übergeben

* who -b : prüfen, wann der letzte Systemstart war
* who -r : zeigt den aktuellen Runlevel an
* sudo grep "Linux Version" /var/log/syslog | cut -f 1 -d ' ' | tr T ' ' : alternativer Weg, um Infos zu ermitteln, wann das System gebootet wurde
* last reboot | head -n 4 : anderer Befehl, um Boot-Zeitpunkte anzuzeigen

* (!) Erste Prozess-ID von SysVinit ist 1 : /sbin/init wird vom Kernel als erster Prozess gestartet
* dmesg --clear : löscht den Ring-Buffer (wird auch bei einem Neustart geleert)
* (!) D-Bus-Maschinen-ID und SSH-Hostschlüssel müssen eindeutig sein : z.B. beim Klonen von VMs/Images darauf achten, dass diese neu generiert werden

* sync : altes Kommando, heute nicht mehr nötig ; schreibt Infos auf den System-Buffer
* wall : write a message to all users
* echo Wartung | wall : Nachricht an alle anderen User-Konsolen senden
* kann vom eigenen Nutzerprofil blockiert werden, aber in anderer Konsole sichtbar (Strg+Alt+F3) ; bis zu 5 Konsolen möglich
* acpid : ermöglicht, dass ein System über ACPI heruntergefahren werden kann (Knopf am Rechner Gehäuse)

* hostnamectl : Anzeigen und Ändern des Computernamens
* sudo hostnamectl set-hostname ubuntu : Rechnername in "ubuntu" ändern

* Übung/Fragerunde:
* Runlevel wechseln, um sicher zu arbeiten (Wartungsarbeiten): init 1 / telinit 1
* /proc/cmdline : enthält Infos, wie der Kernel gebootet wurde

---

102 – Linux Installation and Package Management



102.1 Design hard disk layout


* df -T : zeigt Dateisystemtyp mit an
* /boot/efi : vfat-Dateisystem, getrennt vom Root-Filesystem / (ext4)
* Fedora hat mehr als 2 Dateisysteme (df -T)
* df -Th : zeigt die eingehängten Dateisysteme an ; "T" = Type (Dateisystemtyp), "h" = human-readable
* df -Thi : zeigt zusätzlich die Inode-Auslastung je Dateisystem an ; "i" = Inodes
* df --output=source,target : zeigt nur die gewünschten Spalten an (hier: Quelle und Einhängepunkt)
* Superblock : wird beim Einhängen (mounten) eines Dateisystems (z.B. /boot/efi) in den RAM geladen

* sudo fdisk -l /dev/sda : Partitionstabelle lesen
/dev/sda1 : EFI System Partition bzw. Boot-Partition ()
* /dev/sda2 : Erweiterte Partition / Linux Root
* /dev/sda5 : Linux Swap / Solaris

* Partitionierung von SSD/Festplatten: nicht notwendig, aber üblich (Aufteilung in mehrere logische Platten)
* Inkonsistenzen eines Dateisystems sind logisch begrenzt, z.B. bei Problemen ist nur ein Teil betroffen
* btrfs : Dateisystem-im-Dateisystem anlegbar
* In Produktionsumgebungen jeweils eigene Dateisysteme, um DB, Fileserver etc. logisch zu trennen
* DB möchte große Blockgröße (viele Lese-/Schreibzugriffe)
* Webserver eher kleine Blockgröße (schnellere Zugriffe)

* Überlegungen zum Partitionslayout:
* genügend Plattenplatz
* wenn ein Dateisystem voll ist, sollen andere Platten nicht betroffen sein
* Sicherung überlegen
* häufig eigene Partition: /var (viele Protokolle, Druckeraufträge etc.), /home (sollte häufig gesichert werden)
* selten eigene Partition: /usr (Kommandos), /opt (IDE- und Anwendungssoftware, z.B. Visual Studio Code)
* /boot : sollte groß genug sein, um mehrere Kernel aufzunehmen
* häufig sichern: /home, /var
* gar nicht sichern: /proc, /dev, /tmp
* was in /tmp angelegt wird, ist nach Neustart weg

* swap : Auslagerungsdatei/-partition
* unter Windows sind es Dateien, unter Linux häufiger eigene Platten/Partitionen
* wird benötigt, um den virtuellen Speicher zu erweitern
* RAM + Swap Space = physikalischer Speicher
* wird verwendet, wenn Prozesse/Dateien "warten"
* Faustregel: Swap sollte 2x RAM groß sein
* man kann schnell Swap hinzufügen, um mehr Prozesse vorhalten zu können
* es ist möglich, mehrere Swap-Partitionen zu hinterlegen (mit Priority)
* Swap sollte nicht ständig genutzt werden, da Ein-/Auslagern viel Zeit kostet
* free -th : Speichergröße ermitteln
* swapon -s : prüfen, wie der Auslagerungsspeicher definiert ist und wo die Datei liegt (/swap.img)
* ls -lh /swap.img : Human Readable Größe anzeigen (z.B. 3,5GB)

* Scheduler : Teil des Kernels, zuständig dafür, Prozesse, die etwas tun wollen, den vorhandenen Ressourcen zuzuteilen
* es gibt verschiedene Scheduler, z.B. für Embedded Systeme
* fair-share Scheduler sind normal, für faire Ressourcenaufteilung

* resize2fs : (nicht LPIC-1 Stoff)

* MBR:
* Partitionsinfo am Ende des MBR (512 Bytes)
* primäre und erweiterte Partitionen
* Infos über logische Disks stehen nicht im MBR

* GPT:
* moderne Methode bei UEFI
* größer 2TB
* bietet Platz bis 128 Partitionen
* BIOS-basiertes Linux kann auf GPT-Platten lesend zugreifen, UEFI-basiertes Linux kann auf MBR-Platten lesend zugreifen ; zum Booten braucht es jeweils Sonderkonstruktionen (Hybrid-MBR / CSM)
* GPT reserviert am Anfang Platz, damit MBR zugreifen kann ("protective MBR")

* EFI System Partition (ESP) : wird bei der Installation automatisch angelegt
* fdisk kann auch MBR-partitionierte Platten lesen ; normalerweise nimmt man gdisk für GPT (protective MBR)

* X86-Architektur, BIOS-Firmware (alt):
* fdisk : Platten partitionieren, bis zu 4 primäre Partitionen anlegen
* erweiterte Partition: bis zu 60 (weitere) Partitionen anlegen, Platzhalter für andere logische Partitionen
* primär: Bereich auf der Platte, den man direkt für ein Dateisystem verwenden kann
* TODO: Unterschied logische Partition und primäre Partition genauer ermitteln
* bei GPT gibt es keine primären/logischen Partitionen

* sudo fdisk /dev/sda : ohne "-l" bedeutet schreibend
* mit "n" sieht man den Partitionsbereich

* Info: Partition mit fdisk = MBR-Partition ; Partition mit gdisk = GPT-Partition

* Logical Volume Manager (LVM) :
* fasst Platten zusammen, damit ein Dateisystem über mehrere Platten verteilt werden kann
* bietet keine Redundanz (im Gegensatz zu RAID)
* möglich: LVM auf einem RAID-Array anlegen
* unterstützt Snapshots
* sudo apt install lvm2 : eigentlich nicht vorinstalliert
* 3 Komponenten:
* pv : Physikalisches Volumen
* vg : Volumengruppe
* lv : Logisches Volumen (Partition auf der Platte)
* Physical Extent (PE) : kleinste Speichereinheit bei LVM, standardmäßig 4 MB groß ; Volumengruppen und logische Volumen werden intern in solchen PEs verwaltet
* für LPIC-1: nur wissen, dass es das gibt (Konzept kennen)
* praktischer Nutzen: logisches Volumen vergrößern/hinzufügen, kann größer sein als einzelne Platten, verschiedene Plattentypen im laufenden Betrieb einhängen/vergrößern
* praktisches Beispiel: ein gespiegeltes Logical Volume erstellen und verwenden

* mount / umount :
* sudo umount /boot/efi : Platte aushängen
* sudo mount /boot/efi : Platte einhängen

* UUID einer Partition anzeigen:
* cd /dev/disk
* ls -l by-uuid

102.2 Install a boot manager


* siehe GRUB-Details unter 101.2 (stage1, menu.lst, grub.cfg, grub-install, grub-mkconfig, update-grub)
* Bootloader GRUB Verzeichnis : /boot/grub
* Dateien werden mit grub-install erzeugt

102.3 Manage shared libraries


* Prozess in Linux besteht aus verschiedenen Segmenten
* Programme, die Shared Libs verwenden, sind dynamic Programs
* in Linux heißen Shared Libraries "Shared Objects", Endung .so

* ldd : List Dynamic Dependencies ; zeigt Abhängigkeiten eines Programms, wenn Shared Libraries verwendet werden
* ldd /usr/bin/od : Beispiel

* type -a ls : Suche hört nicht bei der ersten Fundstelle auf, sondern sucht überall (Alias, PATH etc.), nicht nur den einen Treffer

* ldconfig -p | head : zeigt an, welche Shared Libs es gibt (im Cache)
* /etc/ld.so.cache : hier stehen alle Shared Libs drin
* ls -l /etc/ld.so.cache : zeigt, wann sich der Library Cache geändert hat
* sudo ldconfig : erstellt/ersetzt /etc/ld.so.cache und erstellt den Cache neu

* /etc/ld.so.conf : Haupt-Konfigurationsdatei
* cat /etc/ld.so.conf

* /usr/local/lib : hier kann der Systemverwalter dynamisch Shared Libs hinzufügen

find /lib -type f -name ".so" : sucht in /lib alle regulären Dateien, die mit .so enden
find /usr/lib -type f -name ".so" | wc -l : zählt, wie viele solcher Dateien vorhanden sind

* LD_LIBRARY_PATH : User kann darüber testweise eine eigene Shared Library hinzufügen ; ist normalerweise nicht gesetzt
* unset LD_LIBRARY_PATH : löscht die Shell-Variable

* Shared Library für das ganze System freigeben:
cat /etc/ld.so.conf.d/.conf : zeigt u.a. /usr/local/lib
sudo cp .so /usr/local/lib
* ls -l /usr/local/lib
* sudo ldconfig
* ./a.out

* strings /usr/bin/grep | grep libpcre : zeigt Strings innerhalb einer binären Datei

102.4 Use Debian package management


* apt search mdadm : sucht nach dem Paket "mdadm"

* Debian Paketverwaltung:
* tar-balls : Datei, die aus einem Tar-Archiv besteht ; früher genutzt, um Dateien zu verteilen
* Endung von Debian-Paketen ist immer .deb

* apt : modernes Kommando zur Paketverwaltung ; vereint apt-get und apt-cache ; ist moderner und sollte der Standard sein
* apt download nano : würde nano als .deb-Datei herunterladen
* apt search iptraf : kann in den Quellen nach einem Paket suchen
* apt info iptraf-ng : zeigt vorab Infos zum Paket an, bevor es installiert wird
* apt erlaubt auch die Angabe von Quellen über http, https, ftp etc.
* (!) es gibt auch apt --force, aber damit sollte man nicht arbeiten

* apt-cache : sucht im Verzeichnis /var/cache/apt/archives
* apt-cache search iptraf : sucht nach dem Paket
* apt-cache show bash : zeigt Infos zum Paket "bash" an
* apt-cache stats : Infos zu Paketen und Abhängigkeiten
* apt-cache depends bash : prüft, welche Abhängigkeiten das Paket "bash" verwendet
* apt-cache rdepends bash : zeigt umgekehrt an, welche Pakete von "bash" abhängen (reverse depends)
* apt-cache dump : zeigt (sehr umfangreich) weitere Detail-Infos zu den im Cache bekannten Paketen an (Achtung: in der Mitschrift stand großgeschrieben "apt-cache Dump" ; Linux-Kommandos sind case-sensitive, korrekt ist klein geschrieben dump)

* apt-get : kann im Gegensatz zu dpkg Abhängigkeiten auflösen
* apt-get install -f : "-f"/"--fix-broken" ; löst Inkonsistenzen (kaputte Abhängigkeiten) in der Debian-Paketverwaltung auf
* apt-get update : aktualisiert nur die Liste der Pakete ; schaut im Internet nach und prüft, welche Pakete neuer sind als die installierten
* apt list --upgradable | less : zeigt, welche Pakete aktualisiert werden können
* sudo apt-get upgrade : installiert die aktualisierbaren Pakete
* sudo apt-get dist-upgrade : erweiterte Variante von upgrade ; kann dabei auch Pakete entfernen oder neue installieren, falls das aufgrund von Paketabhängigkeiten nötig ist
* sudo apt-get clean : räumt das Verzeichnis /var/cache/apt/archives auf
* cd /var/cache/apt ; ls -l archives/ | wc -l : zählt die zwischengespeicherten Paketdateien
* (!) man kann nur alle Pakete gemeinsam aktualisieren, keine einzelnen Pakete
* (!) Ubuntu-Eigenart: liefert Updates in Stufen aus (wenn Aktualisierungen wegen Phasenstufung zurückgestellt wurden)
* (!) wenn mit apt/apt-get installiert wird, entsteht ein eigenes Log unter /var/log/apt ; der Vorgang wird zusätzlich in das dpkg-Log eingetragen

* dpkg-reconfigure : erlaubt, ein Paket neu zu konfigurieren (wichtig für LPIC-1) ; funktioniert z.B. bei "postfix", um die Postfix-Konfiguration erneut aufzurufen ; hängt vom jeweiligen Paket ab
* sudo dpkg-reconfigure tzdata : Beispiel ; ruft denselben Konfigurationsassistenten erneut auf, der auch bei der Erstinstallation des Pakets (hier: Zeitzonen-Einstellung) angezeigt wurde

* dselect : Frontend zur Paketverwaltung ; muss man kennen, ist aber bei neuen Systemen nicht mehr vorhanden

* dpkg : Low-Level-Paketverwalter ; nicht in der Lage, ins Internet zu gehen ; kann im Gegensatz zu apt-get keine Abhängigkeiten auflösen
* type nano : prüft, ob das Paket bereits auf dem System vorhanden ist
* sudo dpkg -i {Paketname}.deb : installiert ein Paket
* dpkg -l | less : Listing aller installierten Pakete
* dpkg -l {Paketname} : zeigt Infos zu einem bestimmten Paket
* sudo dpkg -r {Name des installierten Pakets} : entfernt Binaries, die Konfigurationsdatei bleibt auf dem System
* sudo dpkg -P {Paketname} : Purge ; entfernt das Paket vollständig
* (!) beim Purge oder Remove können nur Dateien entfernt werden, die nicht im Zugriff sind
* (!) man kann das Verzeichnis eines laufenden Programms löschen, aber das Programm bleibt so lange im Arbeitsspeicher, bis es beendet wird
* dpkg --get-selections | less : zeigt die installierten Pakete übersichtlicher an
* (!) bei dpkg wird immer eine Paketdatei angegeben
* dpkg -I {Paketdatei} : Infos zu einem Paket ermitteln
* dpkg -L {Paketname} | less : zeigt Infos zum Paket an (welche Dateien enthalten sind)
* dpkg -L nano | head -n 5 : z.B. nur die ersten 5 Zeilen anzeigen ; hierbei reicht der Name des Programms, nicht zwingend der exakte Paketname
* dpkg -S /usr/bin/nano : herausfinden, in welchem Paket eine Datei enthalten ist
* type -a init : sucht nicht nur die erste, sondern alle Fundstellen eines Begriffs
* dpkg -S /usr/sbin/init : gibt "systemd-sysv" zurück ; dieses Paket enthält die Kompatibilitätselemente von SysV in systemd
* dpkg -s {Paketname} : Status eines Pakets anzeigen
* dpkg -S /usr/lib/x86_64-linux-gnu/libssl.so.3 : gibt Infos aus, zu welchem Paket die Shared Library gehört
* dpkg -s libssl3t64 : gibt Infos zum Paket aus
* dpkg -L bash | less : zeigt, welche Dateien zum Paket "bash" gehören und wohin sie installiert wurden (wie vom Entwickler angelegt) ; Konfigurationsdateien liegen i.d.R. unter /etc, Binaries unter /usr/bin

(Nicht LPIC-1 prüfungsrelevant, aber für spätere Entwicklung gemerkt) Automatisierung über Parameter beim Installieren mit dpkg: mit --force-conf lässt sich steuern, wie mit geänderten Konfigurationsdateien umgegangen wird, um Skripte ohne manuelle Rückfragen laufen zu lassen
* dpkg --force-confold -i paketname.deb : eigene Änderungen an Konfigurationsdateien werden zwingend beibehalten
* dpkg --force-confnew -i paketname.deb : die neue Version der Konfigurationsdatei vom Entwickler wird zwingend installiert

* /etc/dpkg/dpkg.cfg : Konfigurationsdatei von dpkg
* less /var/log/dpkg.log : Log der Installationen
* /var/lib/dpkg/info/ : enthält Infos wie Prüfsummen etc.
ls -l nano : zeigt z.B. nano.md5sums
* md5sum /usr/bin/nano : erstellt die Prüfsumme einer Datei
* grep 787... nano.md5sums : Beispiel, um die Prüfsumme zu vergleichen
* md5sum -c nano.md5sums : prüft, ob die Prüfsumme noch übereinstimmt
* (!) hiermit kann geprüft werden, ob die Prüfsumme noch dieselbe ist wie zur Auslieferung/Installation des Pakets

* /etc/apt/sources.list : Quellen im Internet, woher die Software kommt ; hier sucht apt im Internet danach

* nm -D /lib/x86_64-linux-gnu/libc.so.6 | grep ' T ' | less : Namensliste eines Shared Objects (nicht LPIC-1-Thema)

* Snap : Ubuntu liefert einige Pakete als Snap aus (eigenes, von apt/dpkg unabhängiges Paketformat)
* (!) Konzept : eine Snap-App bringt alle benötigten Abhängigkeiten (z.B. Shared Libraries) selbst mit, statt auf die Systembibliotheken angewiesen zu sein
* Vorteile:
* Isolation/Sandbox gegenüber dem restlichen System
* alle Abhängigkeiten sind im Snap-Paket enthalten
* distributionsunabhängig einsetzbar
* automatische Updates
* Rollback-Fähigkeit (auf eine vorherige Version zurückwechseln)
* einfacheres Paketieren für Entwickler

102.5 Use RPM and YUM package management


* RedHat Package Manager (RPM) : unterscheidet, anders als dpkg, nicht zwischen -r und -P (kein separates Purge/Remove)
* von Red Hat entwickelt, Paket-Endung ist .rpm
* rpm ist der eigentliche Low-Level-Standard ; yum, dnf und zypper sind Frontends (Wrapper), die darauf aufbauen
* (!) rpm kann Abhängigkeiten nicht selbstständig auflösen

* Frontends je nach Distribution:
* yum : mittlerweile veraltet, abgelöst durch dnf (seit Fedora 22) ; yum ist heute meist ein symbolischer Link auf dnf/dnf5
* dnf : heute der Standard-Frontend für RPM (z.B. Fedora)
* zypper : Frontend für RPM in der SUSE/openSUSE-Welt

* RPM-Befehle (Paketverwaltung):
* rpm -i {Paketdatei}.rpm : installiert ein Paket aus einer Paketdatei
* rpm -e {Paketname} : erase = löscht ein installiertes Paket ; da RPM Abhängigkeiten nicht selbst auflösen kann, meldet der Befehl einen Fehler, wenn noch andere Pakete davon abhängen
* rpm -U {Paketdatei}.rpm bzw. --upgrade : aktualisiert ein Paket
* rpm -qa : query all ; Liste aller installierten Pakete (entspricht rpm --query --all)
* rpm -qa | grep apac : z.B. Suche nach "apache" in den installierten Paketen (Suchbegriff muss nicht vollständig sein)
* rpm -q {Paketname} : query ; prüft, ob ein Paket installiert ist
* rpm -qi {Paketname} : query info ; Infos zu einem bereits installierten Paket
* rpm -qip {Paketdatei}.rpm : query info package ; Infos zu einer (noch nicht installierten) Paketdatei
* rpm -ql {Paketname} : query list ; zeigt, welche Dateien ein bereits installiertes Paket enthält
* rpm -qlp {Paketdatei}.rpm : query list package ; Dateiliste einer Paketdatei
* (!) rpm -qpl : bei den Optionen selbst ist die Reihenfolge egal (-qlp = -qpl) ; nur wenn ein Argument (z.B. Paketname) angegeben werden muss, ist dessen Position relevant
* rpm -qf {Datei} : query file ; findet heraus, zu welchem Paket eine bestimmte Datei gehört
* rpm -qf /usr/bin/bash : Beispiel, liefert z.B. bash-5.3.0-2.fc43.x86_64
* rpm -qR {Paketname} : query requires ; zeigt Abhängigkeiten eines Pakets an, z.B. libc.so
* rpm -V {Paketname} : --verify ; vergleicht das installierte Paket mit der Datenbank (z.B. rpm -V samba-client) ; zeigt dabei u.a. Zeitstempel, MD5-Prüfsumme und Dateigröße an

* Verzeichnisse:
* /usr/lib/rpm : enthält die Skripte
* /var/lib/rpm : RPM-Datenbank (liegt als SQLite-Datenbank vor, im Gegensatz zu dpkg) ; für LPIC-1 nicht prüfungsrelevant

* Paket in ein Archiv umwandeln (RPM zu cpio):
* rpm2cpio nano-2.3.1-10.rpm > nano.cpio : wandelt ein RPM-Paket in ein cpio-Archiv um
* cpio : Dateiarchiv, das mehrere Dateien in einer Datei zusammenfasst
* cpio -tv < nano.cpio : listet den Inhalt des Archivs auf (Standardinput wird per < aus der Datei umgeleitet)
* cpio -idv ./usr/share/nano/sh.nanorc < nano.cpio : extrahiert eine bestimmte Datei aus dem Archiv und legt sie wieder ab ("i" = extract, "d" = Verzeichnisse bei Bedarf anlegen, "v" = verbose)

* dnf (Fedora):
* dnf download nano : lädt das Paket (als .rpm-Datei) herunter, ohne es zu installieren
* dnf repoquery --requires bash : zeigt, welche Pakete/Libs das Paket "bash" benötigt
* dnf repoquery --whatrequires ... : zeigt umgekehrt, welche Pakete von einem bestimmten Paket abhängen
* /etc/dnf/dnf.conf : Konfigurationsdatei von dnf
* dnf check-upgrade : zeigt an, welche Updates verfügbar sind (ohne sie zu installieren)
* (!) Beim RedHat-Paketmanager gibt es keinen Unterschied zwischen dnf update und dnf upgrade

* yum (älteres Frontend, Fedora/RHEL-Welt):
* (!) yum ist ein Frontend zu RPM
* sudo yum install {Paket} : installiert ein Paket
* sudo yum remove {Paket} : entfernt ein Paket
* yum download nano : lädt das Paket herunter, ohne es zu installieren
* yum update : führt (anders als bei apt-get update, das nur die Paketliste aktualisiert) direkt das Update aller Pakete durch
* sudo yum upgrade nano : würde nur das Paket "nano" aktualisieren
* yum repolist : zeigt die konfigurierten Repositories an
* cd /etc/yum.repos.d : wichtig für die Prüfung ; enthält die Repository-Konfigurationsdateien
* fedora.repo : Beispiel für eine Konfigurationsdatei für Fedora
* yum info {Paket} : zeigt Infos zu einem Paket an
* yum check-update : listet die verfügbaren Paketaktualisierungen auf, ohne sie zu installieren
* yumdownloader kernel : lädt ein Paket (hier "kernel") herunter, ohne es zu installieren (vergleichbar mit yum download/dnf download)

* zypper (openSUSE-Welt, Frontend für RPM):
* openSUSE hat weder yum noch dnf, sondern verwendet zypper
* zypper se {Paketname} : sucht nach einem Paket
* zypper in {Paketname} : installiert ein Paket (entspricht zypper install)
* zypper rm {Paketname} : entfernt ein Paket
* zypper info : Infos zu einem Paket
* zypper repos : zeigt, welche Repositories (Quellen im Internet) konfiguriert sind
* zypper shell : startet eine interaktive zypper-Shell
* zypper install ":foo" : installiert alle Pakete, die die angegebene Zeichenkette enthalten (Beispiel aus der Mitschrift, genaue Syntax nicht abschließend geklärt)

* (!) Wichtige Befehle/Pfade für die Prüfung:
* rpm
* rpm2cpio
* /etc/yum.repos.d/
* yum
* zypper

102.6 Linux as a virtualization guest


* Läuft eine virtuelle Maschine langsam, sollte man zuerst die zugewiesene Rechenleistung (Compute Power) prüfen, also RAM und CPU

* Virtualisierung : Vorteile
* mehrere virtuelle Maschinen gleichzeitig auf einem physikalischen Rechner betreiben
* effizientere Nutzung der Hardware
* Umzug einer VM ist einfacher als der eines physischen Rechners
* z.B. ESX kann im laufenden Betrieb eine VM auf einen anderen Server umziehen (Live-Migration)

* Hypervisor : Tool/Software, mit dem virtuelle Maschinen erstellt und verwaltet werden
* Beispiele: VirtualBox, Hyper-V (Microsoft), KVM

* Vollvirtualisierung : der Gast weiß nicht, dass er in einer virtuellen Umgebung läuft
* Paravirtualisierung : der Gast weiß, dass er in einer virtuellen Umgebung läuft ; es gibt eine Interaktionsmöglichkeit zwischen Gast und Host
* Unterschied liegt vor allem in der Abschottung und dem Hardwarezugriff (Latenzen etc.)

* Klonen virtueller Maschinen : eine VM wird geklont, indem ihre (Disk-)Datei kopiert wird
* z.B. Referenzsystem, auf dem bereits Sicherheitsupdates etc. installiert sind
* Beispiel für ein Austauschformat: .ova-Datei

* Nach dem Klonen einer VM müssen angepasst werden:
* Hostname, IP-Adresse, MAC-Adresse
* (!) MAC-Adresse : wird beim Klonen einer VM in der Regel automatisch neu vergeben, um Adresskonflikte im selben Netzwerk zu vermeiden (zwei Geräte mit identischer MAC-Adresse würden sonst zu Netzwerkproblemen führen)
* SSH-Hostkey : identifiziert ein System eindeutig
* ssh-keygen -l -f ssh_host_ecdsa_key.pub : listet den Hostkey
* ssh ubuntu : das Zielsystem meldet sich mit seinem Hostkey
* ssh-keygen -l -f /etc/ssh/ssh_host_ed25519_key : wichtig, muss nach dem Klonen geprüft (und ggf. neu erzeugt) werden

* (!) Wichtig: die Maschinen-ID muss innerhalb einer Hypervisor-Umgebung eindeutig sein, sonst kommt der Hypervisor durcheinander
* cat /etc/machine-id : zeigt die Maschinen-ID an
* dbus-uuidgen --get : D-Bus-Daemon, über den sich Dienste untereinander unterhalten können
* man dbus-uuidgen

* cloud-init : hilft, Probleme zu beheben, die beim Klonen entstanden sind (z.B. Hostname, SSH-Schlüssel), um Systeme eindeutig zu machen ; vereinfacht die Vervielfältigung von virtuellen Maschinen

* Linux als Virtualisierungs-Gast:
* Container / Anwendungscontainer virtualisieren nur Teile eines Betriebssystems
* (!) Unterschied Container vs. VM : ein Application Container nutzt den Kernel des Hosts, während eine virtuelle Maschine ihren eigenen Kernel mitbringt
* chroot : frühe Form der Container-Virtualisierung
* docker : nur wissen, dass es existiert ; nutzt u.a. einen Fair-Share-Scheduler

* Cloud:
* IaaS : Infrastructure as a Service
* Beispiele für Cloud-(Speicher-)Anbieter aus der Notiz: DropBox, OneDrive (Hinweis: das sind in erster Linie Cloud-Speicherdienste, keine klassischen IaaS-Anbieter wie z.B. AWS, Azure oder GCP)
* cloud-init : vereinfacht das Vervielfältigen von virtuellen Maschinen

* Hyper-V : Typ-1-Hypervisor ; läuft direkt auf der Hardware (Bare-Metal-Hypervisor)

---

103 – GNU and Unix Commands



103.1 Work on the command line


* Kommando Option Argument : allgemeiner Aufbau eines Befehls ; die meisten Befehle haben nur 1 Parameter
* Shell : Login startet den Kommando-Interpreter (Bash)
* Es gibt interne (Shell-Buildin-)Befehle wie z.B. cd, echo, pwd sowie externe Befehle (z.B. ls), die über die Suchpfad-Variable $PATH gefunden werden
* Jeder Prozess hat ein aktuelles Arbeitsverzeichnis ; Shell-Variable $PWD (zusätzlich $OLDPWD)
* ${PWD} : eigentlich reicht $PWD ; die geschweifte Klammer braucht man, um direkt weitere Zeichen anzuhängen, z.B. führt echo ${PWD}dir zum Pfad /home/pfad/dir
* (!) Current Directory ist nicht im Suchpfad : externe Befehle im aktuellen Verzeichnis müssen z.B. mit ./Programm aufgerufen werden

* man : zeigt Hilfe zu einem Befehl an
* sudo mandb : aktualisiert die "man" Hilfe
* man passwd : sucht "passwd" über alle Kapitel
* man 5 passwd : sucht "passwd" speziell im Kapitel 5
* man lsusb : "/-k" = Slash eingeben, dann wonach gesucht wird ("-k")

* apropos : Info, in welchem Kapitel des Handbuchs der Befehl vorkommt
* apropos pass : Teilbegriff, zeigt alle Kapitel mit dem Begriff an
* apropos system | grep ctl : hilft, Online-Handbuchseiten anhand eines Suchbegriffs zu finden
* (!) Unterschied apropos und help : bei apropos muss man das vollständige Kommando nicht kennen (Volltext-/Teilbegriffssuche)

* whatis crontab : zeigt Kurzinfo aus den man-Seiten an (nur Manual Seiten ohne Pfad)
* manpath : zeigt, wie das System nach Online-Manuals sucht ; Variable $MANPATH
* whereis bash : ähnlich wie which, findet zusätzlich auch den Pfad der zugehörigen Manual-Seiten
* whereis : sucht standardmäßig u.a. in /usr/bin und den Man-Pages (Manual-Seiten)
* whereis -b bash : "-b" = beschränkt die Suche auf die Binärdatei ; liefert dadurch dasselbe Ergebnis wie which bash

* hash : zeigt die von der Shell gehashten (gemerkten) Kommando-Aufrufpfade an (siehe auch "Shell merkt sich Befehle" unter 105.1)

* dirname : gibt nur den Verzeichnispfad einer Pfadangabe aus
* dirname /usr/bin/cat : Ausgabe /usr/bin
* basename : gibt nur den Dateinamen einer Pfadangabe aus
* basename /usr/bin/cat : Ausgabe cat

* stat . : zeigt den Status (Meta-Infos) einer Datei bzw. des aktuellen Verzeichnisses an (siehe auch stat unter 104.2)
* help cd : Online-Hilfe zu einem Shell-Buildin-Befehl (z.B. cd)
* man bash-builtins : Infos zu den Buildin-Befehlen der Bash
* info bash : ausführliche Info-Dokumentation zur Bash
* Parameter/Hilfe je nach Programm: cmd -h bzw. cmd --help
* cd /usr/share/doc : zusätzliche Dokumentation zu installierten Paketen

* type : zeigt bei Befehlen an, wie die Shell einen Befehl ausführt ; sucht zuerst nach Shell BuildIn Befehlen und dann den Suchpfad
* type ls : Beispiel, ist Alias von "ls --color=auto"
* type pwd : zeigt, dass pwd ein Shell-Buildin-Befehl ist
* type echo : Beispiel-Ausgabe: "echo ist eine Shell Funktion", "echo ist /usr/bin/echo", "echo ist /bin/echo"
* /bin/echo "Hello" : ist ein externes Programm (kein Buildin), dem ein Übergabeparameter übergeben wird, den es auf dem Display ausgibt
* (!) Nur "type" kennt Shell-Buildins : "whereis" und "which" kennen keine Shell-Buildin-Befehle, sondern durchsuchen nur den Suchpfad

* which : liefert den vollständigen Pfad zur ausführbaren Datei eines Befehls ; durchsucht nur den Suchpfad, nicht die BuildIn Befehle
* which cp : Beispiel, liefert z.B. /usr/bin/cp
* which uname which : durchsucht den Suchpfad ($PATH) nach mehreren ausführbaren Dateien gleichzeitig
* (!) which bash : zeigt nur den ersten im Suchpfad gefundenen Treffer an
* which -a bash : "-a" = zeigt ALLE Treffer an, durchsucht dabei den gesamten Suchpfad

* Beispiel, warum man den Punkt (aktuelles Verzeichnis) nicht in $PATH aufnehmen sollte:
* PATH=.:$PATH : fügt "." (aktuelles Verzeichnis) an den Anfang des Suchpfads an ; (!) nicht empfehlenswert, da dadurch Dateien im aktuellen Verzeichnis vor den eigentlichen Systembefehlen gefunden/ausgeführt werden können
* which -a ls liefert danach z.B.:
		./ls
		/usr/bin/ls
		/bin/ls
* (!) Problematisch : liegt im aktuellen Verzeichnis zufällig eine Datei namens "ls" (z.B. bösartig oder versehentlich), würde diese anstelle des echten ls-Kommandos ausgeführt werden

* uptime -s : zeigt an, seit wann das System läuft (Startzeitpunkt)

* PATH : Umgebungsvariable
* echo $PATH : zeigt an, wo die Shell nach ausführbaren Dateien sucht

* Shell Variablen:
* VAR=sometext / echo $VAR
* VAR=${VAR}MeinText : hängt "MeinText" an den bestehenden Wert von VAR an
* set : alle Variablen und Funktionen in der Shell anzeigen
* set | head : erste 10 Zeilen von set ausgeben
* set | less : alle Shell Variablen von set ausgeben
* (!) Unterschied set und env : set zeigt alle Variablen und Funktionen der Shell an ; env zeigt nur die exportierten Umgebungsvariablen, die auch an eine Subshell weitergegeben werden
* echo $$ : Process ID der laufenden Shell
* echo $0 : zeigt z.B. "bash"
* env | less : alle Umgebungsvariablen in der Shell ausgeben

* Command Substitution:
* ls /lib/modules/uname -r : Backticks, Output-Kommando wird ersetzt
* ls /lib/modules/$(uname -r) : moderne Variante, gleiche Wirkung
* systemctl get-default bzw. $(systemctl get-default) : weiteres Beispiel, beide geben "graphical.target" aus (alte vs. moderne Schreibweise)

* bash : startet eine (neue) Bash-Instanz, mit der man ein Kommando ausführen kann
* echo systemctl get-default | bash : übergibt den Befehl per Pipe an die Bash und führt ihn dort aus

* sudo su - : Superuser, "su" = Switch User Root, "-" = Login-Bereich vollständig durchlaufen
* su : Switch User

* history > history_08.04.txt : History-Befehle in Datei schreiben
* alias ls : zeigt Alias für ls
* unalias ls : entfernt Alias

* Skript ausführen:
* vi sh.sh : Skript anlegen
* bash s.sh : ruft die Konsole in einem Sub-Prozess auf
* source s.sh : führt Skript innerhalb der aktuellen Shell aus (nicht im externen Prozess)
* ./s.sh : sagt, dass eine ausführbare (binäre) Datei im Current Dir ausgeführt werden soll ; führt sich immer in einer Subshell aus (Kindprozess) ; dupliziert sich selbst und macht ein exec auf die auszuführende Datei
* /home/.../a.out : eine binäre Datei kann auch über den vollständigen Pfad ausgeführt werden
* (!) Subshell : wird verwendet, um die eigene (Haupt-)Shell nicht zu beeinflussen ; man bleibt auch in der Subshell derselbe User
* (!) Externe Befehle : werden immer in einem Kindprozess (Subshell) ausgeführt
* ./s.sh : wenn das Skript z.B. exit 4 enthält, wird das Shell-Fenster mit diesem Exit-Code beendet
* echo $? : zeigt den Return Code des vorherigen Befehls an

* . : bedeutet zum einen "Current Directory", zum anderen ist es ein Synonym für source (führt einen Befehl/Skript in der aktuellen Shell aus)
* . s.sh : entspricht source s.sh, wird in der aktuellen Shell ausgeführt
(Beispiel: . ./s.sh)
* source /etc/default/grub gefolgt von echo $GRUB_TIMEOUT : Beispiel, wie eine Variable aus einer gesourcten Datei danach zur Verfügung steht

* /.bashrc : Voreinstellungen für die Shell
* export : Umgebungsvariable ; Shell-Build-in-Funktion ; macht eine Shell-Variable (z.B. $VAR) zu einer Umgebungsvariable, sodass sie auch in der Subshell zur Verfügung steht
* env | grep VAR : zeigt Umgebungsvariablen wie VAR=sometext an
* echo $SHLVL : zeigt die Shell-Ebene (Shell Level) an, z.B. "3" (kein LPIC-1-Stoff)

* !! : ruft letztes Kommando erneut auf (z.B. mit sudo: sudo !!)
* / : kann eine Zeile verlängern so dass man in der nächsten Zeile schreiben kann, z.B. ls \
* id ; pwd : zwei Befehle hintereinander ausführen (id zuerst, dann pwd)

* Befehl Aufbau : z.B. "ls -l /" = Befehl Leerzeichen Option Leerzeichen Argument

* bash -v : startet ein Skript im Verbose-Modus ; zeigt mehr Infos an (die Zeilen des Skripts, bevor sie ausgeführt werden)
* bash -v s.sh World : Beispiel ; zeigt z.B. die Skriptzeile Hello $1 und danach die Ausgabe Hello World

* getconf ARG_MAX : fragt den Command Line Buffer (maximale Länge der Argumentliste) ab ; nur Info, nicht prüfungsrelevant

103.2 Process text streams using filters


* Unix-Philosophie : Schreibe Programme, die eine Sache gut machen. Schreibe Programme die zusammen arbeiten.
* textutils-Paket : enthält viele der klassischen Text-Werkzeuge (Textausgabe)

* grep : verarbeitet einen übergebenen Datenstrom und filtert Zeilen heraus
* ls -l / | grep li : findet alles mit "li", z.B. auch "lib"
* ls -l / | grep home : Beispiel
* grep Befehl Datei : zeigt nur Zeilen mit "Befehl" an
* cat Datei | grep -v bash : "-v" = Reverse ; zeigt alle Zeilen an, die "bash" NICHT enthalten
* cat /etc/ssh/ssh_config | grep -v '#' : zeigt alles an, was keine Kommentarzeilen sind
* egrep : Extended Grep (eigenes Programm) ; z.B. cat Datei | egrep "Befehl|String" ; cat datei | egrep "Befehl\||String" sucht nach "Befehl" ODER "String"

* cat : concatenate ; fügt Dateien zusammen bzw. gibt sie am Bildschirm aus (achtet nicht auf Kodierung wie ASCII und UTF-8)
* cat Datei : Inhalt von "Datei" anzeigen
* cat datei1 datei2 : gibt 2 Dateien nacheinander aus
* cat datei1 datei2 > neueDatei : leitet 2 Dateien in eine neue Datei um
* ls | cat : liest Standard Input
* cat -A a : --show-all ; macht Sonderzeichen in Datei "a" sichtbar
* cat /etc/os-release : Infos und Version zum aktuellen Linux anzeigen

* Datei-Kompressionsprogramme:
* gzip dateix : komprimiert die Datei "dateix" als "dateix.gz" und löscht das Original
* bzip2 dateix : komprimiert die Datei und ersetzt diese durch "dateix.bz2"
* xz dateix : am modernsten ; erstellt "dateix.xz" und löscht das Original
* (!) xz : komprimiert/dekomprimiert primär das .xz-Format ; das ältere .lzma-Format wird eher über die Kompatibilitäts-Tools lzma/unlzma (bzw. xz --format=lzma) gelesen
* gzip -d datei.gz : entpackt und löscht das Archiv anschließend
* zcat datei.gz | less : liest eine gzip-komprimierte Datei, ohne sie zu löschen
* bzcat datei.bz2 | less : liest eine bzip2-komprimierte Datei, ohne sie zu löschen
* gzcat datei.gz | less : liest eine gzip-komprimierte Datei, ohne sie zu löschen (Alternative zu zcat)
* (!) gzip/bzip2/xz haben auch Parameter zum Entpacken, aber Programme wie gunzip, bunzip2, unxz sind die einfachen/historisch bedingten Pendants ; gzip -d Datei.gz macht dasselbe wie gunzip Datei.gz
* zcat, bzcat, xzcat : zeigen den Inhalt einer komprimierten Datei an, ohne sie zu entpacken (die "cat"-Varianten der jeweiligen Kompressionstools)

* head : zeigt Default die ersten 10 Zeilen an
* set | head : Beispiel

* tail : zeigt Default die letzten 10 Zeilen an
* tail -f bzw. tail --follow : fortlaufend ; macht neue Änderungen sichtbar
* sudo tail -f /var/log/syslog : wartet auf neue Zeilen im Syslog und liest diese aus

* Pager:
* less Datei : z.B. less /etc/profile ; less muss die Datei nicht komplett einlesen und hat zusätzlich eine Suchfunktion
* more Datei : älterer Befehl ; muss die ganze Datei einlesen
* cat Datei | less : liest so den Standard Input
* g : springt an den Anfang der Datei
* G : springt an das Ende der Datei

* wc : word count ; kann Wörter, Zeilen und Bytes zählen
* wc -l Datei : zählt Zeilen
* wc -w Datei : zählt Wörter
* wc -c Datei : zeigt Dateigröße
* wc Datei : Ausgabe "Zeilen Wörter Dateigröße Dateiname"
* cat a | wc : gibt keinen Dateinamen mit aus, da nur eine Folge von Bytes übergeben wird
wc : wc über alle gefundenen Dateien
find /etc/rc* | wc -l : zeigt Anzahl der Suchergebnisse an (Beispiel: 140)

* nl : number lines ; gibt die Zeilennummern aus
* nl Datei | less : liest die Datei und gibt die Zeilennummern aus
* cat Datei | nl | less : gleiche Wirkung über eine Pipe
* (!) nl zählt standardmäßig keine leeren Zeilen (Default: no empty lines)
* nl -ba Datei : nummeriert auch leere Zeilen
* cat /etc/profile | nl -ba | less : Beispiel ; nl kann sowohl Dateien einlesen als auch über die Pipe den Standard Input verarbeiten

* hexdump : kann Ausgabe dezimal, oktal oder hexadezimal steuern
* sudo hexdump -v /dev/sda | head -n 32 | tail -n 5 : Beispiel
(!) : wenn sich Zeilen wie "0000 0000" etc. wiederholen, wird das mit "*" abgekürzt ; kann mit -v abgeschaltet werden (zeigt dann alle Zeilen einzeln)
* hexdump -v -C : zeigt zusätzlich die ASCII-Zeichen an

* od : octal dump
* od -x : hexadezimal
* od -b : oktal

* sort : sortiert Textdatei oder Standard Input
* sort Datei : sortiert Inhalt der Datei alphabetisch
* mount | sort : Infos zu eingehängten Dateisystemen sortiert ausgeben
* sort -n Datei : sortiert eine Zahlendatei numerisch
* sort -n -o output Datei : schreibt das Ergebnis in die Datei "output"
* sort -r : sortiert umgekehrt (reverse)
* sort -un Datei : "u" = unique, numerisch sortiert und entfernt Duplikate
* (!) Zahlen und Buchstaben gemischt in einer Datei : Zahlen werden zuerst angezeigt

* uniq : blendet Duplikate aus
* sort -n Datei | uniq : sortiert und entfernt Duplikate
* (!) uniq erkennt Duplikate nur, wenn diese direkt nebeneinander liegen (daher vorher meist sortieren)

* split : teilt eine Datei in mehrere Dateien auf
* split Datei : Default zerteilt die Datei in Stücke à 1000 Zeilen
wc -l : Zeilen der entstandenen Teildateien prüfen
cat xa > b : fügt alle Teildateien wieder zu "b" zusammen
* diff b Datei : prüft, ob "b" wieder identisch mit der Ursprungsdatei ist
rm x : löscht alle Teildateien ("x...")
* split -l 5000 Datei : ändert die Zeilenanzahl pro Teildatei von Default 1000 auf 5000
* (!) split funktioniert auch bei binären Dateien
* split -b 5000 myinit : teilt die Datei in Stücke à 5000 Byte
* cmp : Binärvergleich, Byte für Byte
* diff : Vergleich, nur bei Textdateien

* cut : schneidet Felder heraus ; Default-Trennzeichen ist [TAB]
* cut -f 2 Datei : listet Spalte 2 aus einer z.B. mit Tabulator getrennten Datei
* cut -f 2,4 Datei : Felder 2 und 4
* cut -f 2-4 Datei : Felder 2 bis 4
* cut -f 2 -d ' ' Datei : "-d ' '" übergibt das Leerzeichen als Delimiter
* cut -f 1,3,4 -d ' ' Datei : Liesst mehrere Felder die mit dem angegebenen Delimiter getrennt sind
* (!) cut kann die Felder nicht umsortieren
* cut -f 2,4 -d ' ' --output-delimiter=';' Datei : ändert den Output-Delimiter
* cut : kann auch Bytes ausschneiden mit -b
* cut -b 1 /sbin/init | od -cb | less : Beispiel, um das erste Byte einer Datei herauszuholen und anzuschauen
* cut -b 1 /sbin/init | hexdump -C | less : gleiche Idee mit hexdump

* paste : zeigt Dateien zeilenweise nebeneinander an
* paste dateia dateib : Beispiel
* paste -d ',' dateia dateib : ändert das Trennzeichen (Delimiter), z.B. für CSV-Erstellung
* (!) bei paste können die Dateien unterschiedlich viele Zeilen haben
* paste a b c | cat -A : zeigt alle Tabulatoren an ; $ zeigt Zeilenende, ^I zeigt Tabulator

* sed : Stream Editor ; kein interaktiver Editor wie vi/nano, sondern liest jede eingelesene Zeile ein und leitet sie (ggf. verändert) weiter
* cat Datei | sed 's/Haus/Bungalow/' : gibt den Inhalt der Datei aus und ersetzt "Haus" durch "Bungalow"
* sed 's/Haus/Bungalow/' Datei : ersetzt und gibt aus
* sed -i 's/Haus/Bungalow/' Datei : "-i" = Inplace, ändert die Datei direkt
* cat Datei | sed 's/UNIX/Linux/' : ersetzt (ohne "g") nur das erste Vorkommen pro Zeile
* sed 's/UNIX/Linux/g' Datei : "g" = global ; ersetzt alle Vorkommen des Suchstrings in der Zeile
* sed 's,UNIX/,LINUX/,' Datei : der Trenner nach "s" kann frei gewählt werden (hier ",") ; sinnvoll, wenn im Such-/Ersetzungsstring selbst ein "/" vorkommt

* Wichtige sed-Optionen/-Befehle:
* s : Substitute (ersetzen)
* d : Zeilen löschen ; z.B. sed '/^$/d' Datei löscht alle leeren Zeilen (dort, wo direkt nach Zeilenanfang schon das Zeilenende folgt)
* y : ersetzt Zeichen 1:1 (wie tr), z.B. sed 'y/,/;/' ersetzt Kommas durch Semikolons ; dabei müssen Such- und Ersetzungsmenge gleich lang sein
* a : fügt Text ein
* q : Quit ; bricht die Verarbeitung nach einer bestimmten Zeile ab, z.B. sed '3q' Datei zeigt nur die ersten 3 Zeilen
* (!) Wird kein Zeilenbereich angegeben, gilt die Anweisung für alle Zeilen

* Zeilenbereiche/-adressierung:
* sed '6s/Haus/Baum/' Datei : Ersetzung nur in Zeile 6
* sed '1,4s/Haus/Baum/' Datei : Ersetzung nur in den Zeilen 1 bis 4
* cat Datei | sed '5,$d' : zeigt nur von Zeile 5 bis zur letzten Zeile an (löscht alles davor) ; $ = letzte Zeile
* sed -n '3,5p' Datei : "-n" unterdrückt die normale Ausgabe, "p" = Print ; zeigt gezielt nur die Zeilen 3 bis 5 an
* sed '/Haus/d' Datei : löscht alle Zeilen, in denen "Haus" vorkommt
* sed '/Haus/s/abc/Baum/' Datei : Ersetzung von "abc" durch "Baum", aber nur in den Zeilen, in denen "Haus" vorkommt
* sed '/Ha.s/s/abc/Baum/' Datei : wie oben, das Suchmuster für die Zeilenauswahl ist dabei selbst ein regulärer Ausdruck (z.B. "Ha.s" mit "." als Platzhalter)
* sed '/Ha[un]s/s/abc/Baum/' Datei : Zeilenauswahl über Zeichenklasse als regulärer Ausdruck

* Mehrere Ausdrücke/Skriptdateien:
* sed -e 's/Haus/Baum/' -e 's/abc/xxx/' Datei : "-e" bei mehreren Ausdrücken in einem Aufruf
* sed -e '/^$/d' -e '/^#/d' Datei : löscht in einem Aufruf sowohl Leerzeilen als auch Kommentarzeilen
* sed -f scriptdatei Datei : liest die sed-Anweisungen aus einer Datei und wendet sie an
* sed -i.bak -f script.sed Datei : "-i.bak" legt vor dem In-Place-Ändern eine Sicherungskopie mit der Endung ".bak" an
* (!) sed -i (bzw. -i.bak) verändert die Originaldatei ; vorsichtig anwenden
* (!) Früher wurde teils "sed -g" für global verwendet ; das scheint bei vielen aktuellen Distributionen nicht mehr zu funktionieren (heute stattdessen das "g"-Flag direkt im Substitutionsbefehl, z.B. s/.../.../g)

* Praxisbeispiele:
* cat ~/.bashrc | grep '^ \+#' : filtert nur eingerückte Kommentarzeilen
cat ~/.bashrc | grep '^ #' : filtert alle Kommentarzeilen, auch nicht eingerückte
* cat ~/.bashrc | sed -n '/^ \+#/p' : "-n" unterdrückt die Standardausgabe, "p" = Print ; gibt nur die Zeilen aus, auf die der reguläre Ausdruck zutrifft (hier: eingerückte Kommentare)

* tr : Translate ; kann Zeichen ersetzen
* (!) tr kann nur Standard Input lesen und schreibt auf Standard Output, aber keine Dateien direkt auslesen
* echo abc | tr a A : Ausgabe "Abc"
* echo abc | tr a-z A-Z : Ausgabe "ABC"
* echo $PATH | tr : ' ' : ersetzt ":" durch " " im PATH
* ls $(echo $PATH | tr : ' ') : Output an ls übergeben
find $(echo $PATH | tr ':' ' ') -name "ctl" : Beispiel ; durchsucht alle Verzeichnisse aus $PATH nach Dateien, die auf "ctl" enden
* ls /pfad1 /pfad2 : ls können mehrere Pfade übergeben werden
* echo $PATH | tr : '\n' : zeigt alle Pfade untereinander an
* (!) Character-Klassen : z.B. [:lower:]
* cat Datei | tr '\t' ' ' | cat -A : mehrere Befehle kombiniert
* cat Datei | tr -d '\t' : löscht Zeichen aus dem Text
* echo "Hello World" | tr -d eoaiu : "-d" = Delete ; löscht die angegebenen Zeichen (hier alle Vokale) aus der Ausgabe
* echo 'a b' | tr -s ' ' : "-s"/"--squeeze-repeats" ; ersetzt mehrere Leerzeichen hintereinander durch eines
* cat a | tr -s ' ' | cut -f 3 -d ' ' : kombiniertes Beispiel

* seq : erzeugt/gibt eine Zahlenfolge aus
* seq 8 : gibt die Zahlen 1 bis 8 (jeweils untereinander) aus
* seq 6 : gibt die Zahlen 1 bis 6 untereinander aus
* seq -s ' ' 6 : "-s" = Separator ; gibt die Zahlen 1 bis 6 mit Leerzeichen getrennt in einer Zeile aus
* seq 1 5 20 : Start=1, Schrittweite=5, Ende=20 ; Ausgabe: 1, 6, 11, 16 (jeweils +5, nicht mehr über 20 hinaus)

* Prüfsummen (3 Befehle): md5sum, sha256sum, sha512sum
* sha512sum debian_download.iso > SHA512SUBS : Prüfsumme erzeugen und in Datei schreiben
* sha512sum -c Datei : prüft eine Datei anhand ihrer Prüfsumme
md5sum $(which gzip bzip2 xz) | cut -d ' ' -f 1 | xargs -I '{}' grep '{}' /var/lib/dpkg/info/.md5sums : Beispiel ; bildet Prüfsummen der Programme, schneidet nur den Hash heraus und sucht diesen in den dpkg-Prüfsummendateien (siehe auch xargs -I unter 103.4)

103.3 Perform basic file management


* (!) Terminal : ist /dev/tty

* 3 Dateitypen:
* Reguläre Dateien : Dateien und Programme
* Directories (Verzeichnisse) : enthalten Dateien
* Special Files : Ein- und Ausgaben, z.B. tty
* Der Typ ist am ls -l-Kommando erkennbar, z.B. l = symbolic link, b = block special file

* ls : list = zeigt alle Dateien in einem Verzeichnis an
* ls -a : auch versteckte Dateien
* ls /boot : das Boot-Verzeichnis
* ls -la /boot/efi
* ls -l : long listing = detaillierte Metainfos wie Zugriffsrechte, Besitzer, Größe
* ls -ld : "d" = Directory ; zeigt nur für den Ordner selbst die Infos an
* ls -lh : "h" = human-readable ; zeigt keine Bytes, sondern KB/MB/GB
* ls -i : zeigt die Inode-Nummer (Datenblöcke) an ; Infos zum Dateisystem stehen im Superblock
* ls -s : Size ; zeigt die Dateigröße an
* ls > Datei : Datei wird angelegt, Inhalt von "ls" wird in die Datei überschrieben (nur bei Berechtigung, z.B. ls > /swap.img funktioniert nicht)
* ls >> Datei : Inhalt von "ls" an die Datei anhängen
* ls -a : zeigt auch "." (aktuelles Verzeichnis / current dir) und ".." (übergeordnetes Verzeichnis / parent dir)
ls -ld rc* : nur Name der Verzeichnisse, "d" = Directory, aber nicht reingehen
ls -latr /boot : "t" = sortiert nach Änderungszeit, "r" = kehrt die Sortierreihenfolge um (reverse) ; Beispiel: ls -latr /boot/vm

* pwd : print working dir ; zeigt das aktuelle Verzeichnis an

* Punkt-Verzeichnisse:
* . : aktuelles Verzeichnis
* .. : übergeordnetes Verzeichnis
* Inode 2 : zeigt auf das Parent-Verzeichnis von "/" (root)
* (!) Inodes sind innerhalb eines Dateisystems eindeutig (unique)

* ~ : Heimatverzeichnis
* Absoluter Pfad : beginnt immer mit /
* (!) /tmp ist etwas anderes als ~/tmp : eigenes, separates tmp-Verzeichnis im Heimatverzeichnis

* touch : legt eine neue, leere Datei an bzw. aktualisiert bei einer bestehenden Datei den Zeitstempel auf das aktuelle Datum
* touch NeueDatei : Beispiel
* touch -a Datei : "-a" = Last Access Time ändern
* touch -t 0701120 Beispiel : "-t" = setzt den Zeitstempel auf ein angegebenes Datum/Uhrzeit (Format [[CC]YY]MMDDhhmm[.ss] ; die Ziffernfolge im Original-Beispiel war unvollständig/nicht eindeutig)
* touch {1..7}file : legt über Klammer-Erweiterung 7 Dateien an (file1 … file7)
* touch abc.{sh,txt} : legt über Klammer-Erweiterung 2 Dateien mit unterschiedlicher Endung an ("abc.sh" und "abc.txt")
* touch abc.{a..d} : legt über Klammer-Erweiterung 4 Dateien mit den Endungen a bis d an
* Zeitstempel einer Datei : Last Access, Last Modified, Last Change (3 Zeitstempel)
* stat Datei : zeigt Infos zur Datei an, z.B. Erstellungsdatum, letztes Änderungsdatum etc.
* date : zeigt aktuelles Datum und Uhrzeit an
* .Datei : versteckte Dateien beginnen mit einem Punkt (siehe auch ls -a)

* cd : Verzeichnis wechseln (Change Directory)
* cd ~ : Homeverzeichnis
* cd ~alfa : Homeverzeichnis vom Benutzer "alfa"
* cd ~root : liegt in /root
* cd - : in das vorherige Verzeichnis zurück springen ($OLDPWD)

* cp : Copy ; kopiert eine oder mehrere Dateien von Quelle nach Ziel
* (!) überschreibt Datei, wenn diese bereits existiert
* cp DateiA DateiB : kopiert DateiA nach DateiB
* cp -i DateiA DateiB : "-i" = Abfrage, ob die Datei überschrieben werden soll
* cp -p DateiA DateiB : "-p" = preserve Permission ; behält Metainfos/Rechte von DateiA und schreibt sie auf DateiB ; ein normaler (nicht-root) User kann dabei keinen "root"-Besitzer mitkopieren
* cp -R dir1 dir2 : "-R" (bzw. "-r", identisch) ; rekursiv alles von dir1 nach dir2 kopieren
* ls -laR dir1 : zeigt rekursiv den Verzeichnisinhalt an
* cp -v Datei D : "-v" = Verbose ; zeigt "Datei -> D" an
* sudo cp /var/log/syslog . : kopiert Syslog in das aktuelle Verzeichnis
* cp dateia dateib dateic ordnerziel : kopiert mehrere Dateien in ein Zielverzeichnis

* mv : Move ; verschiebt eine oder mehrere Dateien
* mv a myinit : Umbenennen ; Datei "a" wird zu "myinit"
* (!) Liegen Quelle und Ziel im selben Dateisystem, findet kein physisches Verschieben statt, sondern nur der Zeiger (Verzeichniseintrag) wird geändert
* (!) Existiert die Zieldatei bereits, wird sie überschrieben
* mv -i dateia dateib : fragt nach, ob überschrieben werden soll
* (!) Mit Schreibrecht auf das Verzeichnis kann man auch Dateien ersetzen/anlegen, die root gehören, ohne selbst Schreibrecht auf die konkrete Datei zu haben
* mv -f : Force ; ohne Nachfrage/Berechtigungsprüfung ; Vorsicht bei Verwendung
* mv -u : überschreibt nur, wenn die Quelle neuer als die Zieldatei ist oder die Zieldatei fehlt

* rm : Remove ; löscht Dateien ; benötigt das Schreibrecht auf das Verzeichnis, nicht auf die Datei selbst
rm : löscht den gesamten Inhalt des aktuellen Verzeichnisses ; vorher unbedingt prüfen (z.B. mit ls), was gelöscht wird
rm -r (bzw. "-R") : löscht rekursiv, auch Verzeichnisse (gesamtes Verzeichnis, z.B. mit rm -r )
* (!) rm kann ohne "-r" keine Verzeichnisse löschen, nur Dateien
* rm -i Datei : fragt nach, ob die Datei gelöscht werden soll
rm -i : jede Datei aus dem Verzeichnis löschen und bei jeder einzelnen nachfragen
* (!) Gehört eine Datei root, wird zwar nachgefragt, sie lässt sich aber trotzdem löschen (sofern Schreibrecht auf das Verzeichnis besteht)
* rm -v Datei : Verbose ; zeigt an, was gemacht wurde

* mkdir : legt ein Verzeichnis an
* mkdir v/daten/runde1 : schlägt fehl, wenn Zwischenverzeichnisse fehlen
* mkdir -p v/daten/runde1 : "-p" = Parents ; legt fehlende übergeordnete Verzeichnisse mit an
* mkdir -m 111 Verzeichnis : "-m" = Mode ; setzt beim Anlegen direkt die Berechtigungen
* Berechtigungen: 4 = read, 2 = write, 1 = execute ; eine Oktalziffer enthält 3 Bits, z.B. 755 = 111 101 101 = rwxr-xr-x

* rmdir : löscht ein Verzeichnis ; funktioniert nur, wenn es leer ist
* rmdir -p v/daten : "-p" = Parents ; löscht auch übergeordnete Verzeichnisse mit, sofern diese ebenfalls leer sind

* > datei : eine (leere) Umleitung ohne Kommando davor leert eine bestehende Datei (setzt sie auf 0 Bytes), ohne sie zu löschen ; legt die Datei an, falls sie noch nicht existiert

* find -Wildcards:
: null oder mehrere Zeichen, z.B. ls *
* ? : ersetzt genau ein Zeichen, z.B. ls ??
[a-z] : findet a-z am Anfang, dann beliebig viele weitere Zeichen
* [a-d]? : ein Zeichen von a bis d, gefolgt von genau einem weiteren Zeichen
* [a-d] : ersetzt eines dieser Zeichen
* [abcde] : eines dieser Zeichen
* [!a-z] : Negation ; keines dieser Zeichen
* [1-4] : funktioniert auch mit Zahlen
ls [a_] : beliebig viele "a" und Unterstrich
ls _ : findet auch Dateien, die mit Unterstrich beginnen
* (!) Groß-/Kleinschreibung wird unterschieden
* Details in man 7 glob nachschlagbar (glob(3) Library-Routine für Entwickler)

* file : ermittelt den tatsächlichen Dateityp
* file / : Directory
* file test.sh : Textdatei: ASCII text
* file mbr.bin : DOS/MBR boot sector
* file /dev/sda1 : block special (8/1) ; Major Nummer 8 = Treiber in Liste, Minor Nummer 1
file : alle Datei im current Verzeichnis
* (!) In Dateien gibt es schreibbare "Magic Patterns" (siehe man 5 magic) ; file schaut in die Datei hinein und ermittelt so das Format

* tar : Tape Archiver (Archivierungswerkzeug)
tar -cvf ../my.tar : "-c" = Create, "-v" = Verbose, "-f" = File ; legt alle Dateien/Ordner des aktuellen Verzeichnisses in ein Archiv
* tar -t (bzw. tar -tvf ../my.tar) : "-t" = Table of Content ; Inhalt eines Archivs anzeigen
* tar -xf ../my.tar : "-x" = Extract, "-f" = File
* (!) "-f" sollte an letzter Stelle der Optionen stehen
tar -Jcvf ../my.tar (bzw. tar xJvf ../my1.tar) : "J" = Komprimierung mit xz
tar czf ../b.tgz : erstellt ein gzip-komprimiertes tar-Archiv ("z" = gzip) aus allen Dateien im Verzeichnis
* tar tzvf b.tgz : Inhalt eines gzip-komprimierten tar-Archivs anschauen (Long-Listing)
* tar ztf archiv.tgz : Inhalt eines gzip-komprimierten tar-Archivs anzeigen
* cat b.tgz | tar tzf - : "-" = liest nicht aus einer Datei, sondern von Standard Input
* (!) In der Tar-Datei wird der Besitzer als User-ID gespeichert (z.B. "user1/user1") ; beim Entpacken auf einem anderen System mit anderer User-ID-Zuordnung gehört die Datei dann ggf. einem anderen (dort existierenden) Benutzer

* cpio : kopiert Dateien aus/in Archive
* cpio -i (bzw. --extract) : Archiv entpacken
* cpio -o (bzw. --create) : Archiv erstellen
* cpio -p (bzw. --pass-through) : kopiert Dateien direkt (Pass-Through), ohne ein Archiv im Dateisystem anzulegen
* -d : legt bei Bedarf Verzeichnisse mit an
* find | cpio -pd ~/backup : legt im Heimatverzeichnis ein Backup an
ls datei | cpio -ov > archiv.cpio : cpio-Archiv erstellen
* cpio -tv archiv.cpio (bzw. cpio -tv < b.cpio) : Archiv-Inhalt anschauen
* cpio -iv < archiv.cpio : Archiv auspacken

* dd : Disk Dump ; liest von Standard Input und schreibt auf Standard Output (siehe auch MBR-Beispiel unter 101.2)
* (!) Ohne "if="-Parameter liest dd direkt von der Standard-Shell
* dd if=/dev/zero of=mybigfile bs=100kB count=1 : liest aus /dev/zero und schreibt 100kB in die Datei "mybigfile"
* dd besitzt u.a. Parameter wie "kB" oder "K", je nachdem ob Megabyte oder Mebibyte verwendet werden soll
* sudo dd if=/dev/sda2 bs=512 count=3 | hexdump -C | less : gibt den Inhalt von "dd" direkt am Terminal aus

* tree : zeigt den Dateibaum eines Verzeichnisses an (muss explizit installiert werden)
* sudo apt install tree : installiert tree
* tree / | less : gibt den Inhalt seitenweise aus

* cat : concatenate ; lesen und schreiben von Textdateien
* cat Datei : Inhalt von "Datei" anzeigen
* cat /etc/os-release : Infos und Version zum aktuellen Linux anzeigen

* vi-Editor:
* :q : beenden
* :q! : beenden ohne Speichern (wenn nichts geändert wurde)

* find : durchsucht Verzeichnisse nach Dateien (Default: aktuelles Verzeichnis, rekursiv ; find . entspricht einfach find)
* find / -maxdepth 2 | less : "-maxdepth" begrenzt die Suche auf die angegebene Anzahl an Verzeichnisebenen
* find | grep kernel : sucht Dateinamen ab dem aktuellen Verzeichnis
* find -xdev / : durchsucht ab Root, verhindert aber, dass andere eingehängte Dateisysteme mit durchsucht werden
* sudo find /var/log -size +100M : sucht nach Dateien größer als 100 MB
find . -name "s.sh" : "*" = beliebig viele Zeichen (Platzhalter)
* find . -name "s?.sh" : "?" = genau ein Zeichen (Platzhalter)
* find . -name "s?.sh" -exec ls -l {} \; : "{}" = Platzhalter für die gefundene Datei, wird per -exec ausgeführt
* find / -name init : zeigt alle Dateien, deren Name "init" ist ; zeigt dabei auch Fehlermeldungen an, wenn keine Berechtigung zum Lesen besteht
* find / -name init 2>/dev/null : Fehler-Output wird nach /dev/null umgeleitet, damit kein Fehler-Output angezeigt wird
* find / 2>/dev/null | grep init : alternative Variante über grep
find /home -name ".sh" : Wildcard ; alle Namen, die auf ".sh" enden
* find . -iname "beispiel" : "-iname" = case insensitive ; unterscheidet nicht Groß-/Kleinschreibung
* find . -type d : sucht nur nach Directories
* find . -type f : sucht nur nach regulären Dateien (geht auch mit find -type f)
* find . -type b : sucht nach block special files
find /lib -type d -name "lib" : kombinierbar ; alle Verzeichnisse, die mit "lib" beginnen
find -type d,f -name "scr" -ls : "-type" kann kombiniert werden, "-ls" zeigt Long-Listing an
* find /tmp -user root -print : alle Daten in /tmp bzw. Unterverzeichnissen, die root gehören ; -print ist bei find der Default (kann also weggelassen werden)
* find . -user root : Beispiel
* find . -uid 1000 : sucht nach einer bestimmten User-ID
* find . -user root | od -cb : zeigt die Ausgabe als Hex/ASCII an ; man sieht das trennende Newline \n
* find . -user root -print0 | od -cb : zeigt, dass hier statt Newline die binäre Null (\0) als Trennzeichen verwendet wird (wichtig bei Dateinamen mit Leerzeichen, siehe auch xargs unter 103.4)
* (!) Die Option heißt korrekt -name (klein geschrieben) : Linux-Optionen sind case-sensitive ; ein -Name (groß) würde nicht erkannt/nicht funktionieren
find . -name '.txt' : Suchmuster in Anführungszeichen ; dadurch übernimmt find selbst die Auswertung des Platzhalters *
(!) find . -name .txt (ohne Anführungszeichen) : fehlerhaft ; die Shell wertet den Stern hier bereits selbst aus (Globbing) und ersetzt ihn vorher durch die passenden Dateinamen im aktuellen Verzeichnis (z.B. a.txt b.txt), bevor find überhaupt aufgerufen wird ; das kann zu unerwarteten Ergebnissen bzw. Fehlermeldungen führen
* Zeitbasierte Suchkriterien bei find:
* find -amin n : "a" = access ; vor genau n Minuten zuletzt zugegriffen
* find -mmin n : "m" = modified ; vor genau n Minuten zuletzt (inhaltlich) verändert
* find -cmin n : "c" = changed ; vor genau n Minuten zuletzt die Metadaten (z.B. Berechtigungen) geändert
* find -atime n : wie -amin, aber in ganzen Tagen (n mal 24 Stunden) statt Minuten
* find -mtime n : wie -mmin, aber in ganzen Tagen (n mal 24 Stunden)
* find -ctime n : wie -cmin, aber in ganzen Tagen (n mal 24 Stunden)
* +n bzw. -n : vor +n = "mehr als n" (älter als), vor -n = "weniger als n" (jünger als) ; ohne Vorzeichen bedeutet es exakt n

103.4 Use streams, pipes and redirects


* ls -l /dev/stdin /dev/stdout /dev/stderr : zeigt die symbolischen Links für die Datenströme des aktuellen Prozesses

* | : Pipe (wichtig in Linux) ; Output eines Kommandos verbinden und als Input dem nächsten Kommando übergeben
* ls -l / | grep home : Beispiel

* Jeder Prozess in Linux hat 3 Standard-Filedescriptoren: stdin (0, Input), stdout (1, Output), stderr (2, Error)
* ls -l i ii > Output : Standard Output in Datei ; der Fehler-Output geht ans Terminal
* ls -l i ii > Output 2>&1 : Output ist Standard Output (1), Error (2) soll ebenfalls in den Standard Output gehen ; 2>&1 = Standard-Fehler (2) dorthin umleiten, wo Standard-Output (1) hingeht
* ls -l i ii >> output 2> error : Text anhängen an 'output', Fehler separat in 'error' schreiben
* ls Test > OutputDatei 2>/dev/null : schreibt den Output von "Test" in "OutputDatei" und verwirft den Fehler-Output
* ls Test > OutputDatei 2>error : schreibt den Output von "Test" in "OutputDatei" und den Fehler-Output separat in die Datei "error"

* > : überschreiben
* >> : anhängen
* script <datei.in >datei.out 2>datei.err : liest datei.in als Input (stdin) und schreibt die normale Ausgabe nach datei.out sowie Fehler nach datei.err

* (!) Reihenfolge der Umleitungen ist wichtig, da sie von links nach rechts abgearbeitet werden:
* ls -l dsafdsf i > Output 2>&1 : Fehler-Output wird ebenfalls in "Output" umgeleitet, da zum Zeitpunkt von 2>&1 bereits "1" auf "Output" zeigt ; somit steht alles (Ausgabe und Fehler) in einer Datei
* ls -l rewrew Datei 2>&1 > Output : hier zeigt "2" zuerst noch auf das Terminal, danach wird nur "1" nach "Output" umgeleitet ; der Fehler bleibt am Terminal, nur die (fehlerfreie) Ausgabe landet in "Output"
* (!) Auch bei fehlgeschlagenen Befehlen wie ls ddrwer > Output wird die Datei "Output" angelegt/geleert (auch wenn kein Inhalt geschrieben wird)
* (!) ">" entspricht der Umleitung "1>"

* /dev/null : "Mülleimer" ; hierhin schreibt man, wenn man Output verwerfen möchte, z.B. 2>/dev/null
* /dev/zero : Datei für binäre Nullen ; z.B. um eine Datei/ein Laufwerk binär zu löschen bzw. mit Nullen zu beschreiben (z.B. mit dd)
* ; : reserviertes Symbol, um mehrere Befehle nacheinander auszuführen, z.B. id ; pwd

* noclobber : Option, die unbeabsichtigtes Überschreiben einer Datei per > verhindert (Default: aus/false)
* set -o | grep noclobber : zeigt den aktuellen Status der Option an
* set -o noclobber : schaltet die Option ein ; danach kommt bei > auf eine existierende Datei die Meldung "Kann existierende Datei nicht überschreiben"
* set +o noclobber : schaltet die Option wieder aus
* ls >| b : ignoriert eine aktive noclobber-Option und überschreibt die Datei trotzdem
* (!) /dev/null ist von noclobber nicht betroffen
* (!) script kunden-db > kunden-db : würde die Quelldatei erst leeren, bevor sie gelesen wird ; deshalb nicht verwenden (gleiche Datei nicht gleichzeitig als Input und Output-Ziel nutzen)

* Here Document : Folge von Zeilen, die man an ein Kommando übergeben kann
* cat > myfile : wartet standardmäßig auf Tastatur-Input
* cat > file <<EOF : liest so lange weiter, bis das angegebene Terminator-Zeichen (hier "EOF") in einer eigenen Zeile kommt ; erst danach wird die Datei geschrieben
* Beispiel:
		cat &gt; s.sh &lt;&lt;ENDE
		ls -ld $HOME
		pwd
		ENDE
* (!) Im Here-Document werden standardmäßig Variablen- und Command-Substitution durchgeführt, z.B. echo $(systemctl get-default) würde ausgewertet
* (!) Wird der Terminator in einfache Anführungszeichen gesetzt (z.B. <<'ENDE'), findet keine Command-Substitution statt ; der Inhalt wird wörtlich übernommen

* Here String : wird verwendet, wenn man einen einzelnen String übergeben möchte
* cat > datei <<< "Ein String" : Beispiel
* logger <<< "Ein Eintrag ins Systemprotokoll" : Beispiel ; wird an das logger-Kommando übergeben (anschauen z.B. mit sudo tail /var/log/syslog)
* cat > datei <<< "Ein String, der $HOME enthält" : $HOME wird ausgewertet ; verhinderbar durch einfache Anführungszeichen, z.B. 'Mein $HOME Verzeichnis'
* (!) bash stellt sicher, dass eine Umleitung ">" funktioniert und prüft zuerst, ob in das Zielverzeichnis geschrieben werden kann
* Here-Document kombiniert mit Datei-Umleitung, Beispiel:
		cat &lt;&lt; EOF &gt; config.txt
		Zeile 1
		Zeile 2
		EOF
Hierbei wird der eingegebene Text direkt in die Datei "config.txt" geschrieben, statt ihn am Terminal auszugeben
* Beispiel dazu: sudo echo 1 > /proc/sys/net/ipv4/ip_forward funktioniert NICHT, obwohl einige Dateien unter /proc (z.B. für IP-Forwarding) nicht readonly sind ; die Umleitung > wird von der (nicht privilegierten) aktuellen Shell geöffnet, bevor sudo echo überhaupt ausgeführt wird ; nur echo, nicht die Umleitung selbst, läuft mit sudo-Rechten
* Lösung: sudo su (bzw. eine Root-Shell) verwenden, damit die Shell selbst, die die Umleitung öffnet, bereits Root-Rechte hat

* stdin-Umlenkung:
* wc -l s.sh : zählt Zeilen der Datei
* cat s.sh | wc -l : liest ebenfalls Standard Input
* wc -l < s.sh : Datei wird an wc übergeben, ohne dass wc den Dateinamen kennt (daher wird nur die Zeilenzahl ausgegeben)

* tee : "T-Stück" ; liest von stdin und schreibt gleichzeitig nach stdout UND in eine Datei
* find / > filelist : man sieht dabei nicht, was passiert (kein Output am Terminal)
* find / 2>/dev/null | tee filelist : Fehler werden verworfen, die Trefferliste wird gleichzeitig in "filelist" geschrieben und am Terminal angezeigt
* tee -a : Append ; hängt an eine bestehende Datei an, statt sie zu überschreiben
* find /usr/src | tee filelist : erstellt die Datei mit dem Inhalt von /usr/src (/usr/src = Verzeichnis für die Kernel-Quellen)
* find /usr/bin | tee -a filelist : hängt /usr/bin zusätzlich an und gibt es zusätzlich am Terminal aus
* find /usr/bin : ohne weiteren Suchstring wird alles unterhalb des angegebenen Verzeichnisses gesucht
* find (ohne Angabe) : zeigt alles im aktuellen Verzeichnis an

* xargs : typisches Linux-Kommando ; kann mehrzeilige Ausgaben (Liste von Argumenten) an ein Programm übergeben und baut daraus Kommandos zusammen
* find | xargs file : führt "file" für jede gefundene Zeile aus
* cut -d : -f 1 /etc/passwd | xargs -n 1 id : "-n 1" = id bekommt jeweils nur 1 Argument übergeben
* cut -d : -f 1 /etc/passwd | tail -n 5 : gibt die letzten 5 Usernamen zurück
* cut -d : -f 1 /etc/passwd | tail -n 5 | xargs -n 1 id : jeder Username wird als Argument für das nachfolgende Kommando (id) verwendet
* find / -name init 2>/dev/null | xargs ls -ld (entspricht ls -ld $(find / -name init 2>/dev/null)) : beide Varianten funktionieren gleich
* (!) ls -ld $(find / 2>/dev/null) : liefert einen Fehler, da die Argumentliste zu lang wird (Speicher-/Command-Line-Buffer-Überlauf) ; der Command Line Buffer hat eine begrenzte Größe (siehe getconf ARG_MAX unter 103.1)
* find / 2>/dev/null | xargs ls -ld > erg 2>/dev/null : man sieht dabei nicht, was passiert
* find / 2>/dev/null | xargs ls -ld 2>/dev/null | tee erg : besser, da man den Output direkt sieht und nicht zwischenspeichern muss
* find /home -name ".bash_history" | xargs grep sudo : die von xargs übergebene Liste von Dateinamen wird als Argumentliste an grep sudo übergeben ; grep sudo durchsucht dabei den Dateiinhalt, nicht den Dateinamen
* xargs -I '{}' : Parameter, um den übergebenen Wert an einer bestimmten Stelle im Folgekommando einzusetzen (Platzhalter {})
md5sum $(which gzip bzip2 xz) | cut -d ' ' -f 1 | xargs -I '{}' grep '{}' /var/lib/dpkg/info/.md5sums : Beispiel (siehe auch 103.2)

* Leerzeichen/Sonderzeichen in Dateinamen:
find : zeigt nur Dateinamen (ohne Punkt-Dateien)
* find (ohne Argument) : zeigt auch die Punkt-Dateien
* find | xargs file : meldet ggf. einen Fehler, wenn ein Dateiname Leerzeichen enthält (z.B. "./ a b")
* find -print | od -cb : trennt die Ausgabe mit Newline (\n)
* find -print0 | od -cb : trennt die Ausgabe mit einer binären Null (\0)
* find -print0 | xargs -0 file : beides (Ausgabe von find und Übergabe an xargs) wird mit binärer Null getrennt, sodass Dateinamen mit Leerzeichen korrekt verarbeitet werden ; -0 ist bei xargs der passende Parameter zu find -print0 (binäre Null als Trennzeichen)
* getconf ARG_MAX : fragt den Command Line Buffer ab (siehe 103.1)

103.5 Create, monitor and kill processes



* Jobs im Vorder- und Hintergrund:
* Jeder Kommandoaufruf startet einen oder mehrere Prozesse, z.B. ls oder ls | grep
* Programm im Vordergrund : wartet, bis es fertig ist ("wartet auf irgendwas")
* Job im Hintergrund : läuft im Hintergrund weiter und arbeitet
* find / -print : läuft im Vordergrund ; die Kontrolle wird erst zurückgegeben, wenn das Kommando abgearbeitet ist
* find / -print & : läuft im Hintergrund (&) ; es muss nicht gewartet werden, es können direkt weitere Befehle ausgeführt werden ; eine Meldung erscheint, wenn der Job fertig ist
* jobs : zeigt die nicht beendeten Prozesse (Jobs) am aktuellen Terminal an
* jobs -l : zeigt die Jobs inkl. PIDs an
* sleep 300 : läuft im Vordergrund und pausiert
* sleep 300 & : läuft im Hintergrund und pausiert
* (!) Jobs sieht man nur in der aktuellen (Login-)Shell, nie in einer Subshell
* [STRG] + [Z] : Suspend ; schickt einen im Vordergrund laufenden Prozess in den Hintergrund und hält ihn an (pausiert)
* Jobs werden über die Job-ID (%jobid) angesprochen
* fg : Foreground ; holt den zuletzt behandelten Job (mit "+" markiert) in den Vordergrund
* fg %2 : holt Job 2 in den Vordergrund
* bg : Background ; lässt den zuletzt angehaltenen Job im Hintergrund weiterlaufen
* bg %3 : lässt Job 3 im Hintergrund weiterlaufen
* kill %1 : beendet den Job mit der Job-ID 1 (sendet SIGTERM)

* nohup : No Hang Up ; lässt einen Prozess unabhängig vom Terminal weiterlaufen
* nohup ping ubuntu & : Beispiel (nohup {command} &)
* (!) Der Prozess läuft weiter, auch wenn das Terminal/die Sitzung beendet wird
* ps -ef | grep ping : prüfen, ob der Prozess noch läuft

* watch : führt ein Kommando in einem Intervall wiederholt aus, um Prozesse/Änderungen zu beobachten
* (!) Ruft standardmäßig alle 2 Sekunden den Befehl auf
* watch df -h : würde alle 2 Sekunden df -h ausführen, während man selbst etwas anderes machen kann
* watch -n 5 free : "-n" = Update-Intervall in Sekunden (hier alle 5 Sekunden "free" ausgeben)
* watch -d : hebt Änderungen zwischen den Durchläufen farblich hervor, z.B. bei who
* watch -t : schaltet die Titelzeile ab

* uptime : zeigt an, wie lange das System läuft, wie viele User angemeldet sind und den Load Average (Auslastung der CPU der letzten 1, 5 und 15 Minuten)
* uptime -s : zeigt an, wann das System gestartet wurde (siehe auch 103.1)

* who : zeigt an, welcher User was macht
* w : zeigt an, welche Benutzer angemeldet sind und was sie gerade machen (kombiniert quasi die erste Zeile von uptime mit der Ausgabe von who)
* tty : zeigt die zugehörige Konsole/das Terminal an

* free : zeigt den freien Speicher an
* free -h : Anzeige "human readable", zeigt Hauptspeicher- und Swap-Speicher automatisch skaliert an (KB/MB/GB)
* free -m : Anzeige in Megabyte
* free -g : Anzeige in Gigabyte

* Signale an Prozesse schicken:
* (!) ps arbeitet mit der Prozess-ID, pgrep kann dagegen direkt mit einem Namen aufgerufen werden
* pidof : ermittelt ebenfalls die PID eines laufenden Programms, allerdings anhand des exakten Programmnamens (siehe auch pidof bash unter 101.1)
* ps aux | grep bash : gibt Infos zum gesuchten Prozess aus
* pgrep bash : zeigt PIDs laufender Programme anhand des Namens an
* pgrep sleep : findet einen Prozess anhand des Namens "sleep"
* pkill sleep : beendet alle Prozesse mit dem Namen "sleep" (Vorsicht bei Verwendung)
* killall sleep : beendet ebenfalls alle Prozesse mit dem Namen "sleep" (Vorsicht bei Verwendung)
* pgrep watch gefolgt von ps -ef | grep <PID> : ermittelt laufende Prozess-IDs und zeigt Details dazu
* pgrep watch | xargs ps -p : ruft ps -p mit den gefundenen Prozess-IDs auf und zeigt alles an
* ps -l -p 8837 : Long-Listing mit einer bestimmten Prozess-ID
* id alfa : zeigt uid, gid etc., alle Infos zum Benutzer "alfa" an
* pgrep -u alfa | xargs ps -l -p : zeigt Long-Listing aller Prozesse des Users "alfa"
* sudo pkill -u alfa : killt alle Prozesse des Users "alfa"
* pgrep -u alfa : zeigt die PIDs der Prozesse von "alfa" an
* pgrep -u root bzw. pgrep -u 0 : zeigt alle Prozesse des Users "root" an (Name und numerische UID "0" sind hier gleichbedeutend)
* (!) Ein normales (SIGTERM-)Kill wird von manchen Batch-/Hintergrundprozessen ignoriert ; Signal 9 (SIGKILL) wirkt in jedem Fall
* kill -l : zeigt die Liste der Signale an, die Linux kennt
* SIGSPEC : Bezeichnung für die Signal-Spezifikation/-liste, wie sie z.B. kill -l ausgibt (nicht LPIC-1-relevant)
* trap : fängt in Skripten Signale oder Ereignisse ab (nicht LPIC-1-relevant)
* kill 9970 : sendet standardmäßig SIGTERM ; wenn 9970 z.B. die eigene Bash ist, wird diese dadurch nicht beendet
* kill -s 9 9970 : Prozess wird mit SIGKILL hart beendet
* Wichtige Signale:
* 1 = SIGHUP : Hang-Up-Signal ; wird von Daemons genutzt, um die Konfigurationsdatei neu einzulesen, ohne den Dienst zu beenden
* 2 = SIGINT : wird an einen Prozess geschickt, der mit [STRG]+[C] beendet wird (Interrupt)
* 9 = SIGKILL : beendet einen Prozess mit Gewalt (kann nicht abgefangen/ignoriert werden)
* 15 = SIGTERM : reguläres Beenden (Terminate), kann vom Prozess abgefangen werden
* 18 = SIGCONT : lässt einen angehaltenen Prozess weiterlaufen
* 20 = SIGTSTP : schickt einen Prozess in den Hintergrund/pausiert ihn, wie mit [STRG]+[Z]
* kill -s 20 10067 : Beispiel, um einen Prozess anzuhalten (SIGTSTP)
* kill -s 18 10067 : Beispiel, damit der Prozess weiterläuft (SIGCONT)
* pgrep -u root -c : "-c" = Count ; zählt die Prozesse eines Users
* /bin/kill -L : kill ist auch ein eigenständiges Programm (nicht nur Shell-Buildin) ; -L listet die Signalnamen tabellarisch auf

* top und ps:
* ps : zeigt Prozesse statisch (Momentaufnahme) am Terminal an
* top : zeigt Prozesse dynamisch (laufend aktualisiert) an, alle bekannten Prozesse des Systems
* [SHIFT]+[N] (in top) : sortiert nach Prozess-IDs, größte zuerst
* [SHIFT]+[R] (in top) : sortiert nach Prozess-IDs, kleinste zuerst
* f (in top) : Field Management ; Felder ein-/ausblenden
* (!) Default-Sortierung in top: nach %CPU-Auslastung
* PID-Nummer eingeben (in top) : springt zum entsprechenden Prozess, dort kann direkt ein Signal gesendet werden
* htop : neueres, komfortableres top ; muss nachinstalliert werden ; (!) nicht LPIC-1-Stoff
* Tasten innerhalb von top:
* k : Kill ; beendet einen Prozess
* n : Number of ; Anzahl der angezeigten Zeilen
* r : Renice ; ändert den Nice-Wert
* h : Help
* q : beendet top
* %CPU : wie viel Prozent der Rechenleistung eines Prozessorkerns ein Prozess im letzten Zeitintervall genutzt hat
* TIME+ : gesamte CPU-Zeit, die ein Prozess seit dem Start verbraucht hat
* top -i : zeigt nur interaktive Prozesse
* top -b : Batch-Modus ; gibt die Ausgabe fortlaufend alle paar Sekunden ans Terminal aus
* top -d : Delay ; zeigt die Ausgabe verzögert an
* top -q : startet in Echtzeit, falls unterstützt (bei Ubuntu nicht der Fall)
* top $$ : zeigt den Prozess der eigenen Shell an
* top -p $(pidof bash | tr ' ' ,) : übergibt die PID(s) von Bash gezielt an top (moderne Schreibweise mit $(...))
* top -p pidof bash | tr ' ' , : macht dasselbe, alte Schreibweise mit Backticks (Unix-Schreibweise)

* ps : Syntax-Varianten
* BSD-Stil: ps 1 : ohne "-"
* UNIX-Stil: ps -p 1 : mit "-"
* GNU-Stil: ps --pid 1 : mit "--"
* ps (ohne Parameter) : alle Prozesse, die am aktuellen Terminal gestartet wurden
* ps -a : "all" = auch interaktive Prozesse anderer Terminals anzeigen
* (!) Viele Prozesse sind keinem Terminal zugeordnet ; erkennbar am "?" in der TTY-Spalte
* ps -ef : "e" = alle Prozesse, "f" = Full-Listing
* (!) TTY = TeleType (Bezeichnung für das Terminal/die Konsole)
* ps -x : zeigt auch Prozesse an, die keinem Terminal zugeordnet sind
* ps -u alfa : zeigt u.a. die Startzeit der Prozesse von "alfa" an
* ps -C bash : zeigt die Prozesse mit dem Namen "bash" an
* ps -U alfa : zeigt die Prozesse des Users "alfa" an (mit Startzeit)
* (!) Die effektive User-ID kann von der eigenen User-ID abweichen, z.B. bei passwd (SUID-Bit), das trotz fehlendem direkten Zugriff auf die Datei ausgeführt werden kann
* ps aux, ps -A, ps -ef : zeigen (im Wesentlichen) alle Prozesse des Systems an
* ps -A : alle laufenden Prozesse
* ps -ef | grep dm : Beispiel (nicht LPIC-1 Stoff)
* ps -p 1 : zeigt an, was als Prozess 1 gestartet wurde
* ps -p 6019 : zeigt Infos zum (Parent-)Prozess mit der angegebenen PID an

* pstree : zeigt Prozesse in einem Baum an
* pstree | less : zeigt laufende Prozesse baumartig
* pstree 1234 : zeigt den Prozessbaum ausgehend von der angegebenen PID (hier 1234) an
* pstree -d | less : Prozessbaum anzeigen
* pstree -a | less : zeigt zusätzlich die Kommandozeilen-Argumente an
* pstree -pa : zeigt zusätzlich die Prozess-IDs an
* pstree -pn : sortiert die PIDs innerhalb des Baums
* pstree -n : sortiert die PIDs innerhalb eines Elternprozesses
* echo $PPID : zeigt die Parent Process ID (PPID) an

* Terminal-Multiplexer:
* screen und tmux : können Sitzungen aufrechterhalten, auch wenn die Netzwerkverbindung unterbrochen wird oder man sich abmeldet (ähnlicher Effekt wie nohup, es soll kein "Hänger"/Abbruch geben)
* screen : seit 1987 (älterer Befehl) ; standardmäßig nicht installiert
* [STRG]+[A] [S] : Fenster teilen, 2 Bildschirmbereiche in einem Fenster (nur Zusatzinfo)
* [STRG]+[A] [C] : wechselt in einen anderen Bildschirmbereich (nur Zusatzinfo)
* tmux : neuer, seit 2007 ; behält Sessions bei, unterstützt ebenfalls Split-Screen
* (!) tmux baut wie screen eine Session auf, in der Split-Screen möglich ist ; die Sessions bleiben als Sockets erhalten, auch wenn man sich vom System abgemeldet hat
* (!) tmux ignoriert Hangup-Signale
* (!) [STRG]+[B] ist bei tmux das Präfix (Command-Taste) ; danach muss noch eine zweite Taste folgen, z.B.:
* [STRG]+[B], danach [STRG] + " : öffnet ein neues Fenster/Tab
* [STRG]+[B], danach Pfeiltaste (nach oben/unten) : wechselt zwischen Fenstern/Bereichen
* [STRG]+[B], danach ? : zeigt die Hilfe innerhalb von tmux an
* [STRG]+[B], danach [ALT] + Pfeiltaste : vergrössert oder verkleinert das Fenster/Bereich

103.6 Modify process execution priorities



* SMP : symmetrisches Multiprozessor-System ; faire Aufteilung der Prozesse auf die CPU(s)
* (!) Moderne Betriebssysteme sind präemptiv : ein laufender Prozess kann jederzeit zurück in die Warteschlange gestellt werden
* es gibt Zeitscheiben ; das OS bestimmt, wie lange ein Prozess "dran" ist
* nur ein Prozess im Hauptspeicher (RAM) kann die CPU nutzen

* Prozess-Priorität:
* 0 - 99 : Priorität für Real-Time-Prozesse (niedrige Zahl = hohe Priorität)
* 100 - 139 : Priorität für normale Prozesse
* 120 : Default-Priorität eines normalen Prozesses
* SUSE Linux Enterprise Real Time (SLERT) : spezielle Variante von SUSE Linux Enterprise für Echtzeit-Anwendungen (Anmerkung: nicht jedes "SUSE Linux Enterprise" ist automatisch ein Echtzeitsystem, es gibt dafür eine eigene RT-Variante)

* /proc/<PID>/ : Verzeichnisse mit Zahlen entsprechen laufenden Prozessen ; der Kernel verwaltet diese Infos
* /proc/1/sched : Datei, in der u.a. der aktuelle Priority-Wert ("prio") des Prozesses steht
grep prio /sched : zeigt die Priorität aller Prozesse an (ausgeführt innerhalb von /proc)
grep prio /sched | cut -d : -f 3 | sort -n | uniq -c : "-c" = Count ; zählt, wie viele Prozesse welche Priorität haben
grep prio /sched | cut -d : -f 1,3 > /tmp/prios : schreibt alle Prozesse mit ihrer Priorität in eine Datei
grep prio /proc/$$/sched : zeigt die aktuelle Priorität der eigenen (aktuellen) Shell/Prozess-ID an

* Historische Umrechnung der Priorität:
* ps -l : zeigt in der Spalte "PRI" die Priorität an, historisch bedingt um 40 vermindert dargestellt ; um die tatsächliche Kernel-Priorität zu erhalten, müssen wieder +40 hinzugerechnet werden
* (!) top zieht 100 ab : dadurch erscheinen alle Real-Time-Prozesse in top mit einem negativen "PR"-Wert

* nice : jeder normale Prozess hat als Default einen Nice-Wert von 0 ; anderen Prozessen den Vortritt lassen
* Wertebereich: -20 bis 19 (-20 = niedrigster Nice-Wert = höchste Priorität ; 19 = höchster Nice-Wert = niedrigste Priorität)
* (!) Nur der User root darf einen Nice-Wert kleiner als 0 vergeben
* nice (ohne Argument) : zeigt den eigenen aktuellen Nice-Wert an
* nice bash : startet eine Bash mit erhöhtem Nice-Wert 10 ; Priorität dadurch 130 (120 + 10)
* (!) Ein Kindprozess erbt den Nice-Wert : eine aus einer "genicten" Bash gestartete Subshell bekommt denselben (niedrigeren) Prioritätswert vererbt
* nice -n 5 bash : setzt den Nice-Wert auf 5
* nice -n 7 bash (innerhalb der bereits mit nice -n 5 gestarteten Shell) : addiert sich zum bereits vorhandenen Wert, Ergebnis 12 (5 + 7)
* nice -n 15 tar czf home_backup.tar.gz /home : Beispiel, startet tar mit Nice-Wert 15
* nice -15 tar ... : Kurzschreibweise, entspricht nice -n 15 ...
* sudo nice -n -20 bash : startet eine Bash mit dem niedrigstmöglichen Nice-Wert (-20), also der höchsten Priorität innerhalb der normalen Prozesse
* (!) Das macht den Prozess trotzdem nicht "echtzeitfähig" : ein negativer Nice-Wert wirkt nur innerhalb der normalen Scheduling-Klasse (Prioritätsbereich 100–139), nicht im Real-Time-Bereich (0–99) ; siehe chrt weiter unten

* renice : ändert den Nice-Wert eines bereits laufenden Prozesses
* renice -10 -p 2164 : setzt den Nice-Wert des Prozesses mit PID 2164 auf -10
* renice -n 14 6988 : setzt den Nice-Wert bei PID 6988 auf 14 ; renice setzt (anders als bei nice bash, wo sich Werte addieren) den Wert direkt auf den angegebenen absoluten Wert
* sudo renice -10 6099 : setzt die Priorität höher (niedrigerer Nice-Wert = höhere Priorität)

* top und Priorität:
* r (innerhalb von top) : öffnet die Eingabe, um den Renice-Wert eines Prozesses direkt in top zu ändern (siehe auch 103.5)
* (!) Auch root darf mit nice keine Prozesse in den Echtzeitbereich versetzen ; nice/renice sind dafür nicht in der Lage. Für Real-Time-Scheduling wird chrt benötigt (nicht LPIC-1-relevant).
* sudo chrt -o -p 0 <PID> : setzt einen Prozess auf Priorität 120 (normale Priorität) ; "-o" = SCHED_OTHER (normaler Scheduling-Modus)
* sudo chrt -f -p 99 <PID> : macht aus einem Prozess einen Echtzeit-Prozess mit Priorität 0 ; "-f" = SCHED_FIFO (First In, First Out = Echtzeit-Scheduling)

103.7 Search text files using regular expressions


(siehe auch grep unter 103.2)

Jokerzeichen (Wildcards) vs. reguläre Ausdrücke : Jokerzeichen gelten in der Shell (z.B. , ?), reguläre Ausdrücke gelten innerhalb von Programmen wie grep
Bash-Wildcards: = alle (beliebig viele Zeichen), ? = ein Zeichen
* Reguläre Ausdrücke – Metazeichen:
* . : ein beliebiges Zeichen
* ^ : Anfang einer Zeichenkette/Zeile
* $ : Ende einer Zeichenkette/Zeile

* Anfang/Ende einer Zeile:
* grep '^Suchwort' Datei : findet "Suchwort" nur am Anfang einer Zeile
* grep 'Suchwort$' Datei : findet "Suchwort" nur am Ende einer Zeile
* grep '^Suchwort$' Datei : findet Zeilen, die exakt nur aus "Suchwort" bestehen
* cat -A Datei : zeigt auch Zeilenumbrüche und Sonderzeichen an (siehe auch cat -A unter 103.2)

* Der Punkt . als Platzhalter:
* grep '^Such.wort$' Datei : Zeilen, die mit "Such" beginnen, mit "wort" enden und dazwischen genau ein beliebiges Zeichen haben
* grep 'such.wort' Datei : "such" + ein beliebiges Zeichen + "wort", irgendwo in der Zeile

* Zeichenklassen in eckigen Klammern [...]:
* grep 'da[tx]ei' Datei : genau ein Zeichen aus der Liste ("t" oder "x") an dieser Stelle ; findet "datei" und "daxei", nicht aber "datxei"
* grep 'da[^tx]ei' Datei : ^ innerhalb der Klammer negiert ; findet ein Zeichen, das NICHT "t" oder "x" ist
* grep 'da[t-z]ei' Datei : ein Zeichen aus dem Bereich t bis z
* grep '^da[t-z]ei$' Datei : wie oben, zusätzlich auf ganze Zeilen beschränkt (Anfang und Ende)
* grep '^da[^t-z]ei$' Datei : Negierung ; ein beliebiges Zeichen außer t bis z

* Vordefinierte Zeichenklassen, z.B. [:alnum:] oder [:digit:] (zählen ebenfalls nur als EIN Zeichen):
* grep '^da:alnum:ei' Datei : ein alphanumerisches Zeichen an dieser Stelle
* grep '^da[^[:alnum:]]ei$' Datei : negierte Zeichenklasse (kein alphanumerisches Zeichen)
* (!) [[:alnum:][:alnum:]] ist NICHT gleichbedeutend mit [txzyb] : :alnum: deckt alle alphanumerischen Zeichen ab (also weit mehr als nur t, x, z, y, b) ; auch doppelt notiert bleibt es dieselbe (größere) Menge. Näher an [txzyb] käme z.B. der Bereich [t-z], aber auch der ist nicht identisch mit der expliziten Aufzählung [txzyb].

* Escaping/Maskierung von Sonderzeichen im regulären Ausdruck:
* grep '^da\.ei$' Datei : maskiert den Punkt, sodass nur ein wörtliches "." gesucht wird (kein beliebiges Zeichen)
* grep '^da.ei\$' Datei : maskiert das Dollarzeichen, sodass nach einem wörtlichen "$" gesucht wird

* Wiederholungs-Operatoren:
: 0 oder beliebig viele Wiederholungen des vorherigen Zeichens
grep '^da:alpha:ei$' Datei : Beispiel
grep '^da[txzyb]ei$' Datei : Beispiel
* ? : 0 oder 1-malige Wiederholung des vorherigen Zeichens
* (!) In einfachen (basic) regulären Ausdrücken hat "?" keine Sonderbedeutung und muss daher maskiert werden: grep '^da[txzyb]\?ei$' Datei
* egrep '^da[txzyb]?ei$' Datei : in Extended Regular Expressions (ERE) hat "?" direkt seine Sonderbedeutung, keine Maskierung nötig
* grep -E '^da[txzyb]?ei$' Datei : entspricht egrep, "-E" aktiviert Extended Regular Expressions bei grep
* + : 1 oder mehr Wiederholungen des vorherigen Zeichens
* grep '^da[txzyb]\+ei$' Datei : in Basic Regular Expressions muss auch "+" maskiert werden ; alternativ mit -E/egrep ohne Maskierung
* {i} : genau i Wiederholungen des vorherigen Zeichens
* bei grep (BRE) muss die geschweifte Klammer maskiert werden: grep ':digit:\{3\}' Datei (Zeilen mit 3 aufeinanderfolgenden Ziffern)
* bei egrep/grep -E (ERE) muss die geschweifte Klammer NICHT maskiert werden
* grep -w '^:digit:\{3\}' Datei : "-w" = Word ; nur Treffer, bei denen genau 3 Ziffern ein eigenes "Wort" bilden
* grep -w '^:digit:\{2,3\}' Datei : 2 oder 3 Wiederholungen
* grep -w '^:digit:\{2,\}' Datei : mindestens 2 Wiederholungen
* grep -w '[abc]\{2,4\}' Datei : 2 bis 4 Wiederholungen

* \< und \> : markieren Wortanfang bzw. Wortende in regulären Ausdrücken
grep 'ein[1-9]' Datei : findet auch 0 Wiederholungen der Ziffer(n)
grep 'ein[1-9]\>' Datei : Treffer muss am Wortende liegen

* Reguläre Ausdrücke vs. Shell-Suchmuster (Globbing) : ähnliche, aber unterschiedliche Syntax
* [^abc] (regex) entspricht [!abc] (Shell-Glob)
* . (regex, ein beliebiges Zeichen) entspricht ? (Shell-Glob)
^a.\.txt$ (regex) entspricht *.txt (Shell-Glob)
* man 7 regex (reguläre Ausdrücke) vs. man 7 glob (Shell-Suchmuster, für Programmierer)

* grep-Familie – Programme vs. Wrapper:
* ls -l $(which grep egrep fgrep rgrep) : zeigt, dass grep selbst ein eigenständiges Programm (Executable) ist, während egrep, fgrep und rgrep Shell-/Wrapper-Skripte sind, die grep mit bestimmten Parametern aufrufen
* fgrep (bzw. grep -F) : "fixed"/"fast" grep ; kennt keine regulären Ausdrücke (sucht nach dem Suchstring wörtlich), dadurch aber schneller
* Beispiel-Idee dazu: Zeichen, die in regulären Ausdrücken eine Sonderbedeutung haben (z.B. runde Klammern ( )), werden bei grep -F wörtlich (literal) gesucht statt als Regex-Metazeichen interpretiert (Achtung: das konkrete Beispiel aus der Mitschrift, echo '(Hello)' | grep', war unvollständig/abgebrochen notiert und wird hier deshalb nicht 1:1 übernommen)
* grep -r bzw. rgrep : durchsucht rekursiv
* grep -lr UNIX : sucht rekursiv und zeigt nur die Dateinamen der Treffer an ("-l" = Dateinamen)
* grep -o '1\{2\}' : "-o" = zeigt nur den exakten Treffer(-teil) einer Zeile an, nicht die ganze Zeile
* grep -c : Count ; zählt die Anzahl der Treffer(zeilen)
* grep -i : ignoriert Groß-/Kleinschreibung
* grep -v : invertiert die Suche (zeigt Zeilen OHNE Treffer)

find : wenn ein Argument mit einem Minuszeichen beginnt (z.B. "-efq", auch wenn es eigentlich eine Datei/ein Ordner ist), wird es sonst fälschlich als Option interpretiert
* grep Dienst -- -efq : "--" signalisiert, dass alles Nachfolgende KEINE Option mehr ist, sondern z.B. ein Dateiname (siehe auch "--" bei du unter 104.2)

103.8 Perform basic file editing using vi


* vi sh.sh : Skript/Datei anlegen bzw. bearbeiten
* :q / :q! : vi Editor verlassen (siehe 103.3)
* view : Datei nur lesend öffnen (kein Schreiben)
* view /etc/passwd : Beispiel, um z.B. Login-Infos der User anzusehen
* emacs : alternativer Editor, um in der Konsole zu editieren
* (!) : Emacs lässt sich so einstellen, dass er sich z.B. wie vi verhält (vi-Modus/vi-Emulation)

* vi (vim) : interaktiver Editor ; war ursprünglich kommerzielle Software (vi), vim ("Vi IMproved") ist die verbreitete freie Weiterentwicklung
* (!) vi/vim ist praktisch auf jedem Linux-System vorhanden
* vi Datei1 Datei2 /etc/passwd : öffnet zunächst nur die erste Datei, man kann aber zwischen den übergebenen Dateien wechseln
* :n : wechselt zur nächsten Datei in der beim Aufruf übergebenen Dateiliste
* :N : wechselt eine Datei zurück
* Beim Start von vi befindet man sich im Kommandomodus (Normal Mode)

* showmode-Einstellung : hilfreich, um zu sehen, in welchem Modus (z.B. Insert) man sich gerade befindet
* :set showmode? : zeigt den aktuellen Status an ; Default ist "noshowmode"
* :set showmode / :set noshowmode : schaltet die Anzeige ein/aus
* echo "set showmode" >> ~/.vimrc : hinterlegt diese Einstellung dauerhaft als Default

* Wechsel vom Kommando- in den Einfügemodus (diese Befehle werden OHNE führenden Doppelpunkt direkt im Kommandomodus eingegeben, nicht als :-Kommando):
* i : Einfügen VOR der aktuellen Cursorposition
* a : Einfügen (Append) NACH der aktuellen Cursorposition
* I : Einfügen am Anfang der aktuellen Zeile
* A : Einfügen (Append) am ENDE der aktuellen Zeile (Achtung: in der Mitschrift stand hier fälschlich "Anfang der aktuellen Zeile" für "A" ; das entspricht tatsächlich der Funktion von "I")
* [ESC] : verlässt den Einfügemodus, zurück in den Kommandomodus

* Speichern und Verlassen (Kommandomodus, mit vorangestelltem :, außer ZZ):
* :w : speichert ; mit Angabe eines Dateinamens (z.B. :w Datei2) wird der Puffer dorthin geschrieben
* :w! : schreibt auch, wenn die Datei eigentlich readonly geöffnet wurde
* :wq : speichern und Editor verlassen
* :x : ähnlich wie :wq ; speichert (nur bei Änderungen) und verlässt den Editor
* ZZ : (Shift+Z Z, OHNE Doppelpunkt) ; speichert und verlässt den Editor
* :q : Editor verlassen ohne zu speichern (vi meldet sich, falls es ungesicherte Änderungen gibt)
* :q! : Editor verlassen ohne zu speichern, auch bei vorhandenen Änderungen

* Cursorbewegung im Kommandomodus:
* h : ein Zeichen nach links
* j : eine Zeile nach unten
* k : eine Zeile nach oben (Pendant zu j, in der Mitschrift nicht explizit genannt, aber Teil derselben Tastenkombination h j k l)
* l : ein Zeichen nach rechts (ebenfalls Teil von h j k l)
* G : springt zum Ende der Datei
* gg : springt zum Anfang der Datei
* H : springt zum oberen Bildschirmrand
* L : springt zum unteren Bildschirmrand
* Zahlen können den Bewegungsbefehlen vorangestellt werden, z.B. 4j (4 Zeilen runter), 8l (8 Zeichen nach rechts)
* 0 : Zeilenanfang
* $ : Zeilenende
* w : wortweise vorwärts
* b : wortweise zurück
* [STRG]+[F] : eine Seite vorwärts
* [STRG]+[B] : eine Seite zurück
* (!) h j k l : historische Tastenkombination zur Cursorbewegung, aus einer Zeit ohne (verlässliche) Pfeiltasten auf Terminals ; Pfeiltasten funktionieren in modernem vi/vim aber ebenfalls

* Kopieren/Einfügen (Yank & Put):
* yy bzw. Y : kopiert (yankt) die aktuelle Zeile in den Zwischenspeicher (Achtung: in der Mitschrift stand "yy = kopiert die aktuelle UND nächste Zeile" ; das ist so nicht korrekt, yy kopiert standardmäßig nur die eine aktuelle Zeile)
* 4yy : kopiert 4 Zeilen (ab der aktuellen Zeile) in den Zwischenspeicher
* p : fügt den Zwischenspeicher-Inhalt NACH der aktuellen Zeile/Cursorposition ein
* P : fügt den Zwischenspeicher-Inhalt VOR/oberhalb der aktuellen Zeile/Cursorposition ein

* Löschen/Ändern:
* dd : löscht die aktuelle Zeile (Cursorzeile)
* D : löscht vom Cursor bis zum Zeilenende (entspricht d$)
* cc : schneidet die aktuelle Zeile aus und wechselt in den Einfügemodus (Change)
* C : schneidet vom Cursor bis Zeilenende aus und wechselt in den Einfügemodus
* o : erzeugt eine neue, leere Zeile UNTERHALB der aktuellen Zeile und wechselt in den Einfügemodus
* O : erzeugt eine neue, leere Zeile OBERHALB der aktuellen Zeile und wechselt in den Einfügemodus
* x : löscht das Zeichen an der Cursorposition
* 2x : löscht 2 Zeichen ab der Cursorposition
* dw : löscht bis zum Wortende (nicht bis Zeilenende)
* d0 : löscht vom Zeilenanfang bis zur (aber ohne die) Cursorposition
* d$ : löscht vom Cursor bis zum Zeilenende (entspricht D)

* Suchen:
* /regexp : sucht vorwärts nach einem Wort bzw. regulären Ausdruck
* n : wiederholt die Suche in derselben Richtung wie zuvor
* N : wiederholt die Suche in der entgegengesetzten Richtung
* ?Suchwort : sucht rückwärts nach dem angegebenen Begriff

* Weitere nützliche :set-Kommandos:
* :set all : zeigt alle vi/vim-Moduseinstellungen an
* :set list / :set nolist : macht Zeilenenden sichtbar (bzw. schaltet dies aus)
* :set wrapscan (Default) : Suche beginnt bei Erreichen des Dateiendes wieder von vorne
* :set nowrapscan : schaltet dieses "Umbrechen" der Suche aus
* :set ignorecase : ignoriert bei der Suche Groß-/Kleinschreibung
* :set number / :set nonumber : zeigt Zeilennummern an bzw. blendet sie aus

* ~/.vimrc : Konfigurationsdatei, um bei jedem Start Default-Einstellungen zu setzen, z.B.:
	:set showmode
	:set number

* Kommandos innerhalb von vi ausführen:
* :!pwd : führt ein Shell-Kommando (hier pwd) direkt aus vi heraus aus
* :!bash : öffnet eine neue Bash-Shell innerhalb von vi

* Dateien innerhalb des Editors laden:
* :r Datei : liest den Inhalt einer anderen Datei ein und fügt ihn in den aktuellen Puffer ein
* :e Datei : lädt eine (andere) Datei nach ; aktualisiert die Anzeige
* (!) Zum Zeitpunkt des Öffnens wird der Dateiinhalt in den Editor-Puffer eingelesen ; ändert sich die Datei danach extern, wird das im laufenden vi nicht automatisch angezeigt
* :e! : vor einem Dateiwechsel zunächst speichern bzw. Änderungen verwerfen und neu laden

* Text ersetzen in vi (funktioniert ähnlich wie das Substitute-Kommando bei sed):
* :s/t/T/ : ersetzt nur das erste "t" in der aktuellen Zeile durch "T"
* :s/t/T/g : "g" = global ; ersetzt alle "t" in der aktuellen Zeile
* :1,$s/user/Benutzer/ : wendet die Ersetzung auf jede Zeile an (Zeile 1 bis letzte Zeile)
* :s,/,, : löscht (ersetzt durch nichts) einen Schrägstrich in der aktuellen Zeile ; hier wird "," als alternativer Trenner verwendet
* % : steht für die ganze Datei, z.B. :%s/Suchwort/Ersetzen/ (entspricht :1,$s/...)

* Befehlszeilenoptionen beim Aufruf von vi:
* vi /etc/profile +20 : öffnet die Datei und springt direkt in Zeile 20
* vi /etc/profile +/PATH : öffnet die Datei und springt direkt zur ersten Fundstelle von "PATH"

* Alternative Editoren:
* nano : einfacher, anfängerfreundlicher Editor
* emacs : alter, mächtiger Editor ; für die Prüfung reicht es, den Namen zu kennen

* Standard-Editor ändern:
* fc (ohne "type" davor) : ruft den zuletzt ausgeführten Befehl im Standard-Editor zur Bearbeitung auf ("fix command") ; type fc selbst zeigt nur, dass fc ein Shell-Buildin ist, führt aber keinen Editor aus
* export EDITOR=$(which vi) : setzt den Standard-Editor für die aktuelle Sitzung (gilt nur, solange die Shell-Sitzung besteht)
* sudo update-alternatives --config editor : ändert den systemweiten Standard-Editor ; kann nur vom Systemverwalter ausgeführt werden
* ~/.bashrc : kann ebenfalls eine Zeile wie EDITOR=/usr/... enthalten, um den Editor dauerhaft für den eigenen User zu setzen
* /usr/bin/editor : zeigt (über das Alternatives-System) auf den systemweiten Standard-Editor, z.B. -> /etc/alternatives/editor -> /usr/bin/vim.tiny

* vimtutor : interaktives Lernprogramm für vi/vim ; muss meist separat nachinstalliert werden

---

104 – Devices, Linux Filesystems, Filesystem Hierarchy Standard



104.1 Create partitions and filesystems


* /etc/filesystems : zeigt (bzw. listet) die auf dem System möglichen/unterstützten Dateisystem-Typen an
* siehe 102.1 (fdisk, gdisk, MBR, GPT, LVM, Partitionslayout)

* (!) Partitionen im Nachhinein zu verändern ist schwer ; eher Neuinstallation oder gute Vorabplanung
* Bekannte Werkzeuge: fdisk, gdisk, parted

* sudo fdisk -l /dev/sda : mit "-l" greift man auf die ganze Platte zu, nicht nur eine Partition
* Beispiel aus der Mitschrift: sda1 bis sda4 bleiben frei, SWAP fängt ab sda5 an (kurssspezifisches Beispiel-Layout)
* man loop : Infos zu Loop-Devices
* fdisk : kann grundsätzlich auch GPT-Platten verarbeiten, wird aber eigentlich für MBR verwendet
* sudo parted : Achtung, greift standardmäßig auf die (aktuelle) Systempartition zu ; bei parted muss man die Platte explizit angeben
* parted : kennt u.a. den Befehl print free (zeigt Partitionen inkl. freiem Speicher)
* sudo gdisk -l /dev/sda : prüft (lesend), was auf der Platte drauf ist
* sudo gdisk /dev/sda : schreibender Zugriff auf die Partitionierung

* Partitionstypen (Kennungen):
* MBR/fdisk-Kennung 83 entspricht bei GPT/gdisk dem Kurzcode 8300 : Linux Filesystem
* MBR/fdisk-Kennung 82 entspricht bei GPT/gdisk dem Kurzcode 8200 : Linux SWAP
* (!) Achtung : in der Mitschrift stand bei Kennung "82" fälschlich "8300" statt "8200" für SWAP ; das dürfte ein Übertragungsfehler sein, da 8300 für "Linux Filesystem" reserviert ist
* Für LPIC-2 (nicht LPIC-1) reicht es, diese beiden Codes zu kennen
* Beim Anlegen einer Partition ist "Linux Filesystem" der Default-Typ

* swapon -s : zeigt, wie das SWAP-Dateisystem aussieht/wo es liegt, z.B. /swap.img (siehe auch 102.1)

---

Dateisystem anlegen (mkfs):
mkfs : Frontend zum Anlegen von Dateisystemen ; zweimaliges Drücken von [TAB] zeigt die verschiedenen mkfs.-Varianten an
* (!) Default-Dateisystem von mkfs ist ext2
* sudo mkfs /dev/sdb2 : erzeugt als Default ein ext2-Dateisystem
* (!) Zur Sicherheit werden an mehreren Stellen der Platte Sicherungskopien des Superblocks abgelegt (Anmerkung: nicht die Inodes selbst, sondern der Superblock wird redundant/mehrfach gesichert)
* mkfs -t : übergibt mkfs den gewünschten Dateisystem-Typ
* sudo mkfs -t ext3 /dev/sdb1 : legt ein ext3-Dateisystem auf /dev/sdb1 an

* df : zeigt eingehängte Dateisysteme (siehe auch 102.1/104.2)
* ls -l /mnt : Standard-Mount-Verzeichnis
* sudo mount /dev/sdb2 /mnt : hängt das Dateisystem unter /mnt ein
* df -i : zeigt die Inode-Auslastung an (siehe auch df -Thi unter 102.1)
* sudo umount /mnt : hängt das Dateisystem wieder aus

* (!) ext2 ist nicht journal-fähig, ext3 besitzt (im Gegensatz zu ext2) ein Journal
* sudo tune2fs -j /dev/sdb2 : wandelt ein bestehendes ext2- in ein ext3-Dateisystem um (fügt ein Journal hinzu)
* (!) Journal : merkt sich bestimmte zuvor ausgeführte Operationen ; kommt es (z.B. bei einem Absturz) zu Inkonsistenzen im Dateisystem, können anhand des Journals Informationen wiederhergestellt werden
* sudo lsof /dev/sdb1 : List Open Files ; zeigt offene Dateien/Prozesse auf dem Gerät an

* Partition mit fdisk interaktiv anlegen: n (neu), p (primär), 1 (Partitionsnummer)
* (!) "p" : ist innerhalb der interaktiven fdisk-Sitzung (nach fdisk /dev/sdX) der Befehl zum Anzeigen der Partitionstabelle ("print") ; es handelt sich nicht um eine Kommandozeilen-Option wie fdisk -p

* mkfs.ext2, mkfs.ext3, mkfs.ext4 : sind letztlich alle Symlinks/Aufrufe von mke2fs (liegt z.B. unter /usr/sbin)
* ls -l $(which mkfs.ext2 mkfs.ext3 mkfs.ext4) : zeigt, dass alle drei auf dasselbe Programm (mke2fs) verweisen

* ext4 Vorteile gegenüber ext3:
* größere Volumen möglich
* Online-Defragmentierung möglich
* (weitere Vorteile in der Mitschrift nicht vollständig aufgeführt)
* Defragmentierung : Dateien werden im Laufe der Zeit in verschiedenen (nicht zusammenhängenden) Bereichen der Platte abgelegt (Fragmentierung) ; durch Defragmentieren wird wieder zusammenhängender Speicher frei
* (!) ext4 : klassisches, bewährtes Dateisystem ; unter Ubuntu Standard-Dateisystem (Anmerkung: der letzte Satz der Mitschrift dazu war unvollständig/abgebrochen)

* VFAT : häufig bei USB-Sticks verwendet ; unterstützt lange Dateinamen, maximale Dateigröße 4 GiB
* exFAT : häufig bei Flash-/Speicherkarten verwendet ; laut Mitschrift Vorteil gegenüber VFAT bei der maximalen (Datei-)Größe von 64 GiB (Anmerkung: dieser Wert bzw. der in der Mitschrift genannte Zusatz "ACLs = Access Control" zu exFAT wirkten unklar/unvollständig und sollten ggf. nochmal anhand der Kursunterlagen geprüft werden)
* (!) exFAT ist nicht standardmäßig installiert, sondern muss extra nachinstalliert werden
* (!) Ein passendes Dateisystem-Modul (z.B. für exFAT) muss vorhanden sein, damit z.B. entsprechend formatierte Flashkarten gelesen werden können
* sudo apt install exfatprogs : installiert die exFAT-Werkzeuge (Achtung: in der Mitschrift stand fälschlich "extfatprocs")
* dpkg -L exfatprogs | less : zeigt die zum Paket gehörenden Dateien an

* lsblk : zeigt Blockgeräte an
* lsblk --fs : zeigt zusätzlich die Dateisysteme an

---

xfs:
* xfs : Dateisystem-Typ ; standardmäßig (zumindest unter Ubuntu) nicht mitinstalliert
* ursprünglich für IRIX (ein Unix-Derivat, von SGI) entwickelt
* unterstützt Journaling
* großer Schreibcache, wodurch I/O-Zugriffe reduziert werden
* Risiko bei Stromausfall, da Daten im Schreibcache dabei verloren gehen können (der Cache liegt im RAM)
* Paket: xfsprogs (Achtung: in der Mitschrift stand "xfsprocs")
* dpkg -l | grep -i xfs
* sudo mkfs /dev/sdb2 : legt kein neues Dateisystem an, wenn auf dem Gerät bereits eines existiert
* sudo mkfs.xfs -f /dev/sdb2 : "-f" = Force ; erzwingt das Anlegen (überschreibt ein vorhandenes Dateisystem)
* Externes Logfile (Journal auf separatem Gerät):
* mkfs.xfs -f /dev/sdf5 -l logdev=/dev/sdf3
* mount -t xfs /dev/sdf4 -o logdev=/dev/sdf3 /mnt

---

btrfs (B-Tree Filesystem):
* (!) Modernes Dateisystem
* Im Gegensatz zu ext4 (ein Dateisystem = eine Platte) kann ein btrfs-Dateisystem auch über mehrere Platten aufgespannt werden
* guter Gerätesupport, einschließlich Striping und Mirroring
* Komprimierung, Verschlüsselung
* Copy-on-Write-Dateisystem (wird eine Datei "überschrieben", wird zunächst die neue Version geschrieben, dann erst der Verweis auf die alte Version geändert/verworfen)
* Snapshots
* Subvolumes
* Online-Defragmentierung
* kann Inodes dynamisch (nach Bedarf) anlegen

* (!) Fedora nutzt bereits standardmäßig btrfs ; z.B. ist dort /home ein Subvolume auf /dev/sda3
* sudo apt install btrfs-progs : installiert btrfs-Werkzeuge unter Ubuntu nach

* sudo mkfs -t btrfs /dev/sdb1 : zeigt einen Fehler, wenn auf dem Gerät bereits ein Dateisystem liegt
* sudo mkfs -t btrfs -f /dev/sdb1 : "-f" = Force, erzwingt das Anlegen
* sudo mkdir /mnt/sdb1
* sudo mount /dev/sdb1 /mnt/sdb1
* df -Th : zeigt die eingehängten Dateisysteme (inkl. Typ) an

* Subvolumes:
* sudo btrfs subvolume create /mnt/sdb1/subvolume1 : legt ein Subvolume an
* sudo btrfs subvolume list /mnt/sdb1 : listet vorhandene Subvolumes
* sudo mount -o subvol=subvolume1 /dev/sdb1 /mnt/subvolume1 : hängt gezielt ein Subvolume ein
* (!) Subvolume : ermöglicht es, Bereiche innerhalb eines btrfs-Dateisystems voneinander zu trennen (z.B. nutzt Fedora dies für /home)

* ext2 zu btrfs konvertieren (Beispiel):
* mkfs /dev/sdd1 : legt (Default) ein ext2-Dateisystem an
* fdisk -l /dev/sdd > /mnt/somedata : legt eine Beispieldatei an
* btrfs-convert /dev/sdd1 : konvertiert das ext2-Dateisystem in btrfs ; dabei wird ein Abbild ("Snapshot") des vorherigen Dateisystems als Image-Datei gesichert
* nach der Konvertierung liegt unter /mnt u.a. der Ordner ext2_saved (enthält das gesicherte ext2-Image), sowie lost+found und die zuvor angelegten Dateien (z.B. "somedata")
* mount -t ext2 -o loop /mnt/ext2_saved/image /snapshot : hängt das gesicherte ext2-Image über ein Loop-Device ein
* (!) Der so eingehängte Snapshot ist standardmäßig nur read-only
* btrfs subvolume list /mnt : listet Subvolumes

* mount -o compress /dev/sdf2 /mnt : hängt ein Dateisystem mit aktivierter Kompression ein
* btrfs filesystem show : zeigt Infos zu btrfs-Dateisystemen an

---

SWAP-Partition/-Datei anlegen:
* swapon -s : zeigt an, welche SWAP-Bereiche aktiv sind (siehe auch oben/102.1)
* mkswap /dev/sdd2 : erstellt aus /dev/sdd2 ein SWAP-Dateisystem
* swapon -v /dev/sdd2 : aktiviert die Partition als SWAP ("-v" = verbose)
* free -th : zeigt Speicher und Auslagerungsspeicher an

* SWAP-Datei anlegen:
* dd if=/dev/zero of=/swap.file bs=1024 count=1000 : legt eine Auslagerungsdatei mit fester Größe an (Achtung: in der Mitschrift fehlten bei dd die Gleichheitszeichen bei if=/of=)
* chmod 600 /swap.file : wichtig, damit niemand sonst die Datei lesen/beschreiben kann
* mkswap /swap.file : Datei als SWAP-Dateisystem formatieren (in der Mitschrift fehlte dieser Schritt vor dem Aktivieren)
* swapon /swap.file : fügt die SWAP-Datei hinzu (Achtung: in der Mitschrift stand fälschlich der Befehl "swap" statt "swapon")
* swapon -s : zeigt anschließend alle Infos zu den aktiven SWAP-Bereichen an

104.2 Maintain the integrity of filesystems


* (!) lost+found : Ordner ist für Filesystem-Checks da

* du und df : zwei wichtige Kommandos
* df : Disk Free ; arbeitet auf Basis der eingehängten Dateisysteme
* du : Disk Usage ; arbeitet auf Basis von Dateien, zeigt den belegten Platz von Verzeichnissen/Dateien
* du : von Haus aus rekursiv (ausgehend vom aktuellen Verzeichnis)
* du Otto | less : zeigt nur die Größen unterhalb des Verzeichnisses "Otto"
* du -a : "all" ; zeigt alle Dateien, nicht nur Verzeichnisse an
* du -a | sort -n | less : alle Dateien numerisch nach Größe sortiert ("-n" = Numeric)
* du -k | tail : Default-Einheit sind Blöcke (bzw. KB)
* du -m | tail : Anzeige in MB
* du -h : Human Readable (K, M, G)
* du -c : zeigt zusätzlich eine Gesamtsumme an
* du -S : zeigt die Größe der aktuellen Verzeichnisse (ohne Unterverzeichnisse mit einzurechnen)
du -sch -- : "--" beendet die Optionsliste, damit auch Dateien/Ordner mit führendem Minuszeichen korrekt verarbeitet werden (siehe auch -- bei grep unter 103.7)
* du | wc -l : zeigt die Anzahl der Verzeichnisse an (entspricht find -type d | wc -l)
* du -a | wc -l : zeigt die Gesamtzahl aller Dateien/Verzeichnisse an (entspricht find | wc -l)

* df -h . : entspricht df . ; zeigt das Dateisystem des aktuellen Verzeichnisses an
* df -Th . : zeigt zusätzlich den Dateisystem-Typ an
* df -Tx tmpfs : "-x" = schließt den angegebenen Dateisystem-Typ (hier tmpfs) aus der Anzeige aus, alle anderen werden gezeigt

* fsck : File System ChecK ; Frontend, führt einen Dateisystem-Check durch ; Backends sind z.B. fsck.ext2, fsck.ext3, fsck.ext4
ls /sbin/fsck : zeigt die vorhandenen fsck-Varianten
* ls -l $(which fsck fsck.ext2 fsck.ext3 fsck.ext4) : zeigt, dass diese letztlich alle bei e2fsck landen und dieses aufrufen
* sudo mkfs -t ext4 /dev/sdc1 : legt ein ext4-Dateisystem an
* sudo fsck /dev/sdc1 : zeigt an, ob das Dateisystem "sauber" ist
* sudo fsck -f /dev/sdc1 : "-f" = Force ; erzwingt einen Dateisystem-Check, auch wenn er laut Mount-Zähler nicht nötig wäre ; läuft in 5 Durchgängen ab:
* Durchgang 1: Inodes, Blockgrößen
* Durchgang 2: Verzeichnisstruktur
* Durchgang 3: Verzeichnisverknüpfungen
* Durchgang 4: Referenzzähler
* Durchgang 5: zusammengefasste Gruppeninformationen
* (!) Zur Überprüfung sollte das Dateisystem nicht eingehängt sein, da Änderungen, die sich noch im Hauptspeicher befinden, ggf. noch nicht auf die Platte geschrieben wurden
* fsck-Optionen (e2fsck):
* -f : Force
* -b Blocknr : erlaubt es, einen alternativen (Backup-)Superblock zu verwenden
* -y : beantwortet Rückfragen bei Inkonsistenzen automatisch mit "ja" (sonst wird bei jeder Inkonsistenz nachgefragt, ob repariert werden soll)
* (!) mkfs legt beim Anlegen des Dateisystems automatisch alternative (Backup-)Superblöcke an, damit im Bedarfsfall (mit -b) auf einen davon zurückgegriffen werden kann

* fsck : wird (historisch) standardmäßig nach einer bestimmten Anzahl von Mounts oder nach einer bestimmten Anzahl Tage beim Systemstart erzwungen (genaue Default-Werte können je nach Distribution/mke2fs-Version variieren, in der Mitschrift wurden "alle 36 Mounts oder alle 180 Tage" genannt)
* (!) Für SysVinit beim Reboot (funktioniert bei systemd nicht mehr):
* shutdown -rf : unterbindet einen Filesystem-Check beim Reboot
* shutdown -rF : erzwingt einen fsck nach dem Boot
* (!) Alternative bei systemd : touch /forcefsck erzwingt beim nächsten Boot einen fsck (bzw. entsprechender Kernel-Parameter)

* tune2fs : bearbeitet einstellbare (tunable) Dateisystemparameter ; die Infos dazu stehen im Superblock
* sudo tune2fs -l /dev/sdc1 | less : "-l" = liest den Superblock aus und listet die Mount-Infos (z.B. "Last checked")
* tune2fs -c : setzt/zeigt die maximale Anzahl an Mounts, nach der ein Check erzwungen wird
* tune2fs -C : überschreibt den aktuellen Mount-Zähler
* tune2fs -i : setzt das Intervall (in Tagen), nach dem ein Check erzwungen wird
* Maximum Mount Count -1 : deaktiviert den erzwungenen, mount-zahl-basierten Check
* (!) Moderne Systeme deaktivieren "Maximum Mount Count" und "Interval" häufig standardmäßig

* Label (Bezeichnung) eines Dateisystems:
* sudo tune2fs -l /dev/sdc1 | grep -i name : zeigt den aktuellen Namen/Label
* sudo tune2fs -L swapxy /dev/sdc1 : setzt das Label auf "swapxy"
* (!) Ist bei ext2/ext3/ext4 der Weg über tune2fs ; xfs setzt/handhabt Labels anders (eigenes Werkzeug)
* mount -L swapxy /mnt : über das gesetzte Label einhängen

* mke2fs : kann nicht nur ext2-, ext3- oder ext4-Dateisysteme erzeugen, sondern beim Anlegen auch prüfen (z.B. Bad-Block-Scan)
* mke2fs -c /dev/sda1 : Beispiel für einen Bad-Block-Scan beim Anlegen
* man mkfs.ext4 : Option -m = Standardprozentsatz des für den Root-Benutzer reservierten Speicherplatzes (Default 5%)

* xfs-Werkzeuge:
* mkfs.xfs : Erstellung eines xfs-Dateisystems
* xfs_repair : entspricht fsck bei xfs
* xfs_db : Debugging-Tool für xfs
* xfs_db -r : führt im Read-Only-Modus aus
* sudo xfs_db -r /dev/sdb2 : lesender Zugriff, danach z.B. inode 128 und print zum Anzeigen von Low-Level-Infos
* xfs_fsr : Reorganisation, entspricht einer Defragmentierung ; findet er nichts zu tun, passiert einfach nichts
* xfs_fsr /dev/sde1 -v : "-v" = mehr Infos anzeigen
* (!) agno : "Allocation Group Number" ; darüber lassen sich bei xfs u.a. Inodes gezielt ansprechen (Detail-/Debugging-Thema, nicht zentral für LPIC-1)
* (!) Moderne XFS-Systeme sind aufgrund der Allokationsstrategie deutlich weniger fragmentierungsanfällig als früher (der genaue Hintergrund zu "-f"/"-d" in der Mitschrift blieb an der Stelle unklar/unvollständig)

* (!) Inode : Metadatei zu einer Datei (enthält u.a. Berechtigung, User, Gruppe, Änderungsdatum, Dateiname)
* eindeutig innerhalb eines Dateisystems
* wird beim Anlegen des Dateisystems festgelegt (Anzahl) ; wird die Anzahl überschritten, können keine neuen Dateien mehr angelegt werden
* ls -li Datei : zeigt die Inode-Nummer einer Datei an
* ls -lai .. | head -n 5 : zeigt u.a. die Inodes zum übergeordneten (Parent-)Verzeichnis
* stat Datei : zeigt Meta-Infos (u.a. Zeitstempel) zu einer Datei an
* siehe auch df -Thi unter 102.1 (Inode-Auslastung je Dateisystem)

104.3 Control mounting and unmounting of filesystems


* mount / umount : siehe 102.1
* sudo umount /boot/efi
* sudo mount /boot/efi

* /etc/fstab : Datei, in der Einträge für automatisiertes Einhängen von Dateisystemen hinterlegt werden
* mount -t TYP Device Mountpoint : der Dateisystem-Typ ("TYP") muss nicht zwingend angegeben werden, da mount ihn in der Regel automatisch erkennt
* mount (ohne Argumente) : zeigt eingehängte Dateisysteme inkl. Mount-Optionen an
* mount -t xfs bzw. mount -t ext4 : zeigt (ohne weitere Angabe von Gerät/Mountpoint) nur die aktuell eingehängten Dateisysteme des angegebenen Typs an
* mount -t xfs,ext4 : zeigt eingehängte Dateisysteme mehrerer angegebener Typen gleichzeitig an
* (!) mount -f : bedeutet "--fake" (simuliert den Mount-Vorgang, z.B. zum Testen von /etc/fstab-Einträgen), zeigt NICHT die Mount-Optionen eines Dateisystem-Typs an (Achtung: in der Mitschrift stand "mount -f xfs // zeigt die Mount Optionen an" ; das dürfte eine Verwechslung mit mount -t xfs sein)
* lsblk --fs : zeigt die eingehängten Laufwerke inkl. Dateisystem an

* Beispiel /etc/fstab-Zeile:
	/dev/sdc1 /daten ext4 defaults 0 0
	/dev/sdb2 /anwendungen xfs defaults 0 0
* Spalten: Gerät, Mountpoint, Dateisystem-Typ, Mount-Optionen, "Dump"-Flag (0/1, ob dump das Dateisystem berücksichtigen soll), Reihenfolge/Priorität beim fsck-Check
* sudo mount /daten : schaut in /etc/fstab nach und hängt den entsprechenden Eintrag ein (Kurzform funktioniert nur, wenn der Mountpoint dort eingetragen ist)
* sudo umount /daten : hängt das Gerät wieder aus
* systemctl daemon-reload : lädt u.a. die von systemd aus /etc/fstab generierten Mount-Units neu (nötig, wenn sich /etc/fstab geändert hat)

* Mount-Optionen:
* mount -a : "all" ; hängt alle Dateisysteme ein, die in /etc/fstab gelistet sind
* mount -r /anwendungen : hängt nur lesend (read-only) ein
* mount -w : "writable" ; hängt schreibend ein
* sudo mount -r /dev/sr0 /mnt : Beispiel CD/DVD-Laufwerk ; die Quelle ist von sich aus schreibgeschützt, daher immer mit -r
* (!) Es können nur Dateisysteme ausgehängt werden, die gerade nicht benutzt werden
* sudo mount -v -o remount,rw /daten : hängt ein Dateisystem neu ein (remount), ohne bestehende Benutzer/Prozesse "rauszuwerfen"

* Netzwerkressourcen einhängen, z.B. Samba (in der Mitschrift nur angerissen, nicht weiter ausgeführt)

* (!) umount : hängt ein Dateisystem AUS (nicht ein) ; in der Mitschrift stand dazu fälschlich "um alles einzuhängen" - korrekt ist "aushängen"

* lsof : Liste der offenen Dateien/Nutzer, die auf ein Dateisystem zugreifen
* sudo lsof /daten : zeigt, welcher User wie (z.B. über eine Bash) auf das Verzeichnis zugreift
* (!) Funktioniert sowohl auf Mountpoints als auch auf Gerätedateien

* /etc/fstab-Optionen: es gibt diverse weitere Optionen, z.B. exec/noexec ; mit noexec können auf dem Dateisystem liegende Dateien zwar gelesen, aber nicht als Programme ausgeführt werden

* /proc/self/mounts : Liste aller aktuell eingehängten Geräte inkl. Pfad (funktioniert ähnlich wie mount) ; (Achtung: Pfad ist case-sensitive, korrekt klein geschrieben "mounts", nicht "Mounts")

* (!) Jedes beliebige Verzeichnis kann als Mountpoint verwendet werden : ist es vorher nicht leer, wird der ursprüngliche Inhalt für die Dauer des Mounts überdeckt und ist nicht erreichbar (aber nicht gelöscht) ; nach dem umount ist der ursprüngliche Inhalt wieder sichtbar

* mount -t nfs server:/pfad /mountpoint : Beispiel zum Einhängen eines Netzwerk-Dateisystems (NFS), z.B. sudo mount -t nfs centos-linux:/storage /daten

* (!) Bei umount reicht eine Angabe : entweder das Gerät (umount /dev/sdd1) oder der Mountpoint (umount /daten) ; beides gleichzeitig ist nicht nötig

* Wichtige /etc/fstab-Mount-Optionen (durch Komma getrennt, siehe man 8 mount):
* suid / nosuid : SUID-Bit wird beim Ausführen beachtet bzw. ignoriert
* ro / rw : Read-only bzw. Read-Write einhängen
* dev : erlaubt den Zugriff auf Gerätedateien (Special Files) auf dem Dateisystem
* exec / noexec : ausführbare Dateien dürfen bzw. dürfen nicht ausgeführt werden
* auto / noauto : wird beim Hochfahren automatisch eingehängt bzw. nicht ; (!) bei "noauto" hängt auch "sudo mount -a" das Dateisystem NICHT ein
* user / nouser : normale (nicht-root) Benutzer dürfen mounten bzw. nicht (Default ist nouser) ; bei user darf zudem nur derjenige Benutzer, der eingehängt hat, das Dateisystem auch wieder aushängen
* users : jeder Benutzer darf mounten, und auch ein beliebiger anderer Benutzer darf wieder aushängen ; (!) gilt inzwischen als veraltet und wird nicht mehr überall unterstützt
* async : Ein-/Ausgabevorgänge laufen asynchron
* defaults : entspricht der Kombination rw,suid,dev,exec,auto,nouser,async (die üblichen Standardoptionen)

* /etc/mtab : Link auf /proc/self/mounts ; beim Einhängen trägt mount die Infos zusätzlich hier ein
* cat /etc/mtab, cat /proc/mounts und cat /proc/self/mounts zeigen letztlich denselben Inhalt (Links auf dieselbe Datei)

* cat /etc/fstab | grep -v '^#' : zeigt alle Einträge in /etc/fstab ohne Kommentarzeilen (Achtung: in der Mitschrift stand grep -v '^h' ; das dürfte ein Verhörer/Tippfehler für '^#' sein, da Kommentarzeilen in /etc/fstab mit # beginnen, nicht mit "h")

* UUID von Dateisystemen:
* ls -l /dev/disk/by-uuid/ : zeigt symbolische Links von UUIDs auf die jeweiligen Gerätedateien (z.B. 7800bae0-08... -> ../../sda2) (Achtung: in der Mitschrift stand "by-uuid" als "my-uuid" ; korrekt ist das Verzeichnis /dev/disk/by-uuid)
* blkid : zeigt Blockgeräte mit ihrer jeweiligen UUID (und meist auch dem Dateisystem-Typ) an
* blkid | wc -l : zählt die Zeilen der blkid-Ausgabe und zeigt so an, wie viele Partitionen das System hat
* sudo tune2fs -l /dev/sda1 | grep -i uuid : liest die UUID aus dem Superblock aus (siehe auch 104.2)
* lsblk -o +UUID : ergänzt die Standard-lsblk-Ausgabe um die UUID-Spalte (neben lsblk und lsblk --fs, siehe 104.2)

* systemd Mount-Units:
* systemd liest beim Hochfahren ebenfalls /etc/fstab und generiert daraus automatisch passende Mount-Units ; Vorteil: man kann sich den Status der einzelnen Mountpoints wie bei anderen Units gezielt anschauen
* systemctl status daten.mount : zeigt den Status einer aus /etc/fstab generierten Mount-Unit an (Achtung: Standard-Unit-Typ bei systemctl status ist .service, für Mountpoints muss explizit die Endung .mount angegeben werden)
* /run/systemd/generator : hier legt systemd die aus /etc/fstab generierten Mount-Unit-Dateien ab (z.B. daten.mount, anwendungen.mount)
* /media : Standard-Mountpoint für Wechseldatenträger wie USB-Sticks oder optische Laufwerke
* Beispiel /etc/fstab-Zeile: LABEL=swap /daten ext4 defaults,user,noauto 0 0 (Achtung: in der Mitschrift stand beim Dateisystem-Typ "/ext4" mit führendem Slash ; das dritte Feld ist aber nur der reine Typname, z.B. ext4, ohne "/") ; mit sudo mount /daten wird dann das mit Label "swap" versehene Dateisystem eingehängt

104.4 Manage disk quotas


(keine Notizen vorhanden)

104.5 Manage file permissions and ownership


* Linux Datei Rechte:
* r = Read (Lesen)
* w = Write (Schreiben)
* x = eXecute (Ausführen)
* u = User (Eigentümer)
* g = Group (Gruppe)
* o = Other (Rest der Welt)
   u       g       o
┌─────┐ ┌─────┐ ┌─────┐ 
 r w x   r w x   r w x 

* id : Zeigt verschiedene IDs an, z.B. eigene UserID "uid=1000(alfa)"
* eigene UserID ist meist 1000
* sudo id : liest ID von root aus, meist "uid=0(root)"

* Rechte in Zahlenwerten (oktal):
* read (r) = 4 (100)
* write (w) = 2 (010)
* execute (x) = 1 (001)
* Bei ls -l steht z.B. -rw-rw-r-- 2 user1 user1 ... ; die "2" davor ist der Link-Count (Anzahl der Hardlinks auf die Datei), nicht Teil der Rechte

* Dateitypen (ls -l, erstes Zeichen):
* - : normale/reguläre Datei
* d : Directory (Verzeichnis)
* b : Block-orientiertes Gerät (blockweise Übertragung)
* c : Character-orientiertes Gerät (zeichenweise Übertragung, z.B. tty)
* ls -ld Verzeichnis : "-d" = nur die Rechte des Verzeichnisses selbst anzeigen (nicht dessen Inhalt)

* chmod : ändert die Dateimodus-Bits ; sowohl oktal als auch symbolisch möglich
* chmod 755 ergebnis : oktale Schreibweise
* chmod +x ergebnis : symbolische Schreibweise, fügt Execute-Recht hinzu
* chmod u=rwx,g=rx,o=rx ergebnis : setzt die Rechte explizit je Klasse (User/Group/Other) ; (!) zwischen den Parametern darf kein Leerzeichen stehen, sonst würde der Rest als Dateiname interpretiert
* chmod ugo+x ergebnis : fügt allen drei Klassen (User, Group, Other) das Execute-Recht hinzu
chmod -R 755 : "-R" = Rekursiv, wendet die Rechte auf alle Verzeichnisse/Dateien darunter an
* chmod -c u+x Datei : "-c" = "changes" ; zeigt an, was tatsächlich geändert wurde
* Unterschied = vs. +/-:
* chmod a=rx script : setzt für alle ("a") NUR "rx", vorhandene andere Rechte werden entfernt
* chmod +rx script : fügt "r" und "x" hinzu, bestehende Rechte bleiben zusätzlich erhalten
* (!) Eine neu angelegte Datei bekommt grundsätzlich kein Execute-Recht (siehe auch umask)

* Bedeutung von Execute/Write auf Verzeichnissen:
* (!) Execute-Recht auf einem Verzeichnis : bedeutet, dass man das Verzeichnis betreten (hineinwechseln) darf ; dieses Recht muss auf dem gesamten Pfad bis zur Zieldatei vorhanden sein, auch in allen Unterverzeichnissen
* (!) Um eine Datei in einem Verzeichnis anzulegen oder zu löschen, wird das Schreibrecht auf das (übergeordnete) Verzeichnis benötigt (analog zum Execute-Recht)

* SUID, SGID und Sticky Bit (vierte, vorangestellte Ziffer bei 4-stelliger Oktalschreibweise):
* SUID = 4
* SGID = 2
* Sticky Bit = 1
* chmod 4755 Datei : setzt SUID, Ergebnis z.B. -rwsr-xr-x
* (!) Sonderrechte sind der Datei zugeordnet, es bleiben insgesamt 9 Anzeigestellen bei ls -l, nur dass statt einem "x" ein "s" (oder "S") erscheint

* SUID (Set User ID) : ist dieses Bit gesetzt, wird die Datei im Sicherheitskontext des Dateibesitzers ausgeführt (nicht im Kontext des aufrufenden Benutzers)
* Beispiel: -rwsr-xr-x 1 root root /usr/bin/passwd ; dadurch kann passwd mit Root-Rechten auf /etc/shadow zugreifen, obwohl es von einem normalen Benutzer aufgerufen wird
* Programme mit gesetztem SUID-Bit laufen mit den Rechten des Eigentümers (oft root) ; das kann ein Sicherheitsrisiko darstellen
* find / -perm -u+s 2>/dev/null | xargs ls -lad : zeigt alle Dateien mit gesetztem SUID-Bit
* (!) Unter Linux hat das SUID-Bit keine Wirkung auf Verzeichnisse oder Skripte, sondern nur auf (kompilierte) ausführbare Dateien

* SGID (Set Group ID) : bei ausführbaren Dateien bewirkt es, dass die Ausführung im Sicherheitskontext der Gruppe des Dateibesitzers läuft
* Beispiel: -rwxr-sr-x 1 root crontab ... ; die Gruppe "crontab" bekommt hier das "s" bei der Ausführung
* find / -perm -g+s 2>/dev/null | xargs ls -lad : zeigt alle Dateien/Verzeichnisse mit gesetztem SGID-Bit
* (!) Auf ein Verzeichnis angewendet bewirkt SGID, dass alle neu angelegten Dateien/Unterverzeichnisse automatisch die Gruppe des Verzeichnisses erben (nicht die primäre Gruppe des erstellenden Benutzers)
* chmod g+s meinverzeichnis : setzt das SGID-Bit auf ein Verzeichnis

* Groß-/Kleinschreibung bei den Sonderbits:
* s (klein) : das jeweilige Execute-Recht ist zusätzlich gesetzt
* S (groß) : das jeweilige Execute-Recht ist NICHT gesetzt (nur das Sonderbit selbst)

* Sticky Bit : auf einem Verzeichnis angewendet bewirkt es, dass nur der Eigentümer der jeweiligen Datei (oder root) diese Datei aus dem Verzeichnis löschen kann, auch wenn andere Benutzer Schreibrecht auf das Verzeichnis haben
* drwxrwxrwt : das "t" bei "other" zeigt das gesetzte Sticky Bit an
* Beispiel: in einem für alle beschreibbaren Verzeichnis wie /tmp kann jeder Dateien anlegen, aber nur der jeweilige Eigentümer (oder root) kann eine Datei darin auch wieder löschen
* (!) Achtung, mögliches Missverständnis in der Mitschrift: dort wurde unter der Überschrift "Sticky Bit" beschrieben, dass "die Gruppenzugehörigkeit beim Neuanlegen auf die Gruppe angewendet wird" ; das beschreibt tatsächlich das Verhalten von SGID auf Verzeichnissen (siehe oben), nicht das des Sticky Bits

* (!) /tmp ist für jeden beschreibbar ; das gesetzte Sticky Bit sorgt dabei dafür, dass trotzdem niemand fremde Dateien in /tmp löschen kann (Achtung: in der Mitschrift stand als Begründung, dies diene dazu, "dass das Root-Schreibsystem nicht voll wird" ; das ist nicht der eigentliche Grund - der Zweck ist vielmehr, temporäre Dateien für alle Benutzer nutzbar zu machen, während der Sticky Bit vor gegenseitigem Löschen schützt)
* (!) Davon zu unterscheiden : /tmp wird auf manchen Systemen bewusst als eigenes (separates) Dateisystem/eigene Partition (z.B. tmpfs) eingehängt ; das hat einen anderen Zweck als das Sticky Bit oben - hierdurch soll verhindert werden, dass sich /tmp "vollschreibt" und dadurch das Root-Dateisystem (/) volläuft

* SUID-/SGID-Dateien mit find und -perm gezielt suchen:
* -perm wert : exaktes Match der angegebenen Rechte
* -perm -wert : alle angegebenen Bits müssen gesetzt sein (weitere dürfen zusätzlich gesetzt sein)
* -perm /wert : mindestens eines der angegebenen Bits muss gesetzt sein
* find . -perm 4000 : exaktes Match, z.B. eine Datei mit ausschließlich gesetztem SUID-Bit und sonst keinen weiteren Rechten (---S------)
* find . -perm -4000 : findet alle Dateien, bei denen (mindestens) das SUID-Bit gesetzt ist, unabhängig von weiteren Rechten

* chown : Change Owner ; ändert Besitzer und/oder Gruppe einer Datei
* sudo chown user1:sudo abc : ändert Besitzer auf "user1" und Gruppe auf "sudo" (Achtung: in der Mitschrift stand hier chmod statt chown ; für Besitzer-/Gruppenwechsel ist chown das richtige Kommando)
* sudo chown :user1 abc : ändert NUR die Gruppe auf "user1" (Besitzer bleibt unverändert), wenn vor dem Doppelpunkt kein Name angegeben wird
* chown -R : "-R" = Rekursiv, wie bei chmod

* chgrp : Change Group ; ändert nur die Gruppe einer Datei (Alternative zu chown :gruppe)

* umask : legt fest, welche Rechte eine neu erstellte Datei/ein neues Verzeichnis NICHT bekommt
* umask (ohne Parameter) : zeigt die aktuell eingestellte Maske an, typisch 022 ; (!) ist ein Shell-Builtin-Kommando
* Berechnung für neue Dateien: von den maximal möglichen 666 (rw-rw-rw-, Dateien bekommen von Haus aus kein "x") wird die Umask abgezogen
* Beispiel: 666 - 022 = 644 (Achtung: in der Mitschrift stand als Zwischenergebnis fälschlich "544", das abschließende Ergebnis "644" war aber bereits richtig)
* (!) Verzeichnisse bekommen standardmäßig das Execute-Recht, daher wird bei Verzeichnissen von 777 (statt 666) abgezogen
* umask -S : zeigt die Maske in symbolischer Form, z.B. u=rwx,g=rx,o=rx
* Gleichbedeutende Schreibweisen: umask 0027, umask 27 und umask u=rwx,g=rx,o= beschreiben dieselbe Maske
* umask WERT : setzt die Maske neu (nur für die aktuelle Shell-Sitzung, sofern nicht dauerhaft in einer Konfigurationsdatei hinterlegt)

* Dateiattribute (lsattr / chattr, ext2/ext3/ext4):
* (!) wird bei der Prüfung eher selten/am Rande abgefragt, gilt als etwas veraltet
* lsattr Datei : zeigt gesetzte Attribute an, z.B. --------------e------- ("e" = Extents, Standard bei ext4)
* sudo chattr +a Datei : setzt das Attribut "Append-only" ; die Datei kann danach nur noch erweitert (angehängt), aber nicht mehr überschrieben oder gelöscht werden ; Ergebnis z.B. -----a--------e-------
* sudo chattr =e Datei : "=" setzt die Attribute exakt auf die angegebene Liste ; da hier nur "e" (Extents, siehe oben) angegeben wird, werden dadurch alle anderen zuvor gesetzten Attribute (z.B. das "a" von oben) wieder entfernt ("gelöscht")
* es gibt noch weitere Attribute (z.B. i = immutable/unveränderlich), die für die Prüfung typischerweise weniger relevant sind

104.6 Create and change hard and symbolic links


* (!) Harter Link (Hardlink) : verweist direkt auf dieselbe Inode wie die Originaldatei ; funktioniert nur innerhalb desselben Dateisystems, da Inode-Nummern nur dort eindeutig sind
* (!) Symbolischer Link (Symlink) : verweist stattdessen über einen Pfad auf die Zieldatei ; funktioniert auch dateisystem- bzw. partitionsübergreifend, kann aber "ins Leere zeigen" (broken link), wenn das Ziel gelöscht/verschoben wird

* ln : legt Links an
* (!) Links sparen Speicherplatz auf dem Datenträger, da die Datei nicht mehrfach abgelegt wird ; zudem muss inhaltlich nur eine Datei gepflegt werden

* Symbolische Links (Softlinks):
* (!) benötigen (im Vergleich zum Original) nur sehr wenig zusätzlichen Speicherplatz
* ln -s vorhandeneDatei LinkDatei : "-s" = erzeugt einen symbolischen Link
* ln -s Datei datei_sl : Beispiel ; "datei_sl" wird als Symlink auf "Datei" angelegt
* ln -s Verzeichnis verzeichnis_sl : ein symbolischer Link kann auch auf ein Verzeichnis angelegt werden
* ls -l zeigt bei einem Symlink lrwxrwxrwx : das führende "l" steht für "link"
* stat datei : zeigt bei der Originaldatei den Typ "reguläre Datei" an
* stat datei_sl : zeigt beim Symlink den Typ "symbolischer Link" an
* (!) Ein symbolischer Link kann sowohl auf Dateien als auch auf Verzeichnisse angelegt werden
* (!) Ein symbolischer Link kann auch auf eine Datei/ein Verzeichnis in einem anderen Dateisystem verweisen (im Gegensatz zum Hardlink, siehe df)
* (!) Ein symbolischer Link hat immer eine andere Inode-Nummer als die Zieldatei
* (!) Ein symbolischer Link zeigt selbst immer "volle" Berechtigungen an (lrwxrwxrwx), tatsächlich wirksam sind aber die Berechtigungen der Zieldatei ; wird z.B. mit chmod die Berechtigung über den Symlink geändert, wirkt sich das auf die Zieldatei aus, auf die der Link zeigt (gilt ebenso für Verzeichnisse)
* (!) Broken Link : ein Softlink bleibt als Verzeichniseintrag bestehen, auch wenn die Zieldatei gelöscht wurde ; er zeigt dann "ins Leere"
* Verschieben von symbolischen Links:
* Ob ein Symlink nach dem Verschieben noch funktioniert, hängt davon ab, ob beim Anlegen ein absoluter oder ein relativer Pfad als Ziel hinterlegt wurde
* Wurde der Link mit einem absoluten Zielpfad angelegt, bleibt er auch nach einem mv des Links an eine andere Stelle gültig
* Wurde der Link dagegen mit einem relativen Zielpfad angelegt, wird dieser relative Pfad ab dem neuen Speicherort des Links neu ausgewertet ; dadurch kann beim Verschieben ein Broken Link entstehen

* Harte Links (Hardlinks):
* (!) Ein Hardlink ist lediglich ein weiterer Verzeichniseintrag für eine bereits existierende Datei
* (!) belegt keine eigene (neue) Inode, sondern verweist auf dieselbe Inode wie die Originaldatei
* (!) belegt dadurch auch keinen zusätzlichen Speicherplatz für die Dateiinhalte
* (!) Hardlinks können NICHT auf Verzeichnisse angewendet werden, sondern nur auf (reguläre) Dateien
* (!) Hardlinks können nicht partitions-/dateisystemübergreifend eingesetzt werden (da Inode-Nummern nur innerhalb eines Dateisystems eindeutig sind)
* ln datei datei_hl : erstellt einen Hardlink
* stat datei_hl : zeigt genau wie bei "datei" eine reguläre Datei mit derselben Inode-Nummer an ; sichtbarer Unterschied ist nur der "Link Count" (Anzahl der Verzeichniseinträge, die auf diese Inode verweisen)
* find -inum 1049238 / 2>/dev/null : sucht (ab Root) nach allen Dateien mit dieser Inode-Nummer, um so alle Hardlinks zu einer Datei zu finden
* find -inum 1049238 / 2>/dev/null | xargs ls -li : zeigt zu den gefundenen Hardlinks direkt die Long-Listing-Infos inkl. Inode an
* (!) Wird bei einem Hardlink die Berechtigung geändert (z.B. mit chmod), ändert sich die Berechtigung automatisch bei allen anderen Hardlinks mit ; das liegt daran, dass alle Hardlinks dieselbe Inode (und damit dieselben Metadaten/Eigenschaften) referenzieren

Symbolischer Link : z.B. in /etc/rc.d, "S01dbus -> ../init.d/dbus" ist ein symbolischer Link für den Start
* steht dort "K..." statt "S...", handelt es sich um "Kill" (Stop-Link)

(Hinweis: In der Mitschrift von Tag 18 standen zum Thema Hardlink noch mehrere unvollständig abgebrochene Stichpunkte, z.B. "Es gibt keine ...", "Die Zieldatei ..." und "Ein Hardlink ..." ; da der jeweilige Rest fehlt, wurden diese hier bewusst nicht übernommen bzw. ergänzt, um nichts zu erfinden.)*

104.7 Find system files and place files in the correct location


* Datei im System : in Linux ist alles eine Datei ; auch Geräte wie Laufwerke werden als Dateien angegeben
* eine Datei muss komplett in "ein" Dateisystem passen

* Linux Datei Typ:
* drwxr... : "d" = Directory
* -rwxr... : "-" = normale Datei
* crw... : character device ; zeichenweise (Byte für Byte) Übertragung, z.B. "tty"
* brw... : block device ; blockweise Übertragung

* / : Root, Verzeichnisse beginnen immer an der Wurzel mit "/", z.B. /boot
* Absoluter Pfad : z.B. /home/user1/a
* Relativer Pfad : z.B. a ; falls cwd (current working directory) = /home/user1

* /proc/bus/usb : zeigt (legacy) Infos zu angeschlossenen USB-Geräten über das Dateisystem an (auf moderneren Systemen eher über /sys abgebildet)

find /etc/rc* | grep sssd : sucht nach Dateien mit "sssd" (symbolische Links)
ls -l $(find rc* | grep sssd) : Beispiel

* FHS : Filesystem Hierarchy Standard ; Initiative/Vorgabe, damit ein einheitliches Verzeichnislayout für Admins und Entwickler gilt, u.a. auch damit sich Tools/Dateien leichter wiederfinden lassen
* (!) Für Linux gibt es eine zusätzliche Sektion, die Verzeichnisse enthält, die auf gewöhnlichen (anderen) Unix-Systemen nicht zu finden sind
* FHS-Kategorien (zwei unabhängige Einteilungsachsen):
* sharable : Verzeichnisse, die gleichzeitig von mehreren Systemen genutzt werden können, z.B. /usr und /opt
* unshareable : Verzeichnisse, die NICHT gemeinsam (zwischen mehreren Systemen) genutzt werden können, z.B. /etc oder /boot
* variable : Verzeichnisse, deren Datenbestand sich ständig ändert, z.B. /home und /var/mail
* static : Verzeichnisse, deren Inhalt sich kaum ändert, z.B. /boot und /opt
* (!) Statische Daten müssen nicht so oft gesichert (gebackupt) werden wie variable Daten

* echo Hallo > /dev/tty : gibt die Ausgabe direkt auf dem eigenen (aktuellen) Terminal aus

* Für Entwickler interessante Verzeichnisse (laut FHS):
* /usr/include : Header-Dateien für die Systembibliotheken
* /usr/src : Kernel- bzw. sonstiger Quellcode
* /var/spool/cron : Cron-bezogene Spool-Daten

* (!) Sowohl /home als auch /root sind laut FHS optional

* Beispiel, wie eine Anwendung ihre Dateien unter /opt ablegen könnte:
	/opt/anw
	/opt/anw/bin
	/opt/anw/etc
	/opt/anw/lib
Konfigurationsdateien können dabei die Endung .conffiles haben (Sammelbegriff für Konfigurationsdateien)
* (!) Der Ort für die Konfiguration ist laut FHS nicht strikt festgelegt : sie kann entweder unter /opt/... oder unter /etc/ liegen ; letztlich entscheidet das jeweilige Paket/der jeweilige Hersteller, wo die Konfigurationsdatei abgelegt wird

* locate : findet Dateien i.d.R. deutlich schneller als find, da die Suche nicht live im Dateisystem, sondern über eine vorab erstellte Datenbank erfolgt
* updatedb : aktualisiert diese Datenbank
* locate ssh : findet dank der Datenbank sehr schnell alle Treffer mit "ssh" im Namen
* (!) Die Datenbank kann (je nach Konfiguration) an unterschiedlichen Orten liegen
* /etc/updatedb.conf : Konfigurationsdatei von updatedb
* PRUNEPATHS : legt fest, in welchen Pfaden updatedb NICHT sucht
* NETPATHS : betrifft Netzwerkpfade (in der Mitschrift nicht näher ausgeführt)
* (!) locate/updatedb ist nicht Teil der Standard-Grundinstallation und muss in der Regel nachinstalliert werden

---

Exam 102-500



105 – Shells, Scripting and Data Management



105.1 Customize and use the shell environment


* Shell-Konfigurationsdateien:
* für alle User: /etc/profile (Dateien beginnen nicht mit einem Punkt) ; wird von jedem durchlaufen, der sich einloggt
* eigene: ~/.bash_profile (beginnt mit einem Punkt, liegt im Heimatverzeichnis) ; Personalisierung der Shell
* /etc/profile.d/bash_completion.sh : wird beim Login durchlaufen
* /etc/bash.bashrc : systemweite bash.rc für systemweite Shells ; wird beim Login durchlaufen
* /etc/bashrc : wird immer durchlaufen, wenn eine (neue) Bash geöffnet wird ; auf Fedora heißt die Datei ebenfalls /etc/bashrc
* (!) Widerspruch in den Mitschriften : in der Aufzeichnung von Tag 18 steht dazu (ohne weitere Details), die systemweite bashrc-Datei heiße "auf Fedora und Debian unterschiedlich" ; das widerspricht der obigen, ursprünglichen Notiz ("auf Fedora heißt die Datei ebenfalls /etc/bashrc"). Da hierzu keine widerspruchsfreien Details vorliegen, bitte diesen Punkt anhand der Kursunterlagen noch einmal gegenprüfen.
* (!) Beim Login : wird zuerst /etc/bash.bashrc und danach /etc/profile durchlaufen
* (!) Bei einer Subshell : wird nur /etc/bash.bashrc durchlaufen
* bash --norc : startet die Bash, ohne die bashrc zu durchlaufen

* $PS1 : 1. Prompt (primäre Eingabeaufforderung)
* $HOME : eigenes Heimatverzeichnis, z.B. /home/user1

* History:
* history : zeigt die History an ; wird in ~/.bash_history im Heimatverzeichnis abgelegt ; Variable $HISTFILE
* history 5 : zeigt die letzten 5 Einträge
* $HISTFILESIZE : Anzahl der Kommandos, die dauerhaft (auf der Festplatte) in der History-Datei gespeichert werden, z.B. 1000
* $HISTSIZE : Anzahl der Kommandos, die für die aktuelle Terminal-Sitzung im RAM vorgehalten werden
* !! : ruft den letzten Befehl erneut auf
* !N (z.B. !512) : ruft den Befehl mit der entsprechenden Nummer aus der History auf
* !-4 : ruft den Befehl 4 Zeilen zurück auf
* !pw : ruft den letzten Befehl auf, der mit "pw" begonnen hat (z.B. pwd)
* !pi : ruft z.B. pidof als letzten dazu passenden Befehl auf
* !?ct : ruft den letzten Befehl auf, der die Zeichenfolge "ct" enthält
* !?dof : ruft ebenfalls den letzten Befehl mit "dof" auf, z.B. pidof ; mit "?" wird (wie bei !?ct) auch innerhalb des Befehlsnamens gesucht, nicht nur am Anfang
* history > history_08.04.txt : History-Befehle in Datei schreiben (siehe auch 103.1)

* [TAB][TAB] : zweimaliges Drücken der Tab-Taste zeigt mögliche Vervollständigungen/Optionen an

* (!) Shell merkt sich Befehle : Bash merkt sich (hasht) den Pfad bereits ausgeführter Befehle für eine gewisse Zeit im Speicher

* Shell-Variablen (Zuweisung und Anführungszeichen):
* VAR=ein Haus : funktioniert NICHT ; Leerzeichen ist in der Shell ein Trennzeichen ; es muss mit Anführungszeichen gearbeitet werden, z.B. VAR="ein Haus"
* VAR1="$VAR" : doppelte Anführungszeichen ; Variablensubstitution findet statt, $VAR wird ausgewertet
* VAR1='$VAR' : einfache Anführungszeichen ; keine Substitution, $VAR wird wörtlich (als String) ausgegeben
* echo \$VAR : Maskierung mit Backslash verhindert die Substitution
* unset VAR : löscht eine Variable

* Maskierung von Leerzeichen in Dateinamen:
* touch ein haus : legt zwei Dateien an ("ein" und "haus"), da das Leerzeichen als Trennzeichen wirkt
* rm ein haus : löscht entsprechend wieder diese zwei Dateien
* touch ein\ Haus : mit \ (Backslash + Leerzeichen) maskiert, dadurch wird "ein Haus" als eine einzelne Datei angelegt

* readonly : gibt die Readonly-Shell-Variablen aus ; es können auch eigene Readonly-Variablen definiert werden

105.2 Customize or write simple scripts


* Ein Shellscript wird typischerweise mit s.sh bezeichnet (Konvention, aber keine Pflicht)
* /usr/local/bin : hier legt man Skripte ab, die global (systemweit) zur Verfügung stehen sollen
* Positionsparameter in Skripten:
* set Param1 Param2 : setzt manuelle Positionsparameter im der Shell, danach abrufbar mit $1, $2, ...
* set -e : Bricht das Skript sofort ab, wenn ein Befehl fehlschlägt (Exit-Code ungleich 0)
* set -xv : Debugging (Fehlersuche) in Skripten ; "-v" = Verbose, "-x" = Trace (Ausführungspur) ; zeigt die Zeilen an, nachdem Variablen und Befehle ersetzt wurden, aber direkt bevor sie ausgeführt werden
* set +xv : schaltet das Debugging wieder aus
* set -o : zeigt alle eingestellten Optionen der Konsole an (nicht prüfungsrelevant)
* $0 : eigenes Skript
* $1, $2, ... : Parameter 1, 2, ...
* $# : Argument Count ; zählt $0 nicht mit
* \"$1\" : Maskierung der Parameter
* '$1' : macht daraus einen String (keine Substitution)
* echo $$ : Prozess-ID des Skripts/der Shell
* $@ : gibt alle übergebenen Argumente einzeln weiter ; in Anführungszeichen ("$@") bleibt dabei jedes Argument ein eigenes, separates Element
$ : gibt alle übergebenen Argumente als einen einzigen zusammengefügten String weiter
(!) Unquotiert verhalten sich $@ und $ identisch ; der Unterschied zeigt sich erst bei Verwendung in doppelten Anführungszeichen ("$@" vs. "$*")

106 – User Interfaces and Desktops


* gdm3 : (nicht LPIC-1 Stoff, nur erwähnt)
* cd /etc/gdm3 : hier können Einstellungen vorgenommen werden
* head custom.conf
* Beispiel-Einstellungen: AutomaticLoginEnable=false, AutomaticLogin=alfa (muss raus, wenn man mit systemd "isolate" arbeiten möchte)

107 – Administrative Tasks


(keine Notizen vorhanden)

108 – Essential System Services


(keine Notizen vorhanden)

109 – Networking Fundamentals


(keine Notizen vorhanden)

110 – Security


* /etc/passwd : in der Passwort-Spalte steht auf modernen Systemen üblicherweise nur noch ein "x" ; früher stand hier das (verschlüsselte) Passwort direkt in dieser Zeile, heute liegt es stattdessen in /etc/shadow

---

Sonstiges (nicht eindeutig zugeordnet)



* Shell :
* prüft selbst, wie sie mit Ordnern oder Dateien umgeht
* ausführbare Dateien werden mit exec ausgeführt

* df : disk free ; zeigt alle eingehängten Dateisysteme und die Speicherbelegung

* In Linux werden Textdateien immer mit \n (Newline) abgeschlossen

* alias ls : zeigt den Alias für ls an ; z.B. genutzt, um Farben aus dem Terminal-Output zu entfernen

* LPI-Registrierung:
* Registrieren bei LPI, dort anmelden
* Testcenter auswählen und prüfen (am besten auch anrufen, ob es das noch gibt)
* Voucher-Code kommt erst am Montag, dann bei LPI eintragen
* https://www.lpi.org
* https://home.pearsonvue.com

* Offene Punkte / zu klären:
* Welcher Kernel-Parameter unterdrückt Meldungen der meisten Boot-Meldungen? (offen)
* Swap = Abkürzung/Herkunft klären (offen)
* TODO: Unterschied logische Partition und primäre Partition genau ermitteln
* Kann ein Application Container mehrere verschiedene Container beinhalten? (offen, aus Tag 7 – im Gespräch als Frage aufgeworfen, aber nicht abschließend geklärt)
* perplexity.ai (Notiz ohne Kontext)

---