====== Snippets: Shell ====== [[:snippets:start|← Zurück zu :snippets:start]] ==== Kompatibilität ==== Sofern nicht anders gekennzeichnet: ^ Betriebssystem ^ Shell ^ | macOS & GNU/Linux | ''bash'' & ''zsh'' | ===== OpenSSH ===== * Neue Private-Keys als Typ ''ed25519'' generieren (Elliptic-Curve-Algorithmus, deshalb trotz kurzer Keys sicherer als ''rsa'' mit maximaler Länge) * Als Kommentar idealerweise ''user@hostname'' setzen, da dieser an den Public-Key angehängt wird und so ein Key auf einem Remote-System einfach einem Client zugeordnet werden kann. * [[https://man.archlinux.org/man/ssh-keygen.1|ssh-keygen(1) — ArchLinux manual page]] Für moderne Systeme mit OpenSSH kann mit folgendem Befehl ein sicherer Key erzeugt werden. Außer bei Embedded-Distributionen (OpenWRT verwendet z.B. einen minimalen SSH-Server mit weniger Features) hatte ich bisher keine Probleme mit dem folgenden Befehl: # ed25519-Key mit 100 statt 16 KDF-Runden (deutlich sicherer); Kommentar mit Brnutzer- und Hostname; leerem Passwort und ohne Nachfrage nach einem Dateinamen ssh-keygen \ -t ed25519 \ -a 100 \ -C "$USER@$(hostname -f)" \ -N "" \ -f ~/.ssh/id_ed25519 ===== journald/journalctl ===== * System-Log unter systemd-basierten GNU/Linux-Distributionen wie z.B. Debian oder ArchLinux * [[https://wiki.archlinux.org/title/Systemd/Journal|systemd/Journal - ArchWiki]] * [[https://man.archlinux.org/man/journalctl.1|journalctl(1) — ArchLinux manual page]] > Hinweis: Das systemweite Journal kann nur von ''root'' und Mitgliedern der Gruppe ''systemd-journal'' angezeigt werden. ==== Systemlog seit Mitternacht ==== Folgt dem Journal und zeigt neue Meldungen umgehend an. Es wird nicht automatisch ein Pager (z.B. ''less'') gestartet, stattdessen wird über den Puffer des Terminal-Emulators zurück gescrollt. journalctl \ --output=short-iso \ --no-hostname \ --since="$(date +%Y-%m-%d) 00:00:00" \ --no-pager \ --follow ==== Log seit Mitternacht für eine einzelne Unit ==== Wie das vorherige Beispiel, aber auf eine einzelne systemd-Unit beschränken, statt das gesamte System-Log anzuzeigen. * Die dazu gekommene Option ''--service='' akzeptiert jegliche Unit-Typen * Das Standard-Suffix ''.service'' muss dabei zwar nicht explizit genannt werden, ich persönlich bevorzuge aber den ganzen Unit-Namen, deshalb wird es hier genannt. journalctl \ --output=short-iso \ --no-hostname \ --since="$(date +%Y-%m-%d) 00:00:00" \ --no-pager \ --follow \ --unit=apache2.service ==== Unit-Log der aktuellen Stunde ==== Zeigt das Log einer Unit seit dem Beginn der aktuellen Stunde an. Gegenüber dem vorherigen Beispiel wurde nur die Option ''--since'' abgeändert, sodass die Stunde von ''date'' gesetzt wird, statt ''00''. * In der Praxis ist oft nicht mehr als die letzten 20-30 Minuten von Relevanz * Durch Weglassen der Option ''--unit'' kann stattdessen das gesamte System-Log angezeigt werden. journalctl \ --output=short-iso \ --no-hostname \ --since="$(date +%Y-%m-%d\ %H):00:00" \ --no-pager \ --follow \ --unit=NetworkManager.service ===== Textverarbeitung ===== **TODO: Einführungstext** ==== Einrückung ab der zweiten Zeile ==== Mit dem folgenden ''sed''-Befehl lässt sich jede Zeile eines Textes leicht einrücken: sed "s/^/ /" input.txt Aber was ist, wenn die Einrückung erst ab der zweiten Zeile erscheinen soll? Im folgenden Beispiel soll eine mehrzeilige Meldung in eine Logdatei geschrieben werden: Vor der ersten Zeile soll der Zeitstempel stehen, jede weitere Zeile soll mit Leerzeichen um die Länge des Zeitstempel-Prefix eingerückt werden. Dafür wird der Text von einem kleinen ''awk''-Skript verarbeitet, das abhängig von der Zeilennummer (in der Variable ''NR'' gespeichert) entweder die Original-Zeilr wieder ausgibt, oder eben mit einem Prefix. # Die zu loggende Nachricht msg="This is a message with multiple lines." # Zeitstempel und dessen Länge timestamp=$(date --iso-8601=seconds) timestamp_length=$(echo -n "$timestamp" | wc -c) # Der Prefix für alle Zeilen außer der ersten. # Enthält $timestamp_length mal ein Leerzeichen, plus vier weitere für die Klammern und Leerzeichen vor und nach dem Zeitstempel line_prefix=$(yes " " | head -$((timestamp_length + 4)) | tr -d "\n") # Der Zeitstempel ohne abschließenden Zeilenumbruch printf "[${timestamp}] " # Ausgabe der Nachricht $msg inklusive Prefix # Das awk-Skript prüft eine if-Klausel ob die Zeilennummer NR mindestens 2 ist, und gibt dann die ursprüngliche Zeile $0 mit einem Prefix aus, und falls nicht ohne den Prefix. # Lesbare Variante mit Zeilenumbrüchen und Einrückungen: echo "${msg}" | awk "{ if (NR >= 2) { print \"${line_prefix}\"$0; } else { print $0; } }" # Kompakte Variante in einer einzelnen Zeile: echo "${msg}" | awk "{ if (NR >= 2) { print \"${line_prefix}\"$0; } else { print $0;} }"