<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

 <title>Herr-Breier.de Blog</title>
 <link href="https://herr-breier.de/atom.xml" rel="self"/>
 <link href="https://herr-breier.de/"/>
 <updated>2025-12-16T21:16:47+00:00</updated>
 <id>https://herr-breier.de</id>
 <author>
   <name>David Breier</name>
   <email>david@herr-breier.de</email>
 </author>

 
 <entry>
   <title>Linux Basics - awk Grundlagen</title>
   <link href="https://herr-breier.de/2025/12/16/Linux-Basics-awk/"/>
   <updated>2025-12-16T00:00:00+00:00</updated>
   <id>https://herr-breier.de/2025/12/16/Linux-Basics-awk</id>
   <content type="html">&lt;h1 id=&quot;awk---ein-mächtiges-linuxtool-zur-verarbeitung-von-textdaten&quot;&gt;awk - ein mächtiges Linuxtool zur Verarbeitung von Textdaten&lt;/h1&gt;

&lt;p&gt;Das Programm &lt;strong&gt;&lt;em&gt;awk&lt;/em&gt;&lt;/strong&gt; wurde in den 1970er Jahren bei den Bell Labs entwickelt und ist also schon etwas älter. Der Name des Programms leitet sich dabei von den Namen der drei Entwickler &lt;strong&gt;A&lt;/strong&gt;ho, &lt;strong&gt;W&lt;/strong&gt;einberger und &lt;strong&gt;K&lt;/strong&gt;ernighan ab. Das Programm selber wurde entwickelt um strukturierte Daten aus Dateien auszulesen und anderweitig auszugeben, beispielsweise zur Erstellung von Reports.
Dabei ist &lt;em&gt;awk&lt;/em&gt; mittlerweile so komplex dass es rein formal eine vollwertige Programmiersprache darstellt, das keyword hier ist &lt;em&gt;formal&lt;/em&gt; denn obwohl man prinzipiell mit awk Programme schreiben könnte ist das tool nicht dafür ausgelegt und awk Programme sind eher als Kuriosität zu betrachten.
Da awk mittlerweile ein paar Jahre auf dem Buckel hat, wird das ursprüngliche Programm heute eigentlich nicht mehr verwendet, sondern die meisten Linux Distributionen bringen Weiterentwicklungen von awk mit wie bspw. &lt;a href=&quot;https://www.gnu.org/software/gawk/,&quot;&gt;gawk&lt;/a&gt;, &lt;a href=&quot;https://invisible-island.net/mawk/&quot;&gt;mawk&lt;/a&gt; oder &lt;a href=&quot;https://linux.die.net/man/1/nawk&quot;&gt;nawk&lt;/a&gt;. Diese sind in der Regel alle miteinander kompatibel, erweitern aber das Grundprogramm um eine Reihe von Funktionen, short cuts und &lt;em&gt;quality-of-life&lt;/em&gt; Verbesserungen.&lt;/p&gt;

&lt;h2 id=&quot;warum-sollte-ich-awk-verwenden&quot;&gt;Warum sollte ich awk verwenden?&lt;/h2&gt;

&lt;p&gt;Egal wie man es dreht und wendet, awk ist schon ein wenig angestaubt aufgrund seines Alters. Trotzdem ist awk ein unglaublich starkes tool - sofern man sich innerhalb der Grenzen seines Einsatzbereiches bewegt. Sprachen wie &lt;em&gt;Perl&lt;/em&gt; oder &lt;em&gt;Python&lt;/em&gt; sind mit Sicherheit vielseitiger, aber wenn man “nur” Daten bspw. aus einer Log-Datei extrahieren möchte ist awk eines der besten tools die man nutzen kann da die Skripte relativ kurz sind (oft nur 1-2 Zeilen lang) und awk wesentlich schneller arbeitet als beispielsweise ein Python Skript. Ebenfalls eignet sich awk laut meiner Erfahrung ganz wunderbar zur Formatierung von Output, beispielsweise wenn man das Ergebnis einer SQL Abfrage ein wenig umformatieren und aufhübschen möchte. Ein weiterer Faktor den man nicht unterschätzen darf ist die Tatsache dass awk in praktisch jeder Linux Distribution mitgeliefert wird und man nicht erst noch weitere Softwarepakete installieren muss.&lt;/p&gt;

&lt;p&gt;Ein Awk-Programm besteht aus einer Reihe von &lt;strong&gt;Muster-Aktion Paaren&lt;/strong&gt;. Das bedeutet, dass awk eine oder mehrere
Dateien zeilenweise durchsucht und mit dem vorgegebenen Muster abgleicht. Wird eine passende Zeile gefunden,
so wird die zugewiesene Aktion durchgeführt. Muster können hier beispielsweise durch regular expressions, Vergleichsoperationen auf Zahlen, Zeichenketten, Feldern, Variablen usw. vorgegeben sein.&lt;/p&gt;

&lt;p&gt;Awk bietet also durchaus die Möglichkeit auch komplexere Skripte zu schreiben.&lt;/p&gt;

&lt;h2 id=&quot;arbeitsweise-und-syntax-von-awk&quot;&gt;Arbeitsweise und Syntax von awk&lt;/h2&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;awk&lt;/code&gt; arbeitet indem es Daten &lt;strong&gt;zeilenweise&lt;/strong&gt; einliest und anhand eines vorgegebenen &lt;strong&gt;Delimiters &lt;sup id=&quot;fnref:1&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:1&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; in Felder zerlegt&lt;/strong&gt; und diese dann ausgibt. Die Funktionsweise ist &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sed&lt;/code&gt; sehr ähnlich, aber erlaubt wesentlich komplexere Konstrukte.&lt;/p&gt;

&lt;p&gt;Ein typischer awk Aufruf könnte beispielsweise so aussehen:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;awk&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;MUSTER { AKTION }&apos;&lt;/span&gt; dateiname.txt
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Dabei erfolgt der Aufruf von awk mittels des Programmnamens &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;awk&lt;/code&gt;, einem sogenannten &lt;strong&gt;Muster-Aktionen-Paar&lt;/strong&gt; und (in aller Regel) einer Datei auf welche die Operationen angewendet werden sollen (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;awk&lt;/code&gt; kann aber natürlich auch mit Daten aus einem Eingabestrom zurechtkommen).&lt;/p&gt;

&lt;h3 id=&quot;der-delimiter-feld-separator&quot;&gt;Der Delimiter (Feld-Separator)&lt;/h3&gt;

&lt;p&gt;Standardmäßig verwendet AWK &lt;strong&gt;einen oder mehrere aufeinanderfolgende Leerzeichen oder Tabs&lt;/strong&gt; als Feld-Separator.&lt;/p&gt;

&lt;p&gt;Man kann den Separator (Delimiter) jedoch frei bestimmen, was für die Analyse von Log-Dateien, die oft durch Doppelpunkte, Kommas oder Semikola getrennt sind, essenziell ist.&lt;/p&gt;

&lt;p&gt;Der Feld-Separator wird mit der Option &lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-F&lt;/code&gt;&lt;/strong&gt; definiert:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# Trennt die Eingabe am Doppelpunkt&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;awk&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-F&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;:&apos;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;{ print $1 }&apos;&lt;/span&gt; /etc/passwd
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Hierbei steht $1 für das erste Feld (Spalte), $2 für das zweite, und so weiter.&lt;/p&gt;

&lt;h2 id=&quot;muster-aktionen-paare-im-detail&quot;&gt;Muster-Aktionen-Paare im Detail&lt;/h2&gt;

&lt;p&gt;Wie bereits erwähnt, besteht ein AWK-Programm aus &lt;strong&gt;Muster-Aktionen-Paaren&lt;/strong&gt;. Eine &lt;strong&gt;Aktion&lt;/strong&gt; wird nur ausgeführt, wenn das &lt;strong&gt;Muster&lt;/strong&gt; für die aktuelle Zeile zutrifft. Fehlt das Muster, wird die Aktion auf jede Zeile angewendet. Fehlt die Aktion, wird die gesamte Zeile (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;print $0&lt;/code&gt;) ausgegeben, wenn das Muster zutrifft.&lt;/p&gt;

&lt;h3 id=&quot;1-muster-reguläre-ausdrücke-regex&quot;&gt;1. Muster: Reguläre Ausdrücke (RegEx)&lt;/h3&gt;

&lt;p&gt;Die gebräuchlichste Form des Musters ist der &lt;strong&gt;reguläre Ausdruck&lt;/strong&gt;. Er wird von Schrägstrichen (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/&lt;/code&gt;) umschlossen.&lt;/p&gt;

&lt;h4 id=&quot;beispiel-fehlermeldungen-filtern&quot;&gt;Beispiel: Fehlermeldungen filtern&lt;/h4&gt;

&lt;p&gt;Wenn Ihr eine Log-Datei nach Zeilen durchsuchen möchtet, die das Wort &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;error&lt;/code&gt; enthalten, nutzt Ihr einen regulären Ausdruck:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# Durchsucht die gesamte Zeile ($0) nach dem Muster &apos;error&apos;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;awk&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;/error/ { print $0 }&apos;&lt;/span&gt; logfile.txt
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Da die Aktion die Standardaktion (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;print $0&lt;/code&gt;) ist, kann man diese sogar weglassen:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;awk&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;/error/&apos;&lt;/span&gt; logfile.txt
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;2-muster-vergleichsoperationen-auf-feldern&quot;&gt;2. Muster: Vergleichsoperationen auf Feldern&lt;/h3&gt;

&lt;p&gt;Hier wird eine Bedingung für den Inhalt oder Wert eines bestimmten Feldes gestellt.&lt;/p&gt;

&lt;h4 id=&quot;beispiel-http-status-codes-filtern&quot;&gt;&lt;strong&gt;Beispiel: HTTP-Status-Codes filtern&lt;/strong&gt;&lt;/h4&gt;

&lt;p&gt;Um alle Zeilen aus der &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;access.log&lt;/code&gt; zu finden, bei denen der HTTP-Status-Code (Feld 9) gleich &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;404&lt;/code&gt; ist, verwendet Ihr einen numerischen Vergleich:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# Zeigt alle Zeilen mit einem 404-Fehler&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;awk&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;$9 == 404 { print $0 }&apos;&lt;/span&gt; access.log
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;3-muster-begin-und-end&quot;&gt;3. Muster: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BEGIN&lt;/code&gt; und &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;END&lt;/code&gt;&lt;/h3&gt;

&lt;p&gt;Diese beiden Muster sind bspw. für die Erstellung von Reports interessant, da sie &lt;strong&gt;Aktionen vor der eigentlichen Verarbeitung&lt;/strong&gt; und &lt;strong&gt;nach Abschluss der Verarbeitung&lt;/strong&gt; definieren. Dadurch kann man beispielsweise einer Auswertung eine Kopf- und Fußzeile hinzufügen:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;awk&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;
BEGIN {

    # Setzt den Output Field Separator (OFS) für schönere Ausgabe

​    OFS=&quot;\t&quot;

    # Gibt den Header aus

​    print &quot;--- Start des Reports ---&quot;
​    print &quot;IP\tStatus\tLetztes Feld&quot;
​    print &quot;-------------------------&quot;
}
{

    # Hauptaktion: Wird auf jede Zeile angewendet

​    print $1, $9, $NF
}
END {

    # Gibt die Fußzeile aus und meldet, wie viele Zeilen verarbeitet wurden

​    print &quot;-------------------------&quot;
​    print &quot;Ende des Reports. Verarbeitete Zeilen: &quot; NR
}&apos;&lt;/span&gt; access.log
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;felder-und-variablen&quot;&gt;Felder und Variablen&lt;/h3&gt;

&lt;p&gt;AWK definiert beim Einlesen jeder Zeile automatisch einige spezielle Variablen:&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;&lt;strong&gt;Variable&lt;/strong&gt;&lt;/th&gt;
      &lt;th&gt;&lt;strong&gt;Beschreibung&lt;/strong&gt;&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$0&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;Die &lt;strong&gt;komplette&lt;/strong&gt; eingelesene Zeile.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$1&lt;/code&gt;&lt;/strong&gt;, &lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$2&lt;/code&gt;&lt;/strong&gt;, &lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$N&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;Das erste, zweite oder &lt;strong&gt;N-te Feld&lt;/strong&gt; (die N-te Spalte).&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NF&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;Die &lt;strong&gt;Anzahl der Felder&lt;/strong&gt; in der aktuellen Zeile (&lt;em&gt;Number of Fields&lt;/em&gt;).&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NR&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;Die &lt;strong&gt;Zeilennummer&lt;/strong&gt; der aktuellen Zeile (&lt;em&gt;Number of the Record&lt;/em&gt;).&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FS&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;Der &lt;strong&gt;Feld-Separator&lt;/strong&gt; (&lt;em&gt;Field Separator&lt;/em&gt;). Kann mit &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-F&lt;/code&gt; überschrieben werden.&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;h4 id=&quot;beispiel-felder-filtern-und-ausgeben&quot;&gt;&lt;strong&gt;Beispiel: Felder filtern und ausgeben&lt;/strong&gt;&lt;/h4&gt;

&lt;p&gt;Angenommen, Sie haben eine Log-Datei (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;access.log&lt;/code&gt;) mit Leerzeichen als Separator, und Sie möchten nur die IP-Adresse (Feld 1) und den HTTP-Status-Code (Feld 9) ausgeben.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# Access.log: 192.168.1.1 - [10/Feb/2023:10:00:00] &quot;GET /index.html&quot; 200 ...&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;awk&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;{ print &quot;IP: &quot; $1, &quot; | Status: &quot; $9 }&apos;&lt;/span&gt; access.log
&lt;span class=&quot;c&quot;&gt;# Ausgabe: IP: 192.168.1.1 | Status: 200&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;beispiel-das-letzte-feld-ausgeben&quot;&gt;&lt;strong&gt;Beispiel: Das letzte Feld ausgeben&lt;/strong&gt;&lt;/h4&gt;

&lt;p&gt;In manchen Log-Dateien ändert sich die Anzahl der Felder. Um immer das letzte Feld auszugeben (z.B. eine Fehlermeldung), nutzt man die Variable &lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NF&lt;/code&gt;&lt;/strong&gt;:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# Gibt immer das letzte Feld der Zeile aus&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;awk&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;{ print $NF }&apos;&lt;/span&gt; logfile.txt
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;sed-und-awk-arbeiten-wunderbar-zusammen&quot;&gt;sed und awk arbeiten wunderbar zusammen&lt;/h2&gt;

&lt;p&gt;Man kann &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;awk&lt;/code&gt; sehr gut mit &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sed&lt;/code&gt; kombinieren. Anbei ein paar Beispiele. Eine kurze &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sed&lt;/code&gt; Einführung gibt es im &lt;a href=&quot;/2023/01/20/Linux-Basics-sed/&quot;&gt;Artikel zu sed&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;weitere-informationen&quot;&gt;Weitere Informationen&lt;/h2&gt;

&lt;p&gt;Dieser Artikel kann und soll nur einen groben Überblick geben. Umfangreichere Informationen und eine ganze Liste der vordefinierten Variablen, Parameter etc. findet man entweder lokal in den &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;man&lt;/code&gt; und &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;info&lt;/code&gt; pages oder aber &lt;a href=&quot;https://www.gnu.org/software/gawk/manual/&quot;&gt;online&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Als refresher: die man pages ruft man auf über &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;man awk&lt;/code&gt; und die info pages über &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;info awk&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Als einfache und gute Alternative kann ich hier allerdings noch das Tool &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tldr&lt;/code&gt; empfehlen, über das ebenfalls nochmal ein Artikel folgen wird.&lt;/p&gt;

&lt;h2 id=&quot;fußnoten&quot;&gt;Fußnoten&lt;/h2&gt;

&lt;div class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
  &lt;ol&gt;
    &lt;li id=&quot;fn:1&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;Ein Delimiter kann beispielsweise ein Leerzeichen, Tab, Doppelpunkt, Komma o.ä. sein und in awk frei bestimmt werden. &lt;a href=&quot;#fnref:1&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;
</content>
 </entry>
 
 <entry>
   <title>Karakeep als Alternative zu Pocket</title>
   <link href="https://herr-breier.de/2025/06/08/Karakeep_eine_Alternative_zu_Pocket/"/>
   <updated>2025-06-08T00:00:00+00:00</updated>
   <id>https://herr-breier.de/2025/06/08/Karakeep_eine_Alternative_zu_Pocket</id>
   <content type="html">&lt;h1 id=&quot;vorwort&quot;&gt;Vorwort&lt;/h1&gt;

&lt;p&gt;&lt;a href=&quot;https://support.mozilla.org/de/kb/Zukunft-von-Pocket&quot;&gt;Pocket wird Anfang Juli ‘25 abgeschaltet&lt;/a&gt; und im Oktober wird kurzer Prozess gemacht und die Konten werden gelöscht, also brauchen wir eine Alternative. Am besten selbstgehostet und open source. Nach etwas herumsuchen bin ich bei Karakeep gelandet, es gibt aber zum Glück eine ganze Batterie an Alternativen:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://karakeep.app/&quot;&gt;Karakeep&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/omnivore-app/omnivore&quot;&gt;Omnivore&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://grimoire.pro/&quot;&gt;Grimoire&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://wallabag.org/&quot;&gt;Wallabag&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://readeck.org/en/&quot;&gt;Readeck&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;und das sind nur ein paar der Optionen.&lt;/p&gt;

&lt;p&gt;Schlussendlich hatte ich bei meiner kurzen Recherche den Eindruck dass Karakeep (&lt;a href=&quot;https://youtu.be/TDWombBvK8c&quot;&gt;vormals Hoarder&lt;/a&gt;) und Wallabag den besten Eindruck machen. Beide verfügen über eine solide UI, Extensions für die gängigen Browser und mobile Apps für unterwegs.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/pictures/homepage-eaef57c6d48f2e5ddf6720b1d483a995.png&quot; alt=&quot;Homepage&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Karakeep wirbt zusätzlich noch mit einer AI Integration von Ollama oder ChatGPT für automatisches Tagging, Video Transcription, OCR usw. Da ich gerade mit einer ChatGPT Plus Membership experimentiere bin ich deshalb erst einmal bei Karakeep gelandet.&lt;/p&gt;

&lt;h1 id=&quot;administration&quot;&gt;Administration&lt;/h1&gt;

&lt;h2 id=&quot;installation&quot;&gt;Installation&lt;/h2&gt;

&lt;p&gt;Die Installation gestaltet sich dank Docker Compose sehr einfach:&lt;/p&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;na&quot;&gt;services&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;Karakeep&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;ghcr.io/karakeep-app/karakeep:${KARAKEEP_VERSION:-release}&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;restart&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;unless-stopped&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;volumes&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;c1&quot;&gt;# By default, the data is stored in a docker volume called &quot;data&quot;.&lt;/span&gt;
      &lt;span class=&quot;c1&quot;&gt;# If you want to mount a custom directory, change the volume mapping to:&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;/dein/lokaler/Datenordner:/data&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;#mappt lokales Filesystem auf den /data Ordner im Container&lt;/span&gt;
      &lt;span class=&quot;c1&quot;&gt;#- data:/data&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;ports&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;3000:3000&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# Port außen:Port im Container&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;environment&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;NEXTAUTH_SECRET&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# hier zufälliger Key -&amp;gt; bspw. generieren über: openssl rand -base64 36&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;MEILI_ADDR&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;http://meilisearch:7700&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;BROWSER_WEB_URL&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;http://chrome:9222&lt;/span&gt;
      &lt;span class=&quot;c1&quot;&gt;# OPENAI_API_KEY: ...&lt;/span&gt;

      &lt;span class=&quot;c1&quot;&gt;# You almost never want to change the value of the DATA_DIR variable.&lt;/span&gt;
      &lt;span class=&quot;c1&quot;&gt;# If you want to mount a custom directory, change the volume mapping above instead.&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;DATA_DIR&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;/data&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# DON&apos;T CHANGE THIS&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;chrome&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;gcr.io/zenika-hub/alpine-chrome:123&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;restart&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;unless-stopped&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;command&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;--no-sandbox&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;--disable-gpu&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;--disable-dev-shm-usage&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;--remote-debugging-address=0.0.0.0&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;--remote-debugging-port=9222&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;--hide-scrollbars&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;meilisearch&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;getmeili/meilisearch:v1.13.3&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;restart&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;unless-stopped&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;environment&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;MEILI_NO_ANALYTICS&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;true&quot;&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;MEILI_MASTER_KEY&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# hier zufälliger Key -&amp;gt; bspw. generieren über: openssl rand -base64 36&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;volumes&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;meilisearch:/meili_data&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;volumes&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;meilisearch&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;null&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;null&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;networks&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;nginx-net&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;external&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;true&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Das ist erstmal die Basiskonfiguration laut &lt;a href=&quot;https://docs.karakeep.app/Installation/docker&quot;&gt;Anleitung bei Karakeep&lt;/a&gt;. &lt;em&gt;Zu beachten fand ich hierbei dass man einmal selbst die Auth-Keys generieren muss mit denen NextAuth und MeiliSearch arbeiten.&lt;/em&gt; Das geht aber ganz einfach aus der Kommandozeile mit dem Befehl:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;openssl rand -base64 36&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Was mich aber eine Weile zur Verzweiflung getrieben hat war dass ich ständig eine Exception bekommen habe beim Aufruf der Applikation. Am Ende hat sich herausgestellt dass ich, weil ich mit Docker Compose über Dockge die Container starte, &lt;em&gt;die Einträge für die beiden Keys direkt wie oben angegeben als environment Variablen in der docker-compose.yml übergeben musste&lt;/em&gt;. Den separaten Eintrag aus dem .env file will entweder Dockge oder Docker Compose in diesem Fall nicht korrekt verarbeiten.&lt;/p&gt;

&lt;p&gt;Apropos env File:&lt;/p&gt;

&lt;h2 id=&quot;environment-variablen&quot;&gt;Environment Variablen&lt;/h2&gt;

&lt;p&gt;Das .env File sollte laut Anleitung folgende Standard Variablen enthalten:&lt;/p&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;s&quot;&gt;KARAKEEP_VERSION=release&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;NEXTAUTH_SECRET=super_random_string&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;MEILI_MASTER_KEY=another_random_string&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;NEXTAUTH_URL=http://localhost:3000&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# falls ihr eine Subdomain habt kommt die hier rein&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;eine ausführliche Liste mit Variablen, bspw. zur Integration von OpenAI findet sich hier. Nachfolgend die Variablen die ich angepasst habe:&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Name&lt;/th&gt;
      &lt;th&gt;Funktion&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;OPENAI_API_KEY&lt;/td&gt;
      &lt;td&gt;Euer OpenAI Api Key, näheres zur Einrichtung weiter unten&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;INFERENCE_LANG&lt;/td&gt;
      &lt;td&gt;Die Sprache mit der Tags generiert werden, Standard ist englisch&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;INFERENCE_CONTEXT_LENGTH: 2048&lt;/td&gt;
      &lt;td&gt;Abhängig dieser Tokenlänge wird der Text mit AI gecrawled um die Tags zu erstellen. Längerer Text bedeutet besseres Ergebnis aber ggf. auch teurer bzw. benötigt mehr Rechenleistung&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;CRAWLER_FULL_PAGE_SCREENSHOT: True&lt;/td&gt;
      &lt;td&gt;versucht einen kompletten Screenshot der Seite anzulegen, verbraucht naturgemäß mehr Speicher&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;CRAWLER_VIDEO_DOWNLOAD: True&lt;/td&gt;
      &lt;td&gt;Versucht bspw. YouTube Videos herunterzuladen. Benutzt im Hintergrund &lt;a href=&quot;https://github.com/yt-dlp/yt-dlp&quot;&gt;yt-dlp&lt;/a&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;CRAWLER_VIDEO_DOWNLOAD_MAX_SIZE: 100&lt;/td&gt;
      &lt;td&gt;Setzt die max. Größe des runtergeladenen Videos, Qualität wird entsprechend angepasst&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;OCR_LANGS: deu,eng,equ,fra,spa&lt;/td&gt;
      &lt;td&gt;Setzt die Sprachen für OCR. equ setzt die Erkennung für math. Formeln! Benutzt im Hintergrund &lt;a href=&quot;https://github.com/tesseract-ocr/tesseract&quot;&gt;Tesseract&lt;/a&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;MAX_ASSET_SIZE_MB: 100&lt;/td&gt;
      &lt;td&gt;Setzt die max. Asset Size. Standard sind 4MB was mit der SingleFile Extension s.u. zu wenig ist&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;h2 id=&quot;openai-api-key-erstellen&quot;&gt;OpenAI Api Key erstellen&lt;/h2&gt;

&lt;p&gt;Damit Karakeep auf die OpenAI API zugreifen kann benötigt man einen API-Key. Diesen kann man im &lt;em&gt;OpenAI Dashboard&lt;/em&gt; in seinem Account erstellen:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/pictures/image-20250608020519006.png&quot; alt=&quot;image-20250608020519006&quot; style=&quot;zoom:50%;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Diesen Key direkt kopieren, &lt;em&gt;er wird nur einmal angezeigt&lt;/em&gt;. Danach dann den Key in die &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;OPENAI_API_KEY&lt;/code&gt; Variable eintragen.&lt;/p&gt;

&lt;h2 id=&quot;container-starten-reverse-proxy-konfigurieren-und-andere-arbeiten&quot;&gt;Container starten, Reverse Proxy konfigurieren und andere Arbeiten&lt;/h2&gt;

&lt;p&gt;Im Anschluss, abhängig von eurer Konfiguration müsst ihr den Karakeep Hauptcontainer starten und noch in euer Container-Netzwerk einbinden. Ich habe hier ein eigenes Netz für einen NGINX Proxy Manager eingerichtet der sich um die Zertifikate kümmert und Anfragen an die Subdomain weiterleitet die ich für Karakeep eingerichtet habe. Betreibt ihr Karakeep lokal sollte es einfach über &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;http://localhost:3000&lt;/code&gt; erreichbar sein.&lt;/p&gt;

&lt;p&gt;In meinem Fall sah der weitere Workflow so aus:&lt;/p&gt;

&lt;h3 id=&quot;container-starten&quot;&gt;Container starten&lt;/h3&gt;

&lt;p&gt;läuft in meinem Fall über die Dockge WebUi, ansonsten über&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;docker compose up -d&lt;/code&gt;&lt;/p&gt;

&lt;h3 id=&quot;checken-ob-die-container-hochgekommen-sind&quot;&gt;checken ob die Container hochgekommen sind&lt;/h3&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;docker ps|grep kara&lt;/code&gt;&lt;/p&gt;

&lt;h3 id=&quot;falls-kein-docker-netzwerk-vorhanden-eins-anlegen&quot;&gt;Falls kein Docker Netzwerk vorhanden, eins anlegen&lt;/h3&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;docker network create nginx-net&lt;/code&gt;&lt;/p&gt;

&lt;h3 id=&quot;container-in-das-netzwerk-hängen&quot;&gt;Container in das Netzwerk hängen&lt;/h3&gt;

&lt;p&gt;Es sollte mehrere Karakeep Container geben, ihr braucht den Hauptcontainer der auf dem in der Compose Datei festgelegten Ports antwortet. Den Namen könnt ihr aus dem Ergebnis des &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;docker ps&lt;/code&gt; Befehls kopieren:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;docker network connect &amp;lt;Netzwerkname&amp;gt; &amp;lt;Containername&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;h3 id=&quot;checken-ob-der-container-im-docker-netzwerk-hängt&quot;&gt;checken ob der Container im Docker Netzwerk hängt&lt;/h3&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;docker network inspect &amp;lt;Netzwerkname&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;h1 id=&quot;login-und-usage&quot;&gt;Login und Usage&lt;/h1&gt;

&lt;p&gt;Wenn alles geklappt hat können wir nun die Karakeep Login Seite entweder über &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;localhost:3000&lt;/code&gt; oder den in eurem Reverse Proxy konfigurierten Link erreichen:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/pictures/image-20250608035733256.png&quot; alt=&quot;Karakeep Login Page&quot; style=&quot;zoom:50%;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Beim ersten Login/Sign Up &lt;em&gt;wird automatisch ein Admin Benutzer angelegt&lt;/em&gt;. Da&lt;/p&gt;

&lt;p&gt;Man kann nun entweder über das &lt;strong&gt;NEW ITEM&lt;/strong&gt; Feld einen Link, Notiz oder Screenshot einfügen oder direkt Webseiten über die Browser Extensions oder mobile Apps hinzufügen. Die Apps sind selbsterklärend und erwarten die URL für eure Karakeep Instanz und eure Zugangsdaten für euren Karakeep User.&lt;/p&gt;

&lt;h2 id=&quot;user-einstellungen&quot;&gt;User Einstellungen&lt;/h2&gt;

&lt;p&gt;In den User Einstellungen kann man dann weitere Dinge konfigurieren wie RSS Feeds die gecrawled werden sollen, Prompts für die AI Zusammenfassung von Texten usw. Die User Settings erreicht ihr über das Menü rechts oben:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/pictures/image-20250608040523319.png&quot; alt=&quot;User Settings&quot; style=&quot;zoom:50%;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Hier kann man dann alles von AI über Webhooks, RSS Feeds oder auch Imports aus anderen Tools wie Omnivore, Pocket, Linkwarden usw. durchführen oder auch API Keys generieren. Wir werden einen API Key im nächsten Teil benötigen, also könnt ihr auch direkt einen anlegen.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/pictures/image-20250608040818381.png&quot; alt=&quot;User Settings Detailansicht&quot; style=&quot;zoom:50%;&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;einträge-bearbeiten&quot;&gt;Einträge bearbeiten&lt;/h2&gt;

&lt;p&gt;Einzelne Einträge sehen so aus:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/pictures/image-20250608042306182.png&quot; alt=&quot;image-20250608042306182&quot; style=&quot;zoom:50%;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Über die beiden Symbole rechts unten kann man entweder weitere Optionen über die &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;...&lt;/code&gt; anzeigen (bspw. einen neuen Crawl anstoßen, Eintrag archivieren, löschen…)&lt;/p&gt;

&lt;p&gt;Oder man kann den detaillierten Eintrag aufrufen über das maximieren Symbol. Hier findet man bspw. die Option Tags zu bearbeiten, findet einen Transcript zum Inhalt und kann sich auf Wunsch eine Zusammenfassung per AI einfügen lassen oder eigene Notizen schreiben:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/pictures/image-20250608042555196.png&quot; alt=&quot;Detailansicht Karakeep Eintrag&quot; style=&quot;zoom:50%;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Die Zusammenfassung mittels AI sieht dann bspw. so aus:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/pictures/image-20250608042732874.png&quot; alt=&quot;AI Summarization eines Eintrags&quot; style=&quot;zoom:50%;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Achtet nur darauf, dass dies ggf. OpenAI Tokens kostet und damit nicht kostenfrei ist. Ich beobachte mal wie teuer der ganze Spaß ist und poste dann einen Nachtrag in ein paar Wochen oder Monaten.&lt;/p&gt;

&lt;h1 id=&quot;einbinden-singlefile-extension-als-workaround-für-captcha-sites&quot;&gt;Einbinden SingleFile Extension als Workaround für Captcha Sites&lt;/h1&gt;

&lt;p&gt;Leider musste ich feststellen, dass Seiten die durch CAPTCHAS gesichert sind nicht so einfach mit Karakeep funktionieren (was technisch natürlich auch so gewollt ist). Ein &lt;strong&gt;Workaround&lt;/strong&gt; ist momentan die Verwendung der SingleFile Extension als Browser Extension für Firefox oder Chrome. Diese Extension erlaubt es eine ganze Website als html Datei zu speichern. Karakeep erlaubt es dann diese Seite als Asset hochzuladen und zu verarbeiten.&lt;/p&gt;

&lt;p&gt;Momentan funktioniert diese Lösung nur mit dem aktuellen Nightly Release, soll aber mit in das nächste Release einfließen. Deshalb verweise ich hier nur auf die &lt;a href=&quot;https://docs.karakeep.app/next/Guides/singlefile/&quot;&gt;Anleitung bei Karakeep&lt;/a&gt; selbst, da sich natürlich noch einiges ändern kann und nicht jeder den instabilen Nightly Build verwenden möchte.&lt;/p&gt;

&lt;p&gt;Hier die momentane Anleitung in Stichpunkten:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Installiere die &lt;a href=&quot;https://github.com/gildas-lormeau/SingleFile&quot;&gt;SingleFile extension&lt;/a&gt;.&lt;/li&gt;
  &lt;li&gt;In den Einstellungen der Extension auswählen &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Destinations&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;Wähle &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;upload to a REST Form API&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;Bei der URL folgendes eintragen: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;https://YOUR_SERVER_ADDRESS/api/v1/bookmarks/singlefile&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;Beim &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;authorization token&lt;/code&gt; den API Token eintragen den ihr euch in den User Settings von Karakeep generiert habt&lt;/li&gt;
  &lt;li&gt;Das&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;data field name&lt;/code&gt; auf&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;file&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;Das&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;URL field name&lt;/code&gt; auf &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;url&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;(Optional) Fügt &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;amp;ifexists=MODE&lt;/code&gt; zum URL Feld hinzu MODE entspricht einem der Werte: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;skip&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;overwrite&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;overwrite-recrawl&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;append&lt;/code&gt;, oder &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;append-recrawl&lt;/code&gt;. Bei mir steht dies gerade auf &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;overwrite&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Man sollte außerdem noch die &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MAX_ASSET_SIZE_MB: 100&lt;/code&gt; in den ENV Variablen setzen. Standard ist 4MB und das könnte zu wenig sein, da die gerippten Seiten ggf. relativ groß werden&lt;/li&gt;
&lt;/ol&gt;

</content>
 </entry>
 
 <entry>
   <title>Shorts - PIPESTATUS</title>
   <link href="https://herr-breier.de/2025/03/04/shorts-pipestatus/"/>
   <updated>2025-03-04T00:00:00+00:00</updated>
   <id>https://herr-breier.de/2025/03/04/shorts-pipestatus</id>
   <content type="html">&lt;h1 id=&quot;shorts---pipestatus-um-die-fehlercodes-verketteter-befehle-auszugeben&quot;&gt;Shorts - PIPESTATUS um die Fehlercodes verketteter Befehle auszugeben&lt;/h1&gt;

&lt;h2 id=&quot;-gibt-nur-den-exit-code-des-letzten-befehls-aus&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$?&lt;/code&gt; gibt nur den Exit Code des letzten Befehls aus&lt;/h2&gt;

&lt;p&gt;Es kommt öfter vor dass man den Exit Status eines Befehls oder Scripts abrufen möchte. Dazu kann man bspw. die &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$?&lt;/code&gt; Variable verwenden wie in folgendem Beispiel:&lt;/p&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;#!/bin/bash&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;grep &lt;/span&gt;unbekannt.meineDomain.com /etc/hosts
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$?&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-ne&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;0&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;then
    &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Ich kann keinen Eintrag in der hosts Datei finden!&quot;&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;exit &lt;/span&gt;2
&lt;span class=&quot;k&quot;&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Die &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$?&lt;/code&gt; Variable gibt den Exit Code des letzten ausgeführten Befehls aus, in unserem Beispiel oben wird also in der if-Bedingung geprüft ob der Exit Code des vorigen Befehls ungleich (-ne) “0” ist (“0” bedeutet “success”, alles andere “fail”). Soweit, so gut.&lt;/p&gt;

&lt;p&gt;Was macht man aber wenn man bspw. eine Pipe hat, also mehrere Befehle aneinander kettet? Hier kann einem die PIPESTATUS Variable dienlich sein.&lt;/p&gt;

&lt;p&gt;Nehmen wir unser voriges Beispiel, aber pipen wir die Ausgabe von &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;grep&lt;/code&gt; in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tee&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;#!/bin/bash&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;grep &lt;/span&gt;unbekannt.meineDomain.com /etc/hosts 2&amp;gt;&amp;amp;1 | &lt;span class=&quot;nb&quot;&gt;tee&lt;/span&gt; /tmp/grep_results.txt
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$?&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-ne&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;0&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;then
    &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Ich kann keinen Eintrag in der hosts Datei finden!&quot;&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;exit &lt;/span&gt;2
&lt;span class=&quot;k&quot;&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;In diesem Fall würde &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$?&lt;/code&gt; den Exit Code von &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tee&lt;/code&gt; und nicht von &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;grep&lt;/code&gt; ausgeben.&lt;/p&gt;

&lt;p&gt;Visuell lässt sich das bspw. auch so darstellen, auch wenn das Beispiel konstruiert ist:&lt;/p&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;❯ &lt;span class=&quot;nb&quot;&gt;true&lt;/span&gt; | &lt;span class=&quot;nb&quot;&gt;false&lt;/span&gt; | &lt;span class=&quot;nb&quot;&gt;true&lt;/span&gt; | &lt;span class=&quot;nb&quot;&gt;false&lt;/span&gt; | &lt;span class=&quot;nb&quot;&gt;true&lt;/span&gt;
❯ &lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$?&lt;/span&gt;
0
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Die Befehle &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;true&lt;/code&gt; und &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;false&lt;/code&gt; machen genau das was drauf steht und geben “true” (also Exit Code 0) oder “false” (also einen Exit Code ungleich 0) aus. Wie man sieht gibt &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$?&lt;/code&gt; nur den Exit Code des letzten Befehls wieder, egal ob in unserer Pipe irgendwo etwas schiefgelaufen ist.&lt;/p&gt;

&lt;h2 id=&quot;pipestatus-speichert-als-array-variable-alle-zuletzt-gelaufenen-befehle&quot;&gt;PIPESTATUS speichert als Array Variable alle zuletzt gelaufenen Befehle&lt;/h2&gt;

&lt;p&gt;Wie in der Überschrift steht handelt es sich bei PIPESTATUS um eine Array Variable welche die Exit Codes unserer zuletzt ausgeführten Befehle:&lt;/p&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;❯ &lt;span class=&quot;nb&quot;&gt;true&lt;/span&gt; | &lt;span class=&quot;nb&quot;&gt;false&lt;/span&gt; | &lt;span class=&quot;nb&quot;&gt;true&lt;/span&gt; | &lt;span class=&quot;nb&quot;&gt;false&lt;/span&gt; | &lt;span class=&quot;nb&quot;&gt;true&lt;/span&gt;
❯ &lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$pipestatus&lt;/span&gt;
0 1 0 1 0
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;strong&gt;Achtung&lt;/strong&gt;: Ich benutze hier die Z-Shell, deshalb nennt sich die Variable hier &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$pipestatus&lt;/code&gt; in Bash würde die Variable groß geschrieben werden und &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$PIPESTATUS&lt;/code&gt;heißen!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Die crux an der Sache ist leider, dass &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$PIPESTATUS&lt;/code&gt; nicht persistent ist und in unserem Beispiel direkt durch den Exit Code vom &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;echo&lt;/code&gt; Befehl überschrieben wird. Hier muss man ggf. mit einer Hilfsvariable arbeiten und das Array zwischenspeichern wenn man die Ergebnisse später analysieren möchte.&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>Shorts - tldr man pages light</title>
   <link href="https://herr-breier.de/2024/05/31/shorts-tldr/"/>
   <updated>2024-05-31T00:00:00+00:00</updated>
   <id>https://herr-breier.de/2024/05/31/shorts-tldr</id>
   <content type="html">&lt;h1 id=&quot;shorts---tldr-man-pages-light&quot;&gt;Shorts - tldr: man pages light&lt;/h1&gt;

&lt;p&gt;&lt;a href=&quot;https://tldr.sh/&quot;&gt;tldr&lt;/a&gt;, benannt nach einem alten Internet-Akronym für &lt;strong&gt;t&lt;/strong&gt;oo &lt;strong&gt;l&lt;/strong&gt;ong; &lt;strong&gt;d&lt;/strong&gt;idn’t &lt;strong&gt;r&lt;/strong&gt;ead, ist ein tool das getreu seinem Namen die teilweise unnötig langen man pages ergänzen soll. Im Prinzip handelt es sich dabei um ein online repository von in Markdown verfassten Kurzanleitungen (oft mit Beispielen) für diverse Kommandozeilen Tools (primär Linux, aber ebenfalls MacOS und Windows!). Es gibt sowohl lokal installierbare Clients als auch &lt;a href=&quot;https://tldr.inbrowser.app/&quot;&gt;eine online Version&lt;/a&gt; des Tools. Während ich diesen Artikel verfasse gibt es bereits über 16.000 Seiten die ständig von einer aktiven Community erweitert werden.&lt;/p&gt;

&lt;p&gt;Zur Veranschaulichung hier ein Beispiel wie der Kommandozeilen-Client aussieht, gezeigt ist der Node.js Client:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/pictures/tldrBeispiel.png&quot; alt=&quot;Aufruf von tldr für den tar Befehl&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Der Aufruf erfolgt ganz einfach über&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tldr &amp;lt;Befehl&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Wie man sieht erhält man in der Regel eine Kurzbeschreibung was der Befehl eigentlich macht sowie eine Liste mit Aufrufparametern und ggf. Vorschläge für alternative Programme die ähnliche Funktionen erfüllen.&lt;/p&gt;

&lt;p&gt;Die Hilfeseiten selbst sind in Markdown geschrieben und werden von der Community erstellt und verwaltet.&lt;/p&gt;

&lt;h2 id=&quot;installation&quot;&gt;Installation&lt;/h2&gt;

&lt;p&gt;Wie eingangs geschrieben kann man die tldr Seiten auch online über &lt;a href=&quot;https://tldr.inbrowser.app/&quot;&gt;diese Website&lt;/a&gt; abrufen, es gibt aber auch diverse Clients die man installieren kann. Der momentan laut Projektseite beste Client ist der Node.js Client. Dieser lässt sich mittels NPM ganz einfach wie folgt installieren:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;npm install -g tldr&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/tldr-pages/tldr/wiki/tldr-pages-clients&quot;&gt;Weitere Clients&lt;/a&gt; kann man im Wiki finden, es gibt bspw. auch einen Python Client.&lt;/p&gt;

&lt;h2 id=&quot;update&quot;&gt;Update&lt;/h2&gt;

&lt;p&gt;Nach der Installation kann man über&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tldr update&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;ein Update der lokal gespeicherten Pages anstoßen.&lt;/p&gt;

&lt;h2 id=&quot;übersetzungen&quot;&gt;Übersetzungen&lt;/h2&gt;

&lt;p&gt;Es gibt ebenfalls ein Projekt das versucht die tldr pages in möglichst viele Sprachen zu übersetzen um diese zugänglicher zu machen. Den Status des Projekts kann man &lt;a href=&quot;https://lukwebsforge.github.io/tldri18n/&quot;&gt;hier abrufen&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;unterstützung&quot;&gt;Unterstützung&lt;/h2&gt;

&lt;p&gt;Man kann das Projekt auch unterstützen. Dies bietet sich gerade für Anfänger an die noch nicht viel mit Git gearbeitet haben. Das Projekt ermuntert jeden dazu eigene Seiten im &lt;a href=&quot;https://github.com/tldr-pages/tldr&quot;&gt;Repository des Projekts&lt;/a&gt; anzulegen oder bestehende zu verbessern. Dazu einfach im &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/pages&lt;/code&gt; Verzeichnis des Repository anlegen oder bearbeiten und danach ein pull request anstoßen. Bitte beachtet aber die &lt;a href=&quot;https://github.com/tldr-pages/tldr/blob/main/CONTRIBUTING.md&quot;&gt;Contributing Guidelines&lt;/a&gt;!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Linux Basics - sed Grundlagen</title>
   <link href="https://herr-breier.de/2023/01/20/Linux-Basics-sed/"/>
   <updated>2023-01-20T00:00:00+00:00</updated>
   <id>https://herr-breier.de/2023/01/20/Linux-Basics-sed</id>
   <content type="html">&lt;h1 id=&quot;sed---ein-mächtiges-tool-zur-verarbeitung-von-textstreaming-daten&quot;&gt;sed - ein mächtiges Tool zur Verarbeitung von Text/Streaming-Daten&lt;/h1&gt;

&lt;p&gt;Nachdem wir uns &lt;a href=&quot;/2022/09/14/Linux-Streams/&quot;&gt;zuletzt&lt;/a&gt; angesehen haben wie data streams funktionieren und wie man Daten von einem Programm ins nächste pipen kann, wollen wir uns heute eines der beliebteren Tools für diesen Zweck ansehen.&lt;/p&gt;

&lt;p&gt;Der Name sed steht für &lt;em&gt;stream editor&lt;/em&gt; und mit dem tool lassen sich weitreichende Änderungen an Texten durchführen wie beispielsweise search, delete oder replace Operationen.&lt;/p&gt;

&lt;p&gt;Dabei kommt sed auch mit &lt;em&gt;regular expressions&lt;/em&gt; (kurz: &lt;em&gt;RegEx&lt;/em&gt;) klar und erlaubt so die Suche und den Austausch von Textstrings mittels pattern matching.&lt;/p&gt;

&lt;p&gt;Sed funktioniert dabei so dass es Ausgangsdaten entweder aus einer Datei oder direkt aus einem output stream erhält, diese Daten in einem &lt;em&gt;working space&lt;/em&gt; ablegt und nach Ausführung dann in einen output stream (meistens stdout) ausgibt. Dabei werden die Ausgangsdaten (also auch Ausgangsdateien) erstmal nicht verändert, es sei denn man forciert dies durch Nutzung des -i (für &lt;em&gt;in place&lt;/em&gt;) Schalters.&lt;/p&gt;

&lt;h2 id=&quot;syntax&quot;&gt;Syntax&lt;/h2&gt;

&lt;p&gt;Sed folgt den normalen Konventionen eines Programmaufrufs unter Linux:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Bash&quot;&gt;# Triviale Syntax, bei einzelnem command kann man dies einfach angeben, bei mehreren Operationen muss man den -e Schalter vorsetzen

sed [optional:flags] command &amp;lt;filename&amp;gt;

# In diesem Beispiel sucht und ersetzt sed im kompletten Text der Datei Beispieltext.txt das Wort &quot;dieses&quot; durch &quot;jenes&quot;

sed -e s/dieses/jenes/g Beispieltext.txt

# Man kann auch direkt Daten aus einem Datenstream ersetzen

echo &quot;I hate you!&quot; | sed s/hate/love/
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Was passiert hier also?&lt;/p&gt;

&lt;p&gt;Der &lt;em&gt;sed&lt;/em&gt; Befehl ruft das Programm auf, im einfachsten Fall folgt dann eine durchzuführende Operation und der Dateiname. 
In unseren Beispielen oben führen wir dabei eine (s)ubstitution durch. Zwischen den Slashes “/” werden dabei der Suchbegriff und der Ersatzbegriff eingeschlossen. Die Slashes werden dabei als Delimiter bezeichnet und können durch beliebige andere Symbole, bspw. Doppelpunkte (“:”), ersetzt werden. Damit wäre also&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Bash&quot;&gt;
echo &quot;I hate you&quot; | sed s:hate:love:

&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;ebenfalls eine valide Schreibweise!&lt;/p&gt;

&lt;p&gt;Beim ersten Beispiel folgt der (g)lobal Schalter der angibt dass der Ersatz global, also für den gesamten Text erfolgen soll. Ohne den global-Schalter würde nur das erste Auftreten von “dieses” ersetzt.&lt;/p&gt;

&lt;p&gt;Im zweiten Beispiel haben wir den (g)lobal-Schalter weggelassen da wir sowieso nur das eine Wort ersetzen wollen.&lt;/p&gt;

&lt;p&gt;Das zweite Beispiel illustriert dabei dass sed nicht unbedingt mit einer Datei gefüttert werden muss sondern auch direkt Daten bspw. aus einem anderen Befehl erhalten kann.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;sed&lt;/em&gt; kann noch viel mehr, dies zu beschreiben würde aber den Umfang dieses (Einstiegs-)Artikels sprengen. Gegebenenfalls lasse ich nochmal einen weiteren Artikel mit ein paar umfangreicheren Beispielen folgen. Wichtig ist nur zu verstehen dass &lt;em&gt;sed&lt;/em&gt; sehr mächtig ist um Textdaten nicht-interaktiv und automatisiert bearbeiten zu können.&lt;/p&gt;

&lt;p&gt;Im nächsten Schritt gehen wir etwas weiter und schauen uns das häufig gemeinsam mit &lt;em&gt;sed&lt;/em&gt; verwendete tool &lt;em&gt;awk&lt;/em&gt; an.&lt;/p&gt;

&lt;p&gt;Abschließend bleibt vielleicht noch festzuhalten dass man sämtliche Operationen die wir mit &lt;em&gt;sed&lt;/em&gt; und &lt;em&gt;awk&lt;/em&gt; durchführen werden auch mit einem Perl-, Python oder anderweitigem Skript durchführen könnte. &lt;em&gt;sed&lt;/em&gt; und &lt;em&gt;awk&lt;/em&gt; gehören aber zum Standardumfang quasi aller moderner Linux Distributionen und bieten daher sowohl den Vorteil immer “mit an Bord” zu sein und die tools sind sehr klein und können in der Regel auch auf einem ausgelasteten Server laufen um bspw. große log files zu bearbeiten ohne einen nennenswerten impact auf die performance zu haben.&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>Linux Terminal und file streams</title>
   <link href="https://herr-breier.de/2022/09/14/Linux-Streams/"/>
   <updated>2022-09-14T00:00:00+00:00</updated>
   <id>https://herr-breier.de/2022/09/14/Linux-Streams</id>
   <content type="html">&lt;h2 id=&quot;was-sind-file-streamsdescriptors&quot;&gt;Was sind file streams/descriptors&lt;/h2&gt;

&lt;p&gt;Wenn man unter Linux ein Programm ausführt sind per default Verhalten immer drei file streams aktiv (manchmal auch &lt;em&gt;descriptors&lt;/em&gt; genannt):&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th style=&quot;text-align: center&quot;&gt;&lt;strong&gt;Name&lt;/strong&gt;&lt;/th&gt;
      &lt;th style=&quot;text-align: center&quot;&gt;&lt;strong&gt;symbolischer Name&lt;/strong&gt;&lt;/th&gt;
      &lt;th style=&quot;text-align: center&quot;&gt;&lt;strong&gt;Wert&lt;/strong&gt;&lt;/th&gt;
      &lt;th style=&quot;text-align: center&quot;&gt;&lt;strong&gt;Beispiel&lt;/strong&gt;&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;standard input&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;&lt;strong&gt;stdin&lt;/strong&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;0&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;Tastatur&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;standard output&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;&lt;strong&gt;stdout&lt;/strong&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;1&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;Terminal&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;standard error&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;&lt;strong&gt;stderr&lt;/strong&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;2&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;log Datei&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Normalerweise sind diese file streams dabei so belegt dass die &lt;strong&gt;Standardeingabe&lt;/strong&gt; von der Tastatur kommt während die &lt;strong&gt;Standardausgabe&lt;/strong&gt; und die &lt;strong&gt;Fehlerausgabe&lt;/strong&gt; an das angeschlossene Ausgabegerät, also den Bildschirm gesendet wird. Wie man diese Ausgaben umleiten kann erläutere ich gleich ebenfalls noch.&lt;/p&gt;

&lt;h2 id=&quot;io-umleitungen-und-praktische-anwendung&quot;&gt;I/O Umleitungen und praktische Anwendung&lt;/h2&gt;

&lt;p&gt;Da ich selber dieses Konzept am Anfang auch schwer verständlich fand schauen wir uns ein paar Beispiele an:&lt;/p&gt;

&lt;p&gt;Nehmen wir an wir haben ein Programm, dann können wir im Linux Terminal diesem Programm durch Verwendung des kleiner als (“&amp;lt;”) eine beliebige Datei als input zuweisen, es bietet sich an das &amp;lt; als einen Richtungspfeil zu interpretieren:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;Programm &amp;lt; Input_Datei
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Dadurch wird das Programm aufgerufen und gleichzeitig die Input_Datei als Input an das Programm gesendet.
Möchte man umgekehrt den output eines Programms an eine Datei schicken würde man die Richtung des “Pfeils” ändern, also ein größer-als Zeichen verwenden:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;Programm &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; Output_Datei
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Hier würde analog der Output des Programms an “Output_Datei” weitergeleitet.&lt;/p&gt;

&lt;p&gt;Wichtig ist an dieser Stelle dass &amp;lt; und &amp;gt; beides prinzipiell short-hands darstellen und man für den Output rein formal auch schreiben könnte:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;Programm 1&amp;gt; Output_Datei
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Dies ist wichtig zu verstehen da unser Beispielprogramm gegebenenfalls auch noch Fehlercodes erzeugt, diese würden in unserem Beispiel weiterhin an die Standardausgabe gehen, also vermutlich auf dem Monitor ausgegeben werden.
Um die Errorausgabe in eine Datei auszugeben würde man analog zum obigen Beispiel folgendes machen:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;Programm 2&amp;gt; Error_Datei
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;In diesem Beispiel wird der Output des Programms an die Standardausgabe geschickt während etwaige Fehler in Error_Datei landen.&lt;/p&gt;

&lt;p&gt;Möchte man sowohl Output als auch Fehlermeldungen in die gleiche Datei umleiten gibt es auch hierfür eine Kurzfassung:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;Programm &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; Output_Datei 2&amp;gt;&amp;amp;1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Der Zusatz 2&amp;gt;&amp;amp;1 sagt dabei einzig und alleine aus dass Fehlermeldungen (“2&amp;gt;”)an die gleiche Stelle ausgeleitet werden sollen wie der standard output (&amp;amp;1), in diesem Fall würden also Output &lt;em&gt;und&lt;/em&gt; Fehlermeldungen beide in Output_Datei gespeichert werden.&lt;/p&gt;

&lt;p&gt;Unter Bash geht das Ganze sogar noch kürzer indem man die descriptors einfach auslässt da diese impliziert sind:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;Programm &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&amp;amp; Output_Datei
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;umleitung-mittels-der-pipe-in-ein-anderes-programm&quot;&gt;Umleitung mittels der Pipe in ein anderes Programm&lt;/h2&gt;
&lt;p&gt;Nachdem wir nun gelernt haben wie man den Output eines Programms in eine Datei umleitet gibt es unter Linux auch die Möglichkeit den Output eines Programms direkt in ein anderes Programm umzuleiten, also den stdout eines Programms als stdin in ein weiteres Programm zu leiten - oder anders ausgedrückt: zu &lt;strong&gt;&lt;em&gt;pipen&lt;/em&gt;&lt;/strong&gt;!&lt;/p&gt;

&lt;p&gt;Verwendet wird dafür die so genannte Pipe, also das Symbol was auf einer deutschen Tastatur erscheint wenn man &lt;kbd&gt;&lt;kbd&gt;AltGr&lt;/kbd&gt;+&lt;kbd&gt;&amp;lt;&lt;/kbd&gt;&lt;/kbd&gt; drückt. Das Symbol für die Pipe ist ein vertikaler Strich: &lt;code&gt;|&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Programme die über eine Pipe einen Datenstrom empfangen werden auch &lt;strong&gt;&lt;em&gt;Filter&lt;/em&gt;&lt;/strong&gt; genannt.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Achtung!&lt;/strong&gt; Wichtig zu beachten ist dass Pipes &lt;strong&gt;unidirektional&lt;/strong&gt; sind! Das heisst Daten werden immer &lt;code&gt;von | links | nach | rechts&lt;/code&gt; durch die Pipes geleitet.&lt;/p&gt;

&lt;h3 id=&quot;syntax&quot;&gt;Syntax&lt;/h3&gt;

&lt;p&gt;Die Syntax ist relativ einfach:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;command_1 | command_2 | command_3 | .... | command_N
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;man führt also &lt;strong&gt;&lt;em&gt;command_1&lt;/em&gt;&lt;/strong&gt; aus wie man es immer ausführen würde, also bspw. inklusive aller Parameter. Der &lt;strong&gt;&lt;em&gt;stdout&lt;/em&gt;&lt;/strong&gt; von &lt;strong&gt;&lt;em&gt;command_1&lt;/em&gt;&lt;/strong&gt; wird dann in &lt;strong&gt;&lt;em&gt;command_2&lt;/em&gt;&lt;/strong&gt; als &lt;strong&gt;&lt;em&gt;stdin&lt;/em&gt;&lt;/strong&gt; gepiped und so weiter.&lt;/p&gt;

&lt;h3 id=&quot;beispiele&quot;&gt;Beispiele&lt;/h3&gt;

&lt;p&gt;Kommen wir nun zu ein paar anschaulichen, aber auch nützlichen Beispielen dafür wie man die Pipe nutzen kann:&lt;/p&gt;

&lt;p&gt;Nehmen wir an wir möchten eine sortierte Liste mit allen Benutzern des aktuellen Systems. Das kann man relativ leicht wie folgt durchführen:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;cat&lt;/span&gt; /etc/passwd | &lt;span class=&quot;nb&quot;&gt;sort&lt;/span&gt; | &lt;span class=&quot;nb&quot;&gt;awk&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-F&lt;/span&gt;: &lt;span class=&quot;s1&quot;&gt;&apos;{print $1}&apos;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Zur Erklärung: Als erstes wollen wir die Einträge aller User des Systems aus /etc/passwd mittels &lt;strong&gt;&lt;em&gt;cat&lt;/em&gt;&lt;/strong&gt; auslisten. Da diese Liste allerdings nicht sortiert ist, pipen wir sie in das &lt;strong&gt;&lt;em&gt;sort&lt;/em&gt;&lt;/strong&gt; Programm, dort werden die Zeilen dann alphabetisch sortiert. Als letztes wird es (nur ein bisschen) komplizierter weil wir nun unsere sortierte Liste mit Usern noch bereinigen möchten. Wir benötigen nämlich eigentlich nur die Liste der Namen, der Rest ist uns erstmal egal. In diesem Beispiel verwende ich dafür das Programm &lt;strong&gt;&lt;em&gt;awk&lt;/em&gt;&lt;/strong&gt; das wir an anderer Stelle auch nochmal besprechen werden.&lt;/p&gt;

&lt;p&gt;Das Ergebnis obiger Operation könnte bspw. so aussehen:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/pictures/PipingExample1.png&quot; alt=&quot;Piping Beispiel 1&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Man könnte nun noch weiter gehen. Möchtest du wissen wieviele Benutzer das System hat? Einfach das Ergebnis obiger Operation in das Programm wordcount mit dem -l flag pipen:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;cat&lt;/span&gt; /etc/passwd | &lt;span class=&quot;nb&quot;&gt;sort&lt;/span&gt; | &lt;span class=&quot;nb&quot;&gt;awk&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-F&lt;/span&gt;: &lt;span class=&quot;s1&quot;&gt;&apos;{print $1}&apos;&lt;/span&gt; | &lt;span class=&quot;nb&quot;&gt;wc&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-l&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Das Beste an der ganzen Sache ist dass nur der Datenstrom zwischen den Programmen angepasst wird, die ursprüngliche passwd Datei wird &lt;strong&gt;nicht&lt;/strong&gt; verändert!&lt;/p&gt;

&lt;p&gt;Gerne wird die Pipe auch mit grep verwendet um das Ergebnis einer vorigen Operation nochmal mit irgendwelchen regular expression Regeln zu filtern.&lt;/p&gt;

&lt;p&gt;Bleiben wir bei unserem passwd Beispiel könnten wir beispielsweise einfach nach einem bestimmten User filtern, also beispielsweise:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Bash&quot;&gt;cat /etc/passwd | grep TestUser
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Dies würde nur die Zeile der passwd auswerfen die den String “TestUser” enthält.&lt;/p&gt;

&lt;p&gt;Ein anderes gern benutztes Programm in der Pipe ist &lt;strong&gt;&lt;em&gt;uniq&lt;/em&gt;&lt;/strong&gt; über das sich doppelte Einträge etc. ausfiltern lassen. Der Fantasie sind hier keine Grenzen gesetzt und es ist eine gute Idee sich mit dem Thema zu beschäftigen. Leider ist die Pipe dabei nur so mächtig wie das eigene Verständnis von den Tools die auf dem System verfügbar sind, aber wenn man das Prinzip einmal verstanden hat kann man sich richtig mächtige, automatisierte Workflows zusammen bauen die einem viel Arbeit abnehmen.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Shorts - Achtung beim Klonen von Virtualbox VMs</title>
   <link href="https://herr-breier.de/2022/01/19/shorts-VirtualBoxCloneMachineID/"/>
   <updated>2022-01-19T00:00:00+00:00</updated>
   <id>https://herr-breier.de/2022/01/19/shorts-VirtualBoxCloneMachineID</id>
   <content type="html">&lt;h1 id=&quot;das-ausgangsproblem&quot;&gt;Das Ausgangsproblem&lt;/h1&gt;
&lt;p&gt;Ich war dabei eine Testumgebung aufzubauen um mehrere VMs mit verschiedenen dockerisierten Applikationen laufen zu lassen.
Da ich faul bin habe ich mir gedacht dass ich eine VM aufsetze, Docker installiere und die Maschine dann klone. 
Normalerweise organisiere ich mir solche Setups mit mehreren VMs über ein Tool wie &lt;a href=&quot;https://www.vagrantup.com/&quot;&gt;Vagrant&lt;/a&gt;. 
Diesmal habe ich aber einfach eine Maschine in Virtualbox aufgesetzt und diese dann geklont.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;BÖSER FEHLER!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Denn obwohl ich daran gedacht habe beim klonen der VM anzuhakeln dass die neue Maschine eine neue Mac-Adresse bekommt, war das nicht ausreichend!&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/pictures/Virtualbox_clone_dialogue.png&quot; alt=&quot;Virtualbox klonen einer VM&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Nach dem Klonen der VM konnte ich beide VMs hochfahren, musste aber feststellen dass diese sich im Netzwerk nicht sehen konnten.
Nach kurzer Suche dann die große Verwirrung:
&lt;em&gt;beide&lt;/em&gt; Maschinen bekamen die gleiche IP zugewiesen!&lt;/p&gt;

&lt;h2 id=&quot;the-plot-thickens&quot;&gt;The plot thickens!&lt;/h2&gt;

&lt;p&gt;Nach 1,5 Stunden Sucherei und herumprobieren dann die Erkenntnis:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;zusammen mit der Maschine wurde auch die machine-id geklont&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Das war mir so nicht bewusst, obwohl es natürlich logisch ist. Die machine-id ist eine Identifikationsnummer die normalerweise während der Installation des Systems zufallsgeneriert wird und den Host eindeutig identifizieren soll.&lt;/p&gt;

&lt;p&gt;Abrufen kann man die machine-id beispielsweise über:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Bash&quot;&gt;cat /etc/machine-id
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Wer nochmal genauer nachlesen möchte kann eine deutsche Übersetzung der Manpage bspw. &lt;a href=&quot;https://manpages.debian.org/testing/manpages-de/machine-id.5.de.html&quot;&gt;bei Debian finden&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;die-lösung&quot;&gt;Die Lösung&lt;/h2&gt;

&lt;p&gt;Um mein Problem mit den doppelten IPs zu lösen musste ich also eine neue machine-id generieren.&lt;/p&gt;

&lt;p&gt;Das kann man wie folgt machen:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Bash&quot;&gt;sudo rm -f /etc/machine-id
sudo dbus-uuidgen --ensure=/etc/machine-id
sudo rm /var/lib/dbus/machine-id
sudo dbus-uuidgen --ensure
reboot
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Nach einem Reboot wurden dann endlich vom DHCP Server verschiedene IP-Adressen vergeben.&lt;/p&gt;

&lt;p&gt;In Zukunft werde ich aber doch wieder Vagrant verwenden…&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>Shorts - Windows Server remote rebooten</title>
   <link href="https://herr-breier.de/2021/12/04/Windows-Server-remote-rebooten/"/>
   <updated>2021-12-04T00:00:00+00:00</updated>
   <id>https://herr-breier.de/2021/12/04/Windows-Server-remote-rebooten</id>
   <content type="html">&lt;h1 id=&quot;der-shutdown-befehl&quot;&gt;der Shutdown Befehl&lt;/h1&gt;

&lt;p&gt;Neulich hatte ich ein Kundensystem das keine RDP Session mehr aufbauen wollte. In solchen Fällen ist es nützlich dass der shutdown Befehl auch übers Netzwerk ausgeführt werden kann:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;shutdown /r /m \\{RemoteRechner} /t 60
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;dabei sind die einzelnen flags:&lt;/p&gt;

&lt;p&gt;/r Restart&lt;/p&gt;

&lt;p&gt;/m \{IP/Hostname} Remote Rechner&lt;/p&gt;

&lt;p&gt;/t time delay&lt;/p&gt;

&lt;p&gt;Microsoft hat ebenfalls einen eigenen &lt;a href=&quot;https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/shutdown&quot;&gt;Artikel&lt;/a&gt; zum shutdown Befehl und allen seinen flags.&lt;/p&gt;

&lt;h1 id=&quot;windows-kommando-referenz&quot;&gt;Windows Kommando Referenz&lt;/h1&gt;

&lt;p&gt;In diesem Zusammenhang ist sicher auch die &lt;a href=&quot;https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/windows-commands&quot;&gt;Windows Kommando Referenz&lt;/a&gt; sehr interessant. Hier findet man einen A bis Z Glossar aller Windows Server und Client Befehle für die Kommandozeile. Es lohnt sich hier mal durch zu scrollen!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Linux Basics Teil 3 - Terminal, Shell, Command Line und Prompt</title>
   <link href="https://herr-breier.de/2021/09/19/was-ist-ein-terminal/"/>
   <updated>2021-09-19T00:00:00+00:00</updated>
   <id>https://herr-breier.de/2021/09/19/was-ist-ein-terminal</id>
   <content type="html">&lt;h1 id=&quot;worum-geht-es-hier-überhaupt&quot;&gt;Worum geht es hier überhaupt?&lt;/h1&gt;

&lt;p&gt;Fängt man mit Linux an stößt man unweigerlich irgendwann auf die Kommandozeile.
Viele Benutzer schrecken hiervor anfangs zurück weil die Eingabe von Befehlen und die Ausgabe auf einer Textzeile anfangs gewöhnungsbedürftig sind und viele Benutzer sich überfordert fühlen. 
Dieses Problem wird auch nicht dadurch besser dass viele Artikel und auch andere Benutzer in Foren und auf social media wie selbstverständlich mit unbekannten Fremdwörtern um sich werfen.
Dem möchte ich ein wenig mit diesem Artikel entgegen wirken.&lt;/p&gt;

&lt;h2 id=&quot;ein-wenig-historie-und-der-begriff-des-terminals&quot;&gt;Ein wenig Historie und der Begriff des Terminals&lt;/h2&gt;

&lt;p&gt;Ein Terminal, auch genannt Konsole oder auch klassisch deutsch als &lt;em&gt;Datensichtgerät&lt;/em&gt; bezeichnet war früher&lt;sup&gt;TM&lt;/sup&gt; tatsächlich ein externes Gerät zur Abfrage und Eingabe von Daten auf einem Server. Im Prinzip handelte es sich dabei um einen Bildschirm samt Tastatur um auf einem Großrechner aus der Entfernung seine Arbeiten zu verrichten. Die Dinger sahen so aus:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://upload.wikimedia.org/wikipedia/commons/thumb/8/87/Televideo925Terminal.jpg/579px-Televideo925Terminal.jpg&quot; alt=&quot;Bild eines alten Terminals&quot; /&gt;[^Terminal]&lt;/p&gt;

&lt;p&gt;Heute gibt es Terminals in dieser Form kaum noch und in den meisten Firmen und Einrichtungen haben sich die individuellen Personalcomputer durchgesetzt.&lt;/p&gt;

&lt;h3 id=&quot;was-hat-das-nun-mit-linux-zu-tun&quot;&gt;Was hat das nun mit Linux zu tun&lt;/h3&gt;

&lt;p&gt;Nachdem die Hardware Terminals im wesentlichen den Weg des Dodos gegangen sind ist das &lt;em&gt;Software&lt;/em&gt; Terminal unter Linux nach wie vor lebendig.&lt;/p&gt;

&lt;p&gt;Hierunter versteht man im wesentlichen eine Softwareemulation eines Terminals. Wenn man also sowas sieht hat man ein &lt;em&gt;Softwareterminal&lt;/em&gt; vor sich:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/pictures/2021-09-19-terminalexampe.png&quot; alt=&quot;Bild eines Linux Terminals&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Der Begriff des Terminalemulators meint dabei das Fenster bzw. das &lt;em&gt;äußere&lt;/em&gt; Programm. Selber macht der Terminalemulator mehr oder weniger viel, er bietet im wesentlichen den anderen Programmen nur eine &lt;em&gt;Bühne&lt;/em&gt; um ausgeführt zu werden.
Einige Terminals, wie beispielsweise &lt;a href=&quot;https://sw.kovidgoyal.net/kitty/&quot;&gt;kitty&lt;/a&gt; welches ich momentan nutze, haben ein paar besondere Funktionen wie keyboard shortcuts, Tabbing, geteilte Fenster oder sogar ein eigenes Skripting-System.
Teilweise verschmelzen hier auch ein wenig die Grenzen zur Shell. Damit wären wir dann auch…&lt;/p&gt;

&lt;h3 id=&quot;die-shell&quot;&gt;Die Shell&lt;/h3&gt;

&lt;p&gt;Erinnert ihr euch noch als wir &lt;a href=&quot;/2021/08/14/Linux-Basics-Teil-1/&quot;&gt;im ersten Artikel&lt;/a&gt; über die GNU Core Utils gesprochen haben? Im Prinzip ist die Shell das Programmgerüst über das diese weiteren Programme ausgeführt werden.
Verschiedene Shells bringen verschiedene Funktionalitäten und Standardprogramme mit sich. Korn, Bash, Zsh und viele andere sind Beispiele für Shells die sich mal mehr und mal weniger voneinander unterscheiden.&lt;/p&gt;

&lt;p&gt;Welche Shell Ihr momentan verwendet könnt Ihr auf verschiedene Arten herausfinden:&lt;/p&gt;

&lt;p&gt;Zum einen könnt ihr direkt in die Konfigurationsdateien hineinschauen.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Bash&quot;&gt;less /etc/passwd|grep user
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Unter /etc/passwd sind Informationen zu dem einzelnen Usern abgelegt, rufe ich beispielsweise oberen Befehl für meinen User &lt;em&gt;david&lt;/em&gt; auf, so bekomme ich folgenden output:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Bash&quot;&gt;less /etc/passwd|grep david
david:x:1000:1000:david,,,:/home/david:/usr/bin/zsh
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Die Einträge in dieser Datei sind durch &lt;em&gt;:&lt;/em&gt; geteilt und enthalten beispielsweise Informationen zum Usernamen, Home-Directory des Nutzers und so weiter. Wir werden uns diese Datei nochmal ansehen sobald wir behandeln wie man User anlegt und verwaltet. Uns interessiert gerade nur der letzte Eintrag:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;:/usr/bin/zsh&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Dieser sagt aus dass jedes neues Terminal dass für meinen User aufgerufen wird, erstmal mit ZSH als Shell startet. Hier könnte auch eine andere shell, beispielsweise die &lt;em&gt;bash&lt;/em&gt; stehen.&lt;/p&gt;

&lt;p&gt;Ebenfalls kann man aber auch die Shell über Umgebungsvariablen herausfinden:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Bash&quot;&gt;echo $SHELL
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;gibt beispielsweise die &lt;em&gt;default&lt;/em&gt; Shell an die das System benutzt. Hier ist zu beachten dass dies nicht zwangsläufig auch die aktuell laufende Shell sein muss, sondern nur die mit der das Terminal normalerweise startet!&lt;/p&gt;

&lt;p&gt;Etwas &lt;em&gt;hackig&lt;/em&gt; aber funktioniert normalerweise auch wäre dieser Befehl:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Bash&quot;&gt;echo $0
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;wobei $0 den aktuell laufenden Prozess anzeigt, in der Regel ist das die Shell. Eine andere Art den aktuellen Prozess anzuzeigen wäre aus der Variable $$ und wenn man es ganz genau wissen will kann man über den &lt;em&gt;ps&lt;/em&gt; Befehl die Prozess-ID heraussuchen und auf den Namen des Prozesses filtern, das sieht dann so aus:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Bash&quot;&gt;ps -p &quot;$$&quot; -o command=&quot;&quot;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Es gibt noch weitere Varianten die aber zum Teil auf spezifische Features einer Shell zugreifen. Selbst &lt;em&gt;ps -p&lt;/em&gt; funktioniert anscheinend nicht auf allen Systemen, das habe ich persönlich allerdings noch nicht erlebt.&lt;/p&gt;

&lt;p&gt;Eine Liste der auf eurem System installierten Shells findet ihr bei den meisten Distributionen unter &lt;em&gt;/etc/shells&lt;/em&gt;
Also beispielsweise anzeigbar über den Befehl:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Bash&quot;&gt;cat /etc/shells
# /etc/shells: valid login shells
/bin/sh
/bin/bash
/usr/bin/bash
/bin/rbash
/usr/bin/rbash
/bin/dash
/usr/bin/dash
/usr/bin/tmux
/usr/bin/sh
/usr/bin/fish
/usr/local/bin/fish
/bin/zsh
/usr/bin/zsh
&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id=&quot;kleine-liste-von-shells&quot;&gt;kleine Liste von Shells&lt;/h4&gt;

&lt;p&gt;Hier möchte ich &lt;em&gt;kurz&lt;/em&gt; ein paar Shells vorstellen damit Ihr euch eine Vorstellung machen könnt wo die Unterschiede liegen.&lt;/p&gt;

&lt;p&gt;Diese Liste soll sukzessiv zusammen mit weiteren Artikeln zu den einzelnen Shells erweitert werden.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bash&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Bash ist die meines Wissens am weitesten verbreitete Shell, gehört zum GNU Projekt und wurde Ende der 80er Jahre veröffentlicht und wird bis heute weiterentwickelt. 
Unter anderem Ubuntu setzt auf die Bash und auch in MacOS kam sie lange Jahre zum Einsatz und wurde nur aus lizenzrechtlichen Gründen ersetzt.&lt;/p&gt;

&lt;h3 id=&quot;fußnoten&quot;&gt;Fußnoten&lt;/h3&gt;

</content>
 </entry>
 
 <entry>
   <title>Shorts - Windows für mehrere RDP Sessions konfigurieren</title>
   <link href="https://herr-breier.de/2021/09/12/shorts-mehrere-RDP-sessions/"/>
   <updated>2021-09-12T00:00:00+00:00</updated>
   <id>https://herr-breier.de/2021/09/12/shorts-mehrere-RDP-sessions</id>
   <content type="html">&lt;h1 id=&quot;problemstellung&quot;&gt;Problemstellung&lt;/h1&gt;

&lt;p&gt;Seit &lt;em&gt;Windows Server 2012&lt;/em&gt; ist es nicht mehr möglich mehrere RDP Sessions zu dem gleichen Server herzustellen. Man kann dieses Feature durch eine Anpassung der Gruppenrichtlinien jedoch wieder aktivieren. Wie das geht wird im folgenden beschrieben:&lt;/p&gt;

&lt;h2 id=&quot;howto-mehrere-rdp-sessions-erlauben&quot;&gt;Howto: Mehrere RDP Sessions erlauben&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;Auf dem Server einloggen auf dem Remote Desktop Services installiert sind&lt;/li&gt;
  &lt;li&gt;den Gruppenrichtlinieneditor &lt;strong&gt;gpedit.msc&lt;/strong&gt; öffnen (Windows-Start -&amp;gt; gpedit.msc in Suchfeld eingeben)&lt;/li&gt;
  &lt;li&gt;Computerkonfiguration –&amp;gt; Administrative Vorlagen –&amp;gt; Windows-Komponenten –&amp;gt; Remotedesktopdienste –&amp;gt; Remotedesktopsitzungs-Host –&amp;gt; Verbindungen&lt;/li&gt;
  &lt;li&gt;die Richtlinie „Remotedesktopdienste-Benutzer auf eine Remotedesktopdienste-Sitzung beschränken„ &lt;strong&gt;deaktivieren&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;Danach kann in der Richtlinie „Anzahl der Verbindungen einschränken“ die maximale Anzahl von RDP-Sessions konfiguriert werden.&lt;sup id=&quot;fnref:Sessions&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:Sessions&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;fußnoten&quot;&gt;Fußnoten&lt;/h2&gt;

&lt;div class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
  &lt;ol&gt;
    &lt;li id=&quot;fn:Sessions&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;Ich habe hier mehrfach gehört dass es egal ist wieviele Sessions man hier einträgt, die maximale Anzahl Sessions ist »2«. Das habe ich aber bisher noch nicht nachgeprüft. &lt;a href=&quot;#fnref:Sessions&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;
</content>
 </entry>
 
 <entry>
   <title>Linux Basics Teil 2 - Distributionen</title>
   <link href="https://herr-breier.de/2021/08/22/distributionen/"/>
   <updated>2021-08-22T00:00:00+00:00</updated>
   <id>https://herr-breier.de/2021/08/22/distributionen</id>
   <content type="html">&lt;h1 id=&quot;rekapitulation-teil-1&quot;&gt;Rekapitulation Teil 1&lt;/h1&gt;

&lt;p&gt;Im &lt;a href=&quot;/2021/08/14/Linux-Basics-Teil-1/&quot;&gt;letzten Artikel&lt;/a&gt; haben wir kurz besprochen dass der Kernel das eigentliche Linux Basissystem darstellt, welches die Schnittstelle zwischen Software und Hardware bereitstellt.&lt;/p&gt;

&lt;p&gt;Darauf setzen dann die Basis- oder auch coreutils auf. Die meisten Systeme benutzen hierfür die vom GNU Projekt erstellten open source Varianten der tools, die bereits aus dem proprietären UNIX System bekannt waren. Das daraus entstehende System wird (laut Richard Stallmann) GNU/Linux genannt, auch wenn es hier keine Einigkeit gibt und wir der Einfachheit halber in Zukunft nur von “Linux” sprechen werden.&lt;/p&gt;

&lt;p&gt;Die Unterscheidung ist dennoch wichtig da es auch Linux Systeme gibt die komplett ohne Beteiligung des GNU Projekts auskommen. Dazu gehören bspw. Alpine Linux oder diverse BSD Varietäten, wodurch nicht immer sichergestellt ist dass jedes tool auf jedem System gleich funktioniert. Man muss also ggf. seine Scripte regelmäßig prüfen und vor dem Rollout auf einem neuen System die Kompatibilität checken.&lt;/p&gt;

&lt;h1 id=&quot;was-ist-eine-linux-distribution&quot;&gt;Was ist eine Linux Distribution?&lt;/h1&gt;

&lt;p&gt;Eine Linux Distribution nimmt schließlich das GNU/Linux Basissystem und erweitert dieses um weitere Softwarepakete um ein komplettes Betriebssystem zu bauen. Hier wird es leider kompliziert da es eine ganze Reihe an Linux Distributionen gibt die sich teils in der zugrundeliegenden Philosophie, teils im Anwendungsbereich und der technischen Funktionalität unterscheiden.&lt;/p&gt;

&lt;p&gt;So gibt es die klassischen Desktop-Distributionen die im Prinzip ein komplettes Betriebssystem für den Endanwender bereitstellen,inklusive grafischer Oberfläche und einem üppigen Softwarepaket.&lt;/p&gt;

&lt;p&gt;Daneben gibt es reduzierte Varianten die beispielsweise im Serverbereich auf die grafische Oberfläche verzichten oder sogar so weit reduziert sind dass sie nur die notwendige Funktionalität bieten um bspw. einen Kleinstcomputer oder eine Waschmaschine zu steuern.&lt;/p&gt;

&lt;p&gt;Daneben gibt es auch Varianten die für einen speziellen Zweck vorkonfiguriert wurden und bestimmte Softwarepakete direkt mitliefern, beispielsweise im Bereich Hacking und PenTesting.&lt;/p&gt;

&lt;p&gt;Ebenso gibt es Distributionen die sich philosophisch unterscheiden. Beispielsweise gibt es diverse Distributionen die auf Software des GNU Projekts verzichten oder keine proprietäre Software einbinden für die der Quellcode nicht offen liegt (bspw. Grafikkarten- oder Druckertreiber).&lt;/p&gt;

&lt;p&gt;Dementsprechend ist das Linux Umfeld riesengroß und es fällt einem Anfänger sicherlich schwer eine geeignete Distribution zu finden. Je nach Quelle gibt es mehrere hundert bis etwas über eintausend aktiv entwickelte Distributionen. Da fällt es schwer die richtige zu finden.&lt;/p&gt;

&lt;p&gt;Um einen Einstieg zu finden wollen wir uns ein paar der beliebtesten Distributionen kurz anschauen und diskutieren.&lt;/p&gt;

&lt;h2 id=&quot;enterprise-linux&quot;&gt;Enterprise Linux&lt;/h2&gt;

&lt;p&gt;Auch wenn Linux momentan noch ein Schattendasein auf dem Desktop fristet ist es ein ernstzunehmendes Serverbetriebssystem und hat dort, nach Microsoft Windows, den zweithöchsten Marktanteil mit &amp;gt;13% (siehe &lt;a href=&quot;https://www.statista.com/statistics/915085/global-server-share-by-os/&quot;&gt;Statista&lt;/a&gt;). Im wesentlichen gibt es hier nur zwei wirkliche Konkurrenten: &lt;a href=&quot;https://www.suse.com/de-de/&quot;&gt;Suse Linux Enterprise (SLES)&lt;/a&gt; und &lt;a href=&quot;https://www.redhat.com/de/&quot;&gt;Red Hat Linux&lt;/a&gt;. Beide führe ich hier nur der Vollständigkeit auf, da entsprechende Lizenzen für diese Betriebssystem auch wirklich “Enterprise” sind und mehrere tausend Euro betragen können.&lt;/p&gt;

&lt;p&gt;Trotzdem ist es für den geneigten Nutzer vielleicht ganz spannend sich mit beiden auseinander zu setzen, da sowohl Suse als auch Redhat eigene Fortbildungen und Zertifizierungen anbieten. Für Suse wäre hier ein guter Startpunkt der &lt;a href=&quot;https://training.suse.com/certification/sca-sles-15/&quot;&gt;Suse Certified Administrator (SCA)&lt;/a&gt; und für Red Hat der &lt;a href=&quot;https://www.redhat.com/de/services/certification/rhcsa&quot;&gt;Red Hat Certified Systems Administrator (RHCSA)&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Als Alternative lässt sich sicherlich noch die Distributions-agnostische Zertifizierung LPIC-1(und höhere) des Linux Professional Institute. Der Vorteil ist dass diese Prüfung sich nicht auf ein spezielles Linuxsystem stützt sondern allgemein gehalten ist.&lt;/p&gt;

&lt;p&gt;Preislich liegt die LPIC-1 Zertifizierung mit 160€/Prüfung auf dem gleichen Niveau wie die Suse Zertifizierung. Red Hat schert hier ziemlich aus und ruft mit 515€ schon eine ganze Stange mehr Geld auf.&lt;/p&gt;

&lt;p&gt;Welche Zertifizierung man tatsächlich bevorzugt ist im wesentlichen Geschmackssache, inhaltlich ähneln diese sich doch relativ stark und es gab auch einmal die Möglichkeit sich von Suse ein LPIC-1 Zertifikat ausstellen zu lassen.&lt;/p&gt;

&lt;h2 id=&quot;dekstop-linux&quot;&gt;Dekstop Linux&lt;/h2&gt;

&lt;h3 id=&quot;debianubuntu-derivate&quot;&gt;Debian/Ubuntu Derivate&lt;/h3&gt;

&lt;p&gt;Debian ist eine sehr lang gereifte (Bj. 1993) Linux Distribution deren Markenzeichen es ist nur absolut sichere und getestete Software auszuliefern. Dadurch ist Debian immer etwas hinter der Zeit, erkauft sich damit aber eine sehr hohe Systemstabilität. Debian ist aus diesem Grund insbesondere im Serverumfeld sehr beliebt und eignet sich für Desktop User, die nicht nur 10 Jahre alte Software nutzen möchten, eher weniger.&lt;/p&gt;

&lt;h4 id=&quot;ubuntu&quot;&gt;Ubuntu&lt;/h4&gt;

&lt;p&gt;Hier kommt Ubuntu ins Spiel das als Abkömmling von Debian konzipiert wurde mit dem Ziel Debian für den Normaluser nutzbar zu machen. Mittlerweile ist Ubuntu ebenfalls eine sehr ausgereifte Distribution (Bj. 2004) und veröffentlicht in einem halbjährlichen Rhythmus eine neue Version, sowie alle zwei Jahre ein long term release mit erweitertem Support. Ebenfalls dringt Ubuntu langsam aber sicher in den Enterprise Raum vor und nimmt Suse und Red Hat anscheinend Anteile ab. Allerdings ist das nur meine persönliche Erfahrung, mir sind hierzu keine aussagekräftigen Statistiken bekannt.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Eigenschaften von Ubuntu&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Ubuntu basiert wie eingangs erwähnt auf Debian und benutzt deshalb auch den Debian Package Manager der es sehr einfach macht Software auf dem System zu installieren. Da Ubuntu kein reines Community Projekt ist, sondern von der Firma Canonical weiterentwickelt wird, steht hier auch ordentlich Manpower hinter dem Projekt. Software sowie Betriebssystem selber werden umfassend getestet und auf qualitativ hohem Niveau weiterentwickelt. Die Dokumentation ist exzellent und man findet quasi zu jeder Frage die man hat eine Antwort. Im Gegensatz zu vielen anderen Distributionen gibt es für Ubuntu ebenfalls eine große deutschsprachige Community falls man sich als Anfänger nicht direkt den englischen Fachjargon einiger Foren zutraut.
Ubuntu ist eine GNU/Linux Distribution und schwimmt damit im Mainstream mit, was gerade Anfängern entgegen kommen sollte. Als Standard-Shell kommt &lt;a href=&quot;https://www.gnu.org/software/bash/&quot;&gt;Bash&lt;/a&gt; zum Einsatz, eine weitverbreitete und beliebte Shell. 
Für den &lt;a href=&quot;https://de.wikipedia.org/wiki/Fenstermanager&quot;&gt;Window Manager&lt;/a&gt; (also die grafische Benutzeroberfläche) greift Ubuntu in seiner Standard Version auf Gnome zurück, einen soliden und weitverbreiteten Window Manager der eine gute Balance zwischen Ressourcenverbrauch, Usability und Eye Candy findet. Gnome sollte auf allen heute noch gebräuchlichen Computern und Laptops einwandfrei laufen. Solltest Du planen Ubuntu auf einem Kleinstrechner wie einem &lt;a href=&quot;https://www.raspberrypi.org/products/raspberry-pi-4-model-b/&quot;&gt;Raspberry PI&lt;/a&gt; zu installieren bietet Ubuntu allerdings auch andere &lt;a href=&quot;https://ubuntu.com/download/flavours&quot;&gt;Flavours&lt;/a&gt; an.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fazit&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Ubuntu ist ein Allrounder. Dabei macht Ubuntu nichts schlecht, geht aber auch keine Risiken ein. Dadurch dass das System von einer Firma weiterentwickelt wird und auch im Enterprise Umfeld aktiv ist kann man davon ausgehen dass Ubuntu nicht über Nacht vom Markt verschwindet, was gerade Anfängern Sicherheit geben sollte.
Der Großteil der verwendeten Software entspricht dem Standard und die Dokumentation ist hervorragend und die Community riesig. Gerade Anfängern sollte das entgegen kommen.&lt;/p&gt;

&lt;h4 id=&quot;opensuse&quot;&gt;openSUSE&lt;/h4&gt;
&lt;p&gt;Suse führe ich hier aus drei Gründen auf. Zum einen, um das einmal vorweg zu nehmen, stand das S.u.S.E. in SuSE Linux ursprünglich als Akronym für &lt;strong&gt;S&lt;/strong&gt;oftware- &lt;strong&gt;u&lt;/strong&gt;nd &lt;strong&gt;S&lt;/strong&gt;ystem-&lt;strong&gt;E&lt;/strong&gt;ntwicklung. Das ist deshalb so weil SUSE ursprünglich aus Deutschland kommt und 1992 in Nürnberg das Licht der Welt erblickte.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Eigenschaften von SUSE&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Neben diesem kleinen Ausflug in den Lokalpatriotismus bietet SUSE, bzw. sein freier Ableger openSUSE auch einige andere interessante Eigenschaften.&lt;/p&gt;

&lt;p&gt;Zum einen ist SUSE quasi eine Eigenentwicklung die, im Gegensatz zu vielen anderen Distributionen, eben &lt;em&gt;nicht&lt;/em&gt; auf einer der größeren Distributionen wie Debian/Ubuntu, Arch und wie sie alle heißen basiert. 
Das kann man als Vor- oder Nachteil sehen, hebt SUSE aber mit einer Reihe an Software Eigenentwicklungen aus der Masse heraus. 
So benutzt SUSE einen eigenen &lt;a href=&quot;https://de.opensuse.org/Zypper&quot;&gt;Package Manager&lt;/a&gt;, ein eigenes &lt;a href=&quot;https://de.opensuse.org/openSUSE:Snapper_Tutorial&quot;&gt;Snapshot-&lt;/a&gt; und bringt, jedenfalls in der Enterprise Version, auch professionelle Tools für Aufgaben wie &lt;a href=&quot;https://www.suse.com/de-de/products/highavailability/&quot;&gt;Hochverfügbarkeit&lt;/a&gt;, &lt;a href=&quot;https://www.suse.com/de-de/products/longhorn/&quot;&gt;Storage Management&lt;/a&gt; oder &lt;a href=&quot;https://www.suse.com/de-de/products/suse-rancher/&quot;&gt;Cotainerverwaltung&lt;/a&gt; mit. Daneben ist SUSE Linux auch der Partner der Wahl für &lt;a href=&quot;https://www.suse.com/de-de/solutions/run-sap-solutions/&quot;&gt;SAP&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Insgesamt stellt SUSE damit ein umfangreiches, stabiles System mit mehreren Jahrzehnten dar. Dies ist eine der Distributionen die nicht so schnell verschwinden werden.&lt;/p&gt;

&lt;p&gt;Dabei wird SUSE in verschiedenen Varianten entwickelt. SLES, also &lt;strong&gt;S&lt;/strong&gt;USE &lt;strong&gt;L&lt;/strong&gt;INUX &lt;strong&gt;E&lt;/strong&gt;NTERPRISE &lt;strong&gt;S&lt;/strong&gt;ERVER, ist das kommerzielle Enterprise Angebot von SUSE.&lt;/p&gt;

&lt;p&gt;Daneben gibt es noch die “freie” Variante openSUSE die von einer starken und aktiven Community getrieben wird und in zwei Varianten daher kommt: einem rolling release&lt;sup id=&quot;fnref:rollingRelease&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:rollingRelease&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; (&lt;a href=&quot;https://en.opensuse.org/Portal:Tumbleweed&quot;&gt;Tumbleweed&lt;/a&gt;) und einem statischen release (&lt;a href=&quot;https://www.opensuse.org/#Leap&quot;&gt;Leap&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fazit&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;SUSE verfügt über eine sehr aktive Community und hat eine große Firma die das Projekt mittlerweile über Jahrzehnte voran treibt. 
Neben Red Hat Linux ist SUSE die zweite Distribution die fest im Enterprise Bereich verankert ist, was es sicherlich für Menschen mit beruflichen Ambitionen im Linuxumfeld zusätzlich interessant macht. Aus dem größeren Backing ergeben sich unter anderem auch Neu- und Weiterentwicklungen die andere, kleinere Projekte vermutlich so nicht stemmen könnten, gerade das Snapshot und Backup Konzept von SUSE ist schon sehr ausgereift. 
Für Anfänger ist es außerdem sehr angenehm dass SUSE quasi alle administrativen Aufgaben die auf dem System anfallen in seiner YAST Software unter einer einheitlichen Oberfläche vereint.&lt;/p&gt;

&lt;h4 id=&quot;zorinos&quot;&gt;ZorinOS&lt;/h4&gt;

&lt;p&gt;ZorinOS ist eine weitere, Ubuntu basierte, Distribution die sich an Anfänger richtet und insbesondere Umsteiger von Windows ansprechen soll.&lt;/p&gt;

&lt;p&gt;Zorin OS wurde erst kürzlich in Version 16 veröffentlicht (Stand 08/2021) und kommt sowohl in einer kostenlosen &lt;em&gt;Core&lt;/em&gt; als auch einer kostenpflichtigen &lt;em&gt;pro&lt;/em&gt; Version daher.&lt;/p&gt;

&lt;p&gt;Die &lt;em&gt;pro&lt;/em&gt; Version soll $39 kosten und beinhaltet ein paar Goodies die der &lt;em&gt;Core&lt;/em&gt; Version fehlen. Doch dazu später mehr.&lt;/p&gt;

&lt;p&gt;Wie eingangs erwähnt scheint sich ZorinOS vorwiegend an Windows-Umsteiger zu richten und bietet im Auslieferungszustand ein sehr sauberes, helles und an Windows angelehntes, fast schon minimalistisches Design.&lt;/p&gt;

&lt;p&gt;Die Installation verläuft, wie bei den meisten Distributionen, über einen grafischen Installer.
Nach der Installation wird man vom System mit einer geführten Tour durch die wichtigsten Systemfunktionen begrüßt.
Ich hatte beim ausprobieren den Eindruck, dass es ZorinOS insbesondere Anfängern einfach machen will. 
So scheinen die verfügbaren Einstellungen auf das wesentliche reduziert worden zu sein und bieten eine Reihe aussagekräftiger Presets an, beispielsweise kann man bei den Layouts zwischen mehreren Vorlagen auswählen: Windows, Mac, Ubuntu,…).&lt;/p&gt;

&lt;p&gt;Auch bei der Software geht ZorinOS keine Kompromisse ein und bietet &lt;em&gt;out of the box&lt;/em&gt; Support für seine eigenen Software-Repositories, die von Ubuntu sowie Flathub und Snap, was eigentlich alles abdecken sollte.&lt;/p&gt;

&lt;p&gt;Selbst die Integration von Wine zur Installation von Windows Software ist über einen &lt;em&gt;Rechtsklick&lt;/em&gt; aus dem Kontextmenü zu erreichen und schön in das System integriert.&lt;/p&gt;

&lt;p&gt;Darüber hinaus bietet ZorinOS alle Annehmlichkeiten die man auch von anderen Ubuntu/Debian basierten Distributionen kennt.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Education Version&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;ZorinOS bietet eine Education Version seines Betriebssystems die direkt mit diverser freier, dem Zweck angemessener, Software kommt.&lt;/p&gt;

&lt;p&gt;Unter anderem gehören dazu Lernsoftware zu diversen Themen, aber auch Software für Videoconferencing und eine Software die eine hierarchische Steuerung/Überwachung der Schüler-Rechner von einem zentralen Lehrer-PC aus erlaubt (&lt;a href=&quot;https://veyon.io/de/&quot;&gt;Veyon.io&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pro Version&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Neben der &lt;em&gt;Core&lt;/em&gt; und der &lt;em&gt;Education&lt;/em&gt; Version gibt es ebenfalls eine &lt;em&gt;Pro&lt;/em&gt; Version von ZorinOS.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Disclaimer: Ich selber habe die Pro Version &lt;strong&gt;nicht&lt;/strong&gt; getestet und beziehe mich nur auf die Informationen von der Website.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Die &lt;em&gt;Pro&lt;/em&gt; Version soll $39 kosten und beinhaltet, soweit ich sehen konnte, hauptsächlich weitere freie Software Packages die aber bereits kuratiert und ordentlich in das System integriert zu sein scheinen.&lt;/p&gt;

&lt;p&gt;Man zahlt also weniger für spezielle Software, sondern vielmehr für eine saubere und nahtlose Integration in das System.
Eine genaue Liste mit Features der &lt;em&gt;Pro&lt;/em&gt; Version lässt sich auf der &lt;a href=&quot;https://zorin.com/os/pro/&quot;&gt;Homepage&lt;/a&gt; einsehen.&lt;/p&gt;

&lt;p&gt;Persönlich scheint es mir als würde sich diese Version an Firmenkunden richten, denn neben dem was ZorinOS als &lt;em&gt;Professional-grade creative suite of apps&lt;/em&gt; und &lt;em&gt;Advanced productivity software&lt;/em&gt; bewirbt, sind bspw. eine touch-/Stift-fähige Notizsoftware (&lt;a href=&quot;https://xournalpp.github.io/&quot;&gt;Xournal++&lt;/a&gt;), eine Software zur Bildübertragung per Wi-Fi oder Miracast (bspw. für Präsentationen) und eine Software die einen KVM Switch nachahmt (&lt;a href=&quot;https://github.com/debauchee/barrier&quot;&gt;Barrier&lt;/a&gt;) enthalten. Insbesondere Barrier stellt einen Segen dar, denn sie erlaubt es Maus/Tastatur, aber auch Dinge wie die Zwischenablage zwischen Computern zu teilen. Ihr könnt also ganz einfach gleichzeitig an eurem Desktop, einem Raspberry PI und beispielsweise eurem Laptop arbeiten ohne die Hand von der Tastatur nehmen zu müssen. Sehr praktisch!&lt;/p&gt;

&lt;p&gt;Ebenfalls nennenswert ist vielleicht dass ZorinOS für seine &lt;em&gt;Pro&lt;/em&gt; Version einen Update Support bis &lt;em&gt;mindestens&lt;/em&gt; 04/2025 angekündigt hat und für seine Kunden einen Installationssupport bietet.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Zorin Grid&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Grid wurde bisher nur angekündigt und scheint ein Tool zu sein dass die Linie der &lt;em&gt;Pro&lt;/em&gt; Version fortsetzen soll.
Die Software soll wohl eine Art Administrationsoberfläche für ein Netzwerk aus ZorinOS Rechnern bieten.
Das geht zwar alles bereits jetzt schon mit &lt;a href=&quot;https://unix.stackexchange.com/questions/40401/linux-bulk-remote-administration&quot;&gt;anderer Software&lt;/a&gt;. Die meisten tools richten sich dabei aber an den professionellen Administrator und bieten häufig nur, für den Laien, unzugängliche Kommandozeilentools.&lt;/p&gt;

&lt;p&gt;Grid scheint sich für mich eher an “Freizeit-Admins” zu richten, beispielsweise in kleineren Firmen oder Schulen, die die Administration &lt;em&gt;nebenher&lt;/em&gt; erledigen sollen und für die eine einfach zugängliche UI ohne große Einarbeitungszeit wichtig ist.&lt;/p&gt;

&lt;p&gt;Bisher ist Grid noch nicht erschienen, es lohnt sich aber die Augen offen zu halten.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fazit&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;ZorinOS bringt ein auf Hochglanz poliertes Gesamtpaket mit bei dem zwar nur wenig wirklich neue Software auf den Tisch kommt, dafür aber die vorhandene Software exzellent in das System integriert wurde und besonderes Augenmerk darauf gelegt wurde, dass alles wie aus einem Guss funktioniert.&lt;/p&gt;

&lt;p&gt;Wer momentan Windows nutzt, aber gerne einmal sein Glück mit Linux versuchen möchte der sollte einen genauen Blick auf ZorinOS werfen.&lt;/p&gt;

&lt;p&gt;Vor allem kleinere Firmen, Schulen und Selbstständige könnten darüberhinaus mit der &lt;em&gt;Pro&lt;/em&gt; Version glücklich werden. 
Diese scheint sich mit ihrem geringen Preis und der Software an professionelle User zu richten, ohne direkt die Kosten für eine &lt;em&gt;echte&lt;/em&gt; Enterprise Distribution wie Red Hat oder Suse zu verursachen.&lt;/p&gt;

&lt;h4 id=&quot;fedora&quot;&gt;Fedora&lt;/h4&gt;

&lt;h4 id=&quot;centos&quot;&gt;CentOS&lt;/h4&gt;

&lt;h4 id=&quot;manjaro&quot;&gt;Manjaro&lt;/h4&gt;

&lt;h4 id=&quot;elementaryos&quot;&gt;ElementaryOS&lt;/h4&gt;

&lt;h3 id=&quot;fußnoten&quot;&gt;Fußnoten&lt;/h3&gt;
&lt;div class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
  &lt;ol&gt;
    &lt;li id=&quot;fn:rollingRelease&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;Unter einem rolling release versteht man eine Distribution ohne feste Versionsnummern. Diese Distribution wird ständig und nach Bedarf weiterentwickelt und nicht nach einem festgelegten Zeitplan. &lt;a href=&quot;#fnref:rollingRelease&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;
</content>
 </entry>
 
 <entry>
   <title>Linux Basics Teil 1 - Einführung</title>
   <link href="https://herr-breier.de/2021/08/14/Linux-Basics-Teil-1/"/>
   <updated>2021-08-14T00:00:00+00:00</updated>
   <id>https://herr-breier.de/2021/08/14/Linux-Basics-Teil-1</id>
   <content type="html">&lt;h1 id=&quot;was-ist-linux-überhaupt-eine-kurze-einleitung&quot;&gt;Was ist Linux überhaupt? Eine kurze Einleitung.&lt;/h1&gt;

&lt;p&gt;Sicherlich haben die meisten schon von Linux gehört, insbesondere Leute die (vermutlich gezielt) nach einem Blog wie meinem suchen. Deshalb möchte ich mich auch nicht mit ausschweifenden Erklärungen aufhalten. Dennoch gibt es ein paar (historische) Begriffe und Zusammenhänge die vielleicht ganz interessant zu wissen sind. Vielleicht sollte man diesen Abschnitt als eine Art sehr rudimentären Glossar betrachten.&lt;/p&gt;

&lt;h2 id=&quot;linux&quot;&gt;Linux&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;https://www.linux.com/what-is-linux/&quot;&gt;Linux.com&lt;/a&gt; sagt zu der Frage was Linux ist folgendes:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Just like Windows, iOS, and Mac OS, Linux is an operating system. In fact, one of the most popular platforms on the planet, Android, is powered by the Linux operating system. An operating system is software that manages all of the hardware resources associated with your desktop or laptop. To put it simply, the operating system manages the communication between your software and your hardware. Without the operating system (OS), the software wouldn?t function.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Das ist soweit auch richtig, aber doch in der Definition sehr breit gezogen. Spricht man von Linux im engeren Sinne meint man damit eigentlich immer den &lt;em&gt;Linux Kernel&lt;/em&gt;. Dabei versteht man unter dem Linux Kernel schlicht die basale Softwareebene die quasi die Kommunikation zwischen der Hardware (sprich: Prozessor, Arbeitsspeicher, Festplatten, …) sicherstellt und die Kommunikation mit dem “eigentlichen” Betriebssystem sicherstellt. Hier drängt sich natürlich der Verdacht auf dass auch andere Betriebssysteme etwas wie  einen Kernel verwenden und so ist es auch:  sowohl Microsoft Windows als auch MacOS (bzw. Darwin als Grundlage) verwenden ebenfalls einen Kernel. Da diese Systeme dem Nutzer aber weniger Mitspracherecht einräumen bekommt man von dieser Systemkomponente (im Guten wie im Schlechten) kaum etwas mit.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://upload.wikimedia.org/wikipedia/commons/4/46/Linux_Kernel_Struktur.svg&quot; alt=&quot;Die Aufgabenbereiche des Linux Kernels&quot; /&gt;&lt;em&gt;Die Aufgabenbereiche des Linux Kernels&lt;/em&gt;&lt;sup id=&quot;fnref:Kernel&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:Kernel&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;

&lt;h2 id=&quot;gnulinux-unix-posix-und-die-coreutils&quot;&gt;GNU/Linux, Unix, Posix und die coreutils&lt;/h2&gt;

&lt;p&gt;Im Zusammenhang mit Linux hört man immer wieder Begriffe wie Unix, GNU, coreutils und andere und das kann sehr verwirrend werden. Ich möchte die Begrifflichkeiten hier etwas entwirren.&lt;/p&gt;

&lt;p&gt;Unix war ursprünglich ein von Bell Labs entwickeltes Betriebssystem das Ende der 1960er Jahre entwickelt wurde. Allgemein eines der Features war dass Firmen das Betriebssystem an ihre Bedürfnisse anpassen konnten. Dadurch entwickelten sich sehr viele unterschiedliche Ableger des ursprünglichen Systems. Der Begriff UNIX ist übrigens eine eingetragene Marke und darf nur von zertifizierten Produkten verwendet werden. Unix-artige Systeme werden deshalb in aller Regel als “Unix” bezeichnet.&lt;/p&gt;

&lt;p&gt;Die Unix-artigen Systeme kann man dabei hauptsächlich in zwei Gruppen einteilen:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Unix-derivate Systeme&lt;/li&gt;
  &lt;li&gt;Unixoide Systeme
&lt;br /&gt;
&lt;br /&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;unix-derivate&quot;&gt;Unix Derivate&lt;/h3&gt;

&lt;p&gt;Unter Unix Derivaten versteht man im wesentlichen Betriebssysteme die auf dem alten Unix Quellcode von Bell Labs aufbauen und entwickelt wurden. Dazu zählen bspw. das ursprüngliche BSD, HP-UX, AIX, Solaris und auch MacOS.&lt;/p&gt;

&lt;h3 id=&quot;unixoide-systeme&quot;&gt;Unixoide Systeme&lt;/h3&gt;

&lt;p&gt;Im Gegensatz dazu stehen die Unixoiden Systeme die zwar mit Unix (mehr oder weniger) kompatibel sind und den zugrundeliegenden POSIX Standard erfüllen, aber ohne den ursprünglichen Quellcode von Bell Labs entwickelt wurden. Hierzu gehören beispielsweise das (moderne) BSD, aber auch zum Beispiel Linux.&lt;/p&gt;

&lt;h3 id=&quot;posix-und-die-kompatibilität&quot;&gt;POSIX und die Kompatibilität&lt;/h3&gt;

&lt;p&gt;Wie zuvor angedeutet gibt es einen Standard der die Funktionalitäten eines Unix Systems regelt um eine Portabilität und Kompatibilität zwischen den diversen Unix Derivaten zu gewährleisten. Das Reglement des Standards findet man beispielsweise hier: &lt;a href=&quot;https://pubs.opengroup.org/onlinepubs/9699919799.2018edition/&quot;&gt;POSIX&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id=&quot;gnu-und-die-coreutils&quot;&gt;GNU und die coreutils&lt;/h3&gt;

&lt;p&gt;GNU (steht für &lt;em&gt;“GNU is not UNIX”&lt;/em&gt;) wurde ursprünglich als Initiative gegründet um ein Unix-artiges System mit kompatiblen Tools zu entwickeln welches eine komplett freie Alternative zum Produkt der Bell Labs darstellen sollte. Zu diesem Zweck wurden beispielsweise die ganzen Basisprogramme von Unix für das GNU Projekt neu geschrieben (&lt;em&gt;“coreutils”&lt;/em&gt;).&lt;/p&gt;

&lt;p&gt;Dabei wurde aber bewusst an einigen Stellen der POSIX Standard verletzt und es wurden Programme teils um diverse Funktionen erweitert die so in anderen Unix Systemen nicht vorkommen!&lt;/p&gt;

&lt;p&gt;Leider handelt es sich dabei sehr häufig um tatsächlich genutzte Funktionalitäten. Ein Beispiel wäre folgendes&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Bash&quot;&gt;sed -i &apos;s/x/u/&apos; meineDatei
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In diesem Beispiel durchsucht das Programm “sed” die Datei “meineDatei” und ersetzt jedes “x” durch ein “u”. Sed ist eigentlich aber ein Stream-Editor und verändert deshalb nur den output ohne die ursprüngliche Datei zu verändern. Dafür ist das -i flag da, das sed signalisiert dass es die ursprüngliche Datei überschreiben soll.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Dieses flag ist &lt;strong&gt;nicht&lt;/strong&gt; POSIX konform!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Das bedeutet dass das -i flag so nur unter den GNU coreutils verfügbar ist. Damit sind beispielsweise entsprechend verfasste Skripte nicht frei auf andere Unix-Systeme übertragbar und es kann durchaus vorkommen dass man auf seinem Ubuntu System ein Skript schreibt und dieses dann auf dem Mac vom Chef nicht lauffähig ist.&lt;/p&gt;

&lt;p&gt;Leider ist mir nicht bekannt dass es irgendwo eine ausführliche Liste dieser inkompatiblen flags geben würde. Man ist hier also leider ein wenig der Göttin Fortuna ausgeliefert.&lt;/p&gt;

&lt;h3 id=&quot;alternativen&quot;&gt;Alternativen&lt;/h3&gt;

&lt;p&gt;Ich möchte allerdings nicht verschweigen dass es auch POSIX kompatible Alternativen gibt, beispielsweise &lt;a href=&quot;https://9fans.github.io/plan9port/&quot;&gt;Plan 9 from User Space&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Diese Alternativen zu den GNU coreutils bringen allerdings ganz eigene Probleme mit sich, unter anderem den reduzierten (POSIX entsprechenden) Funktionsumfang und teilweise auch die Größe der Projekte und die dadurch entstehenden Risiken was die Zukunft, Bugfixing etc. eines Projekts angeht.&lt;/p&gt;

&lt;p&gt;Es gibt auch komplette, GNU freie, Linux Distributionen wie beispielsweise &lt;a href=&quot;https://www.alpinelinux.org/&quot;&gt;Alpine&lt;/a&gt;
&lt;br /&gt;&lt;/p&gt;
&lt;hr /&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h2 id=&quot;fußnoten&quot;&gt;Fußnoten&lt;/h2&gt;
&lt;div class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
  &lt;ol&gt;
    &lt;li id=&quot;fn:Kernel&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;Das Bild wurde aus dem umfangreichen &lt;a href=&quot;https://de.wikipedia.org/wiki/Linux&quot;&gt;Artikel auf Wikipedia&lt;/a&gt; übernommen &lt;a href=&quot;#fnref:Kernel&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;
</content>
 </entry>
 

</feed>
