<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>private Homepage von Rainer Rose</title>
    <link>https://www.rainerrose.de/</link>
    <description>Recent content on private Homepage von Rainer Rose</description>
    <generator>Hugo</generator>
    <language>de</language>
    <copyright>Copyright © 1998-2026 Rainer Rose. All Rights Reserved.
</copyright>
    <lastBuildDate>Tue, 24 Mar 2026 17:51:10 +0100</lastBuildDate><atom:link href="https://www.rainerrose.de/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Changelog 24.03.2026</title>
      <link>https://www.rainerrose.de/posts/2026/2026-03-24/</link>
      <pubDate>Tue, 24 Mar 2026 17:51:10 +0100</pubDate>
      <guid>https://www.rainerrose.de/posts/2026/2026-03-24/</guid>
      <description><![CDATA[<!-- Anreißer -->

<h2 id="welche-artikel-haben-sich-geändert" data-numberify>Welche Artikel haben sich geändert?<a class="anchor ms-1" href="#welche-artikel-haben-sich-geändert"></a></h2>
<table>
  <thead>
      <tr>
          <th>Seite</th>
          <th>Änderung</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><a href="/docs/linux/docker/">Docker</a></td>
          <td>Erstellungsdatum (Created) eines Images abfragen</td>
      </tr>
      <tr>
          <td><a href="/docs/howto/git/">GIT</a></td>
          <td>Letzte Commit-Message ändern</td>
      </tr>
      <tr>
          <td><a href="/posts/2025/mein-setup-kontakte-kalender-email-passwoerter/">Mein Setup: Kontakte, Kalender, EMail, Passwörter</a></td>
          <td>Typo fixed, Vaultwarden: Hinweis auf Admin-Seite und ein paar Unterüberschriften in diesem Absatz hinzugefügt.</td>
      </tr>
      <tr>
          <td><a href="/posts/2025/mein-setup-kontakte-kalender-email-passwoerter">Nextcloud - Einrichtung eines PAT</a></td>
          <td>Typo fixed</td>
      </tr>
      <tr>
          <td><a href="/docs/linux/sed/">sed</a></td>
          <td><code>[[:space:]]</code> Trick</td>
      </tr>
      <tr>
          <td><a href="/docs/linux/sonstiges/">Sonstiges</a></td>
          <td><code>root</code> passwort wieder löschen</td>
      </tr>
      <tr>
          <td><a href="/docs/linux/systemd/">Systemd</a></td>
          <td><code>failed</code>-Kommandos hinzugefügt</td>
      </tr>
  </tbody>
</table>]]></description>
      <content:encoded><![CDATA[<!-- Anreißer -->

<h2 id="welche-artikel-haben-sich-geändert" data-numberify>Welche Artikel haben sich geändert?<a class="anchor ms-1" href="#welche-artikel-haben-sich-geändert"></a></h2>
<table>
  <thead>
      <tr>
          <th>Seite</th>
          <th>Änderung</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><a href="/docs/linux/docker/">Docker</a></td>
          <td>Erstellungsdatum (Created) eines Images abfragen</td>
      </tr>
      <tr>
          <td><a href="/docs/howto/git/">GIT</a></td>
          <td>Letzte Commit-Message ändern</td>
      </tr>
      <tr>
          <td><a href="/posts/2025/mein-setup-kontakte-kalender-email-passwoerter/">Mein Setup: Kontakte, Kalender, EMail, Passwörter</a></td>
          <td>Typo fixed, Vaultwarden: Hinweis auf Admin-Seite und ein paar Unterüberschriften in diesem Absatz hinzugefügt.</td>
      </tr>
      <tr>
          <td><a href="/posts/2025/mein-setup-kontakte-kalender-email-passwoerter">Nextcloud - Einrichtung eines PAT</a></td>
          <td>Typo fixed</td>
      </tr>
      <tr>
          <td><a href="/docs/linux/sed/">sed</a></td>
          <td><code>[[:space:]]</code> Trick</td>
      </tr>
      <tr>
          <td><a href="/docs/linux/sonstiges/">Sonstiges</a></td>
          <td><code>root</code> passwort wieder löschen</td>
      </tr>
      <tr>
          <td><a href="/docs/linux/systemd/">Systemd</a></td>
          <td><code>failed</code>-Kommandos hinzugefügt</td>
      </tr>
  </tbody>
</table>

<h2 id="warum-diese-seite" data-numberify>Warum diese Seite?<a class="anchor ms-1" href="#warum-diese-seite"></a></h2>
<p>Ab und zu ändere Artikel oder korrigiere Rechtschreibfehler. Manchmal füge dort weitere Informationen hinzu, die keinen eigenen Blogartikel wert sind.
Damit ich diese Änderungen kommunizieren kann, erstelle ich ab und zu solche Übersichtsseiten, wie Ihr hier sie gerade lest.
Eine tabellarische Übersicht der Änderungen mit Verlinkungen auf die jeweiligen Seiten.</p>

<h2 id="technischer-hintergrund" data-numberify>Technischer Hintergrund<a class="anchor ms-1" href="#technischer-hintergrund"></a></h2>
<p>Den Zeitstempel des Artikel zu ändern, bringt RSS-Feeds durcheinander und es ist dann ggf. auch nicht gleich ersichtlich, was geändert worden ist.
Da ich sowieso <code>git commit</code> Messages schreibe, kann ich die auch gleich auswerte, als Tabelle erstellen. Ein Script nimmt dann diese Tabelle und erstellt mit einem Template eine neue Seite im Blog.</p>]]></content:encoded>
    <enclosure url="https://www.rainerrose.de/wallpaper/kodensstreifen_u_turn.jpg" length="114844" type="image/.jpg" />
    </item>
    
    <item>
      <title>Sonntagsspaziergang</title>
      <link>https://www.rainerrose.de/posts/2026/sonntagsspaziergang/</link>
      <pubDate>Sun, 22 Feb 2026 22:06:03 +0100</pubDate>
      <guid>https://www.rainerrose.de/posts/2026/sonntagsspaziergang/</guid>
      <description><![CDATA[<!-- Anreißer -->
<p>Die <a href="https://tools.rainerrose.de/redirect.php?id=62" target="_blank" rel="noopener noreferrer">Miss Megaphon<i class="fas fa-external-link-square-alt ms-1"></i></a> hat auf <a href="https://tools.rainerrose.de/redirect.php?id=63" target="_blank" rel="noopener noreferrer">Mastodon<i class="fas fa-external-link-square-alt ms-1"></i></a> einen kleinen Zettel für eine Sonntagsrallye veröffentlicht, um Kinder an die frische Luft zu bekommen.</p>]]></description>
      <content:encoded><![CDATA[<!-- Anreißer -->
<p>Die <a href="https://tools.rainerrose.de/redirect.php?id=62" target="_blank" rel="noopener noreferrer">Miss Megaphon<i class="fas fa-external-link-square-alt ms-1"></i></a> hat auf <a href="https://tools.rainerrose.de/redirect.php?id=63" target="_blank" rel="noopener noreferrer">Mastodon<i class="fas fa-external-link-square-alt ms-1"></i></a> einen kleinen Zettel für eine Sonntagsrallye veröffentlicht, um Kinder an die frische Luft zu bekommen.</p>
<p>In Zusammenarbeit mit Ihr und mit Ihrer Genehmigung habe ich davon ein veröffentlichbares PDF erstellt und stelle es hier zur Verfügung. &ldquo;Mein&rdquo; &ldquo;Original&rdquo; ist eine Markdown-Datei, die ich ebenfalls hier zum Download anbiete.</p>
<p>Ihr dürft es gerne frei verwenden; wir beide würden uns aber über eine kleine Erwähnung freuen.</p>
<ul>
<li><a href="/images/docs/sonntagsspaziergang.md">sonntagsspaziergang.md</a></li>
<li><a href="/images/docs/sonntagsspaziergang.pdf">sonntagsspaziergang.pdf</a></li>
</ul>]]></content:encoded>
    <enclosure url="https://www.rainerrose.de/images/docs/sonntagsspaziergang-klein.png" length="22996" type="image/.png" />
    </item>
    
    <item>
      <title>Paperless-ngx: Major-Upgrade oder Wechsel der Datenbank in Docker</title>
      <link>https://www.rainerrose.de/docs/howto/paperless-postgres-mariadb-upgrades/</link>
      <pubDate>Sun, 22 Feb 2026 18:21:03 +0100</pubDate>
      <guid>https://www.rainerrose.de/docs/howto/paperless-postgres-mariadb-upgrades/</guid>
      <description><![CDATA[<!-- Anreißer -->
<p>Durch Freunde wurde ich auf das Document Management System <code>paperless</code> aufmerksam, dass im derzeit aktuellen Fork <a href="https://tools.rainerrose.de/redirect.php?id=56" target="_blank" rel="noopener noreferrer">paperless-ngx<i class="fas fa-external-link-square-alt ms-1"></i></a> weiterlebt.
In Verbindung mit einem Einzugsscanner ist es ein wahr gewordener Traum, der mich sehr in meinem Alltag entlastet.</p>
<p>Das Aktualisieren von <em>paperless-ngx</em> (im Folgenden nur noch <em>paperless</em> genannt) unter <em>Docker</em> ist zwar in der <a href="https://tools.rainerrose.de/redirect.php?id=57" target="_blank" rel="noopener noreferrer">Dokumentation<i class="fas fa-external-link-square-alt ms-1"></i></a> recht gut beschrieben, aber das Updaten der Datenbank, finde ich zu kompliziert, weil es nur auf die offizielle <em>PostgreSQL</em>-Dokumentation verweist.</p>
<p>Hier müsste ich mit den CLI-Tools wie <code>pg_dumpall</code> und <code>pg_upgrade</code>  hantieren, was arbeiten im <em>Docker</em>-Container notwendig macht und vermutlich auch doppelte <em>Docker</em>-Container-Instanzen nötig macht. Eine automagische Migration unterstützen die <em>postgres</em>-images nach meinem Wissen derzeit nicht. Also habe ich eine andere Möglichkeit gesucht und auch gefunden!</p>]]></description>
      <content:encoded><![CDATA[<!-- Anreißer -->
<p>Durch Freunde wurde ich auf das Document Management System <code>paperless</code> aufmerksam, dass im derzeit aktuellen Fork <a href="https://tools.rainerrose.de/redirect.php?id=56" target="_blank" rel="noopener noreferrer">paperless-ngx<i class="fas fa-external-link-square-alt ms-1"></i></a> weiterlebt.
In Verbindung mit einem Einzugsscanner ist es ein wahr gewordener Traum, der mich sehr in meinem Alltag entlastet.</p>
<p>Das Aktualisieren von <em>paperless-ngx</em> (im Folgenden nur noch <em>paperless</em> genannt) unter <em>Docker</em> ist zwar in der <a href="https://tools.rainerrose.de/redirect.php?id=57" target="_blank" rel="noopener noreferrer">Dokumentation<i class="fas fa-external-link-square-alt ms-1"></i></a> recht gut beschrieben, aber das Updaten der Datenbank, finde ich zu kompliziert, weil es nur auf die offizielle <em>PostgreSQL</em>-Dokumentation verweist.</p>
<p>Hier müsste ich mit den CLI-Tools wie <code>pg_dumpall</code> und <code>pg_upgrade</code>  hantieren, was arbeiten im <em>Docker</em>-Container notwendig macht und vermutlich auch doppelte <em>Docker</em>-Container-Instanzen nötig macht. Eine automagische Migration unterstützen die <em>postgres</em>-images nach meinem Wissen derzeit nicht. Also habe ich eine andere Möglichkeit gesucht und auch gefunden!</p>
<p><code>paperless</code> liefert die beiden Tools <code>document_exporter</code> und <code>document_importer</code> mit, die ein <strong>vollständiges</strong> Backup und Wiederherstellung (Restore) der kompletten Instanz bereitstellt.</p>
<p>Mit diesen beiden Tools lässt sich ein Major-Upgrade bewerkstelligen. Wie ich heute rausfand ist sogar der Wechsel der Datenbank-Engine ohne allzu große Umstände möglich.</p>

<h2 id="überblick" data-numberify>Überblick<a class="anchor ms-1" href="#überblick"></a></h2>
<p>Der grobe Pfad für ein Major-Upgrade ist daher:</p>
<ul>
<li>Zuerst ein vollständiges Backup anfertigen.</li>
<li>Alle Daten inklusive Volumes wegwerfen.</li>
<li>Die <em>PostgreSQL</em>-Version im <code>docker-compose.yml</code> anpassen.</li>
<li>Schlussendlich alle Daten wieder importieren.</li>
</ul>
<p>Das hat bisher anstandslos geklappt.</p>
<p>Der Wechsel auf eine andere Datenbank-Engine wird weiter unten beschrieben.</p>

<h2 id="voraussetzungen" data-numberify>Voraussetzungen<a class="anchor ms-1" href="#voraussetzungen"></a></h2>
<p>Es setzt voraus, dass die Daten außerhalb der Docker-Umgebung landen. Das <code>export</code> Volume ist also als Verzeichnis unterhalb der <code>docker-compose.yml</code> so wie in den <a href="https://tools.rainerrose.de/redirect.php?id=58" target="_blank" rel="noopener noreferrer">Beispielen<i class="fas fa-external-link-square-alt ms-1"></i></a> definiert.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="ln">1</span><span class="cl"><span class="w">      </span>- <span class="l">./export:/usr/src/paperless/export</span><span class="w">
</span></span></span></code></pre></div><p>Wie ich ein Datenbank-Upgrade im Detail durchführe, beschreibe ich im Folgenden.</p>
<p>Zuerst sollte sichergestellt sein, dass keine Importe ins <em>Paperless</em> stattfinden. Da ich alleine auf dem System arbeite und keinen E-Mail-Import verwende, kann ich das gut sicherstellen.</p>

<h2 id="backup" data-numberify>Backup<a class="anchor ms-1" href="#backup"></a></h2>
<p>Als ersten Schritt fertige ich ein Backup an. Dies geht wunderbar mit dem bereits erwähnten <code>document_exporter</code> folgendermaßen:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">docker compose <span class="nb">exec</span> -T webserver document_exporter ../export -z -zn full-backup
</span></span></code></pre></div><p>Hier sollte dann eine Datei namens <code>full-backup.zip</code> außerhalb des Docker-Umgebung entstanden sein. Dies enthält alle relevanten Informationen für ein Desaster-Recovery.</p>

<blockquote class="alert alert-success" role="alert">
    <p class="alert-heading fw-bold">
      <i class="fas fa-lightbulb me-2"></i>Tipp
    </p>
    <p>Der zusätzliche Parameter <code>--no-progress-bar</code> sorgt für weniger Ausgaben in Backup-Scripten.</p>
</blockquote>

<h2 id="zurück-auf-null" data-numberify>Zurück auf Null<a class="anchor ms-1" href="#zurück-auf-null"></a></h2>
<p>Danach fahre ich alle Container herunter und lösche gleichzeitig alle <em>Docker</em> Volumes:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">docker compose down --volumes
</span></span></code></pre></div><p>Die Ausgabe sollte ungefähr so aussehen:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="ln">1</span><span class="cl">[+] down 8/8
</span></span><span class="line"><span class="ln">2</span><span class="cl"> ✔ Container paperless-webserver-1 Removed   5.6s
</span></span><span class="line"><span class="ln">3</span><span class="cl"> ✔ Container paperless-broker-1    Removed   0.4s
</span></span><span class="line"><span class="ln">4</span><span class="cl"> ✔ Container paperless-db-1        Removed   0.3s
</span></span><span class="line"><span class="ln">5</span><span class="cl"> ✔ Volume paperless_media          Removed   0.2s
</span></span><span class="line"><span class="ln">6</span><span class="cl"> ✔ Volume paperless_pgdata         Removed   0.0s
</span></span><span class="line"><span class="ln">7</span><span class="cl"> ✔ Volume paperless_data           Removed   0.0s
</span></span><span class="line"><span class="ln">8</span><span class="cl"> ✔ Volume paperless_redisdata      Removed   0.0s
</span></span><span class="line"><span class="ln">9</span><span class="cl"> ✔ Network paperless_default       Removed                     
</span></span></code></pre></div>
<h2 id="neue-version-wählen" data-numberify>Neue Version wählen<a class="anchor ms-1" href="#neue-version-wählen"></a></h2>
<p>Nun kann ich in der <code>docker-compose.yml</code>-Datei das Datenbank-Image auf die gewünschte Version der Datenbank hochziehen.</p>
<p>Für PostgreSQL gibt es <a href="https://tools.rainerrose.de/redirect.php?id=59" target="_blank" rel="noopener noreferrer">hier im Repo eine Vorlage<i class="fas fa-external-link-square-alt ms-1"></i></a> an der ich mich orientiert habe. Im Mai 2025 war es die Version 17.
Also änderte ich den Eintrag <code>docker-compose.yml</code> von der Version 16.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="ln">1</span><span class="cl"><span class="w">  </span><span class="nt">db</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="w">    </span><span class="nt">image</span><span class="p">:</span><span class="w"> </span><span class="l">docker.io/library/postgres:16</span><span class="w">
</span></span></span></code></pre></div><p>auf die Version 17</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="ln">1</span><span class="cl"><span class="w">  </span><span class="nt">db</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="w">    </span><span class="nt">image</span><span class="p">:</span><span class="w"> </span><span class="l">docker.io/library/postgres:17</span><span class="w">
</span></span></span></code></pre></div><p>Es empfiehlt sich eh ab und zu da mal einzuschauen, ob nicht z.B. eine neue redis-Version unterstützt wird.
Ich selbst stütze mich nur auf die Haupt (Major-Versionen). Bei Minor- oder Patch-Updates pulle ich das jeweilige neue Image und starte alle Docker-Container neu, das reicht mir und hat sich bei mir bewährt.</p>

<blockquote class="alert alert-warning" role="alert">
    <p class="alert-heading fw-bold">
      <i class="fas fa-exclamation-circle me-2"></i>Hinweis
    </p>
    <p>Aktuell ist im Repo die <em>PostgreSQL</em>-Version 18 angegeben. Leider wirft der Docker-Container <code>db-1</code> einiges an Fehlermeldungen und startet sich immer wieder neu. Eine Lösung dazu beschreibe ich weiter unten; hier soll es jetzt erst einmal mit dem Upgrade von 16 auf 17 weiter gehen; schließlich hat das Update von 15 auf 16 vor einiger Zeit genauso geklappt.</p>
</blockquote>

<h2 id="erster-start" data-numberify>Erster Start<a class="anchor ms-1" href="#erster-start"></a></h2>
<p>Nach dem Ändern der Major-Version (bzw. des Tags) vom <em>postgres</em>-Image, können die Docker-Container von <em>paperless</em> schon wieder gestartet werden. Sofern das Image lokal noch nicht vorliegt, wird es automatisch heruntergeladen.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">docker compose up -d
</span></span></code></pre></div><p>Folgendes sollte als Ausgabe zu sehen sein:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="ln"> 1</span><span class="cl">[+] up 22/22
</span></span><span class="line"><span class="ln"> 2</span><span class="cl"> ✔ Image docker.io/library/postgres:18 Pulled     15.3s
</span></span><span class="line"><span class="ln"> 3</span><span class="cl"> ✔ Network paperless_default           Created    0.0s
</span></span><span class="line"><span class="ln"> 4</span><span class="cl"> ✔ Volume paperless_data               Created    0.0s
</span></span><span class="line"><span class="ln"> 5</span><span class="cl"> ✔ Volume paperless_media              Created    0.0s
</span></span><span class="line"><span class="ln"> 6</span><span class="cl"> ✔ Volume paperless_redisdata          Created    0.0s
</span></span><span class="line"><span class="ln"> 7</span><span class="cl"> ✔ Volume paperless_pgdata             Created    0.0s
</span></span><span class="line"><span class="ln"> 8</span><span class="cl"> ✔ Container paperless-db-1            Created    0.2s
</span></span><span class="line"><span class="ln"> 9</span><span class="cl"> ✔ Container paperless-broker-1        Created    0.2s
</span></span><span class="line"><span class="ln">10</span><span class="cl"> ✔ Container paperless-webserver-1     Created   
</span></span></code></pre></div><p>Nun muss solange gewartet, bis die Login-Maske wieder mit dem Browser besuchbar ist.</p>
<p>Da dies einer Neuinstallation entspricht und daher Datenbanken etc. eingerichtet werden müssen, dauert dies je nach Rechenpower etwas. Daher ist etwas Geduld erforderlich.</p>
<p>Zeigt&rsquo;s im Browser <code>502 Bad Gateway</code> ist noch nicht alles fertig.  Neugierige werfen ein Blick in die Docker-Logs</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">docker compose logs -f
</span></span></code></pre></div><p>Wenn ungefähr folgende Log-Einträge zu sehen sind</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gdscript3" data-lang="gdscript3"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="n">webserver_1</span>  <span class="o">|</span> <span class="p">[</span><span class="n">tasks</span><span class="p">]</span>
</span></span><span class="line"><span class="ln"> 2</span><span class="cl"><span class="n">webserver_1</span>  <span class="o">|</span>   <span class="o">.</span> <span class="n">documents</span><span class="o">.</span><span class="n">bulk_edit</span><span class="o">.</span><span class="n">delete</span>
</span></span><span class="line"><span class="ln"> 3</span><span class="cl"><span class="n">webserver_1</span>  <span class="o">|</span>   <span class="o">.</span> <span class="n">documents</span><span class="o">.</span><span class="n">signals</span><span class="o">.</span><span class="n">handlers</span><span class="o">.</span><span class="n">send_webhook</span>
</span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="n">webserver_1</span>  <span class="o">|</span>   <span class="o">.</span> <span class="n">documents</span><span class="o">.</span><span class="n">tasks</span><span class="o">.</span><span class="n">bulk_update_documents</span>
</span></span><span class="line"><span class="ln"> 5</span><span class="cl"><span class="n">webserver_1</span>  <span class="o">|</span>   <span class="o">.</span> <span class="n">documents</span><span class="o">.</span><span class="n">tasks</span><span class="o">.</span><span class="n">check_scheduled_workflows</span>
</span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="n">webserver_1</span>  <span class="o">|</span>   <span class="o">.</span> <span class="n">documents</span><span class="o">.</span><span class="n">tasks</span><span class="o">.</span><span class="n">consume_file</span>
</span></span><span class="line"><span class="ln"> 7</span><span class="cl"><span class="n">webserver_1</span>  <span class="o">|</span>   <span class="o">.</span> <span class="n">documents</span><span class="o">.</span><span class="n">tasks</span><span class="o">.</span><span class="n">empty_trash</span>
</span></span><span class="line"><span class="ln"> 8</span><span class="cl"><span class="n">webserver_1</span>  <span class="o">|</span>   <span class="o">.</span> <span class="n">documents</span><span class="o">.</span><span class="n">tasks</span><span class="o">.</span><span class="n">index_optimize</span>
</span></span><span class="line"><span class="ln"> 9</span><span class="cl"><span class="n">webserver_1</span>  <span class="o">|</span>   <span class="o">.</span> <span class="n">documents</span><span class="o">.</span><span class="n">tasks</span><span class="o">.</span><span class="n">sanity_check</span>
</span></span><span class="line"><span class="ln">10</span><span class="cl"><span class="n">webserver_1</span>  <span class="o">|</span>   <span class="o">.</span> <span class="n">documents</span><span class="o">.</span><span class="n">tasks</span><span class="o">.</span><span class="n">train_classifier</span>
</span></span><span class="line"><span class="ln">11</span><span class="cl"><span class="n">webserver_1</span>  <span class="o">|</span>   <span class="o">.</span> <span class="n">documents</span><span class="o">.</span><span class="n">tasks</span><span class="o">.</span><span class="n">update_document_content_maybe_archive_file</span>
</span></span><span class="line"><span class="ln">12</span><span class="cl"><span class="n">webserver_1</span>  <span class="o">|</span>   <span class="o">.</span> <span class="n">paperless_mail</span><span class="o">.</span><span class="n">mail</span><span class="o">.</span><span class="n">apply_mail_action</span>
</span></span><span class="line"><span class="ln">13</span><span class="cl"><span class="n">webserver_1</span>  <span class="o">|</span>   <span class="o">.</span> <span class="n">paperless_mail</span><span class="o">.</span><span class="n">mail</span><span class="o">.</span><span class="n">error_callback</span>
</span></span><span class="line"><span class="ln">14</span><span class="cl"><span class="n">webserver_1</span>  <span class="o">|</span>   <span class="o">.</span> <span class="n">paperless_mail</span><span class="o">.</span><span class="n">tasks</span><span class="o">.</span><span class="n">process_mail_accounts</span>
</span></span><span class="line"><span class="ln">15</span><span class="cl"><span class="n">webserver_1</span>  <span class="o">|</span> 
</span></span><span class="line"><span class="ln">16</span><span class="cl"><span class="n">webserver_1</span>  <span class="o">|</span> <span class="p">[</span><span class="mi">2025</span><span class="o">-</span><span class="mi">05</span><span class="o">-</span><span class="mi">29</span> <span class="mi">12</span><span class="p">:</span><span class="mi">50</span><span class="p">:</span><span class="mi">03</span><span class="p">,</span><span class="mi">792</span><span class="p">]</span> <span class="p">[</span><span class="n">INFO</span><span class="p">]</span> <span class="p">[</span><span class="n">celery</span><span class="o">.</span><span class="n">worker</span><span class="o">.</span><span class="n">consumer</span><span class="o">.</span><span class="n">connection</span><span class="p">]</span> <span class="n">Connected</span> <span class="n">to</span> <span class="n">redis</span><span class="p">:</span><span class="o">//</span><span class="n">broker</span><span class="p">:</span><span class="mi">6379</span><span class="o">//</span>
</span></span><span class="line"><span class="ln">17</span><span class="cl"><span class="n">webserver_1</span>  <span class="o">|</span> <span class="p">[</span><span class="mi">2025</span><span class="o">-</span><span class="mi">05</span><span class="o">-</span><span class="mi">29</span> <span class="mi">12</span><span class="p">:</span><span class="mi">50</span><span class="p">:</span><span class="mi">03</span><span class="p">,</span><span class="mi">982</span><span class="p">]</span> <span class="p">[</span><span class="n">INFO</span><span class="p">]</span> <span class="p">[</span><span class="n">celery</span><span class="o">.</span><span class="n">apps</span><span class="o">.</span><span class="n">worker</span><span class="p">]</span> <span class="n">celery</span><span class="err">@</span><span class="mf">7e94</span><span class="n">fdb4f941</span> <span class="n">ready</span><span class="o">.</span>
</span></span></code></pre></div><p>sollte die Login-Maske zur Einrichtung des ersten Benutzerkontos verfügbar sein und es kann mit dem nächsten Schritt weiter gemacht werden.</p>
<p><picture><img class="img-fluid " alt="Paperless-ngx Anmelde-Maske zur Einrichtung des ersten Benutzerkontos" src="https://www.rainerrose.de/images/docs/paperless-login-initial.png?v=960c44cf92448b0054d81f613282f43c" loading="lazy" width="405" height="716" />
</picture>

</p>

<h2 id="daten-wieder-importieren" data-numberify>Daten wieder importieren<a class="anchor ms-1" href="#daten-wieder-importieren"></a></h2>
<p>Über den <code>document_importer</code> lässt sich nun wieder alles importieren: Alle Dokumente, alle Tags, alle Benutzeraccounts, gespeicherten Ansichten usw.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">docker compose <span class="nb">exec</span> -T webserver document_importer ../export/full-backup.zip
</span></span></code></pre></div><p>Ausgabe:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="ln">1</span><span class="cl">Checking the manifest
</span></span><span class="line"><span class="ln">2</span><span class="cl">Installed 4248 object(s) from 1 fixture(s)
</span></span><span class="line"><span class="ln">3</span><span class="cl">Copy files into paperless...
</span></span><span class="line"><span class="ln">4</span><span class="cl">100%|██████████| 1014/1014 [00:04&lt;00:00, 210.59it/s]
</span></span><span class="line"><span class="ln">5</span><span class="cl">Updating search index...
</span></span><span class="line"><span class="ln">6</span><span class="cl">100%|██████████| 1014/1014 [00:10&lt;00:00, 94.50it/s] 
</span></span></code></pre></div><p>Falls im Browser Weiterleitung auf den Unterpfad <code>/accounts/signup/?next=%2F</code> stattfand, diesen Pfad löschen!
Im Browser also wieder die gewohnte URL ansurfen und es sollte wieder die gewohnte Login-Maske erscheinen.</p>

<h2 id="fertig-anmelden" data-numberify>Fertig, anmelden<a class="anchor ms-1" href="#fertig-anmelden"></a></h2>
<p>Schlussendlich stoße ich noch einmal vorsichtshalber mein Backup-Script von Paperless noch an und bin fertig.</p>

<h2 id="postgresql-18" data-numberify>PostgreSQL 18<a class="anchor ms-1" href="#postgresql-18"></a></h2>
<p>Während ich diesen Artikel schrieb, stellte ich fest, dass in den <a href="https://tools.rainerrose.de/redirect.php?id=60" target="_blank" rel="noopener noreferrer">Vorlagen im Repo<i class="fas fa-external-link-square-alt ms-1"></i></a> zu <code>docker-compose.yml</code> schon <em>PostgreSQL</em> 18 unterstützt wird.
Ich bin daher genau nach meiner Anleitung vorgegangen und musste feststellen, dass der Datenbank-Container nicht nach oben kam.</p>
<p>In den Docker-Logs entdeckte ich dann folgende Meldungen:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gdscript3" data-lang="gdscript3"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="n">db</span><span class="o">-</span><span class="mi">1</span>         <span class="o">|</span> <span class="n">Error</span><span class="p">:</span> <span class="ow">in</span> <span class="mi">18</span><span class="o">+</span><span class="p">,</span> <span class="n">these</span> <span class="n">Docker</span> <span class="n">images</span> <span class="n">are</span> <span class="n">configured</span> <span class="n">to</span> <span class="n">store</span> <span class="n">database</span> <span class="n">data</span> <span class="ow">in</span> <span class="n">a</span>
</span></span><span class="line"><span class="ln"> 2</span><span class="cl"><span class="n">db</span><span class="o">-</span><span class="mi">1</span>         <span class="o">|</span>        <span class="n">format</span> <span class="n">which</span> <span class="n">is</span> <span class="n">compatible</span> <span class="n">with</span> <span class="s2">&#34;pg_ctlcluster&#34;</span> <span class="p">(</span><span class="n">specifically</span><span class="p">,</span> <span class="n">using</span>
</span></span><span class="line"><span class="ln"> 3</span><span class="cl"><span class="n">db</span><span class="o">-</span><span class="mi">1</span>         <span class="o">|</span>        <span class="n">major</span><span class="o">-</span><span class="n">version</span><span class="o">-</span><span class="n">specific</span> <span class="n">directory</span> <span class="n">names</span><span class="p">)</span><span class="o">.</span>  <span class="n">This</span> <span class="n">better</span> <span class="n">reflects</span> <span class="n">how</span>
</span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="n">db</span><span class="o">-</span><span class="mi">1</span>         <span class="o">|</span>        <span class="n">PostgreSQL</span> <span class="n">itself</span> <span class="n">works</span><span class="p">,</span> <span class="ow">and</span> <span class="n">how</span> <span class="n">upgrades</span> <span class="n">are</span> <span class="n">to</span> <span class="n">be</span> <span class="n">performed</span><span class="o">.</span>
</span></span><span class="line"><span class="ln"> 5</span><span class="cl"><span class="n">db</span><span class="o">-</span><span class="mi">1</span>         <span class="o">|</span> 
</span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="n">db</span><span class="o">-</span><span class="mi">1</span>         <span class="o">|</span>        <span class="n">See</span> <span class="n">also</span> <span class="n">https</span><span class="p">:</span><span class="o">//</span><span class="n">github</span><span class="o">.</span><span class="n">com</span><span class="o">/</span><span class="n">docker</span><span class="o">-</span><span class="n">library</span><span class="o">/</span><span class="n">postgres</span><span class="o">/</span><span class="n">pull</span><span class="o">/</span><span class="mi">1259</span>
</span></span><span class="line"><span class="ln"> 7</span><span class="cl"><span class="n">db</span><span class="o">-</span><span class="mi">1</span>         <span class="o">|</span> 
</span></span><span class="line"><span class="ln"> 8</span><span class="cl"><span class="n">db</span><span class="o">-</span><span class="mi">1</span>         <span class="o">|</span>        <span class="n">Counter</span> <span class="n">to</span> <span class="n">that</span><span class="p">,</span> <span class="n">there</span> <span class="n">appears</span> <span class="n">to</span> <span class="n">be</span> <span class="n">PostgreSQL</span> <span class="n">data</span> <span class="ow">in</span><span class="p">:</span>
</span></span><span class="line"><span class="ln"> 9</span><span class="cl"><span class="n">db</span><span class="o">-</span><span class="mi">1</span>         <span class="o">|</span>          <span class="o">/</span><span class="k">var</span><span class="o">/</span><span class="n">lib</span><span class="o">/</span><span class="n">postgresql</span><span class="o">/</span><span class="n">data</span> <span class="p">(</span><span class="n">unused</span> <span class="n">mount</span><span class="o">/</span><span class="n">volume</span><span class="p">)</span>
</span></span><span class="line"><span class="ln">10</span><span class="cl"><span class="n">db</span><span class="o">-</span><span class="mi">1</span>         <span class="o">|</span> 
</span></span><span class="line"><span class="ln">11</span><span class="cl"><span class="n">db</span><span class="o">-</span><span class="mi">1</span>         <span class="o">|</span>        <span class="n">This</span> <span class="n">is</span> <span class="n">usually</span> <span class="n">the</span> <span class="n">result</span> <span class="n">of</span> <span class="n">upgrading</span> <span class="n">the</span> <span class="n">Docker</span> <span class="n">image</span> <span class="n">without</span>
</span></span><span class="line"><span class="ln">12</span><span class="cl"><span class="n">db</span><span class="o">-</span><span class="mi">1</span>         <span class="o">|</span>        <span class="n">upgrading</span> <span class="n">the</span> <span class="n">underlying</span> <span class="n">database</span> <span class="n">using</span> <span class="s2">&#34;pg_upgrade&#34;</span> <span class="p">(</span><span class="n">which</span> <span class="n">requires</span> <span class="n">both</span>
</span></span><span class="line"><span class="ln">13</span><span class="cl"><span class="n">db</span><span class="o">-</span><span class="mi">1</span>         <span class="o">|</span>        <span class="n">versions</span><span class="p">)</span><span class="o">.</span>
</span></span><span class="line"><span class="ln">14</span><span class="cl"><span class="n">db</span><span class="o">-</span><span class="mi">1</span>         <span class="o">|</span> 
</span></span><span class="line"><span class="ln">15</span><span class="cl"><span class="n">db</span><span class="o">-</span><span class="mi">1</span>         <span class="o">|</span>        <span class="n">The</span> <span class="n">suggested</span> <span class="n">container</span> <span class="n">configuration</span> <span class="k">for</span> <span class="mi">18</span><span class="o">+</span> <span class="n">is</span> <span class="n">to</span> <span class="n">place</span> <span class="n">a</span> <span class="n">single</span> <span class="n">mount</span>
</span></span><span class="line"><span class="ln">16</span><span class="cl"><span class="n">db</span><span class="o">-</span><span class="mi">1</span>         <span class="o">|</span>        <span class="n">at</span> <span class="o">/</span><span class="k">var</span><span class="o">/</span><span class="n">lib</span><span class="o">/</span><span class="n">postgresql</span> <span class="n">which</span> <span class="n">will</span> <span class="n">then</span> <span class="n">place</span> <span class="n">PostgreSQL</span> <span class="n">data</span> <span class="ow">in</span> <span class="n">a</span>
</span></span><span class="line"><span class="ln">17</span><span class="cl"><span class="n">db</span><span class="o">-</span><span class="mi">1</span>         <span class="o">|</span>        <span class="n">subdirectory</span><span class="p">,</span> <span class="n">allowing</span> <span class="n">usage</span> <span class="n">of</span> <span class="s2">&#34;pg_upgrade --link&#34;</span> <span class="n">without</span> <span class="n">mount</span> <span class="n">point</span>
</span></span><span class="line"><span class="ln">18</span><span class="cl"><span class="n">db</span><span class="o">-</span><span class="mi">1</span>         <span class="o">|</span>        <span class="n">boundary</span> <span class="n">issues</span><span class="o">.</span>
</span></span><span class="line"><span class="ln">19</span><span class="cl"><span class="n">db</span><span class="o">-</span><span class="mi">1</span>         <span class="o">|</span> 
</span></span><span class="line"><span class="ln">20</span><span class="cl"><span class="n">db</span><span class="o">-</span><span class="mi">1</span>         <span class="o">|</span>        <span class="n">See</span> <span class="n">https</span><span class="p">:</span><span class="o">//</span><span class="n">github</span><span class="o">.</span><span class="n">com</span><span class="o">/</span><span class="n">docker</span><span class="o">-</span><span class="n">library</span><span class="o">/</span><span class="n">postgres</span><span class="o">/</span><span class="n">issues</span><span class="o">/</span><span class="mi">37</span> <span class="k">for</span> <span class="n">a</span> <span class="p">(</span><span class="n">long</span><span class="p">)</span>
</span></span><span class="line"><span class="ln">21</span><span class="cl"><span class="n">db</span><span class="o">-</span><span class="mi">1</span>         <span class="o">|</span>        <span class="n">discussion</span> <span class="n">around</span> <span class="n">this</span> <span class="n">process</span><span class="p">,</span> <span class="ow">and</span> <span class="n">suggestions</span> <span class="k">for</span> <span class="n">how</span> <span class="n">to</span> <span class="k">do</span> <span class="n">so</span><span class="o">.</span>
</span></span><span class="line"><span class="ln">22</span><span class="cl"><span class="n">db</span><span class="o">-</span><span class="mi">1</span> <span class="n">exited</span> <span class="n">with</span> <span class="n">code</span> <span class="mi">1</span> <span class="p">(</span><span class="n">restarting</span><span class="p">)</span>
</span></span></code></pre></div><p>Der Downgrade auf 17 war nach der obigen Anleitung recht schnell erledigt und <em>paperless</em> lief wieder zufriedenstellend mit der Version 17 von <em>PostgreSQL</em>.</p>

<h2 id="umstellung-auf-mariadb-12" data-numberify>Umstellung auf MariaDB 12<a class="anchor ms-1" href="#umstellung-auf-mariadb-12"></a></h2>
<p>Ich nahm dies als Anlass, die Datenbank-Engine auf MariaDB umzustellen.
Im Repo des Projektes gibt es dazu ebenfalls <a href="https://tools.rainerrose.de/redirect.php?id=61" target="_blank" rel="noopener noreferrer">eine Vorlage<i class="fas fa-external-link-square-alt ms-1"></i></a>.
Es gab drei Stellen, die ich dafür anpassen musste.</p>
<p>Es mussten im Abschnitt von <code>db</code> ein paar Umgebungsvariablen und natürlich das <code>image</code> umgestellt werden; hier ist 12 gerade aktuell.</p>
<p>Weiter unten im Abschnitt <code>webserver</code> mussten ebenfalls noch ein paar Umgebungsvariablen hinzugefügt werden.</p>
<p>Als letztes musste ich den Volume-Namen im Abschnitt <code>volumes</code> umbenennen.
Danach konnte ich die Container wieder starten und die Daten importieren, wie weiter oben beschrieben.</p>
<p>Nachfolgend ein <code>diff</code> aus meinem <em>ansible</em>-Playbook. (Ja, ich habe <code>restart</code> auch noch gleich umstellt bzw. an die neue Vorlage aus dem Projekt angeglichen. )</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-diff" data-lang="diff"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="gd">--- a/roles/paperless/files/docker-compose.yml
</span></span></span><span class="line"><span class="ln"> 2</span><span class="cl"><span class="gd"></span><span class="gi">+++ b/roles/paperless/files/docker-compose.yml
</span></span></span><span class="line"><span class="ln"> 3</span><span class="cl"><span class="gi"></span><span class="gu">@@ -28,26 +28,24 @@
</span></span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="gu"></span> 
</span></span><span class="line"><span class="ln"> 5</span><span class="cl"> services:
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">   broker:
</span></span><span class="line"><span class="ln"> 7</span><span class="cl"><span class="gd">-    image: docker.io/library/redis:8
</span></span></span><span class="line"><span class="ln"> 8</span><span class="cl"><span class="gd">-    restart: unless-stopped
</span></span></span><span class="line"><span class="ln"> 9</span><span class="cl"><span class="gd"></span><span class="gi">+    image: docker.io/library/redis:7
</span></span></span><span class="line"><span class="ln">10</span><span class="cl"><span class="gi">+    restart: always
</span></span></span><span class="line"><span class="ln">11</span><span class="cl"><span class="gi"></span>     volumes:
</span></span><span class="line"><span class="ln">12</span><span class="cl">       - redisdata:/data
</span></span><span class="line"><span class="ln">13</span><span class="cl"> 
</span></span><span class="line"><span class="ln">14</span><span class="cl">   db:
</span></span><span class="line"><span class="ln">15</span><span class="cl"><span class="gd">-    image: docker.io/library/mariadb:12
</span></span></span><span class="line"><span class="ln">16</span><span class="cl"><span class="gd">-    restart: unless-stopped
</span></span></span><span class="line"><span class="ln">17</span><span class="cl"><span class="gd"></span><span class="gi">+    image: docker.io/library/postgres:17
</span></span></span><span class="line"><span class="ln">18</span><span class="cl"><span class="gi">+    restart: always
</span></span></span><span class="line"><span class="ln">19</span><span class="cl"><span class="gi"></span>     volumes:
</span></span><span class="line"><span class="ln">20</span><span class="cl"><span class="gd">-      - dbdata:/var/lib/mysql
</span></span></span><span class="line"><span class="ln">21</span><span class="cl"><span class="gd"></span><span class="gi">+      - pgdata:/var/lib/postgresql/data
</span></span></span><span class="line"><span class="ln">22</span><span class="cl"><span class="gi"></span>     environment:
</span></span><span class="line"><span class="ln">23</span><span class="cl"><span class="gd">-      MARIADB_HOST: paperless
</span></span></span><span class="line"><span class="ln">24</span><span class="cl"><span class="gd">-      MARIADB_DATABASE: paperless
</span></span></span><span class="line"><span class="ln">25</span><span class="cl"><span class="gd">-      MARIADB_USER: paperless
</span></span></span><span class="line"><span class="ln">26</span><span class="cl"><span class="gd">-      MARIADB_PASSWORD: paperless
</span></span></span><span class="line"><span class="ln">27</span><span class="cl"><span class="gd">-      MARIADB_ROOT_PASSWORD: paperless
</span></span></span><span class="line"><span class="ln">28</span><span class="cl"><span class="gd"></span><span class="gi">+      POSTGRES_DB: paperless
</span></span></span><span class="line"><span class="ln">29</span><span class="cl"><span class="gi">+      POSTGRES_USER: paperless
</span></span></span><span class="line"><span class="ln">30</span><span class="cl"><span class="gi">+      POSTGRES_PASSWORD: paperless
</span></span></span><span class="line"><span class="ln">31</span><span class="cl"><span class="gi"></span> 
</span></span><span class="line"><span class="ln">32</span><span class="cl">   webserver:
</span></span><span class="line"><span class="ln">33</span><span class="cl">     image: ghcr.io/paperless-ngx/paperless-ngx:latest
</span></span><span class="line"><span class="ln">34</span><span class="cl"><span class="gd">-    restart: unless-stopped
</span></span></span><span class="line"><span class="ln">35</span><span class="cl"><span class="gd"></span><span class="gi">+    restart: always
</span></span></span><span class="line"><span class="ln">36</span><span class="cl"><span class="gi"></span>     depends_on:
</span></span><span class="line"><span class="ln">37</span><span class="cl">       - db
</span></span><span class="line"><span class="ln">38</span><span class="cl">       - broker
</span></span><span class="line"><span class="ln">39</span><span class="cl"><span class="gu">@@ -68,13 +66,9 @@ services:
</span></span></span><span class="line"><span class="ln">40</span><span class="cl"><span class="gu"></span>       - extra.env
</span></span><span class="line"><span class="ln">41</span><span class="cl">     environment:
</span></span><span class="line"><span class="ln">42</span><span class="cl">       PAPERLESS_REDIS: redis://broker:6379
</span></span><span class="line"><span class="ln">43</span><span class="cl"><span class="gd">-      PAPERLESS_DBENGINE: mariadb
</span></span></span><span class="line"><span class="ln">44</span><span class="cl"><span class="gd"></span>       PAPERLESS_DBHOST: db
</span></span><span class="line"><span class="ln">45</span><span class="cl"><span class="gd">-      PAPERLESS_DBUSER: paperless # only needed if non-default username
</span></span></span><span class="line"><span class="ln">46</span><span class="cl"><span class="gd">-      PAPERLESS_DBPASS: paperless # only needed if non-default password
</span></span></span><span class="line"><span class="ln">47</span><span class="cl"><span class="gd">-      PAPERLESS_DBPORT: 3306
</span></span></span><span class="line"><span class="ln">48</span><span class="cl"><span class="gd"></span> volumes:
</span></span><span class="line"><span class="ln">49</span><span class="cl">   data:
</span></span><span class="line"><span class="ln">50</span><span class="cl">   media:
</span></span><span class="line"><span class="ln">51</span><span class="cl"><span class="gd">-  dbdata:
</span></span></span><span class="line"><span class="ln">52</span><span class="cl"><span class="gd"></span><span class="gi">+  pgdata:
</span></span></span><span class="line"><span class="ln">53</span><span class="cl"><span class="gi"></span>   redisdata:
</span></span></code></pre></div>]]></content:encoded>
    <enclosure url="https://www.rainerrose.de/images/docs/paperless.png" length="8086" type="image/.png" />
    </item>
    
    <item>
      <title>Kurzlinks</title>
      <link>https://www.rainerrose.de/docs/kontakt/kurzlinks/</link>
      <pubDate>Tue, 10 Feb 2026 18:12:46 +0100</pubDate>
      <guid>https://www.rainerrose.de/docs/kontakt/kurzlinks/</guid>
      <description><![CDATA[<!-- Anreißer -->
<p>Ich verwendet einen eigenen Dienst um URLs zu kürzen.</p>
<p>Solltest Du aus dieser Seite gelandet sein, kann das mehrere Gründe haben.</p>]]></description>
      <content:encoded><![CDATA[<!-- Anreißer -->
<p>Ich verwendet einen eigenen Dienst um URLs zu kürzen.</p>
<p>Solltest Du aus dieser Seite gelandet sein, kann das mehrere Gründe haben.</p>

<h2 id="großkleinschreibung" data-numberify>Groß/Kleinschreibung<a class="anchor ms-1" href="#großkleinschreibung"></a></h2>
<p>Groß/Kleinschreibung ist wichtig! Falls Du den Link abgeschrieben hast, kontrolliere bitte auf Groß- und Kleinschreibung.
Dies gilt für alle URL (Internet-Adressen)!</p>

<h2 id="ungültig" data-numberify>Ungültig<a class="anchor ms-1" href="#ungültig"></a></h2>
<p>Es kann sein, dass einige Kurz-Links nur zeitweise zur Verfügung stehen. Vielleicht hat sich das Thema erledigt oder es gab andere Gründe den Link zu löschen.</p>

<h2 id="liste-aller-links" data-numberify>Liste aller Links<a class="anchor ms-1" href="#liste-aller-links"></a></h2>
<p>Kannst du nicht eine Liste aller Kurz-Links zur Verfügung stellen?</p>
<p>Hahaha. Nein.</p>

<h2 id="fragen" data-numberify>Fragen<a class="anchor ms-1" href="#fragen"></a></h2>
<p>Meist hast Du eine Kontaktmöglichkeit zu mir: Nutze sie und frage mich.</p>]]></content:encoded>
    <enclosure url="https://www.rainerrose.de/wallpaper/docs/abkuerzung.jpg" length="149521" type="image/.jpg" />
    </item>
    
    <item>
      <title>Backups mit restic und resticprofile</title>
      <link>https://www.rainerrose.de/docs/writings/2025/backups-mit-restic-und-resticprofile/</link>
      <pubDate>Fri, 12 Dec 2025 20:58:00 +0100</pubDate>
      <guid>https://www.rainerrose.de/docs/writings/2025/backups-mit-restic-und-resticprofile/</guid>
      <description><![CDATA[<!-- Anreißer -->

<h2 id="veranstaltungsorte" data-numberify>Veranstaltungsorte<a class="anchor ms-1" href="#veranstaltungsorte"></a></h2>
<ul>
<li>
<ol start="22">
<li>März 2025 auf den <a href="https://tools.rainerrose.de/redirect.php?id=47" target="_blank" rel="noopener noreferrer">Chemnitzer Linux-Tagen 2025<i class="fas fa-external-link-square-alt ms-1"></i></a></li>
</ol>
</li>
<li>
<ol start="11">
<li>Dezember 2025 auf den <a href="https://tools.rainerrose.de/redirect.php?id=54" target="_blank" rel="noopener noreferrer">IT-Tage 2025<i class="fas fa-external-link-square-alt ms-1"></i></a></li>
</ol>
</li>
</ul>

<h2 id="kurzprofil" data-numberify>Kurzprofil<a class="anchor ms-1" href="#kurzprofil"></a></h2>
<p>Dieser Vortrag geht zuerst auf grundlegende Details und die Arbeitsweise von <code>restic</code> ein. Wir besprechen lokalen und Cloud Storage, Verschlüsselung, Snapshots, Restore, sowie verschiedene wichtige Optionen.</p>
<p>Im zweiten Teil erklären wir, wie <code>resticprofile</code> funktioniert. Als Beispiel wird ein Backup-Szenario sowohl mittels <code>restic</code> als auch mit <code>resticprofile</code> aufgebaut, um die Unterschiede in der Handhabung zu verdeutlichen.</p>]]></description>
      <content:encoded><![CDATA[<!-- Anreißer -->

<h2 id="veranstaltungsorte" data-numberify>Veranstaltungsorte<a class="anchor ms-1" href="#veranstaltungsorte"></a></h2>
<ul>
<li>
<ol start="22">
<li>März 2025 auf den <a href="https://tools.rainerrose.de/redirect.php?id=47" target="_blank" rel="noopener noreferrer">Chemnitzer Linux-Tagen 2025<i class="fas fa-external-link-square-alt ms-1"></i></a></li>
</ol>
</li>
<li>
<ol start="11">
<li>Dezember 2025 auf den <a href="https://tools.rainerrose.de/redirect.php?id=54" target="_blank" rel="noopener noreferrer">IT-Tage 2025<i class="fas fa-external-link-square-alt ms-1"></i></a></li>
</ol>
</li>
</ul>

<h2 id="kurzprofil" data-numberify>Kurzprofil<a class="anchor ms-1" href="#kurzprofil"></a></h2>
<p>Dieser Vortrag geht zuerst auf grundlegende Details und die Arbeitsweise von <code>restic</code> ein. Wir besprechen lokalen und Cloud Storage, Verschlüsselung, Snapshots, Restore, sowie verschiedene wichtige Optionen.</p>
<p>Im zweiten Teil erklären wir, wie <code>resticprofile</code> funktioniert. Als Beispiel wird ein Backup-Szenario sowohl mittels <code>restic</code> als auch mit <code>resticprofile</code> aufgebaut, um die Unterschiede in der Handhabung zu verdeutlichen.</p>
<p><code>Restic</code> ist eine Open-Source-Backup-Software, die Daten zuverlässig speichert und vor Verlust schützt. Die Software ist plattformunabhängig und unterstützt viele verschiedene Speicherziele, darunter lokale Festplatten, Cloud-Speicher und Netzwerkprotokolle wie SFTP, REST oder S3. <code>Restic</code> implementiert Deduplizierung und bietet Verschlüsselung, um Backups effizient und sicher zu speichern. Deduplizierung sichert nur neue oder veränderte Daten, damit werden Duplikate vermieden und Speicherplatz wird gespart.</p>
<p><code>Resticprofile</code> ist die logische Ergänzung für <code>restic</code>, welches die Konfiguration und Verwaltung mehrerer Backup-Jobs drastisch vereinfacht und übersichtlicher gestaltet.
Es ermöglicht das Anlegen und Verwalten von Backup-Profilen, die alle nötigen Einstellungen speichern, wie Speicherorte, Backup-Zeiten und weitere Parameter. Dies erleichtert die Automatisierung und die übersichtliche Verwaltung von komplexen Backup-Szenarien, indem es die Bedienung von <code>restic</code> optimiert und wiederkehrende Aufgaben systematisch handhabt. Außerdem kann es die Verwaltung der Cronjobs in verschiedenen Systemen übernehmen.</p>

<h2 id="unterlagen" data-numberify>Unterlagen<a class="anchor ms-1" href="#unterlagen"></a></h2>

<h3 id="chemnitzer-linux-tage-2025" data-numberify>Chemnitzer Linux-Tage 2025<a class="anchor ms-1" href="#chemnitzer-linux-tage-2025"></a></h3>
<p>Den Vortrag habe ich das erste Mal zusammen mit <a href="https://tools.rainerrose.de/redirect.php?id=49" target="_blank" rel="noopener noreferrer">Andreas Scherbaum<i class="fas fa-external-link-square-alt ms-1"></i></a> auf den
<a href="https://tools.rainerrose.de/redirect.php?id=47" target="_blank" rel="noopener noreferrer">Chemnitzer Linux-Tagen 2025<i class="fas fa-external-link-square-alt ms-1"></i></a> gehalten.</p>
<ul>
<li><a href="https://tools.rainerrose.de/redirect.php?id=48" target="_blank" rel="noopener noreferrer">Programmankündigung<i class="fas fa-external-link-square-alt ms-1"></i></a></li>
<li><a href="https://download.rainerrose.de/Backups_mit_restic_und_resticprofile.pdf" target="_blank" rel="noopener noreferrer">Folien<i class="fas fa-external-link-square-alt ms-1"></i></a></li>
<li><a href="https://tools.rainerrose.de/redirect.php?id=51" target="_blank" rel="noopener noreferrer">Aufzeichnung<i class="fas fa-external-link-square-alt ms-1"></i></a></li>
</ul>

<h3 id="it-tage-2025" data-numberify>IT-Tage 2025<a class="anchor ms-1" href="#it-tage-2025"></a></h3>
<p>Ein weiteres Mal habe ich den Vortag mit <a href="https://tools.rainerrose.de/redirect.php?id=49" target="_blank" rel="noopener noreferrer">Andreas Scherbaum<i class="fas fa-external-link-square-alt ms-1"></i></a> auf den
<a href="https://tools.rainerrose.de/redirect.php?id=54" target="_blank" rel="noopener noreferrer">IT-Tage 2025<i class="fas fa-external-link-square-alt ms-1"></i></a> gehalten.</p>
<ul>
<li><a href="https://tools.rainerrose.de/redirect.php?id=55" target="_blank" rel="noopener noreferrer">Programmankündigung<i class="fas fa-external-link-square-alt ms-1"></i></a></li>
<li><a href="https://download.rainerrose.de/Backups_mit_Restic_und_resticprofile_IT-Tage_2025.pdf" target="_blank" rel="noopener noreferrer">Folien<i class="fas fa-external-link-square-alt ms-1"></i></a></li>
<li><strong>Aufzeichnung</strong>: Es gab keine Aufzeichnung.</li>
</ul>

<h2 id="changelog" data-numberify>Changelog<a class="anchor ms-1" href="#changelog"></a></h2>
<table>
  <thead>
      <tr>
          <th>Datum</th>
          <th>Änderung</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>24.03.2025</td>
          <td>Weitere Infos und Link zu den Folien hinzugefügt.</td>
      </tr>
      <tr>
          <td>26.03.2025</td>
          <td>Link zur Aufzeichnung hinzugefügt. Text umgestellt.</td>
      </tr>
      <tr>
          <td>12.12.2025</td>
          <td>Text und Unterlagen für die IT-Tage 2025 hinzugefügt.</td>
      </tr>
  </tbody>
</table>]]></content:encoded>
    <enclosure url="https://www.rainerrose.de/images/docs/linuxtage2024.jpg" length="306677" type="image/.jpg" />
    </item>
    
    <item>
      <title>Changelog 12.12.2025</title>
      <link>https://www.rainerrose.de/posts/2025/2025-12-12/</link>
      <pubDate>Fri, 12 Dec 2025 20:55:03 +0100</pubDate>
      <guid>https://www.rainerrose.de/posts/2025/2025-12-12/</guid>
      <description><![CDATA[<!-- Anreißer -->

<h2 id="welche-artikel-haben-sich-geändert" data-numberify>Welche Artikel haben sich geändert?<a class="anchor ms-1" href="#welche-artikel-haben-sich-geändert"></a></h2>
<table>
  <thead>
      <tr>
          <th>Seite</th>
          <th>Änderung</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><a href="/posts/export-nextcloud-rolle/">Ansible Rolle export_nextcloud</a></td>
          <td>Neue optionale Variable <code>export_nextcloud_extra_curl_options</code></td>
      </tr>
      <tr>
          <td><a href="/posts/backupkonzept/">Backupkonzept</a></td>
          <td>Besser verdeutlicht, dass ich Backblaze nicht mehr verwende.</td>
      </tr>
      <tr>
          <td><a href="/docs/writings/2025/">Vorträge 2025</a></td>
          <td>Text und Unterlagen für die IT-Tage 2025 hinzugefügt.</td>
      </tr>
  </tbody>
</table>]]></description>
      <content:encoded><![CDATA[<!-- Anreißer -->

<h2 id="welche-artikel-haben-sich-geändert" data-numberify>Welche Artikel haben sich geändert?<a class="anchor ms-1" href="#welche-artikel-haben-sich-geändert"></a></h2>
<table>
  <thead>
      <tr>
          <th>Seite</th>
          <th>Änderung</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><a href="/posts/export-nextcloud-rolle/">Ansible Rolle export_nextcloud</a></td>
          <td>Neue optionale Variable <code>export_nextcloud_extra_curl_options</code></td>
      </tr>
      <tr>
          <td><a href="/posts/backupkonzept/">Backupkonzept</a></td>
          <td>Besser verdeutlicht, dass ich Backblaze nicht mehr verwende.</td>
      </tr>
      <tr>
          <td><a href="/docs/writings/2025/">Vorträge 2025</a></td>
          <td>Text und Unterlagen für die IT-Tage 2025 hinzugefügt.</td>
      </tr>
  </tbody>
</table>

<h2 id="warum-diese-seite" data-numberify>Warum diese Seite?<a class="anchor ms-1" href="#warum-diese-seite"></a></h2>
<p>Ab und zu ändere Artikel oder korrigiere Rechtschreibfehler. Manchmal füge dort weitere Informationen hinzu, die keinen eigenen Blogartikel wert sind.
Damit ich diese Änderungen kommunizieren kann, erstelle ich ab und zu solche Übersichtsseiten, wie Ihr hier sie gerade lest.
Eine tabellarische Übersicht der Änderungen mit Verlinkungen auf die jeweiligen Seiten.</p>

<h2 id="technischer-hintergrund" data-numberify>Technischer Hintergrund<a class="anchor ms-1" href="#technischer-hintergrund"></a></h2>
<p>Den Zeitstempel des Artikel zu ändern, bringt RSS-Feeds durcheinander und es ist dann ggf. auch nicht gleich ersichtlich, was geändert worden ist.
Da ich sowieso <code>git commit</code> Messages schreibe, kann ich die auch gleich auswerte, als Tabelle erstellen. Ein Script nimmt dann diese Tabelle und erstellt mit einem Template eine neue Seite im Blog.</p>]]></content:encoded>
    <enclosure url="https://www.rainerrose.de/wallpaper/kodensstreifen_u_turn.jpg" length="114844" type="image/.jpg" />
    </item>
    
    <item>
      <title>Mein Setup: Kontakte, Kalender, EMail, Passwörter</title>
      <link>https://www.rainerrose.de/posts/2025/mein-setup-kontakte-kalender-email-passwoerter/</link>
      <pubDate>Tue, 30 Sep 2025 22:07:22 +0200</pubDate>
      <guid>https://www.rainerrose.de/posts/2025/mein-setup-kontakte-kalender-email-passwoerter/</guid>
      <description><![CDATA[<!-- Anreißer -->
<p>Ich wurde schon mal des Öfteren gefragt wie ich denn meine Kontakte, Kalender, Passwörter, EMails usw. verwalte.<br>
Persönlich möchte ich diese Datenschätze nicht oder nur möglichst wenig der &ldquo;Cloud&rdquo; überantworten und mache daher vieles selbst.
Das Setup bzw. das Konzept hat eine jahrelange Entwicklung und eine Menge Veränderungen hinter sich. Zu einigen Teilbereichen sind auch schon vereinzelte Blogartikel entstanden.</p>
<p>Ein Gespräch letztens auf Mastodon hat mich dazu veranlasst, dies mal aufzuschreiben und hier zu veröffentlichen. Wer mag, kann sich aus diesem Text Ideen holen und für seine Situation anpassen.</p>

<h2 id="tldr" data-numberify>TL&DR;<a class="anchor ms-1" href="#tldr"></a></h2>
<ul>
<li><em>Nextcloud</em> selfhostet auf eigener Hardware im Homelab</li>
<li>Passwort-Safes <code>KeePass</code>, <code>KeePassXC</code>, <em>Bitwarden</em>, <em>Vaultwarden</em></li>
<li>Backup mit <code>restic</code> und <code>resticprofile</code> verschlüsselt mit Deduplizierung auf S3-Storage und externen Festplatten</li>
</ul>
<p>Jetzt die Langfassung: Wie sieht mein Setup aus?</p>]]></description>
      <content:encoded><![CDATA[<!-- Anreißer -->
<p>Ich wurde schon mal des Öfteren gefragt wie ich denn meine Kontakte, Kalender, Passwörter, EMails usw. verwalte.<br>
Persönlich möchte ich diese Datenschätze nicht oder nur möglichst wenig der &ldquo;Cloud&rdquo; überantworten und mache daher vieles selbst.
Das Setup bzw. das Konzept hat eine jahrelange Entwicklung und eine Menge Veränderungen hinter sich. Zu einigen Teilbereichen sind auch schon vereinzelte Blogartikel entstanden.</p>
<p>Ein Gespräch letztens auf Mastodon hat mich dazu veranlasst, dies mal aufzuschreiben und hier zu veröffentlichen. Wer mag, kann sich aus diesem Text Ideen holen und für seine Situation anpassen.</p>

<h2 id="tldr" data-numberify>TL&DR;<a class="anchor ms-1" href="#tldr"></a></h2>
<ul>
<li><em>Nextcloud</em> selfhostet auf eigener Hardware im Homelab</li>
<li>Passwort-Safes <code>KeePass</code>, <code>KeePassXC</code>, <em>Bitwarden</em>, <em>Vaultwarden</em></li>
<li>Backup mit <code>restic</code> und <code>resticprofile</code> verschlüsselt mit Deduplizierung auf S3-Storage und externen Festplatten</li>
</ul>
<p>Jetzt die Langfassung: Wie sieht mein Setup aus?</p>

<h2 id="die-details" data-numberify>Die Details<a class="anchor ms-1" href="#die-details"></a></h2>
<p>Angefangen habe ich mit <em>Owncloud</em> auf einem <em>BananaPi</em>. Vor einigen Jahren bin dann zu <em>Nextcloud</em> gewechselt. Aktuell läuft die Installation auf meinem Heim-NAS von <em>QNAP</em> in einer virtuellen Maschine wo ein <em>Debian</em> drauf läuft.<br>
Aus-Gründen<sup>(tm)</sup> waren und sind die Installationen nie von außen erreichbar.</p>

<h2 id="nextcloud" data-numberify>Nextcloud<a class="anchor ms-1" href="#nextcloud"></a></h2>
<p>In der <em>Nextcloud</em> nutze ich überwiegend folgende Funkionen:</p>
<ul>
<li>Verwaltung von
<ul>
<li>Kalendern</li>
<li>Kontakt-Daten (VCards)</li>
</ul>
</li>
<li>Dateiaustausch</li>
</ul>
<p>Die gesamte Familie bindet alles in ihre jeweiligen Mail- und Kalender-Clients auf den unterschiedlichsten Rechnern, mobilen Geräten mit verschiedensten Betriebssystemen an. Die Synchronisation funktioniert somit natürlich nur im heimischen WLAN oder über VPN.</p>

<h3 id="backups" data-numberify>Backups<a class="anchor ms-1" href="#backups"></a></h3>
<p>Da mir meine Daten (Kalender und Kontakte) sehr wichtig sind, sichere ich die Daten regelmäßig und fertige ein Backup an.<br>
Aktuell läuft auf dem Server, wo die Nextcloud installiert ist, ein nächtlicher Cronjob:</p>
<ul>
<li>der die <em>Nextcloud</em> in den Wartungsmodus versetzt,
<ul>
<li>um einen konsistenten Zustand zu erreichen,</li>
</ul>
</li>
<li>einen Dump der mysql-Tabellen auf Festplatte zieht,</li>
<li>eine dateibasierte Sicherung anfertigt</li>
<li>und schlussendlich den Wartungsmodus wieder beendet.</li>
</ul>
<p>Der Cronjob läuft mitten in der Nacht, wenn sowieso alle schlafen. Selbst wenn das mal nicht der Fall sein sollte, verhindert der Wartungsmodus schlimmeres.<br>
Dieses Verfahren existiert schon so seit Jahren und hat sich aus meiner Sicht bewährt. Selbst der Umzug von <em>Owncloud</em> nach <em>Nextcloud</em> sowie vom <em>BananaPi</em> in die virtuelle Maschine hat damit wunderbar funktioniert.</p>
<p>Die dateibasierte Sicherung und die Dumps ins Dateisystem sind nur ein erster Schritt. Wenn ich einzelne Kontakte oder ähnliches wiederherstellen möchte, ist das rauspfriemeln einzelner Daten nicht wirklich schön, beispielsweise eine einzelne aus Versehen gelöschte Kontakt-Karte.<br>
Allerdings gibt es die Möglichkeit alle Kalendereinträge in <strong>eine</strong> <code>ics</code> Datei herunterzuladen und alle Kontakte in <strong>eine</strong> <code>.vcf</code>-Datei herunterzuladen. Daraus ist die Wiederherstellung aus meiner Sicht wesentlich einfacher. Wenn alle Dateien gelöscht sind, reicht ggf. sogar ein Doppelklick im Dateiexplorer auf die jeweilige Datei und es wird im Standard-Mail-Programm geöffnet. Von diesem ist dann ein Import wieder möglich. Dadurch, dass das Mail-Programm wieder in die Nextcloud synchronisiert, ist der Kontakt wieder &ldquo;drin&rdquo;. Natürlich war ich faul und habe dies automatisiert; wie ich dies realisiert habe, lässt sich <a href="/posts/export-nextcloud-rolle/">hier nachlesen</a>.</p>
<p>Die ganzen Datenkopien (wie Dumps und Exporte) sichere ich nun mit einem Backup-Programm. Da mir die Daten allgemein wichtig sind und ich auch vor Diebstahl und Feuer gewappnet sein möchte, setze ich hier auf das 3-2-1 Prinzip.</p>

<h4 id="3-2-1-prinzip" data-numberify>3-2-1-Prinzip<a class="anchor ms-1" href="#3-2-1-prinzip"></a></h4>

<blockquote class="alert alert-info" role="alert">
    <p class="alert-heading fw-bold">
      <i class="fas fa-info-circle me-2"></i>Hinweis
    </p>
    <p>Hinweis: Das 3-2-1-Prinzip bedeutet in kurz:<br>
Du hast <strong>drei</strong> Kopien auf <strong>zwei</strong> unterschiedlichen Medien, wobei <strong>eine</strong> Kopie außerhalb liegt.</p>
</blockquote>
<p>Die bedeutet: Ich habe eine externe Festplatte auf die ich die Backups regelmäßig kopiere, wobei eine Kopie bei meinen Eltern liegt. Das tägliche Backup schiebe ich in die <em>Cloud</em>. <a href="/posts/backupkonzept/#offsite-backup">Details siehe in diesem Blog-Artikel im Abschnitt Offsite-Backup</a>.</p>

<h4 id="cloudspeicher" data-numberify>Cloudspeicher<a class="anchor ms-1" href="#cloudspeicher"></a></h4>
<p>&ldquo;<em>Cloud</em>&rdquo; bedeutet hierbei irgend ein Speicherort, der Dateien aufnehmen kann. Das kann ein <em>OneDrive</em>, eine <em>Dropbox</em>, <em>PDrive</em> oder was auch immer sein.
Bei mir ist dies aktuell ein angemieteter S3-kompatibler-Speicher.<br>
Die Backups verschlüssele ich natürlich, daher ist es egal, wo diese im Endeffekt liegen:</p>
<ul>
<li>ob es nun eine externe Festplatte ist, die geklaut wird</li>
<li>oder irgendein Cloud-Speicher, wo Daten abfließen können.</li>
</ul>
<p>Das gewählte Verschlüsselungspasswort sollte daher möglichst lang und komplex sein.</p>

<h3 id="backup-software" data-numberify>Backup-Software<a class="anchor ms-1" href="#backup-software"></a></h3>
<p>Als Software verwendet ich seit einiger <code>restic</code> in Zusammenarbeit mit <code>resticprofile</code>, da ich mit diesen Tools und die Backup-Jobs gut weg-automatisieren kann. Wenn ich daran denken muss, Backups zu machen, vergesse ich das nur.<br>
Wie die Software funktioniert und bedient wird, haben Andreas und ich mal
<a href="/docs/writings/2025/#backups-mit-restic-und-resticprofile">auf den Chemmnitzer LinuxTagen erzählt</a>.</p>
<p>Aus meiner Sicht ist der Vorteil, dass <code>restic</code></p>
<ul>
<li>die Daten verschlüsselt,</li>
<li>den Platzbedarf mittels Deduplizierung verringert</li>
<li>und ausmisten nach Regeln beherrscht, da kein Speicher unendlich ist.</li>
</ul>
<p><code>resticprofile</code> unterstützt hierbei sogar bei der Erzeugung eines möglichst langen und zufälligem Passwortes.
Dadurch, dass ich Dinge automatisch in die <em>Cloud</em> sichere, aber lokal noch eine Festplatte habe, die ich &ldquo;natürlich&rdquo; (leider) nur unregelmäßig befülle, hat mir dieses Konzept schon mehrfach
<a href="/posts/backupkonzept/#beispiel">wortwörtlich den Hintern gerettet</a>.
Aktuell kostet mich der S3-Storage irgendwas unter 4 Euro pro Monat.
<a href="/posts/backupkonzept/">Bei Interesse nach mehr Details hier klicken</a>.
Die dortige Angabe <em>Backblaze</em> stimmt inzwischen nicht mehr. Wegen <code>#unplugTrump</code> bin ich zu <em>Hetzner</em> <em>StorageShare</em> gewechselt.</p>

<h2 id="passwort-safes" data-numberify>Passwort-Safes<a class="anchor ms-1" href="#passwort-safes"></a></h2>
<p>Ebenfalls seit Jahren nutze ich einen Passwort-Speicher. Bisher reichte mir ein <code>KeePass</code>. Später wechselte ich zu <code>KeePassXC</code>. Die Tresor-Datei lege ich bei mir in meinen <em>Nextcloud</em>-Ordner. Dort synchronisiert sich diese Datei wunderbar zwischen meinen Geräten und ist überall verfügbar, wo ich sie benötige. <br>
Das <code>KeePass</code>-Tersor-Format ist recht verbreitet und es gibt für die unterschiedlichsten Betriebssysteme Software dafür. Die Client-Software für <em>Nextcloud</em> ist ebenso für viele Betriebssysteme verfügbar.</p>
<p>Dank <em>Auto-Fill</em>-Funktion habe ich schon länger kein Passwort mehr getippt und durch die <em>Passwort-Würfeln</em>-Funktion kenne ich auch gar kein Passwort mehr auswendig. Jedem Dienst ein Passwort zu verpassen, ist dadurch für mich recht einfach geworden.
In letzter Zeit musste ich jedoch öfters Passwörter teilen und da hat mir <code>KeePassXC</code> nicht gereicht. <code>KeeShare</code> habe ich erst vor kurzem  <a href="https://tools.rainerrose.de/redirect.php?id=53" target="_blank" rel="noopener noreferrer">in einen Artikel auf gnulinux.ch<i class="fas fa-external-link-square-alt ms-1"></i></a> entdeckt.<br>
Aus diesem Grund habe ich mir einen <em>Vaultwarden</em> installiert. <em>Vaultwarden</em> ist auch perfekt, wenn ich Dateien oder Textschnipsel über unsichere Kanäle verschicken möchte. Die Funktion nennt sich <em>vaultwarden-send</em>. Über diese Funktion kann ich Dateien oder kurze Texte in den Vault hochladen und danach einen Link zum Herunterladen generieren.
Zusätzlich kann ich diesen Link noch mit Passwort-Schutz und sonstigen Parameter versehen. Diesen Link kann ich ruhigen Gewissens unverschlüsselt per E-Mail verschicken. Die Daten liegen verschlüsselt auf der Server-Festplatte und löschen sich  standardmäßig nach sieben Tagen selbst.</p>

<h3 id="tipps-zu-vaultwarden" data-numberify>Tipps zu Vaultwarden<a class="anchor ms-1" href="#tipps-zu-vaultwarden"></a></h3>

<h4 id="standard-einstellungen" data-numberify>Standard-Einstellungen<a class="anchor ms-1" href="#standard-einstellungen"></a></h4>
<p>Ich empfehle zwei Standard-Einstellungen zu ändern:</p>
<ul>
<li><code>Standard-URI Übereinstimmungserkennung</code> auf <code>Beginnt mit</code>
<ul>
<li>das funktioniert bei mir am zuverlässigsten.</li>
<li>gerade auch in Kombination, dass im URL-Feld des jeweiligen Eintrags dann nur die Domain hinterlegt wird.</li>
<li>Das bedeutet ohne Pfade und sonstige Parameter!</li>
<li>Auffindbar derzeit unter: <code>Einstelllungen-&gt;Automatisches Ausfüllen</code></li>
</ul>
</li>
<li><code>Zwischenablage leeren</code> würde ich auf einen kurzen Zeitraum setzen,  z.B. auf 30 Sekunden.
<ul>
<li>soweit ich mich erinnere ist der Standard <code>niemals</code>.</li>
<li>Auffindbar derzeit unter: <code>Einstelllungen-&gt;Sonstiges</code></li>
</ul>
</li>
</ul>
<p>Leider muss die Einstellung in <strong>jedem Client einzeln</strong> gesetzt werden (Browser-Plugin, Smartphone-App usw.)</p>

<h4 id="admin-seite" data-numberify>Admin-Seite<a class="anchor ms-1" href="#admin-seite"></a></h4>
<p>Die Admin-Seite würde ich aus Sicherheitsgründen ausschalten bzw. ausgeschaltet lassen.
Wenn ich die Funktionalität doch einmal benötige, schalte ich sie kurzzeitig ein, auch wenn es zwei kurze Downtimes bedeutet.</p>

<h4 id="verständnis-entwickeln" data-numberify>Verständnis entwickeln<a class="anchor ms-1" href="#verständnis-entwickeln"></a></h4>
<p>Als ich <em>vaultwarden</em> aufgesetzt habe, hatte ich zuerst zwei Test-Accounts angelegt.
Danach habe ich eine &ldquo;Organistation&rdquo; und mehrere &ldquo;Sammlungen&rdquo; angelegt.
Mit diesen zwei Accounts konnte ich dann ein besseres Verständnis der beiden Begriffe und des Berechtigungssystems erlangen.</p>

<h2 id="email" data-numberify>EMail<a class="anchor ms-1" href="#email"></a></h2>
<p>Das ist für mich persönlich so ein großes Unlust-Thema und PITA.<br>
Seit ich online bin, lagere ich diesen Service als Dienstleistung aus. Ich klicke mir irgendwo eine Domain und einen E-Mail-Speicherplatz und lasse das Menschen machen, die mehr Ahnung von dem Thema haben als ich.
Aktuell bin ich seit Jahren sehr glücklich bei <a href="https://tools.rainerrose.de/redirect.php?id=11" target="_blank" rel="noopener noreferrer">uberspace<i class="fas fa-external-link-square-alt ms-1"></i></a>.<br>
Ich habe bei denen mehrere Accounts (<code>asteroid</code> genannt). Dort lassen sich ohne Zusatzkosten Domains &ldquo;aufschalten&rdquo;.
In deren verfügbarer Dokumentation (<code>manual</code>) sind die benötigten Befehle recht gut beschrieben, sofern man sich an die Kommandozeile herantraut.
In deren Dokumentationsbereich namens <code>Uberlab</code> sind weitere Möglichkeiten beschrieben, zusätzliche Software zu installieren; inkl. Update-Schritten. Vielfach ist es nur ein copy&amp;paste von vorgefertigten Befehlen.</p>

<h2 id="idee-und-ausblick" data-numberify>Idee und Ausblick<a class="anchor ms-1" href="#idee-und-ausblick"></a></h2>
<p>Soweit ein Einblick in mein Setup und so wie es für mich funktioniert und bewährt hat. Ich habe versucht es kurz zu halten und bei ausufernden Themen mit Verweisen zu arbeiten.</p>
<p>Wer mag, kann die für sich passenden Informationen herausziehen und die eigenen Verhältnisse und Anforderungen anpassen oder ein Konzept zu entwickeln.</p>
<p>Auf der Wunschliste steht noch die Generierung der TLS-Zertifikate per <em>Let&rsquo;s-Encypt</em>, da muss ich mich nochmal einlesen, wie ich dies umsetze, wenn die Systeme nicht von außen erreichbar sind.</p>

<h2 id="changelog" data-numberify>Changelog<a class="anchor ms-1" href="#changelog"></a></h2>
<table>
  <thead>
      <tr>
          <th>Datum</th>
          <th>Änderung</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>16.01.2026</td>
          <td>Vaultwarden: Hinweis auf Admin-Seite und ein paar Unterüberschriften in diesem Absatz hinzugefügt.</td>
      </tr>
  </tbody>
</table>]]></content:encoded>
    <enclosure url="https://www.rainerrose.de/wallpaper/posts/hardware.jpg" length="1385855" type="image/.jpg" />
    </item>
    
    <item>
      <title>Changelog 28.09.2025</title>
      <link>https://www.rainerrose.de/posts/2025/2025-09-30/</link>
      <pubDate>Sun, 28 Sep 2025 22:17:50 +0200</pubDate>
      <guid>https://www.rainerrose.de/posts/2025/2025-09-30/</guid>
      <description><![CDATA[<!-- Anreißer -->

<h2 id="welche-artikel-haben-sich-geändert" data-numberify>Welche Artikel haben sich geändert?<a class="anchor ms-1" href="#welche-artikel-haben-sich-geändert"></a></h2>
<table>
  <thead>
      <tr>
          <th>Seite</th>
          <th>Änderung</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><a href="/posts/backupkonzept/">Backupkonzept</a></td>
          <td>Hinweis Backblaze und <code>CACHEDIR.TAG</code>. Ein paar Umformulierungen und Typos fixed</td>
      </tr>
      <tr>
          <td><a href="/docs/howto/mastodon/entdecken/">Mastodon entdecken</a></td>
          <td>Mastodon: Eigene Beiträge entdecken</td>
      </tr>
      <tr>
          <td><a href="/docs/howto/git/">GIT</a></td>
          <td>lokale Branches löschenn, letzten Commit rückgängig machen</td>
      </tr>
      <tr>
          <td><a href="/docs/linux/sonstiges/">Linux/Sonstiges</a></td>
          <td>root passwort wieder löschen</td>
      </tr>
  </tbody>
</table>]]></description>
      <content:encoded><![CDATA[<!-- Anreißer -->

<h2 id="welche-artikel-haben-sich-geändert" data-numberify>Welche Artikel haben sich geändert?<a class="anchor ms-1" href="#welche-artikel-haben-sich-geändert"></a></h2>
<table>
  <thead>
      <tr>
          <th>Seite</th>
          <th>Änderung</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><a href="/posts/backupkonzept/">Backupkonzept</a></td>
          <td>Hinweis Backblaze und <code>CACHEDIR.TAG</code>. Ein paar Umformulierungen und Typos fixed</td>
      </tr>
      <tr>
          <td><a href="/docs/howto/mastodon/entdecken/">Mastodon entdecken</a></td>
          <td>Mastodon: Eigene Beiträge entdecken</td>
      </tr>
      <tr>
          <td><a href="/docs/howto/git/">GIT</a></td>
          <td>lokale Branches löschenn, letzten Commit rückgängig machen</td>
      </tr>
      <tr>
          <td><a href="/docs/linux/sonstiges/">Linux/Sonstiges</a></td>
          <td>root passwort wieder löschen</td>
      </tr>
  </tbody>
</table>

<h2 id="warum-diese-seite" data-numberify>Warum diese Seite?<a class="anchor ms-1" href="#warum-diese-seite"></a></h2>
<p>Ab und zu ändere Artikel oder korrigiere Rechtschreibfehler. Manchmal füge dort weitere Informationen hinzu, die keinen eigenen Blogartikel wert sind.
Damit ich diese Änderungen kommunizieren kann, erstelle ich ab und zu solche Übersichtsseiten, wie Ihr hier sie gerade lest.
Eine tabellarische Übersicht der Änderungen mit Verlinkungen auf die jeweiligen Seiten.</p>

<h2 id="technischer-hintergrund" data-numberify>Technischer Hintergrund<a class="anchor ms-1" href="#technischer-hintergrund"></a></h2>
<p>Den Zeitstempel des Artikel zu ändern, bringt RSS-Feeds durcheinander und es ist dann ggf. auch nicht gleich ersichtlich, was geändert worden ist.
Da ich sowieso <code>git commit</code> Messages schreibe, kann ich die auch gleich auswerte, als Tabelle erstellen. Ein Script nimmt dann diese Tabelle und erstellt mit einem Template eine neue Seite im Blog.</p>]]></content:encoded>
    <enclosure url="https://www.rainerrose.de/wallpaper/kodensstreifen_u_turn.jpg" length="114844" type="image/.jpg" />
    </item>
    
    <item>
      <title>pdftk - PDF Dateien bearbeiten</title>
      <link>https://www.rainerrose.de/docs/howto/pdftk/</link>
      <pubDate>Wed, 14 May 2025 18:21:53 +0200</pubDate>
      <guid>https://www.rainerrose.de/docs/howto/pdftk/</guid>
      <description><![CDATA[<!-- Anreißer -->
<p>Zur Massenbearbeitung von PDF-Dateien gibt es das schöne Tool <code>pdftk</code> oder auch manchmal <code>pdftk-java</code> genannt.</p>
<p>Mit diesem Tool lassen sich z.B. PDF-Dateien in Einzel-Dateien aufsplitten, mehrere PDF-Dateien zu einer Gesamtdatei zusammenfassen, Seiten rotieren etc.</p>
<p>Um nicht immer Suchmaschinen bedienen zu müssen, erfolgt hier eine Auflistung <strong>meiner</strong> häufig genutzten Parameter.</p>]]></description>
      <content:encoded><![CDATA[<!-- Anreißer -->
<p>Zur Massenbearbeitung von PDF-Dateien gibt es das schöne Tool <code>pdftk</code> oder auch manchmal <code>pdftk-java</code> genannt.</p>
<p>Mit diesem Tool lassen sich z.B. PDF-Dateien in Einzel-Dateien aufsplitten, mehrere PDF-Dateien zu einer Gesamtdatei zusammenfassen, Seiten rotieren etc.</p>
<p>Um nicht immer Suchmaschinen bedienen zu müssen, erfolgt hier eine Auflistung <strong>meiner</strong> häufig genutzten Parameter.</p>

<h2 id="aufruf" data-numberify>Aufruf<a class="anchor ms-1" href="#aufruf"></a></h2>
<p>Wenn <code>pdftk</code> ohne Parameter aufgerufen wird, gibt es eine Kurzhilfe mit einer groben Auflistung der Parameter.</p>
<p><code>pdftk --help</code> ist zwar schon etwas geschwätziger, aber ein paar Spezialfälle fehlen mir da; diese folgen nun.</p>

<h2 id="zusammenfügen" data-numberify>Zusammenfügen<a class="anchor ms-1" href="#zusammenfügen"></a></h2>
<p>Kommando: <code>cat</code></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">pdftk dateien-*.pdf cat output gesamtdatei.pdf
</span></span></code></pre></div>
<h2 id="trennen" data-numberify>Trennen<a class="anchor ms-1" href="#trennen"></a></h2>
<p>Kommando: <code>burst</code></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">pdftk gesamtdatei.pdf burst output praefix_
</span></span></code></pre></div><p>Ergibt dann bei einer vierseiten PDF-Datei:</p>
<pre><code>doc_data.txt
praefix_pg_0001.pdf
praefix_pg_0002.pdf
praefix_pg_0003.pdf
praefix_pg_0004.pdf
</code></pre>

<h2 id="seiten-abwechselnd-rotieren" data-numberify>Seiten abwechselnd rotieren<a class="anchor ms-1" href="#seiten-abwechselnd-rotieren"></a></h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">pdftk <span class="nv">A</span><span class="o">=</span>PdfDatei.pdf shuffle AoddWest AevenEast output PdfDatei_Rotiert.pdf
</span></span></code></pre></div>
<h2 id="einzelseite-rotieren" data-numberify>Einzelseite rotieren<a class="anchor ms-1" href="#einzelseite-rotieren"></a></h2>
<p>Kommando: <code>burst</code></p>
<p>Der Parameter setzt sich zusammen aus</p>
<ul>
<li>der Seitenzahl, wo begonnen werden soll.</li>
<li>der Seitenzahl, bis zu welcher Seite gedreht werden soll</li>
<li>der Drehrichtung</li>
</ul>
<p>zusammen.</p>
<table>
  <thead>
      <tr>
          <th>Drehrichtung</th>
          <th style="text-align: right">Grad</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>north</td>
          <td style="text-align: right">0</td>
      </tr>
      <tr>
          <td>east</td>
          <td style="text-align: right">90</td>
      </tr>
      <tr>
          <td>south</td>
          <td style="text-align: right">180</td>
      </tr>
      <tr>
          <td>west</td>
          <td style="text-align: right">270</td>
      </tr>
      <tr>
          <td>alternativ</td>
          <td style="text-align: right"></td>
      </tr>
      <tr>
          <td>left</td>
          <td style="text-align: right">-90</td>
      </tr>
      <tr>
          <td>right</td>
          <td style="text-align: right">+90</td>
      </tr>
      <tr>
          <td>down</td>
          <td style="text-align: right">+180</td>
      </tr>
  </tbody>
</table>
<p><strong>Beispielaufruf</strong></p>
<p>Ab Seite 1 bis zur letzten Seite (zum Ende) um 270 Grad:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">pdftk PdfDatei.pdf rotate 1-endwest output rotiert.pdf
</span></span></code></pre></div><p>Alternativen:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">pdftk <span class="nv">A</span><span class="o">=</span>out.pdf shuffle Aoddsouth output rotiert.pdf
</span></span></code></pre></div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">pdftk <span class="nv">A</span><span class="o">=</span>out1.pdf <span class="nv">B</span><span class="o">=</span>out12.pdf cat A1-3 B1-7 A8 output rotiert.pdf 
</span></span></code></pre></div>]]></content:encoded>
    </item>
    
    <item>
      <title>Ansible: source not found</title>
      <link>https://www.rainerrose.de/posts/2025/ansible-source-not-found/</link>
      <pubDate>Thu, 08 May 2025 21:26:11 +0200</pubDate>
      <guid>https://www.rainerrose.de/posts/2025/ansible-source-not-found/</guid>
      <description><![CDATA[<!-- Anreißer -->
<p>Vor ein paar Tagen habe ich mal wieder an einer <code>Ansible</code>-Rolle geschraubt und wurde beim Ausführen von <code>ansible-playbook</code> mit folgender Fehlermeldung begrüßt:</p>
<pre><code>Source /root/.ansible/tmp/ansible-tmp-1746359478.4110813-9236-74562322926004/.source not found
</code></pre>
<p>Das war seltsam, weil ich nur das Modul <code>ansible.builtin.copy</code> aufgerufen hatte, was vorher auf anderen Rechner problemlos funktioniert hatte.</p>
<p>Und jetzt?</p>]]></description>
      <content:encoded><![CDATA[<!-- Anreißer -->
<p>Vor ein paar Tagen habe ich mal wieder an einer <code>Ansible</code>-Rolle geschraubt und wurde beim Ausführen von <code>ansible-playbook</code> mit folgender Fehlermeldung begrüßt:</p>
<pre><code>Source /root/.ansible/tmp/ansible-tmp-1746359478.4110813-9236-74562322926004/.source not found
</code></pre>
<p>Das war seltsam, weil ich nur das Modul <code>ansible.builtin.copy</code> aufgerufen hatte, was vorher auf anderen Rechner problemlos funktioniert hatte.</p>
<p>Und jetzt?</p>

<h2 id="die-fehlermeldung" data-numberify>Die Fehlermeldung<a class="anchor ms-1" href="#die-fehlermeldung"></a></h2>
<pre><code>TASK [meine_rolle : inst | linux_install | Copy Binaries] *************************************************************************************************************************************************************************************************
failed: [t24] (item=/pfad/zur/datei/foo) =&gt; {&quot;ansible_loop_var&quot;: &quot;item&quot;, &quot;changed&quot;: false, &quot;checksum&quot;: &quot;884109935b2a432cb6edb5003c4ac5adc9462cbe&quot;, &quot;item&quot;: &quot;/pfad/zur/datei/foo&quot;, &quot;msg&quot;: &quot;Source /root/.ansible/tmp/ansible-tmp-1746359476.4233594-9236-186673184030632/.source not found&quot;}
failed: [t24] (item=/pfad/zur/datei/bar) =&gt; {&quot;ansible_loop_var&quot;: &quot;item&quot;, &quot;changed&quot;: false, &quot;checksum&quot;: &quot;9e184000b3f2541c07f62dcbf8bf7e8927757bec&quot;, &quot;item&quot;: &quot;/pfad/zur/datei/bar&quot;, &quot;msg&quot;: &quot;Source /root/.ansible/tmp/ansible-tmp-1746359478.4110813-9236-74562322926004/.source not found&quot;}
</code></pre>

<h2 id="die-task" data-numberify>Die Task<a class="anchor ms-1" href="#die-task"></a></h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="ln"> 1</span><span class="cl">- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">inst | linux_install | Copy Binaries</span><span class="w">
</span></span></span><span class="line"><span class="ln"> 2</span><span class="cl"><span class="w">  </span><span class="nt">ansible.builtin.copy</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="ln"> 3</span><span class="cl"><span class="w">    </span><span class="nt">src</span><span class="p">:</span><span class="w"> </span><span class="s1">&#39;{{ item }}&#39;</span><span class="w">
</span></span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="w">    </span><span class="nt">dest</span><span class="p">:</span><span class="w"> </span><span class="s1">&#39;{{ meine_rolle_install_path }}&#39;</span><span class="w">
</span></span></span><span class="line"><span class="ln"> 5</span><span class="cl"><span class="w">    </span><span class="nt">owner</span><span class="p">:</span><span class="w"> </span><span class="s1">&#39;root&#39;</span><span class="w"> 
</span></span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="w">    </span><span class="nt">group</span><span class="p">:</span><span class="w"> </span><span class="s1">&#39;root&#39;</span><span class="w"> 
</span></span></span><span class="line"><span class="ln"> 7</span><span class="cl"><span class="w">    </span><span class="nt">mode</span><span class="p">:</span><span class="w"> </span><span class="s1">&#39;0755&#39;</span><span class="w">
</span></span></span><span class="line"><span class="ln"> 8</span><span class="cl"><span class="w">  </span><span class="nt">become</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span><span class="line"><span class="ln"> 9</span><span class="cl"><span class="w">  </span><span class="nt">loop</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="ln">10</span><span class="cl"><span class="w">    </span>- <span class="s1">&#39;/pfad/zur/datei/foo&#39;</span><span class="w">
</span></span></span><span class="line"><span class="ln">11</span><span class="cl"><span class="w">    </span>- <span class="s1">&#39;/pfad/zur/datei/bar&#39;</span><span class="w">
</span></span></span></code></pre></div>
<h2 id="das-problem" data-numberify>Das Problem<a class="anchor ms-1" href="#das-problem"></a></h2>
<p>Ich bin per <code>ssh</code> auf die betroffene Maschine gesprungen und musste feststellen, dass das Verzeichnis <code>/root/.ansible/tmp/</code> auf der Remote-Maschine wirklich nicht da war. Auch wurde das <code>/root</code> Verzeichnis (meiner Erinnerung nach) nicht angefasst. Ein manuelles Erstellen des Verzeichnisses brachte keine Besserung.</p>
<p>Zuerst kam mir keine Idee und daher hatte ich diverse Suchmaschinen befragt. Ich erwähnte es eingangs: &ldquo;<em>auf anderen Rechner problemlos</em>&rdquo;.
Nun erinnerte ich mich, dass bei mir eine andere Distribution Einzug gehalten hat, die auf Ubuntu basiert.</p>

<h2 id="die-lösung" data-numberify>Die Lösung<a class="anchor ms-1" href="#die-lösung"></a></h2>
<p>Hier scheint das Modul <code>ansible.builtin.copy:</code> mit dem <code>become: true</code> laut meinen Recherchen das Problem zu sein.</p>
<p>Beheben lies sich dies, in dem ich in der <code>ansible.cfg</code> folgende Option gesetzt habe:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl"><span class="nv">remote_tmp</span> <span class="o">=</span> /tmp/ansible_tmp
</span></span></code></pre></div><p>Ich hab das Playbook dann noch mit einem Host, der unter einem Debian 12 läuft, probiert und auch da lief das Playbook anstandslos durch. Ich lass das jetzt so.</p>]]></content:encoded>
    <enclosure url="https://www.rainerrose.de/images/lupe.jpg" length="60818" type="image/.jpg" />
    </item>
    
    <item>
      <title>Changelog 02.05.2025</title>
      <link>https://www.rainerrose.de/posts/2025/2025-05-02/</link>
      <pubDate>Fri, 02 May 2025 22:42:58 +0200</pubDate>
      <guid>https://www.rainerrose.de/posts/2025/2025-05-02/</guid>
      <description><![CDATA[<!-- Anreißer -->

<h2 id="welche-artikel-haben-sich-geändert" data-numberify>Welche Artikel haben sich geändert?<a class="anchor ms-1" href="#welche-artikel-haben-sich-geändert"></a></h2>
<table>
  <thead>
      <tr>
          <th>Seite</th>
          <th>Änderung</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><a href="/docs/linux/docker/">Docker</a></td>
          <td>Neuer Abschnitt <code>Pull und Restart</code></td>
      </tr>
      <tr>
          <td><a href="/docs/howto/git/">GIT</a></td>
          <td>Neuer Abschnitt <code>Git Config User / Email</code></td>
      </tr>
      <tr>
          <td><a href="/posts/impressum/">Impressum</a></td>
          <td>Hinweis Bildrechte</td>
      </tr>
      <tr>
          <td><a href="/posts/osi-modell-layer-8-und-9/">OSI-Modell Layer 8 und 9</a></td>
          <td>Typo fixed</td>
      </tr>
      <tr>
          <td><a href="/docs/linux/screen/">Screen</a></td>
          <td>Neuer Abschnitt: Navigation im Screen Copy-Mode</td>
      </tr>
  </tbody>
</table>]]></description>
      <content:encoded><![CDATA[<!-- Anreißer -->

<h2 id="welche-artikel-haben-sich-geändert" data-numberify>Welche Artikel haben sich geändert?<a class="anchor ms-1" href="#welche-artikel-haben-sich-geändert"></a></h2>
<table>
  <thead>
      <tr>
          <th>Seite</th>
          <th>Änderung</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><a href="/docs/linux/docker/">Docker</a></td>
          <td>Neuer Abschnitt <code>Pull und Restart</code></td>
      </tr>
      <tr>
          <td><a href="/docs/howto/git/">GIT</a></td>
          <td>Neuer Abschnitt <code>Git Config User / Email</code></td>
      </tr>
      <tr>
          <td><a href="/posts/impressum/">Impressum</a></td>
          <td>Hinweis Bildrechte</td>
      </tr>
      <tr>
          <td><a href="/posts/osi-modell-layer-8-und-9/">OSI-Modell Layer 8 und 9</a></td>
          <td>Typo fixed</td>
      </tr>
      <tr>
          <td><a href="/docs/linux/screen/">Screen</a></td>
          <td>Neuer Abschnitt: Navigation im Screen Copy-Mode</td>
      </tr>
  </tbody>
</table>

<h2 id="warum-diese-seite" data-numberify>Warum diese Seite?<a class="anchor ms-1" href="#warum-diese-seite"></a></h2>
<p>Ab und zu ändere Artikel oder korrigiere Rechtschreibfehler. Manchmal füge dort weitere Informationen hinzu, die keinen eigenen Blogartikel wert sind.
Damit ich diese Änderungen kommunizieren kann, erstelle ich ab und zu solche Übersichtsseiten, wie Ihr hier sie gerade lest.
Eine tabellarische Übersicht der Änderungen mit Verlinkungen auf die jeweiligen Seiten.</p>

<h2 id="technischer-hintergrund" data-numberify>Technischer Hintergrund<a class="anchor ms-1" href="#technischer-hintergrund"></a></h2>
<p>Den Zeitstempel des Artikel zu ändern, bringt RSS-Feeds durcheinander und es ist dann ggf. auch nicht gleich ersichtlich, was geändert worden ist.
Da ich sowieso <code>git commit</code>  Messages schreibe, kann ich die auch gleich auswerte, als Tabelle erstellen. Ein Script nimmt dann diese Tabelle und erstellt mit einem Template eine neue Seite im Blog.</p>]]></content:encoded>
    <enclosure url="https://www.rainerrose.de/wallpaper/kodensstreifen_u_turn.jpg" length="114844" type="image/.jpg" />
    </item>
    
    <item>
      <title>Changelog 28.03.2025</title>
      <link>https://www.rainerrose.de/posts/2025/2025-03-28/</link>
      <pubDate>Fri, 28 Mar 2025 17:50:10 +0100</pubDate>
      <guid>https://www.rainerrose.de/posts/2025/2025-03-28/</guid>
      <description><![CDATA[<!-- Anreißer -->

<h2 id="welche-artikel-haben-sich-geändert" data-numberify>Welche Artikel haben sich geändert?<a class="anchor ms-1" href="#welche-artikel-haben-sich-geändert"></a></h2>
<table>
  <thead>
      <tr>
          <th>Seite</th>
          <th>Änderung</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><a href="/posts/backupkonzept/">Backupkonzept</a></td>
          <td>3-2-1 nochmal deutlicher; Hinweis auf meinen <code>restic</code>/<code>resticprofile</code> CLT-Vortrag</td>
      </tr>
      <tr>
          <td><a href="/docs/linux/screen/">Screen</a></td>
          <td>Neuer Abschnitt: Navigation im Screen Copy-Mode</td>
      </tr>
      <tr>
          <td><a href="/docs/howto/ssl/">SSL / TLS</a></td>
          <td>Neuer Abschnitt: dhparam erzeugen</td>
      </tr>
  </tbody>
</table>]]></description>
      <content:encoded><![CDATA[<!-- Anreißer -->

<h2 id="welche-artikel-haben-sich-geändert" data-numberify>Welche Artikel haben sich geändert?<a class="anchor ms-1" href="#welche-artikel-haben-sich-geändert"></a></h2>
<table>
  <thead>
      <tr>
          <th>Seite</th>
          <th>Änderung</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><a href="/posts/backupkonzept/">Backupkonzept</a></td>
          <td>3-2-1 nochmal deutlicher; Hinweis auf meinen <code>restic</code>/<code>resticprofile</code> CLT-Vortrag</td>
      </tr>
      <tr>
          <td><a href="/docs/linux/screen/">Screen</a></td>
          <td>Neuer Abschnitt: Navigation im Screen Copy-Mode</td>
      </tr>
      <tr>
          <td><a href="/docs/howto/ssl/">SSL / TLS</a></td>
          <td>Neuer Abschnitt: dhparam erzeugen</td>
      </tr>
  </tbody>
</table>

<h2 id="warum-diese-seite" data-numberify>Warum diese Seite?<a class="anchor ms-1" href="#warum-diese-seite"></a></h2>
<p>Ab und zu ändere Artikel oder korrigiere Rechtschreibfehler. Manchmal füge dort weitere Informationen hinzu, die keinen eigenen Blogartikel wert sind.
Damit ich diese Änderungen kommunizieren kann, erstelle ich ab und zu solche Übersichtsseiten, wie Ihr hier sie gerade lest.
Eine tabellarische Übersicht der Änderungen mit Verlinkungen auf die jeweiligen Seiten.</p>

<h2 id="technischer-hintergrund" data-numberify>Technischer Hintergrund<a class="anchor ms-1" href="#technischer-hintergrund"></a></h2>
<p>Den Zeitstempel des Artikel zu ändern, bringt RSS-Feeds durcheinander und es ist dann ggf. auch nicht gleich ersichtlich, was geändert worden ist.
Da ich sowieso <code>git commit</code>  Messages schreibe, kann ich die auch gleich auswerte, als Tabelle erstellen. Ein Script nimmt dann diese Tabelle und erstellt mit einem Template eine neue Seite im Blog.</p>]]></content:encoded>
    <enclosure url="https://www.rainerrose.de/wallpaper/kodensstreifen_u_turn.jpg" length="114844" type="image/.jpg" />
    </item>
    
    <item>
      <title>Ansible Rolle export_nextcloud</title>
      <link>https://www.rainerrose.de/posts/export-nextcloud-rolle/</link>
      <pubDate>Sat, 22 Feb 2025 15:37:52 +0100</pubDate>
      <guid>https://www.rainerrose.de/posts/export-nextcloud-rolle/</guid>
      <description><![CDATA[<!-- Anreißer -->
<p>Derzeit sichere ich meine Nextcloud-Instanz mit einem dateibasierten Backup-Tool, sowie einem Dump der Datenbank.
Letztens hatte ich in meinem Umfeld jemanden, der ein paar Kontakte aus Versehen gelöscht hat. Nun können die vermissten Kontakte zwar aus dem Dump der Datenbank herausgepfriemelt werden, schön ist das aber nicht.</p>
<p>Nach etwas Recherche bin ich auf einen recht simplen <code>curl</code>-Befehl gestoßen, der eine <code>.ics</code> bzw <code>.vcf</code>-Datei heraus exportiert.</p>
<p>Dies ist dann doch aus meiner Sicht etwas einfacher. Sofern z.B. alle Kontakte gelöscht worden sind, reicht dann sogar ein Doppelklick auf die Datei und alle Kontakte werden wieder importiert. Dies sollte wesentlich stressfreier sein.</p>
<p>Als Familien-Admin möchte ich den Export für alle Nutzenden der Instanz regelmäßig machen; daher habe ich mir eine Ansible-Rolle dafür gestrickt.</p>
<p>Das Grundprinzip und die Konfiguration der Rolle möchte ich in diesem Artikel beschreiben.</p>]]></description>
      <content:encoded><![CDATA[<!-- Anreißer -->
<p>Derzeit sichere ich meine Nextcloud-Instanz mit einem dateibasierten Backup-Tool, sowie einem Dump der Datenbank.
Letztens hatte ich in meinem Umfeld jemanden, der ein paar Kontakte aus Versehen gelöscht hat. Nun können die vermissten Kontakte zwar aus dem Dump der Datenbank herausgepfriemelt werden, schön ist das aber nicht.</p>
<p>Nach etwas Recherche bin ich auf einen recht simplen <code>curl</code>-Befehl gestoßen, der eine <code>.ics</code> bzw <code>.vcf</code>-Datei heraus exportiert.</p>
<p>Dies ist dann doch aus meiner Sicht etwas einfacher. Sofern z.B. alle Kontakte gelöscht worden sind, reicht dann sogar ein Doppelklick auf die Datei und alle Kontakte werden wieder importiert. Dies sollte wesentlich stressfreier sein.</p>
<p>Als Familien-Admin möchte ich den Export für alle Nutzenden der Instanz regelmäßig machen; daher habe ich mir eine Ansible-Rolle dafür gestrickt.</p>
<p>Das Grundprinzip und die Konfiguration der Rolle möchte ich in diesem Artikel beschreiben.</p>
<p>Auf die Bedienung und Verwendung von Ansible möchte ich hier nicht eingehen, da setze ich entsprechendes Wissen voraus.</p>
<p>Zum Zeitpunkt des Artikel ist die Nextcloud-Version 31 aktuell. Die Pfade, die in der Ansible-Rolle verwendet werden, orientieren sich an diesem Stand. Sollten sich die Subpfade der URLs ändern, müsste die Rolle angepasst werden.</p>

<h2 id="überblick" data-numberify>Überblick<a class="anchor ms-1" href="#überblick"></a></h2>
<p>Um die Rolle zu verstehen, ist es womöglich am einfachsten, sich das Vorgehen zu verdeutlichen, wenn ein manuelles Backup angefertigt werden soll. Dies soll hier in den nächsten Abschnitten beschrieben werden, um dann im nächsten Schritt zur Automatisierung zu kommen.</p>

<h2 id="händisches-backup" data-numberify>Händisches Backup<a class="anchor ms-1" href="#händisches-backup"></a></h2>
<p>Melde dich als ersten Schritt in Deiner Nextcloud an.</p>

<h3 id="kontakte" data-numberify>Kontakte<a class="anchor ms-1" href="#kontakte"></a></h3>
<ul>
<li>Wähle den Reiter <code>Kontakte</code>.</li>
<li>Gehe nach unten auf der linken Seite und klicke da auf <code>Kontakte-Einstellungen</code>.</li>
</ul>
<p><picture><img class="img-fluid " alt="Weg zu den Kontakte-Einstellungen" src="https://www.rainerrose.de/images/posts/export-nextcloud-rolle/nextcloud-kontakte-weg.jpg?v=59fab2dd88dc536d0263c9c2916f2368" loading="lazy" width="595" height="464" />
</picture>

</p>
<ul>
<li>Navigiere jetzt zu den <code>Allgemeinen Einstellungen</code>.</li>
<li>Beim gewünschten Adressbuch auf die drei Punkte klicken (1)</li>
<li>und auf <code>Herunterladen</code> klicken (2).</li>
</ul>
<p><picture><img class="img-fluid " alt="Weg zu den Export der Kontakte" src="https://www.rainerrose.de/images/posts/export-nextcloud-rolle/nextcloud-kontakte-export.jpg?v=59f012e6d6fa7c320100b4896e27c389" loading="lazy" width="925" height="693" />
</picture>

</p>
<ul>
<li>Voilà! Es wird eine <code>.vcf</code>-Datei mit einem aktuellen Datumsstempel zum Download angeboten.</li>
</ul>

<h3 id="kalender" data-numberify>Kalender<a class="anchor ms-1" href="#kalender"></a></h3>
<ul>
<li>Wähle den Reiter <code>Kontakte</code>.</li>
<li>Wähle Deinen Kalender aus, den du exportieren möchtest.</li>
<li>Fahre Deine Maus etwas nach rechts bis das Stift-Icon erscheint (1) und klicke auf diesen.</li>
</ul>
<p><picture><img class="img-fluid " alt="Weg zu den Kalender-Einstellungen" src="https://www.rainerrose.de/images/posts/export-nextcloud-rolle/kalender-einstellungen-weg.jpg?v=4a778c757475d6d8fdc941d53a6da564" loading="lazy" width="623" height="264" />
</picture>

</p>
<ul>
<li>Im nächsten Dialog <code>Kalender bearbeiten</code> gibt es dann eine Schaltfläche mit der Beschriftung <code>Exportieren</code>.</li>
</ul>
<p><picture><img class="img-fluid " alt="Weg zu den Kalender-Einstellungen" src="https://www.rainerrose.de/images/posts/export-nextcloud-rolle/kalender-export.jpg?v=801d80930c1b8ce33e664c38ade642e3" loading="lazy" width="330" height="454" />
</picture>

</p>
<ul>
<li>Voilà! Es wird eine <code>.ics</code>-Datei mit einem aktuellen Datumsstempel zum Download angeboten.</li>
</ul>

<h2 id="automatisierung" data-numberify>Automatisierung<a class="anchor ms-1" href="#automatisierung"></a></h2>
<p>Jetzt wollen wir das ganze automatisieren; dafür gibt es meine Ansible-Rolle <code>export_nextcloud</code>. Die Rolle findet Du auf meinem <a href="https://tools.rainerrose.de/redirect.php?id=46" target="_blank" rel="noopener noreferrer">Gitlab-Account<i class="fas fa-external-link-square-alt ms-1"></i></a>.</p>
<p>Die Rolle solltest Du auf einem Linux-Host deployen, dem Du vertraust und der Zugriff auf die Nextcloud hat.</p>

<h3 id="minimale-angaben" data-numberify>Minimale Angaben<a class="anchor ms-1" href="#minimale-angaben"></a></h3>

<h4 id="variable-export_nextcloud_url" data-numberify>Variable export_nextcloud_url<a class="anchor ms-1" href="#variable-export_nextcloud_url"></a></h4>
<p>Zunächst benötigt die Rolle die URL, worunter die Nextcloud-Instanz erreichbar ist.
Dazu hinterlegst Du diese in der Variable <code>export_nextcloud_url</code> als Hostvariable, wo das Export-Script später laufen soll.</p>
<p>Beispiel:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="ln">1</span><span class="cl"><span class="nt">export_nextcloud_url</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;https://meine.nextcloud.instanz&#34;</span><span class="w">
</span></span></span></code></pre></div>
<h4 id="variable-export_nextcloud_user" data-numberify>Variable export_nextcloud_user<a class="anchor ms-1" href="#variable-export_nextcloud_user"></a></h4>
<p>Jetzt brauchst Du eine Liste mit einem oder mehreren Usernamen, die du sichern möchtest. Zusätzlich ein Passwort und einen Zeitpunkt, wann das Export-Script laufen soll.</p>

<blockquote class="alert alert-warning" role="alert">
    <p class="alert-heading fw-bold">
      <i class="fas fa-exclamation-circle me-2"></i>Empfehlung
    </p>
    <p>Statt des regulären Passwortes für Deinen User, empfehle ich die Generierung eines Personal Access Token kurz &ldquo;<code>PAT</code>&rdquo;.</p>
</blockquote>
<p>Die Einrichtung eines <code>PAT</code> beschreibe ich <a href="/posts/nextcloud-pat-erstellen/">in einem anderem Blog-Artikel</a>.</p>
<p>Als dritten Parameter wird noch der Zeitstempel benötigt, wo der Export laufen soll.
Mit dieser Angabe wird später eine SystemD-Timer-Unit erstellt.</p>
<p>Die Syntax dieses Attributes folgt dem Parameter <code>on_calendar</code> von <a href="https://www.freedesktop.org/software/systemd/man/systemd.timer#OnCalendar=" target="_blank" rel="noopener noreferrer">systemd.unit(5)<i class="fas fa-external-link-square-alt ms-1"></i></a>.
Aus jeden <code>username</code> wird eine extra SystemD-Timer-Units erstellt, nach folgendem Muster:</p>
<ul>
<li><code>export_nextcloud-user1.timer</code></li>
<li><code>export_nextcloud-user2.timer</code></li>
</ul>
<p>Die Konfiguration sieht am Ende zum Beispiel so aus:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="ln">1</span><span class="cl"><span class="nt">export_nextcloud_user</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="w">  </span>- <span class="nt">username</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;user1&#34;</span><span class="w">
</span></span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="w">    </span><span class="nt">password</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;password1&#34;</span><span class="w">
</span></span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="w">    </span><span class="nt">on_calendar</span><span class="p">:</span><span class="w"> </span><span class="s1">&#39;*-*-* 03:00&#39;</span><span class="w">
</span></span></span><span class="line"><span class="ln">5</span><span class="cl"><span class="w">  </span>- <span class="nt">username</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;user2&#34;</span><span class="w">
</span></span></span><span class="line"><span class="ln">6</span><span class="cl"><span class="w">    </span><span class="nt">password</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;password2&#34;</span><span class="w">
</span></span></span><span class="line"><span class="ln">7</span><span class="cl"><span class="w">    </span><span class="nt">on_calendar</span><span class="p">:</span><span class="w"> </span><span class="s1">&#39;*-*-* 03:01&#39;</span><span class="w">
</span></span></span></code></pre></div>
<h3 id="optionale-angaben" data-numberify>Optionale Angaben<a class="anchor ms-1" href="#optionale-angaben"></a></h3>

<h4 id="variable-export_nextcloud_script_path" data-numberify>Variable export_nextcloud_script_path<a class="anchor ms-1" href="#variable-export_nextcloud_script_path"></a></h4>
<p>Die nächste Variable bestimmt, wohin das Script kopiert werden soll. Der Standardpfad lautet <code>/opt/export_nextcloud</code>.</p>

<h4 id="variable-export_nextcloud_backup_path" data-numberify>Variable export_nextcloud_backup_path<a class="anchor ms-1" href="#variable-export_nextcloud_backup_path"></a></h4>
<p>Über diese Variable kann bestimmt werden, wohin die exportierten Kalender- und Kontakte-Dateien hingeschrieben werden sollen.
<code>/backup/nextcloud_export</code> lautet hier der Standardpfad.</p>
<p>Hier entsteht pro Username eine Kalender- und eine Kontakte-Datei mit dem Username
nach folgendem Muster:</p>
<ul>
<li><code>kalender-${username}.ics</code></li>
<li><code>kontakte-${username}.vcf</code></li>
</ul>
<p>Und ja, ich war zu faul, noch ein extra Aufräum-Mechanismus zu schreiben.
Für die Versionierung ist bei mir mein Backup-Programm zuständig ;-) .
Das kann mein Sicherungsprogramm viel effizienter als ich.
Wenn ich an ältere Versionen herankommen möchte, muss ich die Sicherung bemühen; ich spare mir dadurch zusätzliche Fehlerquellen und Abhängigkeiten.</p>

<h4 id="variable-export_nextcloud_prometheus_path" data-numberify>Variable export_nextcloud_prometheus_path<a class="anchor ms-1" href="#variable-export_nextcloud_prometheus_path"></a></h4>
<p>Diese Variable legt den Pfad fest, wo die Prometheus-Statistiken hingeschrieben werden.</p>

<h4 id="variable-export_nextcloud_extra_curl_options" data-numberify>Variable export_nextcloud_extra_curl_options<a class="anchor ms-1" href="#variable-export_nextcloud_extra_curl_options"></a></h4>
<p>Diese Variable habe ich am 03.10.2025 eingeführt, weil der zugrunde liegende <code>curl</code> sich am selbst-signierten Zertifikat meiner Nextcloud-Instanz störte.
Mit dem Parameter <code>-k</code> oder <code>--insecure</code> lässt sich das aber übersteuern. Dies erforderte allerdings eine Anpassung des Scriptes.</p>
<p>Nun können weitere Parameter über diese Variable optional mitgegeben werden.</p>
<p>Im unteren Beispiel Ansible Playbook fügt ihr an den einen Task folgende zwei Zeilen an.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="ln">1</span><span class="cl"><span class="w">  </span><span class="nt">vars</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="w">    </span><span class="nt">export_nextcloud_extra_curl_options</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;--insecure&#34;</span><span class="w">
</span></span></span></code></pre></div>
<h3 id="ansible-playbook" data-numberify>Ansible Playbook<a class="anchor ms-1" href="#ansible-playbook"></a></h3>
<p>Jetzt kannst Du die Rolle in ein Ansible-Playbook einbinden.</p>
<p>Ein minimales Beispiel wäre:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="ln">1</span><span class="cl"><span class="nn">---</span><span class="w">
</span></span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="w"></span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Setup export_nextcloud</span><span class="w">
</span></span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="w">  </span><span class="nt">hosts</span><span class="p">:</span><span class="w"> </span><span class="l">export_nextcloud</span><span class="w">
</span></span></span><span class="line"><span class="ln">5</span><span class="cl"><span class="w">  </span><span class="nt">roles</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="ln">6</span><span class="cl"><span class="w">    </span>- <span class="l">export_nextcloud</span><span class="w">
</span></span></span></code></pre></div>
<h2 id="backup" data-numberify>Backup<a class="anchor ms-1" href="#backup"></a></h2>
<p>Im Nachgang bzw. nach dem Ausführen der jeweiligen SystemD-Timer-Unit, empfehle ich noch ein Backup des Verzeichnisses wo die exportierten Dateien liegen.
Das Verzeichnis kannst zum Beispiel dateibasiert mittels deiner präferierten Wunsch-Backup-Software gesichert werden.
Ich selbst habe dazu die Pfade in meinem Sicherungsscript aufgenommen; hier verwende ich <code>restic</code> seit längerem erfolgreich.</p>

<h2 id="fertig" data-numberify>Fertig.<a class="anchor ms-1" href="#fertig"></a></h2>
<p>Im Grunde war es das auch schon. Viel Spaß beim Benutzen.
Der Source-Code der Rolle liegt in meinem <a href="https://tools.rainerrose.de/redirect.php?id=46" target="_blank" rel="noopener noreferrer">Gitlab-Account<i class="fas fa-external-link-square-alt ms-1"></i></a>.</p>

<h2 id="changelog" data-numberify>Changelog<a class="anchor ms-1" href="#changelog"></a></h2>
<table>
  <thead>
      <tr>
          <th>Datum</th>
          <th>Änderung</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>03.10.2025</td>
          <td>Neue optionale Variable <code>export_nextcloud_extra_curl_options</code></td>
      </tr>
  </tbody>
</table>]]></content:encoded>
    <enclosure url="https://www.rainerrose.de/wallpaper/posts/nextcloud.png" length="9229" type="image/.png" />
    </item>
    
    <item>
      <title>Nextcloud - Einrichtung eines PAT</title>
      <link>https://www.rainerrose.de/posts/nextcloud-pat-erstellen/</link>
      <pubDate>Sat, 22 Feb 2025 15:37:43 +0100</pubDate>
      <guid>https://www.rainerrose.de/posts/nextcloud-pat-erstellen/</guid>
      <description><![CDATA[<!-- Anreißer -->
<p>Soll auf Daten in einer Nextcloud zugegriffen werden, erfolgt dies häufig mittels der Kombination aus <code>Username</code> und <code>Passwort</code>.
Erfolg dieser Zugriff jedoch mittels mobilen Geräten oder automatisiert aus anderen Diensten, ist es meist eine schlechte Idee, das Passwort großflächig zu verteilen. Mobile Geräte haben manchmal die Eigenschaft verloren zu gehen oder gestohlen zu werden.
Weiterhin werden Dienste oder Geräte kompromitert oder unterstützen vielfach keine Zweifaktor-Authentisierung (2FA).
Hierbei hilft die
Generierung eines Personal Access Token kurz &ldquo;<code>PAT</code>&rdquo;.</p>]]></description>
      <content:encoded><![CDATA[<!-- Anreißer -->
<p>Soll auf Daten in einer Nextcloud zugegriffen werden, erfolgt dies häufig mittels der Kombination aus <code>Username</code> und <code>Passwort</code>.
Erfolg dieser Zugriff jedoch mittels mobilen Geräten oder automatisiert aus anderen Diensten, ist es meist eine schlechte Idee, das Passwort großflächig zu verteilen. Mobile Geräte haben manchmal die Eigenschaft verloren zu gehen oder gestohlen zu werden.
Weiterhin werden Dienste oder Geräte kompromitert oder unterstützen vielfach keine Zweifaktor-Authentisierung (2FA).
Hierbei hilft die
Generierung eines Personal Access Token kurz &ldquo;<code>PAT</code>&rdquo;.</p>
<p>Ein <code>PAT</code> hingegen sollte nur genau einem Dienst oder einem Gerät zugeordnet werden.
Das jeweilige <code>PAT</code> und kann dann bei Verlust oder Kompromittierung über den Hauptzugang gesperrt werden, so dass der Zugriff feingranular entzogen werden kann.
Vorteil: Das &ldquo;Hauptpasswort&rdquo; und die anderen <code>PAT</code> müssen nicht geändert werden und können bestehen bleiben.</p>

<h2 id="erstellung" data-numberify>Erstellung<a class="anchor ms-1" href="#erstellung"></a></h2>

<blockquote class="alert alert-info" role="alert">
    <p class="alert-heading fw-bold">
      <i class="fas fa-info-circle me-2"></i>Hinweis
    </p>
    <p>Zum Zeitpunkt des Artikel ist die Nextcloud-Version 31 aktuell.</p>
</blockquote>
<p>Zur Erstellung eines <code>PAT</code> melde dich als ersten Schritt in Deiner Nextcloud an.</p>
<p>Rechts oben sollten Deine Initialen oder Dein Profilbild stehen, dort bitte drauf klicken und es erscheint ein weiteres Pull-Down-Menü, wo du auf <code>Einstellungen</code> klickst.</p>
<p><picture><img class="img-fluid " alt="Einstellungen" src="https://www.rainerrose.de/images/posts/nextcloud-pat-erstellen/01-einstellungen.png?v=dd3ee05e268688d07868de57e9488d74" loading="lazy" width="400" height="384" />
</picture>

</p>
<p>Danach gibt es eine Übersicht von Deinem Profil und links eine Menüstruktur.</p>
<p>Mit Klick auf den Menüpunkt <code>Sicherheit</code> geht es jetzt weiter.
Unterhalb des Abschnittes, findest Du schon eine Auflistung der schon aktiven Zugriffe unterhalb von <code>Geräte &amp; Sitzungen</code>.</p>
<p><picture><img class="img-fluid " alt="Sicherheit" src="https://www.rainerrose.de/images/posts/nextcloud-pat-erstellen/02-sicherheit.png?v=f48c07b99bcfad2d35881e666c8b4ab5" loading="lazy" width="836" height="846" />
</picture>

</p>
<p>Am Ende der Tabelle (sofern sie existiert) gibt es eine Eingabemaske mit <code>App-Name</code> und dem Button &ldquo;Neues App-Passwort erstellen&rdquo;.</p>
<p>Trage hier bitte einen sinnvollen Namen ein, so dass Du das erstellte <code>PAT</code> später wieder zuordnen kannst.
Ein sprechender Name erleichtert Dir später die Suche, falls Du einem Gerät oder Dienst den Zugriff entziehen möchtest.</p>
<p><picture><img class="img-fluid " alt="PAT" src="https://www.rainerrose.de/images/posts/nextcloud-pat-erstellen/03-pat.png?v=00e25fcae9fcb172f39da9a4bf45d5c0" loading="lazy" width="431" height="312" />
</picture>

</p>

<blockquote class="alert alert-primary" role="alert">
    <p class="alert-heading fw-bold">
      <i class="fas fa-exclamation-circle me-2"></i>Wichtig
    </p>
    <p>Wenn Du auf das kleine Fenster wieder schließt, wird der Dialog <strong>geschlossen</strong>. Es gibt <strong>keine</strong> Möglichkeit, das Passwort nochmal anzuzeigen. Daher ist es wichtig, sich das Passwort an einem sicheren Ort zu notieren.
Hast Du dies vergessen, musst Du ein neues <code>PAT</code> anlegen.</p>
</blockquote>
<p>Das generierte <code>PAT</code> ist im Grunde nichts anderes ist, als ein extra Passwort.
Notiere Dir jetzt das generierte Passwort an einer sicheren Stelle, übertrage es z.B. in Deinen Passwort-Safe.
Das Passwort ist <strong>sofort aktiv</strong> und kann verwendet werden. Der gewohnte Benutzername bliebt hierbei gleich.</p>
<p>Wenn Du z.B. den Nextcloud-APP auf deinem Smartphone einrichten möchtest, hast Du jetzt die Chance mit Klick auf <code>QR-Code für mobile Apps anzeigen</code>
Dir einen QR-Code anzeigen zu lassen, den Du mit der Nextcloup-App abscannen kannst und die Tipparbeit und Tippfehler ersparst.</p>
<p><picture><img class="img-fluid " alt="PAT QR-Code" src="https://www.rainerrose.de/images/posts/nextcloud-pat-erstellen/03-pat-qr.png?v=94fb3686146adc3dd4cb7a809719890f" loading="lazy" width="404" height="466" />
</picture>

</p>
<p>Ist das Passwort in der Anwendung hinterlegt, kann der Dialog mit Klick auf das kleine <code>X</code>
geschlossen werden.</p>

<h2 id="löschen" data-numberify>Löschen<a class="anchor ms-1" href="#löschen"></a></h2>
<p>Das Löschen eines <code>PAT</code> wird auf der selben Seite in den Profil-Einstellungen vorgenommen werden.
Über die drei Punkte bekommst Du ein Pulldown-Menü.</p>
<p><picture><img class="img-fluid " alt="PAT löschen" src="https://www.rainerrose.de/images/posts/nextcloud-pat-erstellen/03-pat-loeschen.png?v=870b786167d2329178ac82a03929752c" loading="lazy" width="762" height="219" />
</picture>

</p>
<p>Hier kannst Du das <code>PAT</code> Widerrufen. Sofern der Client dies Unterstützt (z.B. die Smartphone-App) können via Klick auf
<code>Gerät löschen</code>
sogar die lokal vorgehaltenen Daten gelöscht werden.</p>]]></content:encoded>
    <enclosure url="https://www.rainerrose.de/images/posts/nextcloud-pat-erstellen/03-pat.png" length="34145" type="image/.png" />
    </item>
    
    <item>
      <title>Systemd</title>
      <link>https://www.rainerrose.de/docs/linux/systemd/</link>
      <pubDate>Sat, 28 Dec 2024 12:48:58 +0100</pubDate>
      <guid>https://www.rainerrose.de/docs/linux/systemd/</guid>
      <description><![CDATA[<!-- Anreißer -->

<h2 id="notizensammlung" data-numberify>Notizensammlung<a class="anchor ms-1" href="#notizensammlung"></a></h2>
<p>Dinge, die ich mir bei <code>systemd</code> nicht merken kann. Und bevor ich wieder Suchmaschinen oder man-Pages bemühen muss, schreibe ich sie hier lieber nieder.</p>]]></description>
      <content:encoded><![CDATA[<!-- Anreißer -->

<h2 id="notizensammlung" data-numberify>Notizensammlung<a class="anchor ms-1" href="#notizensammlung"></a></h2>
<p>Dinge, die ich mir bei <code>systemd</code> nicht merken kann. Und bevor ich wieder Suchmaschinen oder man-Pages bemühen muss, schreibe ich sie hier lieber nieder.</p>

<h2 id="im-hintergrund-starten" data-numberify>Im Hintergrund starten<a class="anchor ms-1" href="#im-hintergrund-starten"></a></h2>
<p>Parameter <code>--no-block</code> verwenden, damit der Prompt gleich wieder kommt und nicht auf Beendigung gewartet wird; praktisch für Backup-Jobs außerhalb der Reihe.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">systemctl start resticprofile_full-backup.service --no-block
</span></span></code></pre></div>
<h2 id="timer-in-systemd" data-numberify>Timer in SystemD<a class="anchor ms-1" href="#timer-in-systemd"></a></h2>
<p>wird gerne von snap-Paketen genutzt, die keinen cronjob installieren.</p>
<p>Auflistung</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">systemctl list-timers <span class="o">[</span>--all<span class="o">]</span>
</span></span></code></pre></div><p>In der Auflistung steht dann auch der timer, wo die Zeitdefinition drin
steht und welche start-Unit anzieht.</p>
<p>Verzeichnis vielfach: <code>/etc/systemd/system/foo.timer</code></p>

<h2 id="als-ersatz-für-at" data-numberify>Als Ersatz für at<a class="anchor ms-1" href="#als-ersatz-für-at"></a></h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">systemd-run --user --on-calendar<span class="o">=</span><span class="s2">&#34;2024-12-28 10:31:19&#34;</span> Befehl Parameter....
</span></span></code></pre></div><p>ggf. <code>sudo</code> davor für <code>root</code>.</p>

<h2 id="failed-units" data-numberify>failed Units<a class="anchor ms-1" href="#failed-units"></a></h2>

<h3 id="alle-auflisten" data-numberify>Alle auflisten<a class="anchor ms-1" href="#alle-auflisten"></a></h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">systemctl status --failed
</span></span></code></pre></div>
<h3 id="resetten" data-numberify>Resetten<a class="anchor ms-1" href="#resetten"></a></h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">systemctl reset-failed &lt;unit-name&gt;
</span></span></code></pre></div>
<h2 id="auskunft-über-pids" data-numberify>Auskunft über pids<a class="anchor ms-1" href="#auskunft-über-pids"></a></h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">systemctl status &lt;pid&gt;
</span></span></code></pre></div>
<h2 id="changelog" data-numberify>Changelog<a class="anchor ms-1" href="#changelog"></a></h2>
<table>
  <thead>
      <tr>
          <th>Datum</th>
          <th>Änderung</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>05.11.2025</td>
          <td>failed-Kommandos hinzugefügt</td>
      </tr>
      <tr>
          <td>28.03.2026</td>
          <td>Auskunft über pids</td>
      </tr>
  </tbody>
</table>]]></content:encoded>
    </item>
    
    <item>
      <title>Starship - Ansible Rolle</title>
      <link>https://www.rainerrose.de/posts/starship-rolle/</link>
      <pubDate>Fri, 27 Dec 2024 15:11:01 +0100</pubDate>
      <guid>https://www.rainerrose.de/posts/starship-rolle/</guid>
      <description><![CDATA[<!-- Anreißer -->
<p>Das Tool <code>starship</code> hatte ich schon mal in einem <a href="/docs/howto/starship/">Blog-Artikel</a> erwähnt und genauer beschrieben:</p>
<blockquote>
<p>Der Standard-Prompt ist zu langweilig? Die Befüllung der Variablen PS1 ist zu kompliziert und unflexibel? Es sollen mehr Informationen dargestellt werden?</p>
<p>Kein Problem, ich habe jetzt das Tool <code>Starship</code> für mich entdeckt&hellip;</p>
</blockquote>
<p>Vor einiger Zeit habe ich die Installation des Tool inklusive mit meiner Konfiguration in eine Ansible-Rolle gegossen.</p>]]></description>
      <content:encoded><![CDATA[<!-- Anreißer -->
<p>Das Tool <code>starship</code> hatte ich schon mal in einem <a href="/docs/howto/starship/">Blog-Artikel</a> erwähnt und genauer beschrieben:</p>
<blockquote>
<p>Der Standard-Prompt ist zu langweilig? Die Befüllung der Variablen PS1 ist zu kompliziert und unflexibel? Es sollen mehr Informationen dargestellt werden?</p>
<p>Kein Problem, ich habe jetzt das Tool <code>Starship</code> für mich entdeckt&hellip;</p>
</blockquote>
<p>Vor einiger Zeit habe ich die Installation des Tool inklusive mit meiner Konfiguration in eine Ansible-Rolle gegossen.</p>

<h2 id="die-rolle" data-numberify>Die Rolle<a class="anchor ms-1" href="#die-rolle"></a></h2>
<p>Diese Ansible-Rolle findet sich auf meinem persönlichen gitlab-Account im Unterordner <a href="https://tools.rainerrose.de/redirect.php?id=45" target="_blank" rel="noopener noreferrer">ansible-roles<i class="fas fa-external-link-square-alt ms-1"></i></a> des Projektes.</p>
<p>Die Rolle muss nur in das <code>roles</code>-Verzeichnis der jeweiligen Ansible-Playbooks kopiert werden.
Danach kann sie in einem Playbook verwendet werden, wobei mindestens die Namen der Accounts angegeben müssen, wo die Rolle installiert werden soll. Ein Beispiel-Playbook findet sich in der Datei <code>README.md</code> des <a href="https://tools.rainerrose.de/redirect.php?id=45" target="_blank" rel="noopener noreferrer">Unterordners<i class="fas fa-external-link-square-alt ms-1"></i></a> der Rolle.</p>

<h2 id="rollen-variable-starship_user" data-numberify>Rollen-Variable: starship_user<a class="anchor ms-1" href="#rollen-variable-starship_user"></a></h2>
<p>Die Namen der Accounts, wo die Rolle installiert werden soll, müssen als Liste angegeben werden.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="ln">1</span><span class="cl"><span class="nt">starship_user</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="w">  </span>- <span class="l">user1</span><span class="w">
</span></span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="w">  </span>- <span class="l">user2</span><span class="w">
</span></span></span></code></pre></div><p>Die Beschreibung der Rollen-Variablen findet sich aber ebenfalls noch einmal in der Datei <code>README.md</code> inklusive weiterer Erklärungen.</p>

<h2 id="schwierigkeiten-timeout" data-numberify>Schwierigkeiten: Timeout<a class="anchor ms-1" href="#schwierigkeiten-timeout"></a></h2>
<p>Allerdings stieß ich auf die Schwierigkeit bei einem meiner Rechner, dass das <code>git</code>-Kommando mehr als die vordefinierten 500 Millisekunden brauchte. <br>
Daher habe ich die Variable <code>starship_extra_options</code> eingeführt, wo ich das <code>command_timeout</code> höher setzen konnte:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="ln">1</span><span class="cl"><span class="nt">starship_extra_options</span><span class="p">:</span><span class="w"> </span><span class="s1">&#39;command_timeout = 1000&#39;</span><span class="w">
</span></span></span></code></pre></div><p>Theoretisch lassen sich da noch mehr individuelle Optionen setzen, sofern benötigt.</p>
<p>Beispiel:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="ln">1</span><span class="cl"><span class="nt">starship_extra_options</span><span class="p">:</span><span class="w"> </span><span class="p">|</span><span class="sd">
</span></span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="sd">  command_timeout = 1000
</span></span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="sd">  
</span></span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="sd">  [container]
</span></span></span><span class="line"><span class="ln">5</span><span class="cl"><span class="sd">  format = &#39;[$symbol \[$name\]]($style) &#39;</span><span class="w">
</span></span></span></code></pre></div>
<h2 id="minimales-playbook" data-numberify>Minimales Playbook<a class="anchor ms-1" href="#minimales-playbook"></a></h2>
<p>Ein minimales Playbook sieht beispielsweise so aus:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="ln">1</span><span class="cl"><span class="nn">---</span><span class="w">
</span></span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="w"></span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Setup starship</span><span class="w">
</span></span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="w">  </span><span class="nt">hosts</span><span class="p">:</span><span class="w"> </span><span class="l">linuxhosts</span><span class="w">
</span></span></span><span class="line"><span class="ln">5</span><span class="cl"><span class="w">  </span><span class="nt">roles</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="ln">6</span><span class="cl"><span class="w">    </span>- <span class="l">starship</span><span class="w">
</span></span></span><span class="line"><span class="ln">7</span><span class="cl"><span class="w">  </span><span class="nt">vars</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="ln">8</span><span class="cl"><span class="w">    </span><span class="nt">starship_user</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="ln">9</span><span class="cl"><span class="w">      </span>- <span class="l">user1</span><span class="w">
</span></span></span></code></pre></div><p>Vorbei sich die Variable <code>starship_user</code> natürlich noch als Host- oder Gruppenvariable definieren lässt, womit das Playbook noch kleiner wird.</p>
<p>Der alte
<a href="/docs/howto/starship/">Blog-Artikel</a>
findet sich <a href="/docs/howto/starship/">hier</a>, dort wird das Tool noch einmal etwas genauer erklärt.</p>]]></content:encoded>
    <enclosure url="https://www.rainerrose.de/wallpaper/docs/linux/starship-screenshot.png" length="27725" type="image/.png" />
    </item>
    
    <item>
      <title>apt</title>
      <link>https://www.rainerrose.de/docs/linux/apt/</link>
      <pubDate>Thu, 24 Oct 2024 17:11:51 +0200</pubDate>
      <guid>https://www.rainerrose.de/docs/linux/apt/</guid>
      <description><![CDATA[<!-- Anreißer -->
<p>Eine kleine Sammlung an Snippets, die ich immer wieder brauche, mir aber nicht merken kann.</p>]]></description>
      <content:encoded><![CDATA[<!-- Anreißer -->
<p>Eine kleine Sammlung an Snippets, die ich immer wieder brauche, mir aber nicht merken kann.</p>

<h2 id="zu-welchem-paket-gehört-die-datei" data-numberify>Zu welchem Paket gehört die Datei?<a class="anchor ms-1" href="#zu-welchem-paket-gehört-die-datei"></a></h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">dpkg-query -S /bin/bash
</span></span></code></pre></div>
<h2 id="zeige-installierte-paket-version-an" data-numberify>Zeige installierte Paket-Version an<a class="anchor ms-1" href="#zeige-installierte-paket-version-an"></a></h2>
<p>Zeigt ebenfalls an, welche Versionen verfügbar sind. Dies sind ältere, als auch neuere, die noch nicht installiert sind.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">apt-cache policy rabbitmq-server
</span></span></code></pre></div>
<h2 id="zeige-alle-installierten-versionen-an" data-numberify>Zeige alle installierten Versionen an<a class="anchor ms-1" href="#zeige-alle-installierten-versionen-an"></a></h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">apt list --installed
</span></span></code></pre></div>
<h2 id="zeige-alle-pakete-an-die-aktualisiert-werden-können" data-numberify>Zeige alle Pakete an, die aktualisiert werden können<a class="anchor ms-1" href="#zeige-alle-pakete-an-die-aktualisiert-werden-können"></a></h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">apt list --upgradable
</span></span></code></pre></div>
<h2 id="zeige-alle-verfügbare" data-numberify>Zeige alle verfügbare<a class="anchor ms-1" href="#zeige-alle-verfügbare"></a></h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">apt list --all-versions
</span></span></code></pre></div>
<h2 id="zeige-die-enthaltenden-dateien-eines-deb-paketes-an" data-numberify>Zeige die enthaltenden Dateien eines deb-Paketes an<a class="anchor ms-1" href="#zeige-die-enthaltenden-dateien-eines-deb-paketes-an"></a></h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">dpkg -c percona-release_latest.generic_all.deb
</span></span></code></pre></div>]]></content:encoded>
    <enclosure url="https://www.rainerrose.de/wallpaper/docs/linux/apt.png" length="124789" type="image/.png" />
    </item>
    
    <item>
      <title>ssh</title>
      <link>https://www.rainerrose.de/docs/howto/ssh/</link>
      <pubDate>Thu, 03 Oct 2024 18:15:41 +0200</pubDate>
      <guid>https://www.rainerrose.de/docs/howto/ssh/</guid>
      <description><![CDATA[<!-- Anreißer -->
<p>Tipps und Tricks zur SecureShell</p>]]></description>
      <content:encoded><![CDATA[<!-- Anreißer -->
<p>Tipps und Tricks zur SecureShell</p>

<h2 id="erzeugen-des-öffentlichen-schlüssels-aus-dem-privaten-schlüssel" data-numberify>Erzeugen des öffentlichen Schlüssels aus dem privaten Schlüssel<a class="anchor ms-1" href="#erzeugen-des-öffentlichen-schlüssels-aus-dem-privaten-schlüssel"></a></h2>
<p>Um einen fehlenden public key aus dem  private key zu generieren hilft folgendes Linux-Kommando:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">$ ssh-keygen -y -f ~/.ssh/id_rsa &gt; ~/.ssh/id_rsa.pub
</span></span><span class="line"><span class="ln">2</span><span class="cl">Enter passphrase:
</span></span></code></pre></div>
<h2 id="halten-der-verbindung" data-numberify>Halten der Verbindung<a class="anchor ms-1" href="#halten-der-verbindung"></a></h2>
<p><code>~/.ssh/config</code></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">Host *
</span></span><span class="line"><span class="ln">2</span><span class="cl">  ControlPath ~/.ssh/connections/%C
</span></span><span class="line"><span class="ln">3</span><span class="cl">  ControlMaster auto
</span></span><span class="line"><span class="ln">4</span><span class="cl">  ControlPersist 30m
</span></span></code></pre></div>
<h2 id="aufteilen-der-configs" data-numberify>Aufteilen der Configs<a class="anchor ms-1" href="#aufteilen-der-configs"></a></h2>
<p><code>~/.ssh/config</code></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">Include config.d/*
</span></span></code></pre></div>
<h2 id="port-forwarding" data-numberify>Port-Forwarding<a class="anchor ms-1" href="#port-forwarding"></a></h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">ssh -L <span class="o">[</span>&lt;locale ip&gt;:<span class="o">]</span>&lt;lokaler Port&gt;:&lt;zielhost&gt;:&lt;zielport&gt; <span class="o">[</span>user@<span class="o">]</span>zielhost
</span></span></code></pre></div>
<h2 id="jump-host" data-numberify>Jump Host<a class="anchor ms-1" href="#jump-host"></a></h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">ssh -J jumphost &lt;user&gt;@&lt;zielhost&gt;
</span></span></code></pre></div>
<h2 id="kein-hinzufügen-zur-sshknown_hosts" data-numberify>Kein hinzufügen zur ~/.ssh/known_hosts<a class="anchor ms-1" href="#kein-hinzufügen-zur-sshknown_hosts"></a></h2>
<p>Nützlich z.B. beim Arbeiten mit virtuellen Maschinen unter QEMU mit <code>virt-manager</code>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="ln">1</span><span class="cl">Host 192.0.2.*
</span></span><span class="line"><span class="ln">2</span><span class="cl">  StrictHostKeyChecking no
</span></span><span class="line"><span class="ln">3</span><span class="cl">  UserKnownHostsFile=/dev/null
</span></span></code></pre></div><p>Dann kommt folgende Meldung nicht mehr</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="ln">1</span><span class="cl">The authenticity of host &#39;192.0.2.28 (192.0.2.28)&#39; can&#39;t be established.
</span></span><span class="line"><span class="ln">2</span><span class="cl">ED25519 key fingerprint is SHA256:gPyKupGXLCfzRrq8s8kfyL0Kc9HW/4L07VsWJgr5s9U.
</span></span><span class="line"><span class="ln">3</span><span class="cl">This key is not known by any other names.
</span></span><span class="line"><span class="ln">4</span><span class="cl">Are you sure you want to continue connecting (yes/no/[fingerprint])?
</span></span></code></pre></div>
<h2 id="changelog" data-numberify>Changelog<a class="anchor ms-1" href="#changelog"></a></h2>
<table>
  <thead>
      <tr>
          <th>Datum</th>
          <th>Änderung</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>17.01.2024</td>
          <td>Verbindung halten. Config aufteilen</td>
      </tr>
      <tr>
          <td>28.06.2024</td>
          <td>Jump Host und Port-Forwarding</td>
      </tr>
      <tr>
          <td>03.10.2024</td>
          <td>known_hosts Tipp</td>
      </tr>
  </tbody>
</table>]]></content:encoded>
    </item>
    
    <item>
      <title>Bash-Tricks</title>
      <link>https://www.rainerrose.de/docs/linux/bash-tricks/</link>
      <pubDate>Sun, 22 Sep 2024 17:38:20 +0200</pubDate>
      <guid>https://www.rainerrose.de/docs/linux/bash-tricks/</guid>
      <description><![CDATA[<!-- Anreißer -->
<p>Eine kleine Sammlung an <code>bash</code>-Kniffen, Tricks und HowTos.</p>
<p>Diese Unterseite ist bisher ohne durchdachte Sortierung. Werde für Interessierte das Neueste immer oben anfügen.</p>

<h2 id="boot-stick-erstellen" data-numberify>Boot-Stick erstellen<a class="anchor ms-1" href="#boot-stick-erstellen"></a></h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">sudo dd <span class="nv">bs</span><span class="o">=</span>4M <span class="k">if</span><span class="o">=</span>/path/to/manjaro.iso <span class="nv">of</span><span class="o">=</span>/dev/sd<span class="o">[</span>drive letter<span class="o">]</span> <span class="nv">status</span><span class="o">=</span>progress <span class="nv">oflag</span><span class="o">=</span>sync
</span></span></code></pre></div>
<h2 id="dateien-anlegen-via-allokierung" data-numberify>Dateien anlegen via Allokierung<a class="anchor ms-1" href="#dateien-anlegen-via-allokierung"></a></h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">fallocate -l 10GB meine_grosse_datei
</span></span></code></pre></div><p>ggf. Parameter <code>-o offset</code> und <code>-n</code> beachten, bei Größenänderung swap-File.</p>]]></description>
      <content:encoded><![CDATA[<!-- Anreißer -->
<p>Eine kleine Sammlung an <code>bash</code>-Kniffen, Tricks und HowTos.</p>
<p>Diese Unterseite ist bisher ohne durchdachte Sortierung. Werde für Interessierte das Neueste immer oben anfügen.</p>

<h2 id="boot-stick-erstellen" data-numberify>Boot-Stick erstellen<a class="anchor ms-1" href="#boot-stick-erstellen"></a></h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">sudo dd <span class="nv">bs</span><span class="o">=</span>4M <span class="k">if</span><span class="o">=</span>/path/to/manjaro.iso <span class="nv">of</span><span class="o">=</span>/dev/sd<span class="o">[</span>drive letter<span class="o">]</span> <span class="nv">status</span><span class="o">=</span>progress <span class="nv">oflag</span><span class="o">=</span>sync
</span></span></code></pre></div>
<h2 id="dateien-anlegen-via-allokierung" data-numberify>Dateien anlegen via Allokierung<a class="anchor ms-1" href="#dateien-anlegen-via-allokierung"></a></h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">fallocate -l 10GB meine_grosse_datei
</span></span></code></pre></div><p>ggf. Parameter <code>-o offset</code> und <code>-n</code> beachten, bei Größenänderung swap-File.</p>

<h2 id="passwort-generieren" data-numberify>Passwort generieren<a class="anchor ms-1" href="#passwort-generieren"></a></h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">tr -dc A-Za-z0-9 &lt;/dev/urandom <span class="p">|</span> head -c <span class="m">64</span>
</span></span></code></pre></div><p>Als kleine Script-Version in meinem <a href="https://tools.rainerrose.de/redirect.php?id=38" target="_blank" rel="noopener noreferrer">GitLab-Repository<i class="fas fa-external-link-square-alt ms-1"></i></a></p>

<h2 id="datumsberechnungen" data-numberify>Datumsberechnungen<a class="anchor ms-1" href="#datumsberechnungen"></a></h2>

<h3 id="übermorgen" data-numberify>Übermorgen<a class="anchor ms-1" href="#übermorgen"></a></h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">date  --date<span class="o">=</span><span class="s2">&#34;2 days&#34;</span> +<span class="s2">&#34;%d.%m.%Y&#34;</span>
</span></span></code></pre></div>
<h3 id="vorgestern" data-numberify>Vorgestern<a class="anchor ms-1" href="#vorgestern"></a></h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">date  --date<span class="o">=</span><span class="s2">&#34;2 days ago&#34;</span> +<span class="s2">&#34;%d.%m.%Y&#34;</span>
</span></span></code></pre></div>
<h2 id="ausgabe-von-du" data-numberify>Ausgabe von “du”<a class="anchor ms-1" href="#ausgabe-von-du"></a></h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">du -sk * <span class="p">|</span> sort -n
</span></span></code></pre></div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">du -sb * <span class="p">|</span> sort -n <span class="p">|</span> numfmt --to<span class="o">=</span>iec
</span></span></code></pre></div><p>Etwas mehr Erklärung <a href="/posts/disk-usage/">hier im Blog-Artikel</a>.</p>

<h2 id="binary-installiert-" data-numberify>Binary installiert ?<a class="anchor ms-1" href="#binary-installiert-"></a></h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl"><span class="k">if</span> ! <span class="nb">type</span> <span class="s2">&#34;docker-compose&#34;</span> &gt; /dev/null<span class="p">;</span> <span class="k">then</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl">    <span class="nb">echo</span> <span class="s1">&#39;Error: docker-compose is not installed.&#39;</span> &gt;<span class="p">&amp;</span><span class="m">2</span>
</span></span><span class="line"><span class="ln">3</span><span class="cl">    show_error_function
</span></span><span class="line"><span class="ln">4</span><span class="cl">    <span class="nb">exit</span> <span class="m">1</span>
</span></span><span class="line"><span class="ln">5</span><span class="cl"><span class="k">fi</span>
</span></span></code></pre></div>
<h2 id="eingaben" data-numberify>Eingaben<a class="anchor ms-1" href="#eingaben"></a></h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl"><span class="nb">read</span> -rp <span class="s2">&#34;Hier eine Entscheidungsfrage (j/n): &#34;</span> VARIABLE_WO_DER_INHALT_REIN_SOLL
</span></span></code></pre></div>
<h2 id="tabellarische-umformartierung" data-numberify>tabellarische Umformartierung<a class="anchor ms-1" href="#tabellarische-umformartierung"></a></h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;a11 b12_Text c13&#34;</span> &gt; /tmp/beispiel
</span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;a21 b22 c23&#34;</span> &gt;&gt; /tmp/beispiel
</span></span><span class="line"><span class="ln">3</span><span class="cl">column -t /tmp/beispiel
</span></span></code></pre></div><p><strong>Ausgabe:</strong></p>
<pre><code>a11  b12_Text  c13
a21  b22       c23
</code></pre>

<h2 id="alias" data-numberify>Alias<a class="anchor ms-1" href="#alias"></a></h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl"><span class="nb">alias</span> <span class="nv">sdf</span><span class="o">=</span><span class="s1">&#39;df -h|egrep -v &#39;</span><span class="se">\&#39;</span><span class="s1">&#39;^(overlay|nsfs|shm|cgroup|tmpfs|debugfs|mqueue)&#39;</span><span class="se">\&#39;</span><span class="s1">&#39;&#39;</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="nb">alias</span> <span class="nv">smount</span><span class="o">=</span><span class="s1">&#39;mount|egrep -v &#39;</span><span class="se">\&#39;</span><span class="s1">&#39;^(overlay|nsfs|shm|cgroup|tmpfs|debugfs|mqueue)&#39;</span><span class="se">\&#39;</span><span class="s1">&#39;&#39;</span>
</span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="nb">alias</span> <span class="nv">dc</span><span class="o">=</span><span class="s1">&#39;docker-compose&#39;</span>
</span></span><span class="line"><span class="ln">4</span><span class="cl">de<span class="o">()</span> <span class="o">{</span> docker <span class="nb">exec</span> -it <span class="s2">&#34;</span><span class="nv">$1</span><span class="s2">&#34;</span> bash<span class="p">;</span> <span class="o">}</span>
</span></span><span class="line"><span class="ln">5</span><span class="cl"><span class="nb">alias</span> <span class="nv">dpa</span><span class="o">=</span><span class="s1">&#39;docker ps -f status=exited&#39;</span>
</span></span><span class="line"><span class="ln">6</span><span class="cl">psg<span class="o">()</span> <span class="o">{</span> ps aux <span class="p">|</span> grep <span class="s2">&#34;</span><span class="nv">$1</span><span class="s2">&#34;</span> <span class="p">|</span> grep -v grep<span class="p">;</span> <span class="o">}</span>
</span></span><span class="line"><span class="ln">7</span><span class="cl"><span class="nb">alias</span> <span class="nv">t</span><span class="o">=</span><span class="s1">&#39;ls -lrt --color=auto&#39;</span>
</span></span></code></pre></div>
<h2 id="prompting" data-numberify>Prompting<a class="anchor ms-1" href="#prompting"></a></h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl"><span class="nv">PS1</span><span class="o">=</span><span class="s2">&#34;[\u@\H:\w]\$ &#34;</span>
</span></span></code></pre></div><p>Ggf <code>\n</code> einstreuen für extra Zeile.</p>

<h2 id="verzeichniswechsel" data-numberify>Verzeichniswechsel<a class="anchor ms-1" href="#verzeichniswechsel"></a></h2>
<p>Mal wieder beim Verzeichniswechsel vertippt?</p>
<p>Die <code>bash</code> speichert das letzte Verzeichnis, in welchem man sich
befunden hat in der Variable <code>$OLDPWD</code>.</p>
<p>Ein</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl"><span class="nb">cd</span> <span class="nv">$OLDPWD</span>
</span></span></code></pre></div><p>bringt einen also wieder zurück ins alte Verzeichnis.</p>
<p>Kürzer wird es mit:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl"><span class="nb">cd</span> -
</span></span></code></pre></div>
<h2 id="aktuelles-verzeichnis" data-numberify>aktuelles Verzeichnis<a class="anchor ms-1" href="#aktuelles-verzeichnis"></a></h2>
<p>Das aktuelle Verzeichnis kann man sich mit <code>pwd</code> ausgeben lassen.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl"><span class="nb">pwd</span>
</span></span></code></pre></div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">erde:~$ <span class="nb">cd</span> /etc
</span></span><span class="line"><span class="ln">2</span><span class="cl">erde:/etc$ <span class="nb">cd</span> /var
</span></span><span class="line"><span class="ln">3</span><span class="cl">erde:/var$ <span class="nb">cd</span> -
</span></span><span class="line"><span class="ln">4</span><span class="cl">/etc
</span></span><span class="line"><span class="ln">5</span><span class="cl">erde:/etc$ <span class="nb">cd</span> <span class="nv">$OLDPWD</span>
</span></span><span class="line"><span class="ln">6</span><span class="cl">erde:/var$
</span></span></code></pre></div>
<h2 id="schreiben-auf-stderr" data-numberify>Schreiben auf STDERR<a class="anchor ms-1" href="#schreiben-auf-stderr"></a></h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;Dieser Text erscheint auf STDERR&#34;</span> &gt;<span class="p">&amp;</span><span class="m">2</span>
</span></span></code></pre></div>
<h2 id="fehlermeldungen-umleiten" data-numberify>Fehlermeldungen umleiten<a class="anchor ms-1" href="#fehlermeldungen-umleiten"></a></h2>

<h3 id="in-log-datei" data-numberify>in Log-Datei<a class="anchor ms-1" href="#in-log-datei"></a></h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">./foo.sh bar/* &gt;foo-bar.log  2&gt;<span class="p">&amp;</span><span class="m">1</span>
</span></span></code></pre></div>
<h3 id="wegwerfen" data-numberify>wegwerfen<a class="anchor ms-1" href="#wegwerfen"></a></h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">./foo.sh &gt; /dev/null 2&gt;<span class="p">&amp;</span><span class="m">1</span>
</span></span></code></pre></div>
<h2 id="backup-einer-datei" data-numberify>Backup einer Datei<a class="anchor ms-1" href="#backup-einer-datei"></a></h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">cp -p foo<span class="o">{</span>,.bak<span class="o">}</span>
</span></span></code></pre></div><p>ist dasselbe wie</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">cp -p foo foo.bak
</span></span></code></pre></div>
<h2 id="spezial-variablen" data-numberify>Spezial-Variablen<a class="anchor ms-1" href="#spezial-variablen"></a></h2>
<p>Es gibt ein paar Spezialvariablen in der bash, die einem das Tippen
ersparen.</p>

<h3 id="umgebungsvariablen" data-numberify>Umgebungsvariablen<a class="anchor ms-1" href="#umgebungsvariablen"></a></h3>
<table>
  <thead>
      <tr>
          <th>Name</th>
          <th>Erklärung</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>$$</code></td>
          <td>Prozess-ID (PID) des laufenden Programms</td>
      </tr>
      <tr>
          <td><code>$?</code></td>
          <td>Rückgabewert des letzten Befehls</td>
      </tr>
  </tbody>
</table>

<h3 id="in-scripten" data-numberify>in Scripten<a class="anchor ms-1" href="#in-scripten"></a></h3>
<p><code>$*</code> Alle dem Programm übergebenen Parameter, durch Leerzeichen getrennt.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl"><span class="nv">$*</span><span class="o">=</span><span class="nv">$1</span> <span class="nv">$2</span> <span class="nv">$3</span> <span class="nv">$4</span> ...
</span></span></code></pre></div><p><code>&quot;$*&quot; </code>	Alle dem Programm übergebenen Parameter in Anführungszeichen, durch das 1. Zeichen der Variablen $IFS getrennt.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl"><span class="s2">&#34;</span><span class="nv">$*</span><span class="s2">&#34;</span><span class="o">=</span><span class="s2">&#34;</span><span class="nv">$1</span><span class="s2">c</span><span class="nv">$2</span><span class="s2">c</span><span class="nv">$3</span><span class="s2">c</span><span class="nv">$4</span><span class="s2">&#34;</span>...
</span></span></code></pre></div><p><code>$@ </code>	Alle dem Programm übergebenen Parameter, durch Leerzeichen getrennt.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl"><span class="nv">$@</span><span class="o">=</span><span class="nv">$1</span> <span class="nv">$2</span> <span class="nv">$3</span> <span class="nv">$4</span>
</span></span></code></pre></div><p><code>&quot;$@&quot;</code> 	Alle dem Programm übergebenen Parameter, einzeln in Anführungszeichen eingeschlossen und durch Leerzeichen getrennt.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl"><span class="s2">&#34;</span><span class="nv">$@</span><span class="s2">&#34;</span><span class="o">=</span><span class="s2">&#34;</span><span class="nv">$1</span><span class="s2">&#34;</span> <span class="s2">&#34;</span><span class="nv">$2</span><span class="s2">&#34;</span> <span class="s2">&#34;</span><span class="nv">$3</span><span class="s2">&#34;</span> <span class="s2">&#34;</span><span class="nv">$4</span><span class="s2">&#34;</span> ...
</span></span></code></pre></div><p><code>$#</code> 	Anzahl der übergebenen Parameter</p>

<h3 id="historie" data-numberify>Historie<a class="anchor ms-1" href="#historie"></a></h3>
<p><code>!$</code>   letzter Parameter des vorhergehenden Befehls</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">$ ls -l foo
</span></span><span class="line"><span class="ln">2</span><span class="cl">$ <span class="nb">echo</span> !$
</span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="nb">echo</span> foo
</span></span><span class="line"><span class="ln">4</span><span class="cl">foo
</span></span></code></pre></div><p><code>!!</code>   letzter Befehl inkl. aller Parameter</p>

<h4 id="mal-wieder-sudo-vergessen-kein-problem" data-numberify>Mal wieder sudo vergessen? Kein Problem:<a class="anchor ms-1" href="#mal-wieder-sudo-vergessen-kein-problem"></a></h4>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">$ ein script
</span></span><span class="line"><span class="ln">2</span><span class="cl">$ sudo !!
</span></span></code></pre></div><table>
  <thead>
      <tr>
          <th>kurz</th>
          <th>lang</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>history 10</code></td>
          <td><code>history | tail</code></td>
      </tr>
      <tr>
          <td><code>cd !$:h</code></td>
          <td><code>cd !!:$:h</code></td>
      </tr>
  </tbody>
</table>
<p><strong>Beispiel</strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">$ ls -l /etc/apt/apt.conf.d/20auto-upgrades 
</span></span><span class="line"><span class="ln">2</span><span class="cl">$ <span class="nb">cd</span> !$:h
</span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="nb">cd</span> /etc/apt/apt.conf.d
</span></span></code></pre></div>
<h4 id="eselsbrücke-regex-like" data-numberify>Eselsbrücke: RegEx-like<a class="anchor ms-1" href="#eselsbrücke-regex-like"></a></h4>
<table>
  <thead>
      <tr>
          <th>Eingabe</th>
          <th>Funktion</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>!?abc</code></td>
          <td>das erste Kommando in der History suchen, das <code>abc</code> enthält</td>
      </tr>
      <tr>
          <td><code>!abc</code></td>
          <td>das erste Kommando in der History suchen, das mit <code>abc</code> beginnt</td>
      </tr>
      <tr>
          <td><code>!!</code></td>
          <td>zuletzt aufgerufener Befehl</td>
      </tr>
      <tr>
          <td><code>!^</code></td>
          <td>erster Parameter im vorherigen Befehl</td>
      </tr>
      <tr>
          <td><code>!*</code></td>
          <td>alle Parameter im vorherigen Befehl</td>
      </tr>
      <tr>
          <td><code>!$</code></td>
          <td>letzter Parameter im vorherigen Befehl</td>
      </tr>
      <tr>
          <td><code>!n</code></td>
          <td>Befehl an Position <code>n</code> in der History</td>
      </tr>
      <tr>
          <td><code>!-n</code></td>
          <td>Befehl, der an der <code>n</code>-ten Stelle von hinten in der History steht <code>:2</code></td>
      </tr>
      <tr>
          <td><code>:2</code></td>
          <td>Nur der zweite Parameter des Befehls</td>
      </tr>
      <tr>
          <td><code>:2-5</code></td>
          <td>der zweite bis fünfte Parameter des Befehls</td>
      </tr>
      <tr>
          <td><code>:2-$</code></td>
          <td>der zweite und alle weiteren Parameter des Befehls</td>
      </tr>
      <tr>
          <td><code>:*</code></td>
          <td>Sämtliche Parameter des Befehls</td>
      </tr>
      <tr>
          <td><code>:q</code></td>
          <td>den Text in Anführungsstriche setzen</td>
      </tr>
      <tr>
          <td><code>:p</code></td>
          <td>&quot;print&quot; den Befehl nur ausgeben</td>
      </tr>
      <tr>
          <td><code>:h</code></td>
          <td>≈ <code>dirname</code> in einer Pfadangabe das Ende abschneiden <code>/etc/apt/apt.conf.d</code></td>
      </tr>
      <tr>
          <td><code>:t</code></td>
          <td>≈ <code>basename</code> das Ende einer Pfadangabe (zum Beispiel der Dateiname) <code>20auto-upgrades</code></td>
      </tr>
      <tr>
          <td></td>
          <td><code>ls -l /foo/bar.baz</code></td>
      </tr>
      <tr>
          <td><code>:r</code></td>
          <td><strong>remove</strong> alles hinter dem letzten Punkt <strong>abschneiden</strong> (zum Beispiel die Dateiendung) <code>/foo/bar</code></td>
      </tr>
      <tr>
          <td><code>:e</code></td>
          <td><strong>Endung</strong> alles hinter dem letzten Punkt (zum Beispiel die Dateiendung) = <code>baz</code></td>
      </tr>
  </tbody>
</table>
<p><strong>Beispiel Befehlssuche</strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">$ <span class="nb">echo</span> foo bar baz
</span></span><span class="line"><span class="ln">2</span><span class="cl">foo bar baz
</span></span><span class="line"><span class="ln">3</span><span class="cl">$ <span class="nb">echo</span> !echo:2
</span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="nb">echo</span> bar
</span></span><span class="line"><span class="ln">5</span><span class="cl">bar
</span></span></code></pre></div><p>Nur ausgeben:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">$ <span class="nb">echo</span> foo bar baz
</span></span><span class="line"><span class="ln">2</span><span class="cl">foo bar baz
</span></span><span class="line"><span class="ln">3</span><span class="cl">$ <span class="nb">echo</span> !echo:2:p
</span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="nb">echo</span> bar
</span></span></code></pre></div>
<h2 id="schnell-in-bash-mal-würfeln" data-numberify>schnell in bash mal würfeln<a class="anchor ms-1" href="#schnell-in-bash-mal-würfeln"></a></h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl"><span class="nb">let</span> <span class="nv">zufallszahl</span><span class="o">=</span><span class="nv">$RANDOM</span>%6
</span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="nb">echo</span> <span class="nv">$zufallszahl</span>
</span></span></code></pre></div><table>
  <thead>
      <tr>
          <th>Datum</th>
          <th>Änderung</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>03.11.2023</td>
          <td>Passwort generieren</td>
      </tr>
      <tr>
          <td>14.02.2024</td>
          <td>Hinweis auf <code>gen_passwort.sh</code> im GitLab-Repository</td>
      </tr>
      <tr>
          <td>11.09.2024</td>
          <td>fallocate</td>
      </tr>
      <tr>
          <td>22.09.2024</td>
          <td>Bootstick</td>
      </tr>
      <tr>
          <td>13.11.2024</td>
          <td>Fix Typo</td>
      </tr>
      <tr>
          <td>10.02.2026</td>
          <td>Zufallszahl mehr erläutert</td>
      </tr>
  </tbody>
</table>]]></content:encoded>
    </item>
    
    <item>
      <title>Starship - Shell Prompt mit mehr Infos</title>
      <link>https://www.rainerrose.de/docs/howto/starship/</link>
      <pubDate>Sun, 28 Jul 2024 14:45:16 +0200</pubDate>
      <guid>https://www.rainerrose.de/docs/howto/starship/</guid>
      <description><![CDATA[<!-- Anreißer -->
<p>Der Standard-Prompt ist zu langweilig? Die Befüllung der Variablen <code>PS1</code> ist zu kompliziert und unflexibel? Es sollen mehr Informationen dargestellt werden?</p>
<p>Kein Problem, ich habe jetzt das Tool <code>Starship</code> für mich entdeckt. Es ist schnell installiert und auch recht simpel konfiguriert. Wie das funktioniert, habe ich im Nachfolgenden mal aufgeschrieben.</p>]]></description>
      <content:encoded><![CDATA[<!-- Anreißer -->
<p>Der Standard-Prompt ist zu langweilig? Die Befüllung der Variablen <code>PS1</code> ist zu kompliziert und unflexibel? Es sollen mehr Informationen dargestellt werden?</p>
<p>Kein Problem, ich habe jetzt das Tool <code>Starship</code> für mich entdeckt. Es ist schnell installiert und auch recht simpel konfiguriert. Wie das funktioniert, habe ich im Nachfolgenden mal aufgeschrieben.</p>

<h2 id="alte-welt-ps1-variable" data-numberify>Alte Welt: PS1-Variable<a class="anchor ms-1" href="#alte-welt-ps1-variable"></a></h2>
<p>Meine <code>PS1</code>-Variable, die ich in der <code>~./.bashrc</code> setze, sah bisher immer so aus:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl"><span class="nv">PS1</span><span class="o">=</span><span class="s1">&#39;\[\033[01;32m\][\u@\h\[\033[01;37m\]:\w\[\033[01;32m\]]\$\[\033[00m\] &#39;</span>
</span></span></code></pre></div><p>Das sieht dann z.B. so aus:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">mag@rainern:~/homepages/rainerrose.de
</span></span></code></pre></div>
<h2 id="das-ziel" data-numberify>Das Ziel<a class="anchor ms-1" href="#das-ziel"></a></h2>
<p><code>Starship</code> bietet die Möglichkeit noch weitere Informationen einblenden zu lassen, z.B.:</p>
<ul>
<li>aktueller Name des git-Branches</li>
<li>virtuelles Enviroment unter Python</li>
<li>aktueller Name des Openstack-Projekt</li>
</ul>
<p>Im folgenden Screenshot sieht man die potentiellen Möglichkeiten.</p>
<p><picture><img class="img-fluid " alt="Screenshot eines bunten Prommpts" src="https://www.rainerrose.de/wallpaper/docs/linux/starship-screenshot.png?v=6961075f81e888ea9f3039d26da236b7" loading="lazy" width="1647" height="116" />
</picture>

</p>
<p>Aus Gründen musste ich ein paar Informationen blurren.</p>

<h2 id="installation" data-numberify>Installation<a class="anchor ms-1" href="#installation"></a></h2>

<h3 id="schritt-1-binary-installieren" data-numberify>Schritt 1: Binary installieren<a class="anchor ms-1" href="#schritt-1-binary-installieren"></a></h3>
<p>Die Installation ist recht einfach und gut auf der <a href="https://tools.rainerrose.de/redirect.php?id=39" target="_blank" rel="noopener noreferrer">Projekt-Homepage<i class="fas fa-external-link-square-alt ms-1"></i></a> beschrieben.</p>

<h3 id="schritt-2-aktivieren" data-numberify>Schritt 2: Aktivieren<a class="anchor ms-1" href="#schritt-2-aktivieren"></a></h3>
<p>Je nach gewählter Shell, muss Starship jetzt noch gestartet werden.</p>
<p>Für die <code>bash</code>, die ich verwendet ist dies ein</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl"><span class="nb">echo</span> <span class="s1">&#39;eval &#34;$(starship init bash)&#34;&#39;</span> &gt;&gt; ~/.bashrc
</span></span></code></pre></div><p>Alle anderen Shells sind gut auf der
<a href="https://tools.rainerrose.de/redirect.php?id=40" target="_blank" rel="noopener noreferrer">Projekt-Webseite<i class="fas fa-external-link-square-alt ms-1"></i></a>
beschrieben.</p>

<h2 id="konfiguration" data-numberify>Konfiguration<a class="anchor ms-1" href="#konfiguration"></a></h2>
<p>Zu erst erstellst Du Dir am besten eine leere Konfigurationsdatei.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">mkdir -p ~/.config <span class="o">&amp;&amp;</span> touch ~/.config/starship.toml
</span></span></code></pre></div><p>danach kannst Du meine Konfigurationsdatei weiter unten auf dieser Seite als Vorlage nehmen und sie anpassen.</p>
<p>Auf der <a href="https://tools.rainerrose.de/redirect.php?id=41" target="_blank" rel="noopener noreferrer">Projekt-Webseite<i class="fas fa-external-link-square-alt ms-1"></i></a>
sind es weitere, gute Beispiele aufgeführt.
In der Regel kannst Du die Beispiele aus der Doku 1:1 in Deine Konfigurationsdatei übernehmen und musst sie ggf. nur etwas anpassen.</p>

<h2 id="nacharbeiten" data-numberify>Nacharbeiten<a class="anchor ms-1" href="#nacharbeiten"></a></h2>
<p>Auf meinen <code>Manjaro</code>-Systemen, welche ja auf <code>Arch Linux</code> basieren, musste ich das Fontspaket <code>extra/noto-fonts-emoji</code> nachinstallieren, weil sonst einige Glyphen nicht dargestellt werden konnten.</p>
<p>Um zu testen, ob es Probleme mit einigen Symbolen bzw. Emojis gibt, reichen folgende zwei Befehle:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl"><span class="nb">echo</span> -e <span class="s2">&#34;\xf0\x9f\x90\x8d&#34;</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="nb">echo</span> -e <span class="s2">&#34;\xee\x82\xa0&#34;</span>
</span></span></code></pre></div><p>Das erste Symbol sollte eine Schlange darstellen, das zweite ein Strich mit einem Pfeil der daneben läuft.</p>
<p>In der
<a href="https://tools.rainerrose.de/redirect.php?id=64" target="_blank" rel="noopener noreferrer">FAQ auf der Projekt-Seite<i class="fas fa-external-link-square-alt ms-1"></i></a>
steht es nochmal genauer.</p>

<h2 id="fertig" data-numberify>Fertig<a class="anchor ms-1" href="#fertig"></a></h2>
<p>Beim nächsten Start einer <code>bash</code> oder das Sourcen der <code>~/.bashrc</code> sollte Dir den Prompt im neuen Gewand präsentieren.</p>

<h2 id="dank" data-numberify>Dank<a class="anchor ms-1" href="#dank"></a></h2>
<p>Mein Dank geht an Kevin für die Tipps und den Hinweis auf dieses Tool.</p>

<h2 id="meine-konfig-datei" data-numberify>Meine Konfig-Datei<a class="anchor ms-1" href="#meine-konfig-datei"></a></h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-toml" data-lang="toml"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="c"># https://starship.rs/config/</span>
</span></span><span class="line"><span class="ln"> 2</span><span class="cl"><span class="c"># Get editor completions based on the config schema</span>
</span></span><span class="line"><span class="ln"> 3</span><span class="cl"><span class="s2">&#34;$schema&#34;</span> <span class="p">=</span> <span class="s1">&#39;https://starship.rs/config-schema.json&#39;</span>
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">
</span></span><span class="line"><span class="ln"> 5</span><span class="cl"><span class="c"># Inserts a blank line between shell prompts</span>
</span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="nx">add_newline</span> <span class="p">=</span> <span class="kc">true</span>
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">
</span></span><span class="line"><span class="ln"> 8</span><span class="cl"><span class="p">[</span><span class="nx">directory</span><span class="p">]</span>
</span></span><span class="line"><span class="ln"> 9</span><span class="cl"><span class="nx">truncate_to_repo</span> <span class="p">=</span> <span class="kc">false</span>
</span></span><span class="line"><span class="ln">10</span><span class="cl"><span class="nx">truncation_length</span> <span class="p">=</span> <span class="mi">0</span>
</span></span><span class="line"><span class="ln">11</span><span class="cl">
</span></span><span class="line"><span class="ln">12</span><span class="cl"><span class="p">[</span><span class="nx">git_metrics</span><span class="p">]</span>
</span></span><span class="line"><span class="ln">13</span><span class="cl"><span class="nx">added_style</span> <span class="p">=</span> <span class="s1">&#39;bold blue&#39;</span>
</span></span><span class="line"><span class="ln">14</span><span class="cl"><span class="nx">format</span> <span class="p">=</span> <span class="s1">&#39;[+$added]($added_style)/[-$deleted]($deleted_style) &#39;</span>
</span></span><span class="line"><span class="ln">15</span><span class="cl">
</span></span><span class="line"><span class="ln">16</span><span class="cl"><span class="p">[</span><span class="nx">git_status</span><span class="p">]</span>
</span></span><span class="line"><span class="ln">17</span><span class="cl"><span class="nx">conflicted</span> <span class="p">=</span> <span class="s1">&#39;🏳&#39;</span>
</span></span><span class="line"><span class="ln">18</span><span class="cl"><span class="nx">ahead</span> <span class="p">=</span> <span class="s1">&#39;🏎💨&#39;</span>
</span></span><span class="line"><span class="ln">19</span><span class="cl"><span class="nx">behind</span> <span class="p">=</span> <span class="s1">&#39;😰&#39;</span>
</span></span><span class="line"><span class="ln">20</span><span class="cl"><span class="nx">diverged</span> <span class="p">=</span> <span class="s1">&#39;😵&#39;</span>
</span></span><span class="line"><span class="ln">21</span><span class="cl"><span class="nx">up_to_date</span> <span class="p">=</span> <span class="s1">&#39;✓&#39;</span>
</span></span><span class="line"><span class="ln">22</span><span class="cl"><span class="nx">untracked</span> <span class="p">=</span> <span class="s1">&#39;🤷&#39;</span>
</span></span><span class="line"><span class="ln">23</span><span class="cl"><span class="nx">stashed</span> <span class="p">=</span> <span class="s1">&#39;📦&#39;</span>
</span></span><span class="line"><span class="ln">24</span><span class="cl"><span class="nx">modified</span> <span class="p">=</span> <span class="s1">&#39;📝&#39;</span>
</span></span><span class="line"><span class="ln">25</span><span class="cl"><span class="nx">staged</span> <span class="p">=</span> <span class="s1">&#39;[++\($count\)](green)&#39;</span>
</span></span><span class="line"><span class="ln">26</span><span class="cl"><span class="nx">renamed</span> <span class="p">=</span> <span class="s1">&#39;👅&#39;</span>
</span></span><span class="line"><span class="ln">27</span><span class="cl"><span class="nx">deleted</span> <span class="p">=</span> <span class="s1">&#39;🗑&#39;</span>
</span></span><span class="line"><span class="ln">28</span><span class="cl">
</span></span><span class="line"><span class="ln">29</span><span class="cl"><span class="p">[</span><span class="nx">openstack</span><span class="p">]</span>
</span></span><span class="line"><span class="ln">30</span><span class="cl"><span class="nx">format</span> <span class="p">=</span> <span class="s1">&#39;on [$symbol$cloud(\($project\))]($style) &#39;</span>
</span></span><span class="line"><span class="ln">31</span><span class="cl"><span class="nx">style</span> <span class="p">=</span> <span class="s1">&#39;bold yellow&#39;</span>
</span></span><span class="line"><span class="ln">32</span><span class="cl"><span class="nx">symbol</span> <span class="p">=</span> <span class="s1">&#39;☁ &#39;</span>
</span></span><span class="line"><span class="ln">33</span><span class="cl">
</span></span><span class="line"><span class="ln">34</span><span class="cl"><span class="p">[</span><span class="nx">hostname</span><span class="p">]</span>
</span></span><span class="line"><span class="ln">35</span><span class="cl"><span class="nx">ssh_only</span> <span class="p">=</span> <span class="kc">false</span>
</span></span><span class="line"><span class="ln">36</span><span class="cl"><span class="nx">format</span> <span class="p">=</span> <span class="s1">&#39;[$ssh_symbol](bold blue)[$hostname](bold red):&#39;</span>
</span></span><span class="line"><span class="ln">37</span><span class="cl"><span class="nx">trim_at</span> <span class="p">=</span> <span class="s1">&#39;.companyname.com&#39;</span>
</span></span><span class="line"><span class="ln">38</span><span class="cl"><span class="nx">disabled</span> <span class="p">=</span> <span class="kc">false</span>
</span></span><span class="line"><span class="ln">39</span><span class="cl">
</span></span><span class="line"><span class="ln">40</span><span class="cl"><span class="p">[</span><span class="nx">username</span><span class="p">]</span>
</span></span><span class="line"><span class="ln">41</span><span class="cl"><span class="nx">style_user</span> <span class="p">=</span> <span class="s1">&#39;white bold&#39;</span>
</span></span><span class="line"><span class="ln">42</span><span class="cl"><span class="nx">style_root</span> <span class="p">=</span> <span class="s1">&#39;black bold&#39;</span>
</span></span><span class="line"><span class="ln">43</span><span class="cl"><span class="nx">format</span> <span class="p">=</span> <span class="s1">&#39;[$user]($style)@&#39;</span>
</span></span><span class="line"><span class="ln">44</span><span class="cl"><span class="nx">disabled</span> <span class="p">=</span> <span class="kc">false</span>
</span></span><span class="line"><span class="ln">45</span><span class="cl"><span class="nx">show_always</span> <span class="p">=</span> <span class="kc">true</span>
</span></span><span class="line"><span class="ln">46</span><span class="cl"><span class="nx">aliases</span> <span class="p">=</span> <span class="p">{</span> <span class="s2">&#34;corpuser034g&#34;</span> <span class="p">=</span> <span class="s2">&#34;matchai&#34;</span> <span class="p">}</span>
</span></span><span class="line"><span class="ln">47</span><span class="cl">
</span></span><span class="line"><span class="ln">48</span><span class="cl"><span class="p">[</span><span class="nx">kubernetes</span><span class="p">]</span>
</span></span><span class="line"><span class="ln">49</span><span class="cl"><span class="nx">disabled</span> <span class="p">=</span> <span class="kc">false</span>
</span></span><span class="line"><span class="ln">50</span><span class="cl"><span class="nx">format</span> <span class="p">=</span> <span class="s1">&#39;[$symbol$context( \($namespace\))]($style) &#39;</span>
</span></span><span class="line"><span class="ln">51</span><span class="cl">
</span></span><span class="line"><span class="ln">52</span><span class="cl"><span class="p">[[</span><span class="nx">kubernetes</span><span class="p">.</span><span class="nx">contexts</span><span class="p">]]</span>
</span></span><span class="line"><span class="ln">53</span><span class="cl"><span class="nx">context_pattern</span> <span class="p">=</span> <span class="s2">&#34;.*_(customers|infrastructure)_(?P&lt;cluster&gt;[\\w-]*)_(tooling|bootstrap).*&#34;</span>
</span></span><span class="line"><span class="ln">54</span><span class="cl"><span class="nx">context_alias</span> <span class="p">=</span> <span class="s2">&#34;$cluster&#34;</span>
</span></span><span class="line"><span class="ln">55</span><span class="cl">
</span></span><span class="line"><span class="ln">56</span><span class="cl"><span class="p">[</span><span class="nx">env_var</span><span class="p">]</span>
</span></span><span class="line"><span class="ln">57</span><span class="cl"><span class="nx">style</span> <span class="p">=</span> <span class="s1">&#39;red bold&#39;</span>
</span></span><span class="line"><span class="ln">58</span><span class="cl"><span class="nx">variable</span> <span class="p">=</span> <span class="s1">&#39;KUBECONFIG&#39;</span>
</span></span></code></pre></div>
<h2 id="ansible-rolle" data-numberify>Ansible-Rolle<a class="anchor ms-1" href="#ansible-rolle"></a></h2>
<p>Update: 27.12.2024</p>
<p>Inzwischen habe ich für die Installation eine Ansible-Rolle geschrieben. Den <a href="/posts/starship-rolle/">dazugehörigen Blog-Artikel</a> findet Du <a href="/posts/starship-rolle/">hier</a>.</p>

<h2 id="kubernetes-context-lange-namen" data-numberify>Kubernetes Context (lange Namen)<a class="anchor ms-1" href="#kubernetes-context-lange-namen"></a></h2>
<p>Update 29.03.2026</p>
<p>Aktuell arbeite ich mit längeren Namen im <code>context</code> was zu sehr langen Zeilen führt, wenn man folgende Format-Syntax wählt:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-toml" data-lang="toml"><span class="line"><span class="ln">1</span><span class="cl"><span class="nx">format</span> <span class="p">=</span> <span class="s1">&#39;on [☸ $user on $context](dimmed green) &#39;</span>
</span></span></code></pre></div><p>Weiterhin habe ich <code>starship</code> auf die Version <code>1.24.2</code> aktualisiert, dort kann Pattern-Matching verwendet werden.</p>
<p>Ich habe also oben im Abschnitt <code>kubernetes</code> das Format geändert und die beiden Abschnitte <code>kubernetes.contexts</code> und <code>env_var</code> hinzugefügt.</p>
<p>Über den <code>context_alias</code> kann ich nun alles für mich nicht relevante wegschneiden. Im Grunde wird mir jetzt nur noch der Name des Clusters angezeigt.</p>
<p>Beispiele:</p>
<ul>
<li><code>cluster-api</code></li>
<li><code>foo</code></li>
<li><code>bar</code></li>
</ul>

<h2 id="changelog" data-numberify>Changelog<a class="anchor ms-1" href="#changelog"></a></h2>
<table>
  <thead>
      <tr>
          <th>Datum</th>
          <th>Änderung</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>25.10.2024</td>
          <td>Abschnitt kubernetes in der Konfig hinzugefügt. Synatx-Highlighting gefixed.</td>
      </tr>
      <tr>
          <td>27.12.2024</td>
          <td>Erwähnung der Ansible-Rolle <code>starship</code>.</td>
      </tr>
      <tr>
          <td>29.03.2026</td>
          <td>Kubernetes Context. Änderungen vom Format. Typos gefixed.</td>
      </tr>
  </tbody>
</table>]]></content:encoded>
    <enclosure url="https://www.rainerrose.de/wallpaper/docs/linux/starship-screenshot.png" length="27725" type="image/.png" />
    </item>
    
    <item>
      <title>Sonstiges</title>
      <link>https://www.rainerrose.de/docs/linux/sonstiges/</link>
      <pubDate>Fri, 28 Jun 2024 23:16:19 +0200</pubDate>
      <guid>https://www.rainerrose.de/docs/linux/sonstiges/</guid>
      <description><![CDATA[<!-- Anreißer -->
<p>Alles was nicht so recht in eine Kategorie passt oder wo ich zu faul war zu kategorisieren. :-D</p>

<h2 id="curl-mit-ipv6" data-numberify>curl mit IPv6<a class="anchor ms-1" href="#curl-mit-ipv6"></a></h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">curl  <span class="s2">&#34;http://[ipv6:addresse]:port/&#34;</span>
</span></span></code></pre></div>
<h2 id="root-passwort-wieder-löschen" data-numberify>root passwort wieder löschen<a class="anchor ms-1" href="#root-passwort-wieder-löschen"></a></h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">passwd -dl root
</span></span></code></pre></div>
<h2 id="magic-sys-key" data-numberify>Magic Sys Key<a class="anchor ms-1" href="#magic-sys-key"></a></h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl"><span class="nb">echo</span> s &gt; /proc/sysrq-trigger
</span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="nb">echo</span> u &gt; /proc/sysrq-trigger
</span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="nb">echo</span> b &gt; /proc/sysrq-trigger
</span></span></code></pre></div><p>Und im Falle von Turnschuhnetzwerk und direkt vor dem Rechner geht das auch mit:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="ln">1</span><span class="cl">ALT-PrintScr-S
</span></span><span class="line"><span class="ln">2</span><span class="cl">ALT-PrintScr-U
</span></span><span class="line"><span class="ln">3</span><span class="cl">ALT-PrintScr-B 
</span></span></code></pre></div>]]></description>
      <content:encoded><![CDATA[<!-- Anreißer -->
<p>Alles was nicht so recht in eine Kategorie passt oder wo ich zu faul war zu kategorisieren. :-D</p>

<h2 id="curl-mit-ipv6" data-numberify>curl mit IPv6<a class="anchor ms-1" href="#curl-mit-ipv6"></a></h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">curl  <span class="s2">&#34;http://[ipv6:addresse]:port/&#34;</span>
</span></span></code></pre></div>
<h2 id="root-passwort-wieder-löschen" data-numberify>root passwort wieder löschen<a class="anchor ms-1" href="#root-passwort-wieder-löschen"></a></h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">passwd -dl root
</span></span></code></pre></div>
<h2 id="magic-sys-key" data-numberify>Magic Sys Key<a class="anchor ms-1" href="#magic-sys-key"></a></h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl"><span class="nb">echo</span> s &gt; /proc/sysrq-trigger
</span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="nb">echo</span> u &gt; /proc/sysrq-trigger
</span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="nb">echo</span> b &gt; /proc/sysrq-trigger
</span></span></code></pre></div><p>Und im Falle von Turnschuhnetzwerk und direkt vor dem Rechner geht das auch mit:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="ln">1</span><span class="cl">ALT-PrintScr-S
</span></span><span class="line"><span class="ln">2</span><span class="cl">ALT-PrintScr-U
</span></span><span class="line"><span class="ln">3</span><span class="cl">ALT-PrintScr-B 
</span></span></code></pre></div>
<h2 id="xubuntu-auf-neues-distro-upgrade-checken" data-numberify>XUbuntu auf neues Distro-Upgrade checken<a class="anchor ms-1" href="#xubuntu-auf-neues-distro-upgrade-checken"></a></h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl"><span class="k">do</span>-release-upgrade -c
</span></span></code></pre></div>
<h2 id="resolvconf-wird-immer-überschrieben" data-numberify>resolv.conf wird immer überschrieben<a class="anchor ms-1" href="#resolvconf-wird-immer-überschrieben"></a></h2>
<p>Nach Änderung des DNS-Servers wird die <code>/etc/resolv.conf</code> immer wieder überschrieben?</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">systemctl restart NetworkManager.service
</span></span></code></pre></div><p>Erst mal alle Interfaces anzeigen:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">nmcli -p connection show
</span></span></code></pre></div><p>In diesem Fall half, das Interface neu hochzufahren</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">nmcli c up enp0s8
</span></span></code></pre></div>
<h2 id="netzwerkkarten-konfiguration" data-numberify>Netzwerkkarten-Konfiguration<a class="anchor ms-1" href="#netzwerkkarten-konfiguration"></a></h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">nmtui
</span></span><span class="line"><span class="ln">2</span><span class="cl">systemctl restart NetworkManager.service
</span></span><span class="line"><span class="ln">3</span><span class="cl">ip link <span class="nb">set</span> enp0s8 down
</span></span><span class="line"><span class="ln">4</span><span class="cl">ip link <span class="nb">set</span> enp0s8 up
</span></span></code></pre></div>
<h2 id="ignore-case-bei-less" data-numberify>Ignore case bei less<a class="anchor ms-1" href="#ignore-case-bei-less"></a></h2>
<ol>
<li>im Befehlsmodus <code>-i</code></li>
<li>gleich als Parameter aufrufen <code>less -i</code></li>
</ol>

<h2 id="eben-mal-schnell-konvertieren" data-numberify>Eben mal schnell konvertieren<a class="anchor ms-1" href="#eben-mal-schnell-konvertieren"></a></h2>
<p>Eben mal schnell ein Dokument von einem Format ins andere konvertieren? Nicht überall gibt es <code>pandoc</code> oder zum Teil nur in einer veralteten Version. <code>docker</code> hilft hier:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">docker run --rm --volume <span class="s2">&#34;`pwd`:/data&#34;</span> --user <span class="sb">`</span>id -u<span class="sb">`</span>:<span class="sb">`</span>id -g<span class="sb">`</span> pandoc/latex <span class="nv">$*</span>
</span></span></code></pre></div><p>Benennt man das Script z.B. <code>pandoc.sh</code> lässt es sich zum Beispiel so von Markdown in Dokuwiki umwandeln</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">pandoc.sh -f markdown -t dokuwiki index.md
</span></span></code></pre></div>
<h2 id="usb-palm" data-numberify>USB-Palm<a class="anchor ms-1" href="#usb-palm"></a></h2>
<p>Wo schließe ich denn meinen USB-Palm an? Das Device heiß:
<code>/dev/usb/ttyUSB1</code></p>
<p>Im Kernel ist es zu konfigurieren als:</p>
<pre><code>USB support ---&gt; USB Serial Converter support ---&gt; USB Serial Converter support
USB Handspring Visor / Palm m50x / Sony Clie Driver
</code></pre>
<p>Am besten einfach einen symbolischen Link drauflegen.</p>

<h2 id="suchen-eines-textes-in-dateien-im-aktuellen-verzeichnis" data-numberify>Suchen eines Textes in Dateien im aktuellen Verzeichnis<a class="anchor ms-1" href="#suchen-eines-textes-in-dateien-im-aktuellen-verzeichnis"></a></h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">find . <span class="p">|</span> xargs grep Suchmuster 2&gt; /dev/null
</span></span></code></pre></div>
<h2 id="vergessen-in-welches-verzeichnis-ein-programm-installiert-wurde" data-numberify>Vergessen, in welches Verzeichnis ein Programm installiert wurde?<a class="anchor ms-1" href="#vergessen-in-welches-verzeichnis-ein-programm-installiert-wurde"></a></h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">which Programm-Name
</span></span></code></pre></div><p>liefert den absoluten Pfad, sofern es sich im Suchpfad befindet.</p>

<h2 id="scsii-zip-drive" data-numberify>SCSII-ZIP-Drive<a class="anchor ms-1" href="#scsii-zip-drive"></a></h2>
<p>Das SCSII-ZIP-Drive erst nach dem booten angeschlossen?</p>
<p>Kein Problem:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;scsi add-single-device 0 0 6 0&#34;</span> &gt; /proc/scsi/scsi
</span></span></code></pre></div><p>und mit</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">mount -t dateisystem /dev/sd?4 /mnt
</span></span></code></pre></div><p>ins Dateisystem einhängen.</p>
<p>Falls das ZIP-Drive die ID <code>5</code> hat, einfach oben die <code>6</code> durch die <code>5</code>
ersetzen.</p>

<h2 id="multivolume-archive-erstellen" data-numberify>Multivolume Archive erstellen<a class="anchor ms-1" href="#multivolume-archive-erstellen"></a></h2>

<h3 id="mit-gleichem-dateinamen" data-numberify>Mit gleichem Dateinamen<a class="anchor ms-1" href="#mit-gleichem-dateinamen"></a></h3>
<p>erstellen:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">tar -c -L &lt;Größe in MB&gt; -f &lt;arch.tar&gt;
</span></span></code></pre></div><p>entpacken:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">tar -xMf &lt;archiv.tar&gt;
</span></span></code></pre></div><p>Mit unterschiedlichem Dateinamen (<code>archiv.tar.aa, archiv.tar..ab, archiv.tar..ac, archiv.tar..&lt;PREFIX&gt;...</code> )</p>

<h3 id="mit-temporärer-datei" data-numberify>Mit temporärer Datei<a class="anchor ms-1" href="#mit-temporärer-datei"></a></h3>
<p>erstellen:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">tar -czf &lt;archiv.tar&gt; &lt;Source&gt;<span class="p">;</span> split -b&lt;Größe in MB&gt;M &lt;archiv.tar&gt; &lt;archiv.tar.split.&gt;
</span></span></code></pre></div><p>Bsp (95MB-Archive):</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">tar czf /mnt/zip /home/user<span class="p">;</span> split -b95 archiv.tz archiv.tgz.split.
</span></span></code></pre></div><p>entpacken:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">cat &lt;archiv.tar.split.&gt;* &gt; archiv.tar
</span></span></code></pre></div><p>Bsp:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">cat archiv.tgz.split.* &gt; archiv.tgz
</span></span></code></pre></div>
<h3 id="ohne-temporärer-datei" data-numberify>ohne temporärer Datei<a class="anchor ms-1" href="#ohne-temporärer-datei"></a></h3>
<p>erstellen:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">tar cz &lt;Source&gt; <span class="p">|</span> split -b&lt;Größe in MB&gt;M &lt;archiv.tar.split.&gt;
</span></span></code></pre></div><p>Bsp (95MB-Archive):</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">tar cz /home/user <span class="p">|</span> split -b95M - archiv.tgz.split.
</span></span></code></pre></div><p>entpacken:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">cat &lt;archiv.tar.split.*&gt; <span class="p">|</span> tar xz
</span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="sb">```</span> bash
</span></span><span class="line"><span class="ln">3</span><span class="cl">
</span></span><span class="line"><span class="ln">4</span><span class="cl">Bsp: 
</span></span><span class="line"><span class="ln">5</span><span class="cl"><span class="sb">```</span> bash
</span></span><span class="line"><span class="ln">6</span><span class="cl">cat archiv.tgz.split.* <span class="p">|</span> tar xz
</span></span></code></pre></div><p>entpacken unter Dos:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">copy /b archiv.tgz.split.aa+archiv.tgz.split.ab+archiv.split.ac archiv.tgz
</span></span></code></pre></div><p>Alle Dateien müssen beim <code>copy</code>-Befehl angegeben werden! Danach normal
das tgz-Archiv entpacken.</p>

<h2 id="datei-endung-datei-format-verbaselt-gelöscht-unbekannt" data-numberify>Datei-Endung, Datei-Format verbaselt, gelöscht, unbekannt<a class="anchor ms-1" href="#datei-endung-datei-format-verbaselt-gelöscht-unbekannt"></a></h2>
<p>mit dem kleinen Progrämmchen file bekommen Sie es heraus.</p>
<p>Beispiel:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">file unbekanntes_Datei-Format
</span></span><span class="line"><span class="ln">2</span><span class="cl">unbekanntes_Datei-Format: gzip compressed data, deflated, last modified: Wed Jan <span class="m">16</span> 21:36:14 2002, os: Unix
</span></span></code></pre></div>
<h2 id="attachments-in-der-mail" data-numberify>Attachments in der Mail<a class="anchor ms-1" href="#attachments-in-der-mail"></a></h2>
<p>Man kennt, es. Attachments landen mal wieder in der Mail.</p>
<ol>
<li>Mail in einer TextDatei abspeichern.</li>
<li>Alles vor dem: <code>begin 666 dateiname</code> in der Textdatei löschen.</li>
<li><code>uudecode -oneuer_dateiname codierte_datei_im_bin_format</code></li>
</ol>
<p>Fertich. (Version: uudecode (GNU sharutils) 4.2c)</p>

<h2 id="reguläre-ausdrücke" data-numberify>Reguläre Ausdrücke<a class="anchor ms-1" href="#reguläre-ausdrücke"></a></h2>
<p>Reguläre Ausdrücke (Englisch: Regular Expression, RegExp) sind
Suchmuster, die mittels Platzhalterzeichen (Jokers) gebildet werden. Sie
dienen hauptsächlich zum Suchen nach und dem Ersetzen von Textstellen.
Platzhalterzeichen sind Sonderzeichen wie z.B. der Stern (<code>*</code>) unter DOS
und Windows. Anders als dort sind in der Unix-Welt Reguläre Ausdrücke
mit zahlreichen weiteren Platzhalterzeichen und -sequenzen möglich. Die
wichtigsten sind nachstehend aufgeführt:</p>
<table>
  <thead>
      <tr>
          <th>Steuerzeichen</th>
          <th>Erläuterung</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>[xyz...]</code></td>
          <td>Eines dieser Zeichen</td>
      </tr>
      <tr>
          <td><code>[^xyz...]</code></td>
          <td>Keines dieser Zeichen</td>
      </tr>
      <tr>
          <td><code>.</code></td>
          <td>Ein beliebiges Zeichen</td>
      </tr>
      <tr>
          <td><code>.*</code></td>
          <td>Keines, eines oder mehrere beliebige Zeichen. Greedy (gefräßig)Suche</td>
      </tr>
      <tr>
          <td><code>.+</code></td>
          <td>Eines oder mehrere beliebige Zeichen</td>
      </tr>
      <tr>
          <td><code>.?</code></td>
          <td>Keines oder ein beliebiges Zeichen</td>
      </tr>
      <tr>
          <td><code>.*?</code></td>
          <td>lazy Suche. Möglichst viel, aber auch möglichst wenig. Quasi beim ersten Treffer aufhören. Gegenteil von greedy</td>
      </tr>
      <tr>
          <td><code>$</code></td>
          <td>Am Ende einer Zeile</td>
      </tr>
      <tr>
          <td><code>^</code></td>
          <td>Am Anfang einer Zeile</td>
      </tr>
      <tr>
          <td><code>(...)</code></td>
          <td>Gruppe von Zeichen</td>
      </tr>
      <tr>
          <td><code>\</code></td>
          <td>Schutzzeichen für Jokers (wird vorangestellt, wenn z.B. nach . oder * gesucht wird)</td>
      </tr>
  </tbody>
</table>
<p>Reguläre Ausdrücke sind eine (mathematische) Wissenschaft für sich, und
es gibt ganze Bücher darüber. Die Anwendungen sind sehr vielfältig.</p>

<h2 id="strom-sparen" data-numberify>Strom sparen<a class="anchor ms-1" href="#strom-sparen"></a></h2>
<p>Bildschirmschoner sollte man deaktivieren. Sie verbrauchen nur CPU-Zeit
(damit Strom) und der Monitor nicht auch noch Strom verbraucht. Der
VESA-DPMS-Standard schaltet nämlich den Bildschirm selbstständig ab.</p>
<p>Ob der VESA-DPMS-Standard aktiviert ist, bekommt man durch die Eingabe
von:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">xset -q
</span></span></code></pre></div><p>auf der Kommandozeile zu sehen.</p>
<p>Neben verschiedenen Ausgaben sollte die aktuelle DPMS-Konfiguration eine
Antwort geben.</p>
<p>Die Zahlen geben wieder nach welchen Zeitabständen der Monitor die
nächste Stufe des DPMS-Standards annimmt.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">xset
</span></span></code></pre></div><p>mit &quot;DPMS is disabled&quot; sollten Sie:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">xset dpms
</span></span></code></pre></div><p>oder</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">xset dpms <span class="m">60</span> <span class="m">120</span> <span class="m">180</span>
</span></span></code></pre></div><p>DPMS aktivieren (mit 1, 2 und 3 Minuten).</p>
<p>Wird der xdm verwendet hilft zudem ein Eintrag in: <code>/etc/X11/xdm/Xsetup</code></p>
<p>Ein Ändern der Zeile von von <code>no</code> in <code>yes</code>.</p>
<p>Unter <em>KDE</em> im Kontroll-Zentrum beim Unterpunkt Energie-Kontrolle.</p>
<p>Unter <em>GNOME</em> ebenfalls im Kontroll-Zentrum.</p>
<p><code>CONFIG_APM_CPU_IDLE=y</code> in der Kernel-Konfiguration sorgt für einen
Stromsparmodus der CPU auf Kernelebene.</p>

<h2 id="letzte-zugriffszeit" data-numberify>letzte Zugriffszeit<a class="anchor ms-1" href="#letzte-zugriffszeit"></a></h2>
<p>Wer die letzte Zugriffszeit von seinen Dateien nicht braucht, kann zudem
seine Partitionen mit dem Parameter:</p>
<pre><code>noatime
</code></pre>
<p>mounten. Bei Dateien, die nur häufig gelesen werden, und sich eh im RAM
befinden, spart man somit einen Schreibzugriff. Bei Laptops mit fast
leerem Akku lebenswichtig.</p>

<h2 id="java-applets-unter-firefox" data-numberify>Java(-Applets) unter Firefox<a class="anchor ms-1" href="#java-applets-unter-firefox"></a></h2>
<p>Wenn es noch nicht existiert, <code>plugins</code>-Verzeichnis im Homeverzeichnis
des Firefox anlegen. Z.B.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">mkdir ~/.mozilla/plugins
</span></span></code></pre></div><p>Jetzt nur noch ein Symlink auf die Libary <code>libjavaplugin_oji.so</code> aus dem
JRE oder SDK in das <code>plugins</code>-Verzeichnis anlegen.</p>
<p>Ist etwas Sucharbeit, müsste sich aber finden lassen. Die besten
Erfahrungen habe ich mit dem JRE von Sun selbst gemacht. Bei vielen
Distributionen lässt sich das Java aber inzwischen auch per
Paketverwaltung als Plugin systemweit nachinstallieren. Der Ort der
Java-Installation lässt sich aus der Umgebungsvariablen JAVA_HOME
ablesen.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl"><span class="nb">echo</span> <span class="nv">$JAVA_HOME</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl">/opt/java/jre
</span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="nb">cd</span> ~/.mozilla/plugins
</span></span><span class="line"><span class="ln">4</span><span class="cl">ln -s /opt/java/jre/plugin/i386/ns610-gcc32/libjavaplugin_oji.so libjavaplugin_oji.so
</span></span></code></pre></div><p>&lt;note tip&gt;Inzwischen nutze ich OpenJDK und das ist genauso
gut&lt;/note&gt;</p>
<p>Jetzt noch den Firefox neu starten und das Plugin sollte benutzbar sein
sowie unter <code>about:plugins</code> auftauchen.</p>

<h2 id="mime-type--encoding-einer-datei-identifizieren" data-numberify>MIME-Type / Encoding einer Datei identifizieren<a class="anchor ms-1" href="#mime-type--encoding-einer-datei-identifizieren"></a></h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">file –bi &lt;dateiname&gt;
</span></span></code></pre></div>
<h2 id="avidemux-meldet-defekte-avi-datei" data-numberify>avidemux meldet defekte avi-Datei<a class="anchor ms-1" href="#avidemux-meldet-defekte-avi-datei"></a></h2>
<p>Reparatur mit:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">avconv -i defekt.avi -codec copy reparatiert.avi
</span></span></code></pre></div>
<h2 id="ip-adresse" data-numberify>IP-Adresse<a class="anchor ms-1" href="#ip-adresse"></a></h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">hostname -i
</span></span></code></pre></div>
<h2 id="md5" data-numberify>md5<a class="anchor ms-1" href="#md5"></a></h2>
<p>md5-Summe in Text-Datei mit Dateinamen reinschreiben</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;2317a049f2c83b735e75cad08022247b foo.sh&#34;</span> &gt; foo.md5.txt
</span></span></code></pre></div><p>Checken mit Download, der dann <code>foo.sh</code> im Dateinamen haben muss.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">md5sum -c foo.md5.txt
</span></span></code></pre></div>
<h2 id="einstellungen-von-putty-exportieren--importieren" data-numberify>Einstellungen von PuTTY exportieren / importieren<a class="anchor ms-1" href="#einstellungen-von-putty-exportieren--importieren"></a></h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="ln">1</span><span class="cl">regedit /e &#34;%userprofile%\Desktop\PuttyEinstellungen.reg&#34; HKEY_CURRENT_USER\Software\Simontatham
</span></span></code></pre></div><p>legt reg-Datei auf den Desktop. Per Doppelklick $IRGENDWO wieder
importieren, fertig.</p>

<h2 id="patch-files" data-numberify>Patch-Files<a class="anchor ms-1" href="#patch-files"></a></h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">diff -u original.txt modifiziert.txt &gt; original.patch
</span></span></code></pre></div><p>patch -u working.slang.c -i slang.patch</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">patch -b -u original.txt -i original.patch
</span></span></code></pre></div><p><code>-b</code> für Backup</p>

<h2 id="changelog" data-numberify>Changelog<a class="anchor ms-1" href="#changelog"></a></h2>
<table>
  <thead>
      <tr>
          <th>Datum</th>
          <th>Änderung</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>30.10.2023</td>
          <td>Xubuntu-Distro-Upgrade Tipp</td>
      </tr>
      <tr>
          <td>14.11.2023</td>
          <td>Magic Sys Key</td>
      </tr>
      <tr>
          <td>28.06.2024</td>
          <td>curl mit IPv6</td>
      </tr>
      <tr>
          <td>28.12.2024</td>
          <td>Systemd-Timer umgelagert auf <a href="../systemd">Systemd</a>.</td>
      </tr>
      <tr>
          <td>29.09.2025</td>
          <td>root passwort wieder löschen</td>
      </tr>
  </tbody>
</table>]]></content:encoded>
    </item>
    
    <item>
      <title>Docker</title>
      <link>https://www.rainerrose.de/docs/linux/docker/</link>
      <pubDate>Sat, 01 Jun 2024 16:28:13 +0200</pubDate>
      <guid>https://www.rainerrose.de/docs/linux/docker/</guid>
      <description><![CDATA[<!-- Anreißer -->
<p>Ein paar kleine Tricks und Kniffe zum Thema Docker.</p>]]></description>
      <content:encoded><![CDATA[<!-- Anreißer -->
<p>Ein paar kleine Tricks und Kniffe zum Thema Docker.</p>

<h2 id="mysqldump-ohne-passwort-in-prozessliste" data-numberify>mysqldump ohne Passwort in Prozessliste<a class="anchor ms-1" href="#mysqldump-ohne-passwort-in-prozessliste"></a></h2>
<p>Unter docker werden die Zugangsdaten meist über Umgebungsvariablen
weitergegeben.</p>
<p>Arbeitet man jedoch bei <code>mysqldump</code> mit dem Parameter <code>-p</code> gibt es
folgende Warnung</p>
<pre><code>mysqldump: [Warning] Using a password on the command line interface can be insecure.
</code></pre>
<p>Um jetzt nicht alles nach <code>/dev/null</code> umzuleiten, um noch echte Fehler
mitzubekommen, kann man mittels des Parameters <code>--defaults-file</code> das
Passwort in eine Datei kopieren. Da sich Zugangsdaten ändern können,
empfiehlt es sich, das dynamisch per Script zu erzeugen und das Passwort
aus der Umgebungsvariable des Containers auszulesen.</p>
<p>Das Script legt man entweder in ein lokales Volume oder kopiert es via
<code>docker cp</code> in den Container.</p>
<p>Das Beispiel-Script zum dynamischen Erzeugen der Credentials-Datei:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl"><span class="cp">#!/bin/bash
</span></span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="cp"></span><span class="nv">CRED_FILE</span><span class="o">=</span><span class="s2">&#34;/docker-entrypoint-initdb.d/credentials-root.conf&#34;</span>
</span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="c1">#loeschen</span>
</span></span><span class="line"><span class="ln">4</span><span class="cl">&gt; <span class="s2">&#34;</span><span class="si">${</span><span class="nv">CRED_FILE</span><span class="si">}</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="ln">5</span><span class="cl">chmod <span class="m">600</span> <span class="s2">&#34;</span><span class="si">${</span><span class="nv">CRED_FILE</span><span class="si">}</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="ln">6</span><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;[client]&#34;</span> &gt;&gt;  <span class="s2">&#34;</span><span class="si">${</span><span class="nv">CRED_FILE</span><span class="si">}</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="ln">7</span><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;password=</span><span class="si">${</span><span class="nv">MYSQL_ROOT_PASSWORD</span><span class="si">}</span><span class="s2">&#34;</span> &gt;&gt; <span class="s2">&#34;</span><span class="si">${</span><span class="nv">CRED_FILE</span><span class="si">}</span><span class="s2">&#34;</span>
</span></span></code></pre></div><p>Und noch ein Auszug aus einem Backup-Script:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">docker <span class="nb">exec</span> -i  onlyoffice-mysql-server  /bin/bash /docker-entrypoint-initdb.d/gen_cred_config.sh
</span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="o">(</span>docker <span class="nb">exec</span> -i onlyoffice-mysql-server mysqldump  --defaults-file<span class="o">=</span>/docker-entrypoint-initdb.d/credentials-root.conf &lt;weitere Dump-Parameter&gt;  -u root -h&lt;hostname&gt;  <span class="p">|</span> xz -c &gt; <span class="s2">&#34;</span><span class="si">${</span><span class="nv">BACKUPDIR</span><span class="si">}</span><span class="s2">/dump.sql.xz&#34;</span>
</span></span></code></pre></div>
<h2 id="umgebungsvariable-aus-docker-container-auslesen" data-numberify>Umgebungsvariable aus Docker-Container auslesen<a class="anchor ms-1" href="#umgebungsvariable-aus-docker-container-auslesen"></a></h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">docker <span class="nb">exec</span> -i onlyoffice-community-server /bin/bash -c <span class="s1">&#39;/bin/echo ${MYSQL_SERVER_PASS}&#39;</span>
</span></span></code></pre></div>
<h2 id="unterordner-in-docker-volume-ignorieren" data-numberify>Unterordner in Docker-Volume ignorieren<a class="anchor ms-1" href="#unterordner-in-docker-volume-ignorieren"></a></h2>
<p>Dem <code>docker-compose</code> ein Verzeichnis der lokalen Maschine übergeben,
aber einzelne Unterverszeichnisse davon ausnehmen:</p>
<p>Das funktioniert, indem für die auszunehmenden Unterordner ein zweites
Volume angeben wird. Volume darf keine Zuordnung mit einem Doppelpunkt
enhalten:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="ln">1</span><span class="cl"><span class="nt">volumes</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="w"></span>- <span class="l">./webseite/html:/var/www/html</span><span class="w">
</span></span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="w"></span>- <span class="l">/var/www/html/static/</span><span class="w">
</span></span></span></code></pre></div><p>Im Beispiel bekommt ein Webserver die ganze Webseite übergeben, der
Ordner <code>static</code> wird aber aus dem Container benutzt.</p>

<h2 id="backups--recover-via-volume-mounten" data-numberify>Backups & Recover via Volume mounten<a class="anchor ms-1" href="#backups--recover-via-volume-mounten"></a></h2>

<h3 id="reingucken" data-numberify>reingucken<a class="anchor ms-1" href="#reingucken"></a></h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">docker run -it --rm -v portainer_data:/data:ro -v <span class="k">$(</span><span class="nb">pwd</span><span class="k">)</span>:/backup alpine /bin/sh
</span></span></code></pre></div>
<h3 id="sichern" data-numberify>sichern<a class="anchor ms-1" href="#sichern"></a></h3>

<h4 id="variante-1" data-numberify>Variante 1<a class="anchor ms-1" href="#variante-1"></a></h4>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">docker run --rm -v portainer_data:/data:ro -v <span class="k">$(</span><span class="nb">pwd</span><span class="k">)</span>:/backup alpine tar cjvf /backup/data.tbz2 -C /data ./
</span></span></code></pre></div>
<h4 id="variante-2" data-numberify>Variante 2<a class="anchor ms-1" href="#variante-2"></a></h4>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">docker run --rm -v portainer_data:/data alpine tar cf - -C /data ./ <span class="p">|</span> xz &gt; ./portainer_data_volume.txz
</span></span></code></pre></div>
<h3 id="recover" data-numberify>Recover<a class="anchor ms-1" href="#recover"></a></h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">docker run --rm -v portainer_data:/data -v ./portainer_data_volume.txz:/backup.tgz alpine tar tJf -C /data /backup.tgz
</span></span></code></pre></div>
<h2 id="volumes" data-numberify>Volumes<a class="anchor ms-1" href="#volumes"></a></h2>
<p>Wie unterscheiden sich nochmal die Bezeichnungen bei den Volumes?</p>
<ul>
<li>bind volume</li>
<li>named volume</li>
<li>volume</li>
</ul>

<h2 id="logfiles-auf-die-konsole" data-numberify>Logfiles auf die Konsole<a class="anchor ms-1" href="#logfiles-auf-die-konsole"></a></h2>
<p>Logfile-Ausgaben können über STDOUT einfach an das &quot;Terminal&quot; geblasen
werden, der dann via <code>docker log &lt;container-name&gt;</code> bzw. Portainer
auslesbar ist.</p>
<p>Eine Apache-Konfig <code>conf-enabled/other-vhosts-access-log.conf</code> kann z.B. so aussehen:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-apache" data-lang="apache"><span class="line"><span class="ln">1</span><span class="cl"><span class="c"># Define an access log for VirtualHosts that don&#39;t define their own logfile</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="nb">CustomLog</span> <span class="sx">/proc/self/fd/1</span> vhost_combined
</span></span></code></pre></div><p>Im Container selbst ist dann der Grund zu sehen, warum das funktioniert:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl"><span class="c1"># ls -l /proc/self/fd/1</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl">lrwx------. <span class="m">1</span> root root <span class="m">64</span> Jul  <span class="m">8</span> 16:19 /proc/self/fd/1 -&gt; /dev/pts/0
</span></span></code></pre></div><p>Habe ich mal in einem ubuntu-basierten Container gesehen, ziemlich
genial.</p>

<h2 id="docker-entrypoint" data-numberify>docker ENTRYPOINT<a class="anchor ms-1" href="#docker-entrypoint"></a></h2>
<p>Weil ich mir nie merken kann, wie wann was gestartet wird, hier mal eine Tabelle:</p>
<table>
  <thead>
      <tr>
          <th>ENTRYPOINT</th>
          <th>CMD</th>
          <th>run-Parameter</th>
          <th>ausgeführt wird</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>[&quot;script.sh&quot;]</code></td>
          <td></td>
          <td></td>
          <td><code>script.sh</code></td>
      </tr>
      <tr>
          <td><code>[&quot;script.sh&quot;]</code></td>
          <td></td>
          <td><code>/bin/bash</code></td>
          <td><code>script.sh /bin/bash</code></td>
      </tr>
      <tr>
          <td><code>[&quot;script.sh&quot;]</code></td>
          <td><code>[&quot;mysqld&quot;]</code></td>
          <td></td>
          <td><code>script.sh mysqld</code></td>
      </tr>
      <tr>
          <td><code>[&quot;script.sh&quot;]</code></td>
          <td><code>[&quot;mysqld&quot;]</code></td>
          <td><code>/bin/bash</code></td>
          <td><code>script.sh /bin/bash</code></td>
      </tr>
      <tr>
          <td></td>
          <td><code>[&quot;/bin/sh&quot;]</code></td>
          <td></td>
          <td><code>/bin/sh</code></td>
      </tr>
      <tr>
          <td></td>
          <td><code>[&quot;/bin/sh&quot;]</code></td>
          <td><code>/bin/bash</code></td>
          <td><code>/bin/bash</code></td>
      </tr>
  </tbody>
</table>

<h2 id="zeitzonen" data-numberify>Zeitzonen<a class="anchor ms-1" href="#zeitzonen"></a></h2>
<p>Die lokale Zeitzone lässt sich per Volume-Mount an den Container durchreichen, sofern die Applikation das unterstützt bzw. beachtet.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="ln">1</span><span class="cl"><span class="w">    </span><span class="nt">volumes</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="w">      </span>- <span class="l">/etc/timezone:/etc/timezone:ro</span><span class="w">
</span></span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="w">      </span>- <span class="l">/etc/localtime:/etc/localtime:ro</span><span class="w">
</span></span></span></code></pre></div>
<h2 id="pull-und-restart" data-numberify>Pull und Restart<a class="anchor ms-1" href="#pull-und-restart"></a></h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">docker compose up -d --pull always
</span></span></code></pre></div><p>bzw.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">docker compose up -d --build --pull always
</span></span></code></pre></div>
<h2 id="erstellungsdatum-created-eines-images-abfragen" data-numberify>Erstellungsdatum (Created) eines Images abfragen<a class="anchor ms-1" href="#erstellungsdatum-created-eines-images-abfragen"></a></h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">docker inspect docker.io/photoprism/photoprism:latest -f <span class="s2">&#34;{{ .Created}}&#34;</span>
</span></span></code></pre></div>
<h2 id="changelog" data-numberify>Changelog<a class="anchor ms-1" href="#changelog"></a></h2>
<table>
  <thead>
      <tr>
          <th>Datum</th>
          <th>Änderung</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>08.11.2023</td>
          <td>Backup via Volume weitere Variante sowie Recover-Möglichkeit.</td>
      </tr>
      <tr>
          <td>01.06.2024</td>
          <td>docker ENTRYPOINT</td>
      </tr>
      <tr>
          <td>25.11.2024</td>
          <td>Zeitzonen-Volumes</td>
      </tr>
      <tr>
          <td>02.05.2025</td>
          <td>Pull und Restart</td>
      </tr>
      <tr>
          <td>24.03.2026</td>
          <td>Erstellungsdatum (Created) eines Images abfragen</td>
      </tr>
  </tbody>
</table>]]></content:encoded>
    </item>
    
    <item>
      <title>XFree</title>
      <link>https://www.rainerrose.de/docs/linux/xfree/</link>
      <pubDate>Sat, 01 Jun 2024 16:20:47 +0200</pubDate>
      <guid>https://www.rainerrose.de/docs/linux/xfree/</guid>
      <description><![CDATA[<!-- Anreißer -->
<p>Tipps und Tricks zum Display-Server-Protokoll für X11.</p>]]></description>
      <content:encoded><![CDATA[<!-- Anreißer -->
<p>Tipps und Tricks zum Display-Server-Protokoll für X11.</p>

<h2 id="die-tasten--und--funktionieren-nicht" data-numberify>Die Tasten ~ und ^ funktionieren nicht.<a class="anchor ms-1" href="#die-tasten--und--funktionieren-nicht"></a></h2>
<p>Es gibt zwei Möglichkeiten das Problem zu beheben:</p>
<p>Gefolgt vom <code>~</code> oder <code>^</code> einfach die
Leertaste (Space) drücken.</p>
<p>Man editiere als <code>root</code> die Datei <code>/etc/X11/XF86Config</code></p>
<p>In der Rubrik:</p>
<div class="highlight" title="/etc/X11/XF86Config"><pre tabindex="0" class="chroma"><code class="language-ini" data-lang="ini"><span class="line"><span class="ln">1</span><span class="cl"><span class="na">Section     &#34;InputDevice&#34;</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="na">Driver  &#34;keyboard&#34;</span>
</span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="na">Identifier  &#34;Keyboard[0]&#34;</span>
</span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="na">Option  &#34;Protocol&#34; &#34;Standard&#34;</span>
</span></span><span class="line"><span class="ln">5</span><span class="cl"><span class="na">Option  &#34;XkbLayout&#34; &#34;de&#34;</span>
</span></span><span class="line"><span class="ln">6</span><span class="cl"><span class="na">Option  &#34;XkbModel&#34; &#34;pc102&#34;</span>
</span></span><span class="line"><span class="ln">7</span><span class="cl"><span class="na">Option  &#34;XkbRules&#34; &#34;xfree86&#34;</span>
</span></span></code></pre></div><p>folgende Zeile hinzufügen:</p>
<div class="highlight" title="/etc/X11/XF86Config"><pre tabindex="0" class="chroma"><code class="language-ini" data-lang="ini"><span class="line"><span class="ln">1</span><span class="cl"><span class="na">Option &#34;XkbVariant&#34; &#34;nodeadkeys&#34;</span>
</span></span></code></pre></div><p>Und nach einem Restart des <code>XFree</code> sollten die Tasten funktionieren.</p>

<h2 id="x11-oder-wayland" data-numberify>X11 oder Wayland?<a class="anchor ms-1" href="#x11-oder-wayland"></a></h2>
<p>Um herauszufinden ob man noch unter X11 oder schon unter Wayland unterwegs ist, gibt es eine schöne Umgebungsvariable:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl"><span class="nb">echo</span> <span class="nv">$XDG_SESSION_TYPE</span>
</span></span></code></pre></div><p>Sofern</p>
<pre><code>x11
</code></pre>
<p>ausgeben wird, befindet man sich unter gleichnamigen.</p>

<h2 id="changelog" data-numberify>Changelog<a class="anchor ms-1" href="#changelog"></a></h2>
<table>
  <thead>
      <tr>
          <th>Datum</th>
          <th>Änderung</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>01.06.2024</td>
          <td>X11 oder Wayland</td>
      </tr>
  </tbody>
</table>]]></content:encoded>
    </item>
    
    <item>
      <title>CACHEDIR.TAG</title>
      <link>https://www.rainerrose.de/posts/cachedirtag/</link>
      <pubDate>Sat, 01 Jun 2024 15:50:36 +0200</pubDate>
      <guid>https://www.rainerrose.de/posts/cachedirtag/</guid>
      <description><![CDATA[<!-- Anreißer --> 
<p>Bei einem dateibasierten Backup wollte ich nicht immer alle Dateien und Unterverzeichnisse in die Sicherung mit aufnehmen.</p>
<p>Viele Tool wie <code>restic</code>, <code>backup</code> oder auch <code>tar</code> unterstützen eine externe Datei, wo diese Ausnahmen gepflegt werden können.</p>
<p>Allerdings vergesse ich manchmal diese Datei zu pflegen oder die Syntax ist etwas umständlich.</p>
<p>Manchmal möchte man auch <em>nur-mal-eben-schnell</em> <sup>(tm)</sup> ein Verzeichnis ausschließen.</p>
<p>Dafür gibt es die Möglichkeit über eine Datei namens <code>CACHEDIR.TAG</code> zu nutzen.</p>]]></description>
      <content:encoded><![CDATA[<!-- Anreißer --> 
<p>Bei einem dateibasierten Backup wollte ich nicht immer alle Dateien und Unterverzeichnisse in die Sicherung mit aufnehmen.</p>
<p>Viele Tool wie <code>restic</code>, <code>backup</code> oder auch <code>tar</code> unterstützen eine externe Datei, wo diese Ausnahmen gepflegt werden können.</p>
<p>Allerdings vergesse ich manchmal diese Datei zu pflegen oder die Syntax ist etwas umständlich.</p>
<p>Manchmal möchte man auch <em>nur-mal-eben-schnell</em> <sup>(tm)</sup> ein Verzeichnis ausschließen.</p>
<p>Dafür gibt es die Möglichkeit über eine Datei namens <code>CACHEDIR.TAG</code> zu nutzen.</p>

<h2 id="voraussetzungen" data-numberify>Voraussetzungen<a class="anchor ms-1" href="#voraussetzungen"></a></h2>
<p>Diese Datei muss nur zwei Voraussetzungen erfüllen:</p>
<ol>
<li>Der Name der Datei muss <code>CACHEDIR.TAG</code> lauten und zwar in genau der Schreibweise.</li>
<li>Der Inhalt der Datei muss einen bestimmten Inhalt haben.</li>
</ol>

<h2 id="name-der-datei" data-numberify>Name der Datei<a class="anchor ms-1" href="#name-der-datei"></a></h2>
<p>Der Name der Datei muss genau <code>CACHEDIR.TAG</code> lauten; hierbei ist auch auf Groß- und Kleinschreibung zu achten.</p>

<h2 id="inhalt-der-datei" data-numberify>Inhalt der Datei<a class="anchor ms-1" href="#inhalt-der-datei"></a></h2>
<p>Am Anfang der Datei muss ein bestimmter Inhalt stehen, er lautet:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="ln">1</span><span class="cl">Signature: 8a477f597d28d172789f06886806bc55
</span></span></code></pre></div><p>So eine Datei kann auch über ein Shell erstellt werden, z.B. so:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;Signature: 8a477f597d28d172789f06886806bc55&#34;</span> &gt; CACHEDIR.TAG
</span></span></code></pre></div><p>Wichtig hierbei sind nur die ersten 43 Octets der Datei. Danach können noch weitere Informationen kommen, wie z.B. eine kleine Notiz:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="ln">1</span><span class="cl">Signature: 8a477f597d28d172789f06886806bc55
</span></span><span class="line"><span class="ln">2</span><span class="cl"># Diese Datei bedeutet, dass dieses Unterverzeichnis und seine Inhalte vom Backup ausgeschlossen werden.
</span></span></code></pre></div><p>Aber auch hier muss auf die Groß- und Kleinschreibung beim Inhalt der Datei geachtet werden.
Alternativ kann man diese Datei auch nutzen, um eine solche Datei mit Ausnahmen zu erstellen.
Diese Datei lässt sich dann z.B. mit dem Programm <code>tar</code> auswerten, um ein Archiv zu erstellen, was diese Verzeichnisse auslässt.</p>
<p>Beispiel:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">find . -name CACHEDIR.TAG <span class="p">|</span> sed -e <span class="s1">&#39;s/[/]CACHEDIR.TAG-//g&#39;</span> &gt;/tmp/excludes
</span></span><span class="line"><span class="ln">2</span><span class="cl"> tar cvf /tmp/backup.tar --exclude-from/tmp/excludes .
</span></span></code></pre></div><p>Diese Tagging-Konvention lässt sich somit auch für weitere Tools benutzen, auch wenn diese die Konvention noch nicht direkt unterstützen. Definitionen von Ausnahme-Listen unterstützen meist viele Programme und über diesen kleinen Umweg, lässt sich die Tagging-Technik schon jetzt meist ohne Änderung der Programme nutzen.</p>
<p>Die Tools <code>restic</code> und <code>borg</code> können mit dem Parameter <code>--exclude-caches</code> angewiesen werden, die Datei <code>CACHEDIR.TAG</code> zu berücksichtigen. Hier werden dann automatisch die Verzeichnisse mit ihren Unterinhalten vom Backup ausgenommen, die eine solche Datei enthalten.</p>
<p>Beispiel:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">restic -r /backup/backup_home_dirs backup --exclude-caches /home/
</span></span></code></pre></div><p>Auch Verzeichnisse wie <code>/var/cache</code> lassen sich damit elegant aus dem Backup aussparen.</p>
<p>Ich bin sehr froh dieses entdeckt zu haben, da ich jetzt nicht mehr für jede Ausnahme pflegen muss und dann wieder das Backup-Script irgendwo einchecken oder auf irgendwelche Server verteilen muss. Hier reicht jetzt das triviale Anlegen einer Datei in dem gewünschten Verzeichnis.</p>

<h2 id="credits" data-numberify>Credits<a class="anchor ms-1" href="#credits"></a></h2>
<p>Die ursprüngliche Idee bzw. Vorschlag stammt von Bryan Ford und kann <a href="https://tools.rainerrose.de/redirect.php?id=42" target="_blank" rel="noopener noreferrer">hier nachgelesen<i class="fas fa-external-link-square-alt ms-1"></i></a>  werden.</p>]]></content:encoded>
    </item>
    
    <item>
      <title>SSH-Tricks: Hold on</title>
      <link>https://www.rainerrose.de/posts/ssh-tricks_hold_on/</link>
      <pubDate>Thu, 08 Feb 2024 18:15:02 +0100</pubDate>
      <guid>https://www.rainerrose.de/posts/ssh-tricks_hold_on/</guid>
      <description><![CDATA[<!-- Anreißer -->
<p>Letztens habe ich ein weiteren Kniff gelernt, der in Zusammenhang mit <code>ssh</code>-Verbindungen hilfreich ist.</p>]]></description>
      <content:encoded><![CDATA[<!-- Anreißer -->
<p>Letztens habe ich ein weiteren Kniff gelernt, der in Zusammenhang mit <code>ssh</code>-Verbindungen hilfreich ist.</p>
<p>Führt man mehrere <code>ssh</code>-Kommandos kurz hintereinander aus, muss für jede Verbindung ein erneuter Kontakt zum jeweiligen Server aufgebaut werden.
Das sind zwar immer (je nach Verbindung und Schnelligkeit des Servers) vielleicht nur ein paar Millisekunden, aber zum Beispiel in Zusammenhang mit <code>Ansible</code>-Playbooks kann sich das schon mal addieren und den Lauf durchaus in die Länge ziehen. Zudem ist es nicht sehr ressourcenschonend.</p>
<p>In der <code>ssh</code>-Konfiguration des aktuellen Benutzers
(<code>~/.ssh/config</code>) kann jedoch eine Option gesetzt werden, die ein Socket-File aufmacht und somit die Verbindung offen hält. Mit einem gesetzten Timeout von zum Beispiel 30 Minuten, muss nun nicht mehr jedes Mal eine neue Verbindung initiiert werden. Damit entfällt das ganze Geraffel mit Handshake etc.</p>
<p><code>Ansible</code>-Playbooks laufen jetzt bei mir <strong>wesentlich</strong> schneller!</p>

<h2 id="konfiguration" data-numberify>Konfiguration<a class="anchor ms-1" href="#konfiguration"></a></h2>
<p>Konfiguriert wird dieses Verhalten in der <code>ssh</code>-Konfiguration des jeweiligen Benutzers.</p>
<p>Der entsprechende Ausschnitt aus meiner <code>~/.ssh/config</code></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">Host *
</span></span><span class="line"><span class="ln">2</span><span class="cl">  ControlPath ~/.ssh/connections/%C
</span></span><span class="line"><span class="ln">3</span><span class="cl">  ControlMaster auto
</span></span><span class="line"><span class="ln">4</span><span class="cl">  ControlPersist 30m
</span></span></code></pre></div><p>Eine paar kleine Erläuterungen und Hinweise zur obigen Datei:</p>

<h3 id="parameter-host" data-numberify>Parameter Host<a class="anchor ms-1" href="#parameter-host"></a></h3>
<p>Das Asterik (<code>*</code>) hinter <code>Host</code> sagt, dass es für jeden Host gilt.</p>

<h3 id="parameter-controlpath" data-numberify>Parameter ControlPath<a class="anchor ms-1" href="#parameter-controlpath"></a></h3>
<p>Das genannte Verzeichnis im <code>ControlPath</code> muss <strong>vorher</strong> angelegt werden:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">mkdir ~/.ssh/connections
</span></span></code></pre></div><p>Sofern das Unterverzeichnis <code>~/.ssh</code> noch nicht existiert, muss es mit den richtigen Rechten angelegt werden.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">mkdir ~/.ssh
</span></span><span class="line"><span class="ln">2</span><span class="cl">chmod <span class="m">700</span> ~/.ssh
</span></span></code></pre></div>
<h3 id="parameter-controlmaster" data-numberify>Parameter ControlMaster<a class="anchor ms-1" href="#parameter-controlmaster"></a></h3>
<p>Dieser Parameter aktiviert erst die gemeinsame Benutzung von mehreren Sitzungen über eine einzelne Netzwerkverbindung. Erst damit wird diese Funktionalität nutzbar bzw. aktiviert.</p>

<h3 id="parameter-controlpersist" data-numberify>Parameter ControlPersist<a class="anchor ms-1" href="#parameter-controlpersist"></a></h3>
<p>Hier wird die Haltedauer der Verbindung angegeben. In meinem Beispiel 30 Minuten.  Nach Ablauf der definierten Zeitspanne werden die Sockets automatisch gelöscht.</p>

<h2 id="tipps" data-numberify>Tipps<a class="anchor ms-1" href="#tipps"></a></h2>

<h3 id="problem-lösungen" data-numberify>Problem-Lösungen<a class="anchor ms-1" href="#problem-lösungen"></a></h3>
<p>Ändern sich die Hostkeys des Servers einmal, kann das Socket-File einfach gelöscht werden.
Dies passiert zum Beispiel in der Entwicklung-Phase wenn neue VMs neu deployed werden müssen und sich dann der <code>ssh</code>-Hostkey ändert. <code>ssh</code> wertet dies beim erneuten Verbindungsversuch als massives Problem und verweigert den Verbindungsaufbau. In so einem Fall, kann das entsprechende Socket einfach gelöscht werden, statt 30 Minuten zu warten.</p>

<h3 id="warum-c-" data-numberify>Warum %C ?<a class="anchor ms-1" href="#warum-c-"></a></h3>
<p>Ja, es gibt noch andere Parameter, wo der Dateinamen dann unter anderem dem Hostnamen entspricht. Dies würde das gezielte Löschen einzelner Sockets im oben beschrieben Fall vereinfachen.</p>
<p>Allerdings hat die Pfad-Länge von <code>ControlPath</code> eine maximal definierte Länge (den genauen Wert habe ich leider vergessen).
Der Parameter <code>%C</code> macht aus der Pfadangabe einen Hash-Wert, der dieses Problem umgeht.</p>

<h3 id="vpn-und-das-controlpersist" data-numberify>VPN und das ControlPersist<a class="anchor ms-1" href="#vpn-und-das-controlpersist"></a></h3>
<p>Ich muss des öfteren mal VPN-Verbindungen wechseln. Leider hat dies (bisher) den unschönen Nebeneffekt gehabt, dass das Socket noch bestehen bleibt.
Da ich mit jedem neuen Verbindungsaufbau allerdings eine neue Quell-IP etc. bekomme, komme ich nun nicht mehr auf das System. Nun muss ich das entsprechende Socket-File löschen.
Da ich ja Hash-Werte benutze, ist das nicht so einfach, zudem ist es eine händische Arbeit; mag ich nicht.</p>
<p>Da ich faul bin, habe ich nach einer Lösung gesucht und gefunden.</p>
<p>Unterhalb von <code>/etc/NetworkManager/dispatcher.d/</code> habe ich mir folgendes Script hingelegt:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl"><span class="cp">#!/usr/bin/bash
</span></span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="cp"></span><span class="c1"># Connection-Pool aufräumen</span>
</span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="c1"># Ort: /etc/NetworkManager/dispatcher.d</span>
</span></span><span class="line"><span class="ln">4</span><span class="cl">find /home/rainerr/.ssh/connections -type f -delete
</span></span></code></pre></div><p>Jetzt wird bei jedem neuen VPN-Verbindungsaufbau einfach alles stumpf weggeworfen. \o/</p>

<h2 id="changelog" data-numberify>Changelog<a class="anchor ms-1" href="#changelog"></a></h2>
<table>
  <thead>
      <tr>
          <th>Datum</th>
          <th>Änderung</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>08.02.2024</td>
          <td>neuer Absatz: <em>VPN und das ControlPersist</em></td>
      </tr>
  </tbody>
</table>]]></content:encoded>
    </item>
    
    <item>
      <title>SSH-Tricks: Config-Split</title>
      <link>https://www.rainerrose.de/posts/ssh-tricks_config_split/</link>
      <pubDate>Tue, 23 Jan 2024 17:21:12 +0100</pubDate>
      <guid>https://www.rainerrose.de/posts/ssh-tricks_config_split/</guid>
      <description><![CDATA[<!-- Anreißer -->
<p>Wenn man wie ich mit mehreren Servern jongiert, wird die <code>ssh</code>-Konfigurationsdatei irgendwann recht voll und unübersichtlich. Mittels eines Paramters, kann ich die Konfigurationsdatei allerdings in unterschiedliche Dateien aufteilen.</p>]]></description>
      <content:encoded><![CDATA[<!-- Anreißer -->
<p>Wenn man wie ich mit mehreren Servern jongiert, wird die <code>ssh</code>-Konfigurationsdatei irgendwann recht voll und unübersichtlich. Mittels eines Paramters, kann ich die Konfigurationsdatei allerdings in unterschiedliche Dateien aufteilen.</p>
<p>In der <code>SSH</code>-Konfiguration des aktuellen Benutzers</p>
<p><code>~/.ssh/config</code></p>
<p>kann ich mit dem Parameter <code>Include</code> sagen, wo die anderen Dateien liegen, die ich einbinden möchte:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="ln">1</span><span class="cl">Include config.d/*
</span></span></code></pre></div><p>Das genannte Verzeichnis im <code>Include</code>-Parameter muss <strong>vorher</strong> angelegt werden:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">mkdir ~/.ssh/connections
</span></span></code></pre></div><p>Sofern das Unterverzeichnis <code>~/.ssh</code> noch nicht existiert muss es mir den richtigen Rechten angelegt werden.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">mkdir ~/.ssh
</span></span><span class="line"><span class="ln">2</span><span class="cl">chmod <span class="m">700</span> ~/.ssh
</span></span></code></pre></div><p>In das oben genannte Verzeichnis <code>~/.ssh/connections</code> kann ich jetzt die Hosts strukturiert auslagern.</p>
<p>Mein Unterverzeichnis sieht dann z.B. folgendermaßen aus:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">ls -lR config.d/
</span></span><span class="line"><span class="ln">2</span><span class="cl">config.d/:
</span></span><span class="line"><span class="ln">3</span><span class="cl">insgesamt <span class="m">8</span>
</span></span><span class="line"><span class="ln">4</span><span class="cl">-rw-rw-r-- <span class="m">1</span> rainer rainerr <span class="m">239</span> Jan <span class="m">12</span> 17:52 produktionsSysteme
</span></span><span class="line"><span class="ln">5</span><span class="cl">-rw-rw-r-- <span class="m">1</span> rainer rainerr  <span class="m">60</span> Jan <span class="m">12</span> 17:52 testSysteme
</span></span></code></pre></div><p>Die oben genannten Dateien sind genauso aufgebaut wie auch sonst die Datei <code>~/.ssh/config</code>.</p>
<p>Vielleicht bringt es ja auch in Euren Alltag etwas mehr Ordnung.</p>]]></content:encoded>
    </item>
    
    <item>
      <title>Tipps</title>
      <link>https://www.rainerrose.de/docs/howto/mastodon/tipps/</link>
      <pubDate>Sun, 14 Jan 2024 15:37:36 +0100</pubDate>
      <guid>https://www.rainerrose.de/docs/howto/mastodon/tipps/</guid>
      <description><![CDATA[<!-- Anreißer -->
<p>Kochrezepte, Tipps und Hinweise zu Mastodon als kleine Sammlung.</p>
<p>Die Liste wird immer mal wieder erweitert; dabei wird dann hier das Datum einfach aktualisiert.</p>]]></description>
      <content:encoded><![CDATA[<!-- Anreißer -->
<p>Kochrezepte, Tipps und Hinweise zu Mastodon als kleine Sammlung.</p>
<p>Die Liste wird immer mal wieder erweitert; dabei wird dann hier das Datum einfach aktualisiert.</p>

<h2 id="lesezeichen" data-numberify>Lesezeichen<a class="anchor ms-1" href="#lesezeichen"></a></h2>
<p>Nutzen! Selbiger Grund wie bei <a href="../posten#hashtags">Hashtags</a> ; sonst wird das Wiederfinden schwer bis unmöglich.</p>

<h2 id="threads-in-einem-stück-lesen-unroll" data-numberify>Threads in einem Stück lesen (unroll)<a class="anchor ms-1" href="#threads-in-einem-stück-lesen-unroll"></a></h2>
<p>Dafür gibt es die schöne Webseite <a href="https://tools.rainerrose.de/redirect.php?id=37" target="_blank" rel="noopener noreferrer">mastoreader.io<i class="fas fa-external-link-square-alt ms-1"></i></a>. Dort kann die URL des Threads als URL-Parameter mitgebenen werden oder nach Besuch der Seite in ein Eingabe-Feld übergeben werden.
Auf der Webseite kann dann der Thread in einem Stück konsumiert werden.</p>
<p>Alternativ erwähnt man das Mastodon-Konto im einem Post <code>@mastoreaderio@mastodon.social</code></p>

<h2 id="changelog" data-numberify>Changelog<a class="anchor ms-1" href="#changelog"></a></h2>
<table>
  <thead>
      <tr>
          <th>Datum</th>
          <th>Änderung</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>14.01.2024</td>
          <td>mastoreader.io</td>
      </tr>
  </tbody>
</table>]]></content:encoded>
    </item>
    
    <item>
      <title>Monitoring Docker-Images</title>
      <link>https://www.rainerrose.de/posts/check_last_docker_pull/</link>
      <pubDate>Tue, 19 Dec 2023 17:52:17 +0200</pubDate>
      <guid>https://www.rainerrose.de/posts/check_last_docker_pull/</guid>
      <description><![CDATA[<!-- Anreißer --> 
<p>Ich stand vor der Herausforderung, dass ich wissen wollte, ob es für Docker-Images, die ich verwende, Updates bzw. eine neue Image-Version gibt. Der Klassiker ist <code>latest</code> wie z.B. bei <code>jellyfin/jellyfin:latest</code>. Aber auch Haupt-Versionen werden zum Teil benannt: <code>postgres:13</code> .</p>
<p>Bei der Verwendung von <code>docker compose</code> sind die Docker-Images sind z.B. in einer <code>docker-compose.yml</code>-Datei hinterlegt, wo ich das selbstgeschrieben Script <code>update_docker_images.sh</code> verwende, um die Container zu aktualisieren.</p>]]></description>
      <content:encoded><![CDATA[<!-- Anreißer --> 
<p>Ich stand vor der Herausforderung, dass ich wissen wollte, ob es für Docker-Images, die ich verwende, Updates bzw. eine neue Image-Version gibt. Der Klassiker ist <code>latest</code> wie z.B. bei <code>jellyfin/jellyfin:latest</code>. Aber auch Haupt-Versionen werden zum Teil benannt: <code>postgres:13</code> .</p>
<p>Bei der Verwendung von <code>docker compose</code> sind die Docker-Images sind z.B. in einer <code>docker-compose.yml</code>-Datei hinterlegt, wo ich das selbstgeschrieben Script <code>update_docker_images.sh</code> verwende, um die Container zu aktualisieren.</p>
<p>Mit dem Tool <a href="https://tools.rainerrose.de/redirect.php?id=34" target="_blank" rel="noopener noreferrer">watchtower<i class="fas fa-external-link-square-alt ms-1"></i></a> bin ich nicht zurecht gekommen bzw. es hat meine Anforderungen nicht erfüllt oder ich sie nicht umsetzen konnte.
Eine Hürde war, dass ein Teil der Server, die ich betreue, keinen Zugriff auf das Internet haben.
Ebenso baue ich durchaus eigene Images und Watchtower &ldquo;sieht&rdquo; meines Wissens nicht das <code>Dockerfile</code> was im Build-Prozess benötigt wird. Updates des verwendeten Basis-Images bekomme ich also nicht mit.</p>
<p>Somit musste eine eigene Lösung her. Zeitgleich hatte ich das Tool <code>jq</code> entdeckt und sah es als Möglichkeit, mich an einem konkreten Beispiel mit diesem auseinanderzusetzen.</p>

<h2 id="konfigurationsdatei" data-numberify>Konfigurationsdatei<a class="anchor ms-1" href="#konfigurationsdatei"></a></h2>
<p>Damit ich mir (bzw. das Script) merken kann, wann der letzte pull eines Docker-Images stattfand, brauche ich eine Konfigurationsdatei.</p>
<p>Der Aufbau der Konfigurationsdatei ist eine Datei im <code>json</code>-Format. Jeder Unterelement hat genau einen Wert.</p>
<p>Es gibt folgende Elemente</p>
<ul>
<li><code>imagename</code></li>
<li><code>tag</code></li>
<li><code>info</code></li>
<li><code>date</code></li>
</ul>
<p>Diese werden im Folgenden erläutert.</p>

<h3 id="imagename" data-numberify>imagename<a class="anchor ms-1" href="#imagename"></a></h3>
<p>Zum Herunterladen sollen zwei Docker-Images als Beispiel dienen</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">docker pull jellyfin/jellyfin:latest
</span></span><span class="line"><span class="ln">2</span><span class="cl">docker pull postgres:13
</span></span></code></pre></div><p>Der einfache Fall ist die Angabe des Names des Docker-Images, also:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="ln">1</span><span class="cl"><span class="nt">&#34;imagename&#34;: </span><span class="s2">&#34;jellyfin/jellyfin&#34;</span><span class="w">
</span></span></span></code></pre></div><p>Alle Docker-Images, die das Badge <em>Docker Official Image</em> haben, muss noch ein <code>library</code> davor gestellt bekommen. Das ist später für das Script wichtig.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="ln">1</span><span class="cl"><span class="nt">&#34;imagename&#34;: </span><span class="s2">&#34;library/postgres&#34;</span><span class="w">
</span></span></span></code></pre></div>
<h3 id="tag" data-numberify>tag<a class="anchor ms-1" href="#tag"></a></h3>
<p>Aus dem obigen <code>docker pull</code> Befehl kann jetzt hier der Tag angeben werden. Durch die Trennung vom Image-Namen und Tag, lassen sich auch unterschiedliche Versionen beobachten.</p>

<h3 id="info" data-numberify>info<a class="anchor ms-1" href="#info"></a></h3>
<p>Dies ist reines Prosa-Feld und dient zur eigenen Information bzw. Dokumentation. Ich schreibe hier z.B. die URL zum Changelog auf.</p>
<p>Ein anderer Einsatzzweck ist die Dokumentation, in welchem <code>docker-compose</code>-File ich das Image verwendet. In unten genannten Fall, z.B. im Dunstkreis von <em>paperless-ngx</em> .</p>

<h3 id="date" data-numberify>date<a class="anchor ms-1" href="#date"></a></h3>
<p>Hier steht der Zeitstempel drin, wann das jeweilige Image zuletzt auf docker-Hub hochgeladen wurde. Die Information stammt aus der <code>json</code>-Antwort vom Docker-Hub; dort steht es im Element <code>last_updated</code> und genau dieser Wert wird mit dem Wert der Konfigurations-Datei verglichen.</p>

<h3 id="komplette-beispieldatei" data-numberify>Komplette Beispieldatei<a class="anchor ms-1" href="#komplette-beispieldatei"></a></h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="p">[</span>
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">  <span class="p">{</span>
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">    <span class="nt">&#34;imagename&#34;</span><span class="p">:</span> <span class="s2">&#34;library/postgres&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">    <span class="nt">&#34;tag&#34;</span><span class="p">:</span> <span class="s2">&#34;13&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">    <span class="nt">&#34;info&#34;</span><span class="p">:</span> <span class="s2">&#34;paperless-ngx&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">    <span class="nt">&#34;date&#34;</span><span class="p">:</span> <span class="s2">&#34;2023-11-03T05:09:17.243391Z&#34;</span>
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">  <span class="p">{</span>
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">    <span class="nt">&#34;imagename&#34;</span><span class="p">:</span> <span class="s2">&#34;library/redis&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="ln">10</span><span class="cl">    <span class="nt">&#34;tag&#34;</span><span class="p">:</span> <span class="s2">&#34;7.0&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="ln">11</span><span class="cl">    <span class="nt">&#34;info&#34;</span><span class="p">:</span> <span class="s2">&#34;paperless-ngx&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="ln">12</span><span class="cl">    <span class="nt">&#34;date&#34;</span><span class="p">:</span> <span class="s2">&#34;2023-11-04T04:12:52.019118Z&#34;</span>
</span></span><span class="line"><span class="ln">13</span><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="ln">14</span><span class="cl">  
</span></span><span class="line"><span class="ln">15</span><span class="cl">  <span class="p">{</span>
</span></span><span class="line"><span class="ln">16</span><span class="cl">    <span class="nt">&#34;imagename&#34;</span><span class="p">:</span> <span class="s2">&#34;jellyfin/jellyfin&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="ln">17</span><span class="cl">    <span class="nt">&#34;tag&#34;</span><span class="p">:</span> <span class="s2">&#34;latest&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="ln">18</span><span class="cl">    <span class="nt">&#34;info&#34;</span><span class="p">:</span> <span class="s2">&#34;&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="ln">19</span><span class="cl">    <span class="nt">&#34;date&#34;</span><span class="p">:</span> <span class="s2">&#34;2023-11-05T18:28:02.143505Z&#34;</span>
</span></span><span class="line"><span class="ln">20</span><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="ln">21</span><span class="cl"><span class="p">]</span>
</span></span></code></pre></div>
<h2 id="das-script" data-numberify>Das Script<a class="anchor ms-1" href="#das-script"></a></h2>

<h2 id="voraussetzungen" data-numberify>Voraussetzungen<a class="anchor ms-1" href="#voraussetzungen"></a></h2>
<p>Das Script benötigte folgende installierte Tools</p>
<ul>
<li><code>jq</code></li>
<li><code>curl</code></li>
<li><code>bash</code></li>
</ul>
<p>Die Konfigurationsdatei muss im selben Verzeichnis sein, wie das Script.</p>

<h2 id="script-aufruf" data-numberify>Script-Aufruf<a class="anchor ms-1" href="#script-aufruf"></a></h2>
<p>Das Script kann ohne Parameter aufgerufen werden. Es arbeitet die Konfigurationsdatei ab und sucht sich alle Elemente des Typs <code>imagename</code> heraus.</p>
<p>In einer <code>while</code>-Schleife pickt es sich dann das zugehörige <em>Tag</em> und den letzten Zeitstempel heraus.</p>
<p>Diese Angaben werden zu einer URL zusammengesetzt und das Ergebnis ausgewertet.
Der Datenstrom besteht aus einer <em>json</em>-Antwort, wo wiederum ein Zeitstempel <code>last_updated</code> aufgeführt ist. Dieser Zeitstempel wird auf Docker-Hub aktualisiert, wenn von der Image-Maintainer*in ein neues Image hochgeladen (gepushed) wurde. Der Zeitstempel wird mit einem simplen String-Vergleich mit der Datumsangabe aus der Konfigurationsdatei verglichen.
Sind beide gleich, wird eine &ldquo;OK&rdquo;-Meldung herausgegeben und das nächste Image wird abgearbeitet.
Unterscheiden sich die Zeitstempel, wird eine Warnmeldung herausgegeben. Zusätzlich wird der Return-Codes des Scriptes auf <code>1</code> gesetzt, um diesen potentiell später auswerten zu können.</p>
<p>In beiden Fällen, wird der Inhalt der Elements <code>info</code> ausgeben. Dies ist z.B. im Rahmen eines Cronjobs hilfreich. Hier trage ich z.B. eine URL zu den Release-Infos ein, um mich über Änderungen vor einem Update zu informieren oder bekomme einen Hinweis, in welchen <code>docker-compose</code>-Dateien das Image verwendet wird.</p>

<h3 id="parameter--q" data-numberify>Parameter “-q”<a class="anchor ms-1" href="#parameter--q"></a></h3>
<p>Der Parameter <code>-q</code> reduziert die Ausgabe des Scriptes. Images, die aktuell sind und wo es kein neues auf Docker-Hub gibt, werden nicht mehr ausgegeben. Das ist für cronjobs praktisch, weil ich da nur eine E-Mail bekommen möchte, wenn es neue Images gibt. Das reduziert das Mail-Aufkommen.</p>

<h3 id="parameter--u" data-numberify>Parameter “-u”<a class="anchor ms-1" href="#parameter--u"></a></h3>
<p>Der Parameter <code>-u</code> erzeugt noch eine weitere Ausgabe am Ende des Scriptes.</p>
<pre><code>WARNING: Neues Docker-Image verfuegbar library/postgres:13 seit 2023-11-23 13:08 (&quot;2023-11-23T12:08:41.624052Z&quot;) Info: paperless-ngx
./update_rc.sh library/postgres:13 2023-11-23T12:08:41.624052Z # paperless-ngx
</code></pre>
<p>Um sich das händische Aktualisieren des neuen Zeitstempels zu erleichtern, gibt es das Script <code>update_rc.sh</code>.
Die benötigten Parameter mit dem jeweiligen Zeitstempel werden benutzungsfertig für Copy und Paste auf STDOUT mit ausgeben.</p>

<h3 id="beispiel-ausgabe" data-numberify>Beispiel-Ausgabe<a class="anchor ms-1" href="#beispiel-ausgabe"></a></h3>
<pre><code>$ ./check_last_docker_pull.sh -u
WARNING: Neues Docker-Image verfuegbar jellyfin/jellyfin:latest seit 2023-11-29 22:57 (&quot;2023-11-29T21:57:57.203009Z&quot;) Info: 
WARNING: Neues Docker-Image verfuegbar library/postgres:13 seit 2023-12-16 04:10 (&quot;2023-12-16T03:10:26.057478Z&quot;) Info: paperless-ngx
WARNING: Neues Docker-Image verfuegbar library/redis:7.0 seit 2023-12-16 03:08 (&quot;2023-12-16T02:08:55.087065Z&quot;) Info: paperless-ngx
./update_rc.sh jellyfin/jellyfin:latest 2023-11-29T21:57:57.203009Z # Info:  
./update_rc.sh library/postgres:13 2023-12-16T03:10:26.057478Z # Info: paperless-ngx 
./update_rc.sh library/redis:7.0 2023-12-16T02:08:55.087065Z # Info: paperless-ngx
</code></pre>
<p>Sofern das Image dann auf dem entsprechenden Computer oder Server heruntergeladen wurde, kann die Konfigurationsdatei mit dem oben ausgegeben Kommando aktualisiert werden; also z.B.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">./update_rc.sh library/redis:7.0 2023-12-16T02:08:55.087065Z
</span></span></code></pre></div><p>Der <code>#</code> ist gleichzeitig Kommentar in der Shell, so dass es nicht stört, wenn aus Versehen zu viel markiert wird.</p>

<h2 id="check_last_github_releasesh" data-numberify>check_last_github_release.sh<a class="anchor ms-1" href="#check_last_github_releasesh"></a></h2>
<p>Allerdings gibt es inzwischen einige Images oder Tools, die auf <em>github</em> liegen bzw. in deren Docker-Registry.
Da <em>github</em> ebenfalls eine API anbietet, dessen Ausgabe in einem ähnlichen JSON-Format anbietet, habe ich das obige Script etwas umgeschrieben.</p>
<p>Hier wird eine weitere Konfigurationsdatei benötigt mit dem Namen <code>check_last_github_release.rc.json</code>.</p>
<p>Folgende Elemente werden verwendet</p>
<ul>
<li><code>repro</code></li>
<li><code>release</code></li>
<li><code>info</code></li>
</ul>

<h3 id="repro" data-numberify>repro<a class="anchor ms-1" href="#repro"></a></h3>
<p>Hier wird nach der selben Mimik wie weiter oben der Image-Name eingetragen.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="ln">1</span><span class="cl">    <span class="s2">&#34;repro&#34;</span><span class="err">:</span> <span class="s2">&#34;paperless-ngx/paperless-ngx&#34;</span><span class="err">,</span>
</span></span></code></pre></div>
<h3 id="release" data-numberify>release<a class="anchor ms-1" href="#release"></a></h3>
<p>Im Gegensatz zu oben verwende ich feste Versionsnummern:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="ln">1</span><span class="cl">    <span class="s2">&#34;release&#34;</span><span class="err">:</span> <span class="s2">&#34;1.17.4&#34;</span><span class="err">,</span>
</span></span></code></pre></div>
<h3 id="info-1" data-numberify>info<a class="anchor ms-1" href="#info-1"></a></h3>
<p>Hier gilt selbiges wie oben; eine kleine Stelle zur Dokumentation oder Verweis auf eine URL.</p>

<h3 id="check_last_github_releasercjson" data-numberify>check_last_github_release.rc.json<a class="anchor ms-1" href="#check_last_github_releasercjson"></a></h3>
<p>Hier jetzt ein vollständiges Beispiel einer Konfigurationsdatei.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="p">[</span>
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">  <span class="p">{</span>
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">    <span class="nt">&#34;repro&#34;</span><span class="p">:</span> <span class="s2">&#34;paperless-ngx/paperless-ngx&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">    <span class="nt">&#34;release&#34;</span><span class="p">:</span> <span class="s2">&#34;1.17.4&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">    <span class="nt">&#34;info&#34;</span><span class="p">:</span> <span class="s2">&#34;&#34;</span>
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">  <span class="p">{</span>
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">    <span class="nt">&#34;repro&#34;</span><span class="p">:</span> <span class="s2">&#34;mar10/wsgidav&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">    <span class="nt">&#34;release&#34;</span><span class="p">:</span> <span class="s2">&#34;4.3.0&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="ln">10</span><span class="cl">    <span class="nt">&#34;info&#34;</span><span class="p">:</span> <span class="s2">&#34;&#34;</span>
</span></span><span class="line"><span class="ln">11</span><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="ln">12</span><span class="cl">  <span class="p">{</span>
</span></span><span class="line"><span class="ln">13</span><span class="cl">    <span class="nt">&#34;repro&#34;</span><span class="p">:</span> <span class="s2">&#34;restic/restic&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="ln">14</span><span class="cl">    <span class="nt">&#34;release&#34;</span><span class="p">:</span> <span class="s2">&#34;0.16.2&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="ln">15</span><span class="cl">    <span class="nt">&#34;info&#34;</span><span class="p">:</span> <span class="s2">&#34;https://restic.net/blog/&#34;</span>
</span></span><span class="line"><span class="ln">16</span><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="ln">17</span><span class="cl">  <span class="p">{</span>
</span></span><span class="line"><span class="ln">18</span><span class="cl">    <span class="nt">&#34;repro&#34;</span><span class="p">:</span> <span class="s2">&#34;go-gitea/gitea&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="ln">19</span><span class="cl">    <span class="nt">&#34;release&#34;</span><span class="p">:</span> <span class="s2">&#34;1.20.5&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="ln">20</span><span class="cl">    <span class="nt">&#34;info&#34;</span><span class="p">:</span> <span class="s2">&#34;https://blog.gitea.com/&#34;</span>
</span></span><span class="line"><span class="ln">21</span><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="ln">22</span><span class="cl"><span class="p">]</span>
</span></span></code></pre></div>
<h2 id="das-script-1" data-numberify>Das Script<a class="anchor ms-1" href="#das-script-1"></a></h2>

<h3 id="voraussetzungen-1" data-numberify>Voraussetzungen<a class="anchor ms-1" href="#voraussetzungen-1"></a></h3>
<p>Ähnlich wie oben das Script <code>check_last_docker_pull.sh</code> benötigt es dieselben Software-Tools:</p>
<ul>
<li><code>jq</code></li>
<li><code>curl</code></li>
<li><code>bash</code></li>
</ul>
<p>Derzeit wird zum Auswerten <strong>zusätzlich</strong> noch</p>
<ul>
<li><code>perl</code></li>
</ul>
<p>benötigt. Dies soll zukünftig durch <code>sed</code> ersetzt werden, was IMHO verbreiteter installiert ist.</p>

<h3 id="script-aufruf-1" data-numberify>Script-Aufruf<a class="anchor ms-1" href="#script-aufruf-1"></a></h3>
<p>Das Script selbst kann ohne Parameter aufgerufen werden. Ähnlich wie <code>check_last_docker_pull.sh</code> hangelt es sich durch die Konfigurationsdatei und prüft alle Repositorys auf neuere Versionen.
Da in der URL mit dem Keyword <code>latest</code> gearbeitet werden kann, muss nur ein String-Vergleich mit der Versionsnummer aus der Konfigurationsdatei stattfinden. Bei Differenzen gibt es eine entsprechende Warnung. Die neue Version steckt schon in der <em>json</em>-Antwort und wird ebenfalls mit ausgegeben. Der Exit-Code ist auch hier wiederum <code>1</code>.</p>
<p>Aktuell muss die neue Version nach einem erfolgten Update noch per Hand neu gesetzt werden. Perspektivisch soll es hier auch ein Update-Script geben, da ja alle Informationen vorliegen.</p>

<h3 id="parameter--q-1" data-numberify>Parameter “-q”<a class="anchor ms-1" href="#parameter--q-1"></a></h3>
<p>Auch hier kann das Script mit dem Parameter <code>-q</code> aufgerufen werden, um den Output des Scriptes zu reduzieren.</p>

<h3 id="beispiel-ausgabe-1" data-numberify>Beispiel-Ausgabe<a class="anchor ms-1" href="#beispiel-ausgabe-1"></a></h3>
<pre><code>$ ./check_last_github_release.sh 
WARNING: Neues Release verfuegbar go-gitea/gitea alt: 1.20.5 neue Version 1.21.2 Info: https://blog.gitea.com/
OK: Release mar10/wsgidav Info: 
WARNING: Neues Release verfuegbar paperless-ngx/paperless-ngx alt: 1.17.4 neue Version 2.1.3 Info: 
OK: Release restic/restic Info: https://restic.net/blog/
</code></pre>

<h2 id="baustellen" data-numberify>Baustellen<a class="anchor ms-1" href="#baustellen"></a></h2>
<p>Die oben erwähnten Baustellen sollen demnächst<sup>(tm)</sup> mal behoben werden. Wenn dem so ist, werde ich den Blog-Artikel aktualisieren und entsprechend kennzeichnen.</p>

<h2 id="die-scripte---der-code" data-numberify>Die Scripte - der Code<a class="anchor ms-1" href="#die-scripte---der-code"></a></h2>
<p>Alle Scripte liegen auf <em>GitLab</em> innerhalb des Projektes <a href="https://tools.rainerrose.de/redirect.php?id=35" target="_blank" rel="noopener noreferrer">cli-tools<i class="fas fa-external-link-square-alt ms-1"></i></a> unterhalb des Verzeichnisses <a href="https://tools.rainerrose.de/redirect.php?id=36" target="_blank" rel="noopener noreferrer">watch_docker_images<i class="fas fa-external-link-square-alt ms-1"></i></a> , wo ich mehrere solcher Tools sammle</p>]]></content:encoded>
    <enclosure url="https://www.rainerrose.de/wallpaper/posts/check_last_docker_pull.png" length="61070" type="image/.png" />
    </item>
    
    <item>
      <title>Backupkonzept</title>
      <link>https://www.rainerrose.de/posts/backupkonzept/</link>
      <pubDate>Sat, 16 Dec 2023 17:46:08 +0200</pubDate>
      <guid>https://www.rainerrose.de/posts/backupkonzept/</guid>
      <description><![CDATA[<!-- Anreißer -->
<p>Heute möchte ich über das Thema Datensicherung aka Backups schreiben. Hier und da wurde ich gefragt, wie ich das löse bzw. umgesetzt habe.</p>
<p>Mariannes <a href="https://tools.rainerrose.de/redirect.php?id=28" target="_blank" rel="noopener noreferrer">Blog-Artikel<i class="fas fa-external-link-square-alt ms-1"></i></a>
gab den Ausschlag dieses nun endlich mal aufzuschreiben.</p>
<p>Es wird eine kleine Reise werden. Ich werde über die grundsätzlichen Gedanken berichten, die ich mir gemacht habe, als auch etwas in technische Details gehen.
Ebenso werde ich Dinge niederschreiben, die sich <strong>nicht</strong> bewährt haben, da dies evtl. für andere ebenfalls hilfreich erweisen sein.</p>
<p>Dieser Artikel wird länger ;-)</p>]]></description>
      <content:encoded><![CDATA[<!-- Anreißer -->
<p>Heute möchte ich über das Thema Datensicherung aka Backups schreiben. Hier und da wurde ich gefragt, wie ich das löse bzw. umgesetzt habe.</p>
<p>Mariannes <a href="https://tools.rainerrose.de/redirect.php?id=28" target="_blank" rel="noopener noreferrer">Blog-Artikel<i class="fas fa-external-link-square-alt ms-1"></i></a>
gab den Ausschlag dieses nun endlich mal aufzuschreiben.</p>
<p>Es wird eine kleine Reise werden. Ich werde über die grundsätzlichen Gedanken berichten, die ich mir gemacht habe, als auch etwas in technische Details gehen.
Ebenso werde ich Dinge niederschreiben, die sich <strong>nicht</strong> bewährt haben, da dies evtl. für andere ebenfalls hilfreich erweisen sein.</p>
<p>Dieser Artikel wird länger ;-)</p>

<h2 id="start" data-numberify>Start<a class="anchor ms-1" href="#start"></a></h2>
<p>Grundsätzlich wollte ich das Backup am Ende so gestalten, dass es für mich relativ einfach ist anzuwenden. Sind beim Anfertigen eines Backups mehrere Vorbereitungen notwendig oder muss ich minutenlang einem Script zuschauen, neige ich dazu, das Backup zu vergessen oder &ldquo;gerade keine Zeit&rdquo; zu haben.
Und ein Backup sollte natürlich möglichst aktuell sein.
<strong>Ein</strong> Ziel von mehreren muss also <em>die Cloud</em><sup>(tm)</sup> sein.
Damit entfällt das Gestöpsel von einer externe Festplatte und es gibt eine Ausrede weniger. Weiterhin bietet dies die Möglichkeit, das Backup weiter zu automatisieren, z.B. beim Runterfahren des PCs. Dazu jedoch später mehr.</p>

<h2 id="was-will-ich-sichern-und-warum" data-numberify>Was will ich sichern und warum?<a class="anchor ms-1" href="#was-will-ich-sichern-und-warum"></a></h2>
<p>Der erste Schritt, den ich getan habe, war mir zu überlegen, <strong>was</strong> ich alles sichern möchte und ich habe mir folgende Fragen gestellt:</p>

<h3 id="was-ist-mir-wichtig" data-numberify>Was ist mir wichtig?<a class="anchor ms-1" href="#was-ist-mir-wichtig"></a></h3>
<p>Habe ich Dinge, an denen mein Herz hängt? Die Antwort lautet: <em>&ldquo;Ja&rdquo;</em> und zwar z.B.</p>
<ul>
<li>Fotos, Videos</li>
<li>bestimmte E-Mails</li>
<li>Systemeinstellungen</li>
<li>Programm-Einstellungen</li>
<li>selbst geschriebene Scripte</li>
<li>Dokumente</li>
</ul>

<h3 id="gibt-es-nicht-ganz-so-wichtige-daten" data-numberify>Gibt es nicht ganz so wichtige Daten?<a class="anchor ms-1" href="#gibt-es-nicht-ganz-so-wichtige-daten"></a></h3>
<p>Gibt es Dinge, die ich zwar sichern möchte, aber es vielleicht nicht so schlimm ist, wenn ich sie doch verliere? Dies wird später wichtig, in welche Sicherungs-Archive ich Dateien zuordne. Zum Beispiel:</p>
<ul>
<li>ISO-Dateien von gekauften CDs</li>
<li>alte Installations-CDs von Steuer- oder Finanzsoftware</li>
</ul>

<h3 id="habe-ich-unwichtige-dinge" data-numberify>Habe ich unwichtige Dinge?<a class="anchor ms-1" href="#habe-ich-unwichtige-dinge"></a></h3>
<p>Kann ich Daten sparen bzw. das Backup kleiner machen? Kann ich Dinge ausschließen? Beispiele:</p>
<ul>
<li>temporäre Dateien</li>
<li>Download-Ordner</li>
<li><code>thumbnails</code>-Ordner</li>
<li><code>Cache</code>-Ordner</li>
</ul>
<p>All das verringert unter anderem die Größe eines Archivs, was wiederum Kosten spart. Eine größere externe Festplatte oder mehr Cloud-Speicherplatz kosten nun mal Geld.
Dateien, die beim Backup übergangen werden können, sparen zudem Zeit, weil sie nicht gelesen werden müssen. Das hat den Vorteil, dass auch der einzelne Lauf schneller geht, was wiederum mehr motiviert, ein Backup durchzuführen.</p>
<p>Je nach Art des Backup-Programms gibt es unterschiedliche Möglichkeiten, entweder bestimmte Dateien oder
Pfade zu definieren, die ich ausschließen möchte. Zum Teil lassen sich sogar generische Muster von Dateinamen oder Verzeichnispfaden
definieren. Diese Muster sind flexibler als starre Listen, weil ich dann nicht mehr absolut und gewissenhaft jeden einzelnen
<code>thumbnails</code>-Unterordner definieren muss.</p>
<p>Einige Backup-Programme unterstützen auch eine Datei namens <a href="/posts/cachedirtag/">CACHEDIR.TAG</a> .<br>
Dies ist eine simple Text-Datei, die einen bestimmten Inhalt haben muss. Befindet sich diese Datei in einem Ordner (zum Beispiel der Download-Ordner) so wird dieser Inhalt vom Backup-Lauf ausgenommen. Wie die Datei genau aussehen muss, habe ich in <a href="/posts/cachedirtag/">diesem Blog-Artikel</a> beschrieben.</p>

<h3 id="vertraulichkeit" data-numberify>Vertraulichkeit<a class="anchor ms-1" href="#vertraulichkeit"></a></h3>
<p>Zudem wollte ich ein Backup haben, das für andere Personen wertlos ist, wenn es ihnen in die Hände fällt. Hier bietet es sich an das Archiv zu verschlüsseln.</p>

<h2 id="wie-will-ich-sichern" data-numberify>Wie will ich sichern?<a class="anchor ms-1" href="#wie-will-ich-sichern"></a></h2>
<p>Ich habe mich für eine <strong>dateibasierte Sicherung</strong> entschieden. Vielfach musste ich in der Vergangenheit bisher nur einzelne Dateien oder Ordner wiederherstellen. Im allerschlimmsten Fall, musste ich meinen Rechner komplett neu aufsetzen. In diesem Fall habe ich die Installationsmedien des Betriebssystems und der jeweiligen installierten Programme zu Hause vorrätig.</p>
<p>Alternativ müsste ich mir die Medien aus diesem Internet neu herunterladen. Es gibt zwar Tools, mit denen man die komplette Festplatte inklusive ihrer Konfigurationen sichern kann, aber dies erfordert meist mehrere Handgriffe und eine Downtime des Rechners. Die Erfahrung zeigt, dass man dies nur selten macht, eben weil es so umständlich ist.
Als initiale Sicherung mag dies jedoch eine gute Idee sein.</p>
<p>Insofern wollte ich eine bequeme Lösung haben, wo ich nicht viel tun muss. Ich wollte nicht allzu oft meine externe Festplatte anschließen, denn das bietet sonst nur Ausreden Nahrung.</p>

<h3 id="und-was-ist-mit-dem-betriebssystem" data-numberify>Und was ist mit dem Betriebssystem?<a class="anchor ms-1" href="#und-was-ist-mit-dem-betriebssystem"></a></h3>
<p>Ich habe vom jeweiligen Betriebssystem ein Installationsmedium; das reicht mir. Im schlechtesten Fall muss ich den kompletten Rechner neu aufsetzen; egal ob Windows oder Linux. Im schlimmsten Fall sind die Installationsmedien auch noch aus dem Internet herunterladbar.</p>

<h2 id="3-2-1" data-numberify>3-2-1<a class="anchor ms-1" href="#3-2-1"></a></h2>

<blockquote class="alert alert-info" role="alert">
    <p class="alert-heading fw-bold">
      <i class="fas fa-info-circle me-2"></i>Hinweis
    </p>
    <p>Hinweis: Das 3-2-1-Prinzip bedeutet in kurz:<br>
Du hast <strong>drei</strong> Kopien auf <strong>zwei</strong> unterschiedlichen Medien, wobei <strong>eine</strong> Kopie außerhalb liegt.</p>
</blockquote>

<h3 id="schnelle-sicherung-lokal" data-numberify>Schnelle Sicherung: lokal<a class="anchor ms-1" href="#schnelle-sicherung-lokal"></a></h3>
<p>Was im Grunde übrig bleibt, sind viele Dateien unterschiedlicher Größe und Wichtigkeit. Sehr lange habe ich dafür
<a href="https://tools.rainerrose.de/redirect.php?id=29" target="_blank" rel="noopener noreferrer">BorgBackup<i class="fas fa-external-link-square-alt ms-1"></i></a> benutzt, einfach auch weil es bei meiner Distribution dabei war und ich mich dann nicht um Programm-Updates kümmern muss(te).
Inzwischen verwende ich <a href="https://tools.rainerrose.de/redirect.php?id=30" target="_blank" rel="noopener noreferrer">restic<i class="fas fa-external-link-square-alt ms-1"></i></a> - zu den Gründen komme ich später.</p>
<p>Die allererste Sicherung geht erst einmal lokal auf die Festplatte in einem extra Bereich; unter Linux ist das bei mir der Pfad <code>/backup</code>. Die Dateisystem-Rechte sind so gesetzt, dass hier nur ein Benutzer mit administrativen Rechten herankommt. Das schützt unter anderem vor versehentlichen Löschen.</p>
<p>Die eigentliche Arbeit erledigt ein selbst geschriebenes <code>bash</code>-Script. Dieses Script kann z.B. beim Runterfahren des PCs verwendet werden. Der Vorteil: Ich muss dem Script nicht zugucken und alle Programme sind geschlossen. Dies ermöglicht ein konsistentes Backup der Dateien, weil sich keine Dateien mehr ändern. Ggf. kann ich dies sogar remote per ssh vom Handy aus aufrufen, weil ich für ein <code>bash</code>-Script keine Oberfläche benötige.</p>
<p>Wenn das Script fertig ist, fährt es den PC komplett runter und schickt mir eine Discord-Nachricht aufs Handy mit einer Statusmeldung.
Für dieses Script habe ich mich schon vor einiger Zeit in einen <a href="../discord-bot/">eigenen Blog-Artikel</a>
verfasst.</p>
<p>Wenn das Script fehler<strong>frei</strong> durchgelaufen ist, kann ich die Steckerleiste ausschalten und habe keinen Standby-Stromverbrauch mehr. Im <strong>Fehlerfall</strong> weiß ich Bescheid, dass irgendwo ein Fehler passiert ist und ich evtl. kein aktuelles Backup habe.</p>
<p>Auf Servern starte ich dieses (ggf. abgewandelte und angepasste Script) automatisch per <code>crontab</code>. Im Fehlerfall weiß ich Bescheid, dass ich bei nächster Gelegenheit mal auf das System gucken sollte, was da genau schief gelaufen ist. Im einfachsten Fall ist es eine Datei, die sich dann im laufenden Betrieb geändert hat, aber auch schon volle Backup-Partitionen hatte ich. Ja, Monitoring auf den privaten Systemen ist Punkt 3.520.230 auf meiner TODO-Liste.</p>

<h3 id="aufräumen" data-numberify>Aufräumen<a class="anchor ms-1" href="#aufräumen"></a></h3>
<p>Am besten räumt man vorher auf, hat also etwas Datendisziplin. Mehrere Versionen einen Schnappschusses bereinigt man um die Version, die man aufheben möchte. Eigene Filmaufnahme oder Filmschnipsel kürzen und verwackelte, unscharfe Handyvideos fressen auch nur unnötig Platz.</p>
<p>Die Programme <code>borg</code> bzw. <code>restic</code> können Sicherungen zudem automatisch ausdünnen. Über Parameter kann ein Backup anhand definierter Regeln ausgedünnt werden. Beispielweise bleiben die letzten 7 täglichen Backups erhalten und für den Rest des Monats wird ein wöchentlicher Schnappschuss aufbewahrt. Danach wird nur der neueste monatliche Schnappschuss aufbewahrt. Durch die fest definierten Regeln, wird ein manuelles und damit meist fehlerträchtiges Heraussuchen vermieden.</p>

<h3 id="sicherung-cloud" data-numberify>Sicherung Cloud<a class="anchor ms-1" href="#sicherung-cloud"></a></h3>
<p>Das selbe Script hat einen optionalen Schalter, wo diese Sicherung &ldquo;in die Cloud&rdquo; angeschaltet werden kann. Dieser Schritt kommt zwischen dem Ende der lokalen Sicherung und dem letztendlichen Herunterfahren des Rechners.</p>

<h3 id="offsite-backup" data-numberify>Offsite-Backup<a class="anchor ms-1" href="#offsite-backup"></a></h3>
<p>Um eine weitere Kopie meiner Daten zu haben, habe ich mir zwei externe Festplatten beschafft. Eine liegt immer neben dem Rechner, ist aber nicht angeschlossen, die andere liegt bei meinen Eltern. Die externen Platten sind außen beschriftet und haben auch ein Software-Label, so dass ich sie beim Einhängen in das Dateisystem unterscheiden kann.
Alle paar Tage stöpsle ich dann die externe Festplatte an und synchronisiere die lokale Sicherung vom dem PC auf diese. Nach der Sicherung stöpsle ich sie wieder ab und die Festplatte ist dann vor versehentlichen Löschen sicher.</p>
<p>Diese Festplatte bringe ich dann alle paar Wochen zu meinen Eltern und tausche sie mit dort liegenden Festplatte aus.
So habe ich im Fall der Fälle (Hausbrand, Einbruch usw.) eine weitere Kopie an einem anderen Ort. Der Stand der Sicherung ist dann möglicherweise ein paar Wochen alt, aber immerhin besser als ein Totalverlust.</p>
<p>In der Summe sind die Daten jetzt <strong>fünfmal</strong> vorhanden.</p>

<h2 id="aber-" data-numberify>Aber !?!<a class="anchor ms-1" href="#aber-"></a></h2>

<h3 id="die-kosten" data-numberify>Die Kosten<a class="anchor ms-1" href="#die-kosten"></a></h3>

<h4 id="usb-festplatten" data-numberify>USB-Festplatten<a class="anchor ms-1" href="#usb-festplatten"></a></h4>
<p>Die externen Festplatten tausche ich alle paar Jahre aus. Nicht nur weil sie irgendwann zu klein werden, sondern ich möchte Bitfäule und mechanischem Ausfall vorbeugen. Die Variante als drehenden Rost ist derzeit noch die billigste Variante pro Gigabyte.</p>

<h4 id="cloud" data-numberify>Cloud<a class="anchor ms-1" href="#cloud"></a></h4>
<p>Ja auch Cloud-Storage-Anbieter möchten Geld verdienen; schließlich müssen Server und Personal irgendwie bezahlt werden.</p>

<h4 id="alternative" data-numberify>Alternative?<a class="anchor ms-1" href="#alternative"></a></h4>
<p>In der Summe sind mir meine Daten lieb und diesen Preis wert. Die Alternative wäre ein Totalverlust und das möchte ich nicht.</p>

<h3 id="sync" data-numberify>Sync<a class="anchor ms-1" href="#sync"></a></h3>
<p>Das führende Backup ist die Sicherung auf dem lokalen PC. Zum Synchronisieren auf die externe Platte nutze ich <code>rsync</code>, in die Cloud verwende ich <code>rclone</code>. Beide Tools haben mehrere Vorteile. Das lokale Backup hat einen konsistenten Stand. Die Synchronisation kann im Hintergrund laufen. Weil der neueste Stand immer lokal vorhanden ist, müssen nur die Differenzen in die Cloud oder die externe Festplatte übertragen werden, d.h. es geht sehr schnell.
Zudem muss ich mir keine Gedanken machen, wo wie welcher Stand ist und ob und wo ich irgendwelche Voll- oder inkrementelle Backups gemacht habe oder noch machen muss.
Auch das automatische Ausdünnen bzw. aufräumen der Backups wird dann auf allen Zielen automatisch mitgezogen bzw. vollzogen.
Da ich nur stumpf Dateien hin und her kopiere, ist die Wahl des Backup-Programms (<code>borg</code> oder <code>restic</code>) irrelevant.</p>

<h3 id="online-speicher-aka-cloud" data-numberify>Online-Speicher aka Cloud<a class="anchor ms-1" href="#online-speicher-aka-cloud"></a></h3>
<p>Cloud !!!111EinsElf Oh! Nein! Doch!</p>
<p>Die Programme <code>borg</code> bzw. <code>restic</code> können Out-of-the-box stark verschlüsseln. Die Archive können mit einer Datei oder einen starken Passwort gesichert werden. Insofern ist Wahl des Anbieters für den Cloud-Storage unabhängig von dessen Vertrauenswürdigkeit. Mit den verschlüsselten Dateien kann ohne das Passwort niemand etwas anfangen. Somit können Parameter wie Zuverlässigkeit, Geschwindigkeit und der Preis entscheiden.</p>
<p>Ich persönlich habe mich aufgrund
<a href="https://tools.rainerrose.de/redirect.php?id=31" target="_blank" rel="noopener noreferrer">Mariannes restic-Artikel<i class="fas fa-external-link-square-alt ms-1"></i></a>
ebenfalls für <del><em>Backblaze</em></del><sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup> entschieden. Das Tool <code>rclone</code> synchronisiert wie gefordert die dateibasierte Sicherung und unterstützt deren Produkt <em>B2 Cloud</em>.</p>

<h3 id="download-kostet-aber" data-numberify>Download kostet aber<a class="anchor ms-1" href="#download-kostet-aber"></a></h3>
<p><del><em>Backblaze</em></del><sup id="fnref1:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup> verlangte für den Download der Daten Geld; inzwischen gibt es ein bestimmtes Freikontingent. Andere Anbieter verlangen allerdings auch zum Teil Download-Gebühren.</p>
<p>Hier stellte ich mir die Frage, wann ich jemals Download-Traffic in Anspruch nehmen werde. Ja genau, beim Recover. Und diesen Fall wollte ich erstens so selten wie möglich und wenn, dann ist der Cloud-Speicher ja <strong>einer</strong> meiner Standbeine.
Und im Fall einer Wiederherstellung sind mir die Daten so wichtig, dass ich das Geld auch gerne ausgebe, um die wiederzubekommen. Schließlich war genau dies der Zweck, den der Anbieter erfüllen sollte.</p>
<p>Im Bestfall kann der Großteil der Sicherung auch von der externen Festplatte gezogen werden und es müssen nur noch die Differenz aus der Cloud heruntergeladen werden. Dadurch minimiert sich dann die Größe der Dateien, die heruntergeladen werden müssen. Und damit sinken die Download-Kosten und natürlich auch die benötigte Zeit.</p>

<h4 id="beispiel" data-numberify>Beispiel<a class="anchor ms-1" href="#beispiel"></a></h4>
<p>Genau so einen Fall hatte ich vor einiger Zeit schon einmal. Ich wollte eine alte, externe Festplatte verschenken und daher diese sicher löschen.
Ich hatte leider nicht gut genug aufgepasst und mit <code>dc3dd</code> die falsche Partition geschreddert; inklusive der lokalen Backup-Kopie unter <code>/backup</code>.
Die letzte Sicherung auf der externen Festplatte war drei Wochen alt, weil ich wohl zu diesem Zeitpunt längere Zeit zu faul war sie anzustöpseln. Der Stand im Cloud-Speicher war aber vom Vortag. <em>Yay!</em> Das war meine Rettung. Einige E-Mails lagen eh noch auf dem IMAP-Server und ein paar Downloads wie Rechnungen, Kontoauszüge, musste ich dann eben neu herunterladen. Das Delta aus der Cloud war damit gering und ging schnell von statten. Im Grunde hatte ich kaum etwas verloren.
Ohne Cloud-Backup wären mir drei Wochen Daten flöten gegangen, es hat mir wortwörtlich den Hintern gerettet.</p>

<h3 id="jeder-ort-ein-repo" data-numberify>Jeder Ort ein Repo<a class="anchor ms-1" href="#jeder-ort-ein-repo"></a></h3>
<p>Hier gehe ich einen anderen Weg, als allgemein empfohlen. Viele Backup-Konzepte raten dazu für jedes Ziel (lokale Festplatte, externe Festplatte oder Cloud) einen komplett neuen Lauf zu starten.
Aus meiner Sicht laufen die Stände dann auseinander. Man hat überall unterschiedliche Stände. Wenn ich eine Datei wiederherstellen möchte, muss ich gucken welcher meiner Sicherungsorte die gewünschte Datei zu einem vorhandenen Sicherungszeitpunkt noch beinhaltet.
Außerdem dauern die Sicherungen länger, weil wieder alle Quell-Dateien neu eingelesen werden müssen, um zu schauen, welche Dateien sich geändert haben.
Dieser Schritt fällt bei mir weg, weil die Anzahl der Dateien in meinem Backup prinzipbedingt schon geringer ist und die Daten schon komprimiert wurden. Das Übertragen auf einen weiteren Ort, geht also wesentlich schneller.
Zudem müsste ich so mehrere Scripte vorhalten, die nur unterschiedliche Zielpfade haben, oder das Script so generisch schreiben, dass wiederum die Komplexität steigt und Wartbarkeit leidet.</p>
<p>In meinem Fall ist es ein einfacher <code>rsync</code> oder <code>rclone</code>-Aufruf.</p>

<h2 id="wann" data-numberify>Wann<a class="anchor ms-1" href="#wann"></a></h2>

<h3 id="linux" data-numberify>Linux<a class="anchor ms-1" href="#linux"></a></h3>
<p>Ich habe mich bewusst gegen einen Automatismus an meinem persönlichen Desktop-PC entschieden. Es erfordert etwas Disziplin, hat sich bisher aber für mich bewährt.</p>
<p>Aktuell kann ich spontan entscheiden, ob ich den PC nur schnell runterfahren möchte oder ob ich ein Backup fahren möchte.
Wenn ich mich entscheide, kein Backup zu machen, weil ich z.B. nur schnell ein paar E-Mails geschrieben habe, kann ich den PC schneller wieder runterfahren. Das Ausschalten über die Steckerleiste hilft mir dann wieder Strom sparen.</p>
<p>Habe ich viele Änderungen an den Daten vorgenommen und entscheide ich mich <strong>für</strong> das Backup, wird eine lokale Kopie auf dem Rechner angelegt. Dies kann auch durchaus mehrmals am Tag sein. Am Ende des Tages setze ich dann per Script-Parameter, dass im Anschluss eine Synchronisation in die Cloud stattfinden soll. Ich kann dann den Rechner verlassen und mich anderen Dingen widmen. Etwas später, z.B. kurz vor dem ins Bett gehen, kann ich dann die Steckerleiste ausschalten. Die automatische Discord-Benachrichtigung zum Schluss des Scriptes erinnert mich daran.
Da ich das Script kurz vor dem Runterfahren des Rechners ausführe, ist auch egal wie lange es dauert.
Solange ich außerhalb jeglichen Glasfaser-Ausbau-Gebieten wohne, muss ich nun mal mit der langsamen Upload-Leitung leben.</p>

<h4 id="was" data-numberify>Was<a class="anchor ms-1" href="#was"></a></h4>
<p>Unter Linux sichere ich z.B. den <code>/etc</code>-Baum, wo viele Einstellungen und Konfigurationen liegen. Der größere Teil liegt dann im Benutzer-Verzeichnis (bei mir unterhalb von <code>/home</code>). Genauere Details dazu wird es mal in einem späteren Blog-Artikel geben.</p>

<h4 id="wiederherstellung" data-numberify>Wiederherstellung<a class="anchor ms-1" href="#wiederherstellung"></a></h4>
<p>Das letzte Mal, als ich mein System wiederherstellen musste, hat es gereicht <code>/etc</code> als auch <code>/home</code> neu einzuspielen und ich war überwiegend wieder arbeitsfähig. Die Programm-Installation unter Linux gestaltet sich relativ einfach und unkompliziert, zumindest bei den Dingen, die von der jeweiligen Distribution mitgeliefert werden.</p>

<h3 id="windows" data-numberify>Windows<a class="anchor ms-1" href="#windows"></a></h3>
<p>Bei Familienmitgliedern, die Windows verwenden, läuft das Backup-Script wiederum beim Anmelden am System. Ich habe noch keine Möglichkeit gefunden, dass es beim Herunterfahren ausgeführt wird.
Ein extra Klick mit einer Verknüpfung hat sich nicht bewährt, weil es gerne vergessen wird und der Rechner einfach nur stumpf via Windows-Menü heruntergefahren wird.
Durch den automatisierten Aufruf während des Logins, entfällt ein manueller Eingriff und es läuft jedes Mal.</p>

<h4 id="was-1" data-numberify>Was<a class="anchor ms-1" href="#was-1"></a></h4>
<p>Bei Windows im Enduser-Bereich sichere ich ebenfalls hauptsächlich den Benutzerordner, da dort vieles wichtiges abgelegt ist.
Mir ist klar, dass auch durchaus einige Einstellungen in der Registry stehen, aber für die weitere Recherche reicht meine Motivation nicht. Wahrscheinlich ist es eh besser, im K-Fall<sup id="fnref:2"><a href="#fn:2" class="footnote-ref" role="doc-noteref">2</a></sup> das System komplett neu aufzusetzen und dann nur die Benutzerdaten wiederherzustellen.</p>

<h2 id="server" data-numberify>Server<a class="anchor ms-1" href="#server"></a></h2>
<p>Zu Hause läuft noch ein NAS-System mit virtuellen Servern. Dort wird mittels Crontab fast dasselbe Backup-Script ausgeführt. Der Sync in die Cloud findet allerdings täglich statt.
Da ich noch Webanwendungen betreibe, ist das Backup-Script etwas aufgebohrt. Je nach Dienst dreht es noch ein paar Schleifen.
Bei neueren Systemen habe ich sogar schon auf <code>resticprofile</code> umgestellt.</p>
<p>Beispielsweise hat das interne Kanboard eine Datenbank-Anbindung. Vor dem Start der dateibasierten Sicherung wird noch ein logischer Datenbank-Dump in ein Verzeichnis geschrieben, dass dann ebenfalls mitgesichert wird.
Ich weiß, dass es da z.T. bessere Möglichkeiten gibt, als ein schnöder <code>mysqldump</code>. Da ich schon mehrfach die Webanwendung <em>Kanboard</em> und andere Dienste wiederherstellen konnte, hat es für mich bisher so gereicht.</p>
<p>Anwendungen in Docker-Containern stoppe ich vorher, um einen konsistenten Stand zu sichern oder fahre, wie bei <em>paperless</em>, einen automatisierten Export der Daten in das Dateisystem.</p>

<h2 id="recover-testen" data-numberify>Recover testen<a class="anchor ms-1" href="#recover-testen"></a></h2>
<p>Auch das Thema Recover, also der Wiederherstellen der Daten, sollte man nicht unterschätzen. <strong>Testet Eure Backups</strong> und versucht die Daten wieder herzustellen!</p>
<p>Nichts ist schlimmer, als wenn man meint immer ein Backup gemacht zu haben und man dann feststellen muss, dass es kaputt ist oder wichtige Dinge fehlen.
Der Test schützt vor dem Verlust wichtiger Dateien bzw. Daten. Wenn Ihr Software wie zum Beispiel <em>Tandoor Recipes</em> aufsetzt, befüllt sie zu Anfang mit nur ein paar wenigen Daten. Dann macht Ihr ein Backup und löscht die komplette Installation. Im nächsten Schritt versucht Ihr die Anwendung oder auch die Daten aus dem Backup wieder herzustellen.</p>
<p>Pro-Tipp am Rande: <strong>Dokumentiert</strong> in diesem Fall gleich, wie ihr vorgegangen seid, die Daten wieder herzustellen.
Wenn Ihr Daten verloren habt, befindet Ihr Euch meist sowieso in einer Stress-Situation. Wenn ihr dann noch rausfinden müsst, wie ihr wieder an Eure Daten kommt und wie der alten Zustand wieder hergestellt werden kann, bedeutet das zusätzlichen Stress, den ihr mit diesem Vorgehen vermeiden könnt.
Eine gute Anleitung erleichtert später die Arbeit und trägt wesentlich zur Entspannung bei.</p>

<h2 id="verfeinerung" data-numberify>Verfeinerung<a class="anchor ms-1" href="#verfeinerung"></a></h2>

<h3 id="sortierung-nach-wichtigkeit" data-numberify>Sortierung nach Wichtigkeit<a class="anchor ms-1" href="#sortierung-nach-wichtigkeit"></a></h3>
<p>Ich sortiere meine Backups in unterschiedliche Container bzw. Repositorys.</p>
<p>Es gibt persönlich mir wichtige Sachen, wie E-Mails und Bilder, selbst geschriebene Scripte etc.
Dann gibt es
nicht so wichtige Dinge, wie ISO-Dateien von gekauften CDs oder alter Installations-CDs von Steuer- oder Finanzsoftware.</p>
<p>Einige Dateien ziehe ich auch über das Netz, wie das Backup-Archiv vom NAS. Dies dauert dann länger und daher möchte ich das nicht immer machen.</p>
<p>Es gibt ein extra Repo und Script für die Sicherung meiner digitalen Bilder. Dies erfordert durchaus Disziplin, um da den Überblick zu behalten, aber die Bilder-Ordner erfahren aber auch nicht so oft eine Änderung, als dass das täglich nötig wäre.</p>
<p>Ebenso gibt es Backups-Repos, die nur auf der externen Festplatte landen und nicht in der Cloud.</p>

<h3 id="meta-daten" data-numberify>Meta-Daten<a class="anchor ms-1" href="#meta-daten"></a></h3>
<p>Ein paar wichtige Meta-Daten, wie die Aufteilung der Festplatte, schreibe ich ebenso automatisiert während des Backup-Laufs in einen speziellen Unterordner. Diesen sichere ich gleich mit.</p>
<p>Auch Infos zum LVM, Filesysteme oder installierte Pakete speichere ich in Textdateien und nehme diese Pfade in zu sichernden auf.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="c1"># Partitionen</span>
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">parted -l &gt; <span class="s2">&#34;</span><span class="si">${</span><span class="nv">METAINFOSDIR</span><span class="si">}</span><span class="s2">/parted-l.txt&#34;</span>
</span></span><span class="line"><span class="ln"> 3</span><span class="cl"><span class="c1"># Filesysteme</span>
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">mount &gt;&gt; <span class="s2">&#34;</span><span class="si">${</span><span class="nv">METAINFOSDIR</span><span class="si">}</span><span class="s2">/parted-l.txt&#34;</span>
</span></span><span class="line"><span class="ln"> 5</span><span class="cl"><span class="c1"># Software-Pakete</span>
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">pacman -Qqet &gt; <span class="s2">&#34;</span><span class="si">${</span><span class="nv">METAINFOSDIR</span><span class="si">}</span><span class="s2">/manjrao_installierte_pakete&#34;</span>
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">pacman -Qqm &gt; <span class="s2">&#34;</span><span class="si">${</span><span class="nv">METAINFOSDIR</span><span class="si">}</span><span class="s2">/manuell-installierte-pakete.txt&#34;</span>
</span></span><span class="line"><span class="ln"> 8</span><span class="cl"><span class="c1"># LVM-Infos</span>
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">vgdisplay &gt;  <span class="s2">&#34;</span><span class="si">${</span><span class="nv">METAINFOSDIR</span><span class="si">}</span><span class="s2">/lvm_infos.txt&#34;</span>
</span></span><span class="line"><span class="ln">10</span><span class="cl">pvdisplay &gt;&gt; <span class="s2">&#34;</span><span class="si">${</span><span class="nv">METAINFOSDIR</span><span class="si">}</span><span class="s2">/lvm_infos.txt&#34;</span>
</span></span><span class="line"><span class="ln">11</span><span class="cl">lvdisplay &gt;&gt; <span class="s2">&#34;</span><span class="si">${</span><span class="nv">METAINFOSDIR</span><span class="si">}</span><span class="s2">/lvm_infos.txt&#34;</span>
</span></span></code></pre></div>
<h2 id="probleme-borg" data-numberify>Probleme: Borg<a class="anchor ms-1" href="#probleme-borg"></a></h2>
<p>Lange Zeit habe ich <code>borg</code> für meine Sicherungen benutzt. In der Vergangenheit hatte ich ein paar Unschönheiten, die ich aber lösen könnte.
Irgendwann hatte ich Probleme meine Sicherung in die Cloud zu schieben; doch der Reihe nach.</p>

<h3 id="anderer-ort" data-numberify>Anderer Ort<a class="anchor ms-1" href="#anderer-ort"></a></h3>
<p>Dadurch, dass ich meine Repos immer nur per <code>rsync</code> übertrage, nörgelt <code>borg</code>, wenn ich mal einen Blick in das Archiv werfen wollte, was auf einer externen Festplatte liegt.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="ln">1</span><span class="cl">borg list bilder
</span></span><span class="line"><span class="ln">2</span><span class="cl">Warning: The repository at location /run/media/rainer/backup_hdd_1/backup_nuc/bilder was previously located at /backup/borgbackup/bilder
</span></span><span class="line"><span class="ln">3</span><span class="cl">Do you want to continue? [yN]
</span></span></code></pre></div><p>Vielleicht war es ein Bug oder es gab ein anderes Problem. Es gab mal eine Zeit, wo genau dieser der Zugriff außerhalb des Original-Ortes meiner Erinnerung nach verweigert wurde. Eine Lösung hatte ich damals gefunden. Durch das oben beschriebene Konzept mit <code>rsync</code> konnte ich es z.B. wieder an den ursprünglichen Ort kopieren. Danach war der Zugriff wieder möglich. Ich kann es derzeit nicht mehr nachstellen; aktuell scheint es wieder zu gehen, wenn die Frage einfach bejaht wird.
Es ist mir negativ im Gedächtnis geblieben und es schwirrte schon lange die Idee in meinem Kopf herum, dass ich mich um eine Alternative zu <code>borg</code> kümmern müsse.</p>

<h3 id="große-dateien" data-numberify>Große Dateien<a class="anchor ms-1" href="#große-dateien"></a></h3>
<p>Ausschlaggebend für den endgültigen Wechsel war ein Problem mit <del><em>Backblaze</em></del><sup id="fnref2:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup> vor einiger Zeit.</p>
<p>Wie weiter oben beschrieben habe ich mehrere Repos. Eines der größeren Archive mit ca. 66 GB machte beim Upload nach B2 Probleme:</p>
<p>Das Logfile war sehr hilfreich - nicht:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="ln">1</span><span class="cl"> data/0/31: Error sending chunk 0 (retry=true): incident id ec43eb366fa6-744fae19214412f6 (500 internal_error): &amp;api.Error{Status:500, Code:&#34;internal_error&#34;, Mes 
</span></span></code></pre></div><p>Ich lernte, dass es bei größeren Repos, wie dem 66 GB in meinem Fall,  irgendwann recht große Dateien (ca. 500MB pro Stück) mit <code>borg</code> entstehen.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="ln"> 1</span><span class="cl">ls -hl data/0/ |head
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">insgesamt 46G
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">-rw------- 1 root root 503M 29. Sep 2022  10
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">-rw------- 1 root root 504M 11. Okt 2022  100
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">-rw------- 1 root root 503M 11. Okt 2022  101
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">-rw------- 1 root root 501M 11. Okt 2022  102
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">-rw------- 1 root root 503M 11. Okt 2022  103
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">-rw------- 1 root root 503M 11. Okt 2022  104
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">-rw------- 1 root root 502M 11. Okt 2022  105
</span></span><span class="line"><span class="ln">10</span><span class="cl">-rw------- 1 root root 504M 11. Okt 2022  106
</span></span><span class="line"><span class="ln">11</span><span class="cl">-rw------- 1 root root 501M 11. Okt 2022  107
</span></span></code></pre></div><p>Dieses führte beim Upload zu <del><em>Backblaze</em></del><sup id="fnref3:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup> Problemen und warf daher mehrere Fehler beim Ausführen von <code>rclone</code>.</p>
<p>Bei meinen Recherchen in diesem Internet fand ich folgenden Blog-Artikel mit dem Titel
<a href="https://tools.rainerrose.de/redirect.php?id=32" target="_blank" rel="noopener noreferrer">What To Do When You Get a B2 503 (or 500) Server Error<i class="fas fa-external-link-square-alt ms-1"></i></a>.</p>
<p>Im Grunde steht da nur stumpf, dass man es nach einer gewissen Zeit nochmal probieren soll. Nach ein paar Tagen mit dem selben Fehlerbild war ich genervt und las den Artikel nochmal genauer. Dort wird auf
<a href="https://tools.rainerrose.de/redirect.php?id=33" target="_blank" rel="noopener noreferrer">B2 error handling protocols<i class="fas fa-external-link-square-alt ms-1"></i></a>
verwiesen, wo unter dem Absatz &ldquo;<em>Multithreading Uploads</em>&rdquo;
Hinweise in Bezug auf Dateien größer als 200 MB gegeben werden. Diese Dateien sollen beim Upload gesplittet werden und dann parallel hochgeladen werden. Ich vermute mal, dass das <code>rclone</code> unter der Haube macht; nachgeschaut habe ich nicht.</p>
<p>Bisher war nur ein Repo betroffen und andere Repos konnte ich problemlos nach <del><em>Backblaze</em></del><sup id="fnref4:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup> hochladen bzw. synchronisieren mittels <code>rclone</code>.</p>
<p>Große Lust dem <del><em>Backblaze</em></del>-Support<sup id="fnref5:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup> hinterherzulaufen oder debugging im <code>rclone</code>-Umfeld zu betreiben, hatte ich nicht.</p>

<h2 id="umstieg-auf-restic" data-numberify>Umstieg auf restic<a class="anchor ms-1" href="#umstieg-auf-restic"></a></h2>
<p>Damit war die Entscheidung gefallen; ich würde alle meine Backup-Scripte auf <code>restic</code> umstellen. Ein kleiner Test ergab, dass ein <code>restic</code>-Lauf zwar wesentlich mehr Dateien der selben Quell-Dateien ergab, aber auch wesentlich kleinere.
Da ich alle meine Backups in einem Unterverzeichnis sammle, war die Analyse mittels <code>find</code> recht simpel.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">find borgbackup -size +200M <span class="p">|</span> wc -l
</span></span></code></pre></div><p>Das Ergebnis: 816 Treffer.</p>
<p>Mein Testverzeichnis mit dem selbigen problembehafteten Dateien bzw. Repo in <code>restic</code> gebaut ergab keine Treffer</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">find resticbackup -size +200M <span class="p">|</span> wc -l
</span></span></code></pre></div><p>und es ging <strong>wesentlich</strong> schneller. Alleine der initiale Durchlauf beim allerersten Erstellen des Archivs war um Zeitfaktor 10 schneller. Es waren nur zwei statt zwanzig Minuten nötig, was mich zusätzlich bestärkt hat umzusteigen.</p>

<h2 id="erleichterungen" data-numberify>Erleichterungen<a class="anchor ms-1" href="#erleichterungen"></a></h2>
<p>Um mich noch etwas unabhängiger im K-Fall zu machen, speichere zusätzlich das <code>restic</code>-Binary noch im Verzeichnis aller restic-Repos. Dieses wird dann ebenfalls via <code>rsync</code> mit auf die externen Festplatten kopiert, so dass ich immer eine aktuelle Version habe.</p>
<p>Für Neuigkeiten abonniere ich noch den RSS-Feed und habe einen
Watcher auf die <em>Github</em> Releases. Aber das ist einen extra Blog-Artikel wert.</p>
<p>Tipps und Tricks zu Bedienung lege ich in eine extra Datei namens <code>restic-hilfe.md</code>. Hier stehen dann die wichtigsten Befehle zum Wiederherstellen der Dateien und zum Mounten des gewünschten Repos ins aktuelle Dateisystems.</p>
<p>Alles im Sinne der Stress-Reduzierung während eines potentiellen Recover-Scenarios.</p>

<h2 id="ende" data-numberify>Ende<a class="anchor ms-1" href="#ende"></a></h2>
<p>Ich hoffe, ich konnte ein paar Einblicke in meine Überlegung zu meiner Backup-Strategie geben.
Vielleicht hilft es dem einem oder anderen ein Konzept selbst zu überlegen oder sein oder ihr existierendes anzupassen.</p>
<p>Wenn Ihr ich jetzt nach den Scripten fragt, muss ich Euch auf die Zukunft vertrösten.
Die Scripte selbst sind einen eigen Blog-Artikel wert.</p>

<h2 id="ausblick-update" data-numberify>Ausblick (Update)<a class="anchor ms-1" href="#ausblick-update"></a></h2>
<p>Inzwischen habe ich auf den Chemnitzer Linux-Tagen einen Vortrag über <code>restic</code> gehalten.
Auch habe ich vor demnächst<sup>tm</sup> die Scripte auf <code>resticprofile</code> umzustellen.
Über beide Tools erzähle ich was in meinem <a href="/docs/writings/2025/">Vortag</a>.</p>

<h2 id="changelog" data-numberify>Changelog<a class="anchor ms-1" href="#changelog"></a></h2>
<table>
  <thead>
      <tr>
          <th>Datum</th>
          <th>Änderung</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>23.12.2023</td>
          <td>Fix: Typos, Grammatik</td>
      </tr>
      <tr>
          <td>03.01.2024</td>
          <td>Fix: Typo</td>
      </tr>
      <tr>
          <td>28.01.2025</td>
          <td>Fix: Typo</td>
      </tr>
      <tr>
          <td>27.03.2025</td>
          <td>Hinweis auf meinen <code>restic</code>/<code>resticprofile</code> CLT-Vortrag, Definition 3-2-1 nochmal deutlicher</td>
      </tr>
      <tr>
          <td>08.05.2025</td>
          <td>Hinweis auf <code>CACHEDIR.TAG</code>. Ein paar Umformulierungen und Typos fixed</td>
      </tr>
      <tr>
          <td>29.09.2025</td>
          <td>Besser verdeutlicht, dass ich Backblaze nicht mehr verwende.</td>
      </tr>
      <tr>
          <td>15.01.2026</td>
          <td>Ein paar Typos korrigiert.</td>
      </tr>
  </tbody>
</table>

<h2 id="fußnoten" data-numberify>Fußnoten<a class="anchor ms-1" href="#fußnoten"></a></h2>
<div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p>Diese Angabe stimmt inzwischen nicht mehr. Im Rahmen von <code>#UnPlugTrump</code> bin ich zu <em>Hetzner</em> <em>StorageShare</em> gewechselt.&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a>&#160;<a href="#fnref1:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a>&#160;<a href="#fnref2:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a>&#160;<a href="#fnref3:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a>&#160;<a href="#fnref4:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a>&#160;<a href="#fnref5:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:2">
<p>Krisen-Fall&#160;<a href="#fnref:2" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
</ol>
</div>]]></content:encoded>
    <enclosure url="https://www.rainerrose.de/wallpaper/posts/backupkonzept.png" length="24827" type="image/.png" />
    </item>
    
    <item>
      <title>GIT</title>
      <link>https://www.rainerrose.de/docs/howto/git/</link>
      <pubDate>Mon, 11 Dec 2023 22:00:11 +0200</pubDate>
      <guid>https://www.rainerrose.de/docs/howto/git/</guid>
      <description><![CDATA[<!-- Anreißer -->
<p>Notizen, Tipps und Tricks zum Versionsverwaltung <code>git</code>.</p>
<p>Änderungen siehe Changelog unten.</p>]]></description>
      <content:encoded><![CDATA[<!-- Anreißer -->
<p>Notizen, Tipps und Tricks zum Versionsverwaltung <code>git</code>.</p>
<p>Änderungen siehe Changelog unten.</p>

<h2 id="schickeres-diff" data-numberify>schickeres diff<a class="anchor ms-1" href="#schickeres-diff"></a></h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl"><span class="nb">alias</span> <span class="nv">diffogram</span><span class="o">=</span><span class="s1">&#39;git --no-pager diff --no-index&#39;</span>
</span></span></code></pre></div>
<h2 id="nur-gucken" data-numberify>nur gucken<a class="anchor ms-1" href="#nur-gucken"></a></h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">git show origin/&lt;branchname&gt;:pfad/datei.name
</span></span></code></pre></div><p><strong>Beispiel</strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">git show origin/main:local-deb-repo/README.md
</span></span></code></pre></div>
<h2 id="master-in-main-umbenennen" data-numberify>master in main umbenennen<a class="anchor ms-1" href="#master-in-main-umbenennen"></a></h2>
<p>Wer aus <a href="/sammlung/alltags-rassisums-in-der-it">$GRUENDEN</a> seinen
<code>master</code>-Zweig in den <code>main</code>-Zweig<sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup> umbenennen möchte, kann das
folgendermaßen tun:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln"> 1</span><span class="cl">$ git branch -m master main
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">$ git push -u origin main
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">Gesamt <span class="m">0</span> <span class="o">(</span>Delta 0<span class="o">)</span>, Wiederverwendet <span class="m">0</span> <span class="o">(</span>Delta 0<span class="o">)</span>
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">remote: 
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">remote: To create a merge request <span class="k">for</span> main, visit:
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">remote:   https://gitlab.com/rainerrose/unbound-tools/-/merge_requests/new?merge_request%5Bsource_branch%5D<span class="o">=</span>main
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">remote: 
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">To gitlab.com:rainerrose/unbound-tools.git
</span></span><span class="line"><span class="ln"> 9</span><span class="cl"> * <span class="o">[</span>new branch<span class="o">]</span>      main -&gt; main
</span></span><span class="line"><span class="ln">10</span><span class="cl">Branch <span class="s1">&#39;main&#39;</span> folgt nun Remote-Branch <span class="s1">&#39;main&#39;</span> von <span class="s1">&#39;origin&#39;</span>.
</span></span></code></pre></div><p>Das <code>-m</code> bewirkt, dass auch die Historie verschoben<sup id="fnref:2"><a href="#fn:2" class="footnote-ref" role="doc-noteref">2</a></sup> wird, es bleiben
also alle Änderungen erhalten.</p>

<h2 id="default-branch-in-git-setzen" data-numberify>Default Branch in git setzen<a class="anchor ms-1" href="#default-branch-in-git-setzen"></a></h2>
<p>Geht wohl erst <strong>ab Version 2.28</strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">git config --global init.defaultBranch main
</span></span></code></pre></div><p>dann soll auch folgendes gehen</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">git init --initial-branch<span class="o">=</span>main
</span></span><span class="line"><span class="ln">2</span><span class="cl">git init -b main
</span></span></code></pre></div>
<h2 id="default-branch-in-gitlab-setzen" data-numberify>Default Branch in Gitlab setzen<a class="anchor ms-1" href="#default-branch-in-gitlab-setzen"></a></h2>
<p>Anschließend lässt sich der Default-Branch in Gitlab folgenderweise auf
<code>main</code> setzen:</p>
<p><code>Allgemein</code>-&gt;<code>Einstellungen</code>-&gt;<code>Repository</code>-&gt;<code>Default-Branch</code>-&gt;<code>Aufklappen</code></p>
<p>Dort jetzt noch <code>main</code> auswählen und schlussendlich die Änderungen
abspeichern (<code>Save changes</code>).</p>

<h2 id="zwei-faktor-authentisierung-bei-gitlab" data-numberify>Zwei-Faktor-Authentisierung bei Gitlab<a class="anchor ms-1" href="#zwei-faktor-authentisierung-bei-gitlab"></a></h2>
<p>Wird die <a href="https://tools.rainerrose.de/redirect.php?id=15" target="_blank" rel="noopener noreferrer">2FA in Gitlab<i class="fas fa-external-link-square-alt ms-1"></i></a>
aktiviert, kann sich nicht mehr über HTTPS per Username/Passwort
angemeldet werden. (SSH mit Pub-Key geht weiterhin).</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">$ git pull
</span></span><span class="line"><span class="ln">2</span><span class="cl">remote: HTTP Basic: Access denied
</span></span><span class="line"><span class="ln">3</span><span class="cl">remote: You must use a personal access token with <span class="s1">&#39;read_repository&#39;</span> or <span class="s1">&#39;write_repository&#39;</span> scope <span class="k">for</span> Git over HTTP.
</span></span><span class="line"><span class="ln">4</span><span class="cl">remote: You can generate one at https://gitlab.com/-/profile/personal_access_tokens
</span></span><span class="line"><span class="ln">5</span><span class="cl">fatal: Authentication failed <span class="k">for</span> <span class="s1">&#39;https://gitlab.com/username/projekt-name.git&#39;</span>
</span></span></code></pre></div>
<h3 id="abhilfe" data-numberify>Abhilfe<a class="anchor ms-1" href="#abhilfe"></a></h3>

<h4 id="in-gitlab" data-numberify>in Gitlab<a class="anchor ms-1" href="#in-gitlab"></a></h4>
<p>In Gitlab anmelden:
<a href="https://tools.rainerrose.de/redirect.php?id=16" target="_blank" rel="noopener noreferrer">Benutzereinstellungen-&gt;Zugangs-Token<i class="fas fa-external-link-square-alt ms-1"></i></a></p>
<p>Dort ein &quot;persönliches Zugangs-Token&quot; (Add a personal access token)
generieren und Rechte vergeben <code>read_repository</code> oder <code>write_repository</code></p>

<h4 id="im-repository" data-numberify>im Repository<a class="anchor ms-1" href="#im-repository"></a></h4>
<p>Erstmal wegnehmen</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">$ git remote remove origin
</span></span></code></pre></div><p>remote mit geheimen Token einfügen</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">$ git remote add origin https://oauth2:HIER_GEHEIMES_TOKEN_EINFUEGEN@gitlab.com/username/projekt-name.git
</span></span></code></pre></div><p>Upstream-Branch setzen</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">$ git branch --set-upstream-to<span class="o">=</span>origin/master master
</span></span></code></pre></div>
<blockquote class="alert alert-info" role="alert">
    <p class="alert-heading fw-bold">
      <i class="fas fa-info-circle me-2"></i>Tipp
    </p>
    <p>Falls nach <code>git pull</code> genörgelt wird, denselben Befehl im Upstream-Branch nochmal absetzen.</p>
</blockquote>

<h2 id="alle-branches-auch-remote-anzeigen" data-numberify>Alle branches (auch remote) anzeigen<a class="anchor ms-1" href="#alle-branches-auch-remote-anzeigen"></a></h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">git branch -a
</span></span></code></pre></div>
<h2 id="git-remote-branch-lokal-speichern" data-numberify>git remote branch lokal speichern<a class="anchor ms-1" href="#git-remote-branch-lokal-speichern"></a></h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">git checkout -b &lt;<span class="nb">local</span> branch name&gt; origin/&lt;remote branch name&gt;
</span></span><span class="line"><span class="ln">2</span><span class="cl">git checkout -b serverfix origin/serverfix
</span></span></code></pre></div>
<h2 id="branch-hochladen" data-numberify>Branch hochladen<a class="anchor ms-1" href="#branch-hochladen"></a></h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">git push origin &lt;Name des Branch&gt;
</span></span></code></pre></div>
<h2 id="mit-anderem-ssh-key-anmelden" data-numberify>mit anderem ssh-key anmelden<a class="anchor ms-1" href="#mit-anderem-ssh-key-anmelden"></a></h2>
<p>In der SSH-Konfiguration einen neuen Eintrag anlegen</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">$ cat ~/.ssh/config
</span></span><span class="line"><span class="ln">2</span><span class="cl">Host gutMerkbarerName
</span></span><span class="line"><span class="ln">3</span><span class="cl">  HostName der.gitlab.host.name.fqdn
</span></span><span class="line"><span class="ln">4</span><span class="cl">  User rose
</span></span><span class="line"><span class="ln">5</span><span class="cl">  IdentityFile /home/rose/.ssh/id_ed25519.rose
</span></span><span class="line"><span class="ln">6</span><span class="cl">  IdentitiesOnly yes
</span></span></code></pre></div><p>Jetzt kann noch ein neues Remote-Ziel angelegt werden</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">$ git remote add rose ssh://git@gutMerkbarerName:22/rose/project.git
</span></span></code></pre></div><p>jetzt kann mit</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">$ git push rose
</span></span></code></pre></div><p>hochgeladen werden und git fragt nach dem anderen key</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">Enter passphrase <span class="k">for</span> key <span class="s1">&#39;/home/rose/.ssh/id_ed25519.rose&#39;</span>:
</span></span></code></pre></div><p>statt</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">$ git push origin
</span></span><span class="line"><span class="ln">2</span><span class="cl">Enter passphrase <span class="k">for</span> key <span class="s1">&#39;/home/rose/.ssh/id_ed25519&#39;</span>:
</span></span></code></pre></div>
<h2 id="als-anderer-committen" data-numberify>als anderer committen<a class="anchor ms-1" href="#als-anderer-committen"></a></h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">$ git config --local user.name <span class="s2">&#34;Rainer Rose&#34;</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl">$ git config --local user.email <span class="s2">&#34;email@adresse&#34;</span>
</span></span><span class="line"><span class="ln">3</span><span class="cl">$ git commit
</span></span><span class="line"><span class="ln">4</span><span class="cl">$ git config --local --unset user.name
</span></span><span class="line"><span class="ln">5</span><span class="cl">$ git config --local --unset user.email
</span></span></code></pre></div><p>Alternativen zu <code>--local</code>:</p>

<h2 id="git-config-user--email" data-numberify>Git Config User / Email<a class="anchor ms-1" href="#git-config-user--email"></a></h2>
<table>
  <thead>
      <tr>
          <th>Parameter</th>
          <th>Ort</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>--local</code></td>
          <td><code>.git/config</code></td>
      </tr>
      <tr>
          <td><code>--global</code></td>
          <td><code>~/.gitconfig</code></td>
      </tr>
      <tr>
          <td><code>--system</code></td>
          <td><code>/etc/gitconfig</code></td>
      </tr>
  </tbody>
</table>

<h2 id="tags-pushen" data-numberify>Tags pushen<a class="anchor ms-1" href="#tags-pushen"></a></h2>

<h3 id="einzelner" data-numberify>einzelner<a class="anchor ms-1" href="#einzelner"></a></h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">git push origin v0.42
</span></span></code></pre></div>
<h3 id="alle" data-numberify>alle<a class="anchor ms-1" href="#alle"></a></h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">git push origin --tags
</span></span></code></pre></div>
<h2 id="lokale-branches-löschen" data-numberify>lokale Branches löschen<a class="anchor ms-1" href="#lokale-branches-löschen"></a></h2>

<blockquote class="alert alert-info" role="alert">
    <p class="alert-heading fw-bold">
      <i class="fas fa-info-circle me-2"></i>Hinweis
    </p>
    <p><strong>Außer</strong> den aktuellen Branch, der ausgechecked ist!</p>
</blockquote>

<h3 id="nur-die-die-gemerged-sind" data-numberify>nur die, die gemerged sind<a class="anchor ms-1" href="#nur-die-die-gemerged-sind"></a></h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">git branch --merged <span class="p">|</span> grep -v <span class="se">\*</span> <span class="p">|</span> xargs git branch -D
</span></span></code></pre></div>
<h3 id="alle-1" data-numberify>alle<a class="anchor ms-1" href="#alle-1"></a></h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">git branch <span class="p">|</span> grep -v <span class="se">\*</span> <span class="p">|</span> xargs git branch -D
</span></span></code></pre></div>
<h2 id="letzten-commit-rückgängig-machen" data-numberify>letzten Commit rückgängig machen<a class="anchor ms-1" href="#letzten-commit-rückgängig-machen"></a></h2>
<p>Wenn man z.B. aus Versehen auf <code>main</code> committed hat&hellip;.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">git reset --soft HEAD~1
</span></span></code></pre></div>
<h2 id="letzte-commit-message-ändern" data-numberify>Letzte Commit-Message ändern<a class="anchor ms-1" href="#letzte-commit-message-ändern"></a></h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">git commit --amend
</span></span></code></pre></div>
<h2 id="changelog" data-numberify>Changelog<a class="anchor ms-1" href="#changelog"></a></h2>
<table>
  <thead>
      <tr>
          <th>Datum</th>
          <th>Änderung</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>11.10.2023</td>
          <td>zwei neue Tipps: &ldquo;schickeres diff&rdquo; &amp; &ldquo;Nur gucken&rdquo;</td>
      </tr>
      <tr>
          <td>06.12.2023</td>
          <td>git remote branch lokal speichern</td>
      </tr>
      <tr>
          <td>11.12.2023</td>
          <td>Branch hochladen</td>
      </tr>
      <tr>
          <td>29.04.2025</td>
          <td>Neuer Abschnitt <code>Git Config User / Email</code></td>
      </tr>
      <tr>
          <td>15.05.2025</td>
          <td>lokale Branches löschen</td>
      </tr>
      <tr>
          <td>22.09.2025</td>
          <td>letzten Commit rückgängig machen</td>
      </tr>
      <tr>
          <td>12.03.2026</td>
          <td>Letzte Commit-Message ändern</td>
      </tr>
  </tbody>
</table>
<div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p>ist ja nichts anderes als ein <code>Branch</code>&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:2">
<p>moved2&#160;<a href="#fnref:2" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
</ol>
</div>]]></content:encoded>
    </item>
    
    <item>
      <title>resolv.conf aktualisiert sich nicht</title>
      <link>https://www.rainerrose.de/posts/resolv-conf/</link>
      <pubDate>Thu, 30 Nov 2023 23:04:50 +0200</pubDate>
      <guid>https://www.rainerrose.de/posts/resolv-conf/</guid>
      <description><![CDATA[<!-- Anreißer -->
<p>Vor einigen Wochen hatte ich das Problem, dass ich den DNS-Server eines RedHat-System ändern musste.
Dabei bin ich über einige Fallstricke gestolpert, die ich hier kurz darstellen möchte. Ich habe wieder einiges gelernt und vielleicht hilft es ja auch jemand anderen.</p>]]></description>
      <content:encoded><![CDATA[<!-- Anreißer -->
<p>Vor einigen Wochen hatte ich das Problem, dass ich den DNS-Server eines RedHat-System ändern musste.
Dabei bin ich über einige Fallstricke gestolpert, die ich hier kurz darstellen möchte. Ich habe wieder einiges gelernt und vielleicht hilft es ja auch jemand anderen.</p>
<p>Das vorliegende System war ein RHEL 8. Ich hatte den erforderlichen DNS-Eintrag schon per <code>nmtui</code> gesetzt und auch per <code>grep</code> kontrolliert:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">grep -i dns /etc/sysconfig/network-scripts/ifcfg-ens192
</span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="nv">DNS1</span><span class="o">=</span>172.x.x.x
</span></span></code></pre></div><p>Ein nachfolgendes <code>systemctl reload NetworkManager.service</code> hat zwar die <code>/etc/resolv.conf</code> angefasst, aber es wurde immer wieder die alte IP eingetragen.</p>
<p>Ebenso hatte ich nach der alten IP unterhalb von <code>/run</code> gesucht. Ich hatte zwei Treffer:</p>
<ul>
<li><code>/run/NetworkManager/resolv.conf</code> und</li>
<li><code>/run/NetworkManager/no-stub-resolv.conf</code></li>
</ul>
<p>Zudem ergab ein</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">nmcli  -p connection show ens192 <span class="p">|</span> grep -i dns
</span></span></code></pre></div><p>zwei spannende Treffer:</p>
<pre><code>ipv4.dns: 172.x.x.x
IP4.DNS[1]:  62.x.x.x.x
</code></pre>
<p>hier waren beide IPs (die alte und die neue IP) eingetragen.</p>
<p>RHELs kanonisches Netzwerkmanagement ist der <em>Network-Manager</em> ist und nicht <em>systemd-networkd</em>; daher war der Weg eine Sackgasse.</p>
<p>Eine vermutlich recht simple Lösung wäre gewesen den Server neu zu starten, was aber eine Offline-Zeit der Services bedeutet hätte. Dies wollte ich in diesem Fall vermeiden.</p>
<p>Dann habe ich gelernt, dass ein</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">nmcli c up ens192
</span></span></code></pre></div><p>ausreicht, damit die Konfiguration neu gezogen wird und die  <code>/etc/resolv.conf</code> neu geschrieben wird. Den <em>Networkmanager</em> neustarten hilft da nicht immer, weil der sich die Konfiguration nicht neu zieht, sondern seinen existierenden Cache verwendet.</p>
<p><strong>Wichtig hierbei</strong>: Alle Arbeiten können über <em>ssh</em> stattfinden, die <em>ssh</em>-Sitzung bleibt erhalten. Für vorsichtige Naturen wie mich, kann ich empfehlen noch parallel eine zweite <em>ssh</em>-Verbindung auf zu haben. Somit hat man einen zweiten &ldquo;Finger&rdquo; auf dem System und es kann durchaus mal recht hilfreich sein, wenn es zu Problemen kommt. Und sei es nur, dass der gerade absetzte Befehl länger braucht als gedacht und man parallel eine Analyse betreiben kann; ob und wo es ggf. zu Problemen kommt.</p>
<p>Mein Dank für die damalige Unterstützung geht an Kevin, Jan und Christoph.</p>]]></content:encoded>
    <enclosure url="https://www.rainerrose.de/wallpaper/posts/resolv-conf.png" length="16752" type="image/.png" />
    </item>
    
    <item>
      <title>update_docker_images.sh</title>
      <link>https://www.rainerrose.de/posts/update_docker_images/</link>
      <pubDate>Thu, 30 Nov 2023 22:54:19 +0200</pubDate>
      <guid>https://www.rainerrose.de/posts/update_docker_images/</guid>
      <description><![CDATA[<!-- Anreißer -->
<p>Beim Arbeiten mit vielen <code>docker-compose.yml</code> Dateien habe ich öfter die Anforderung gehabt, <strong>einzelne</strong> Images neu zu pullen. In der Regel reicht ein <code>docker compose pull</code>, was aber heißt, dass er <strong>alle</strong> images zieht.</p>
<p>Es gibt jedoch bei mir durchaus öfters den Fall, dass ich dies nicht möchte. Zudem hatte ich einige Container, wo nur auf ein bestimmtes Versions-Tag (z.B. <code>mysql:8</code>) gepulled wird oder ich sogar mit <code>latest</code> arbeite. Dies bedeutete, dass ich mir jedes Image einzeln aus der docker-compose-datei rauspfriemeln musste.
Damit ich im Wiederherstellungsfall das alte Image schneller wiederfinde, wollte ich das speziell taggen.
In der Regel habe ich an den Namen des Tags ein <code>_backup</code> dran gehängt. Vorher musste das vorherige Image mit diesem Tag gelöscht werden. Diese manuelle Arbeit habe ich nun in ein Script gegossen.</p>
<p><strong>Update 30.11.2023:</strong> siehe unten Changelog</p>]]></description>
      <content:encoded><![CDATA[<!-- Anreißer -->
<p>Beim Arbeiten mit vielen <code>docker-compose.yml</code> Dateien habe ich öfter die Anforderung gehabt, <strong>einzelne</strong> Images neu zu pullen. In der Regel reicht ein <code>docker compose pull</code>, was aber heißt, dass er <strong>alle</strong> images zieht.</p>
<p>Es gibt jedoch bei mir durchaus öfters den Fall, dass ich dies nicht möchte. Zudem hatte ich einige Container, wo nur auf ein bestimmtes Versions-Tag (z.B. <code>mysql:8</code>) gepulled wird oder ich sogar mit <code>latest</code> arbeite. Dies bedeutete, dass ich mir jedes Image einzeln aus der docker-compose-datei rauspfriemeln musste.
Damit ich im Wiederherstellungsfall das alte Image schneller wiederfinde, wollte ich das speziell taggen.
In der Regel habe ich an den Namen des Tags ein <code>_backup</code> dran gehängt. Vorher musste das vorherige Image mit diesem Tag gelöscht werden. Diese manuelle Arbeit habe ich nun in ein Script gegossen.</p>
<p><strong>Update 30.11.2023:</strong> siehe unten Changelog</p>
<p>Das Script was auf <a href="https://gitlab.com/rainerrose/cli-tools/-/blob/main/docker/update_docker_images.sh" target="_blank" rel="noopener noreferrer">GitLab<i class="fas fa-external-link-square-alt ms-1"></i></a> liegt, durchpflügt die <code>docker-compose.yml</code>-Datei (parameterisierbar in der Datei) und fragt interaktiv nach, ob ein neues Image gepulled werden soll.</p>
<p>Wenn ja (default), dann legt das Script vorher ein <em>&ldquo;Backup&rdquo;</em> des Containers an, indem es an den Tag-Namen des aktuellen Containers ein <code>_backup</code> dran hängt.
Vorher wird das evtl. vorhandene und so benannte Image noch gelöscht, damit die Festplatte nicht platzt.
Das Suffix des Tags ist anpassbar im Script.</p>
<p>Bei jedem Durchlauf werden nochmal alle passenden Images angezeigt, damit alte Images nochmal aufgelistet werden. So fallen ungetaggte Images mit z.B. <code>&lt;none&gt;</code> leichter auf.</p>
<p>Die Ausgabe sieht dann z.B. so aus:</p>
<pre><code>Update docker image: mysql:8 [j]|n: 
Lösche evtl. Backups
docker images mysql:8_backup
LINES_MIT_HEADER=2
lösche altes Image
docker image rm mysql:8_backup
Untagged: mysql:8_backup
Untagged: mysql@sha256:566007208a3f1cc8f9df6b767665b5c9b800fc4fb5f863d17aa1df362880ed04
Deleted: sha256:b2013ac9910129ded1da4c96495142b2ed0638ddf7e86e65156400d9a8503777
Deleted: sha256:d24171674816d2cdb9a7cfaf9980f3ba574930efe226ca7fa840084072974e08
Deleted: sha256:046ec448aa8eaaa27e4118211c9f77da24d35b8a84b25f997334c3473d14a870
Deleted: sha256:ab05f09658d83ed8ff487d346fcc9fa4cecf5a23906a7e7feffaea83a1332a14
Deleted: sha256:96db44e22a968a3a16890685d95bd96d420d99a8880966056721c36842fa38af
Deleted: sha256:402981938079002ce0b77d9fe7a892608155b3866ad1967313b4934d0d8a6d3c
Deleted: sha256:e38cf6d3efcf0edd5d80758556fdafa43e9e3136edbc05928febf8771b1cba31
Deleted: sha256:0d197db846f4e62ab3d29cef5d359f5896ddd6869ba49608f276741da328ef29
Deleted: sha256:121010cc4276929c2ba287fe57dfd0c61483862809dfc884c2aa3d998d6cc292
Deleted: sha256:b72678d2fc4485cc1febd27ab3cc6fe2ddc9ef62b2f016aaa8620040a339677f
Deleted: sha256:b42107e741524c1f305a1a4649a4d96a5921c48c5b8c438ad871ab7cc5815231
Lege Backup an 
docker tag mysql:8 mysql:8_backup
8: Pulling from library/mysql
210eb976c4c7: Pull complete 
ebb4c64fd647: Pull complete 
cb8397d67a0f: Pull complete 
ff0e9bc8aa4e: Pull complete 
e6f52b272e7f: Pull complete 
e2d9e8e437ee: Pull complete 
e61517738248: Pull complete 
cfb2700e7252: Pull complete 
4044404847dd: Pull complete 
c142db3aeff8: Pull complete 
Digest: sha256:1ee299bf9eb8d2218fcb4fad666a090c92caef48ce524e6edce35f2e2d55170d
Status: Downloaded newer image for mysql:8
docker.io/library/mysql:8
REPOSITORY   TAG        IMAGE ID       CREATED        SIZE
mysql        8_backup   8da80fe49fcf   4 weeks ago    577MB
mysql        8          2d9aad1b5856   2 months ago   574MB
</code></pre>

<h2 id="besonderheit" data-numberify>Besonderheit<a class="anchor ms-1" href="#besonderheit"></a></h2>
<p>Bei einigen Containern arbeite ich mit konkreten Versionsnummern in den Tags.</p>
<p>Beispiel-Ausschnitt aus einer <code>docker-compose.yml</code></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="ln">1</span><span class="cl"><span class="w">    </span><span class="nt">image</span><span class="p">:</span><span class="w"> </span><span class="l">onlyoffice/documentserver:7.5.1.1</span><span class="w">
</span></span></span></code></pre></div><p>In diesem Fall muss die obige Abfrage</p>
<pre><code>Update docker image: onlyoffice/documentserver:7.5.1.1 [j]|n: 
</code></pre>
<p>mit <code>n</code> für <em>nein</em> beantwortet werden. Hier findet ja gerade eine Versionierung bzw. Backup über den Namen des Tags statt. Zudem kann ich hier schlecht die nächste Versionsnummer erraten.
Weiterhin kann ja auch ein Überspringen einer Subversion gewünscht sein.
Da die Images sowieso anhand Ihres Tags schon als Image-Version vorliegen, muss die Version somit im  <code>docker-compose.yml</code> -File angepasst werden.</p>
<p>Dieses Script ist somit nur für die fixen Version-Strings wie oben bei <em>mysql</em> oder dem oben erwähnten <em>lastest</em> geeignet, erleichert aber meinen Alltag ungemein.</p>

<h2 id="changelog" data-numberify>Changelog<a class="anchor ms-1" href="#changelog"></a></h2>
<table>
  <thead>
      <tr>
          <th>Datum</th>
          <th>Änderung</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>30.11.2023</td>
          <td>Teaser erweitert, einige Sätze ausgebessert. Letzten Absatz &ldquo;Besonderheit&rdquo; hinzugefügt.</td>
      </tr>
  </tbody>
</table>]]></content:encoded>
    <enclosure url="https://www.rainerrose.de/wallpaper/posts/update_docker_images.png" length="33926" type="image/.png" />
    </item>
    
    <item>
      <title>v4l2 / Webcams</title>
      <link>https://www.rainerrose.de/docs/linux/v4l2/</link>
      <pubDate>Wed, 08 Nov 2023 22:42:04 +0200</pubDate>
      <guid>https://www.rainerrose.de/docs/linux/v4l2/</guid>
      <description><![CDATA[<!-- Anreißer -->
<p>Tipps und Tricks zu Video4Linux</p>]]></description>
      <content:encoded><![CDATA[<!-- Anreißer -->
<p>Tipps und Tricks zu Video4Linux</p>

<h2 id="liste-alle-devices" data-numberify>Liste alle Devices<a class="anchor ms-1" href="#liste-alle-devices"></a></h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">v4l2-ctl --list-devices
</span></span></code></pre></div>
<h3 id="ausgabe" data-numberify>Ausgabe<a class="anchor ms-1" href="#ausgabe"></a></h3>
<pre><code>HD Pro Webcam C920 (usb-0000:00:14.0-3.3):
	/dev/video0
	/dev/video1
	/dev/media0
</code></pre>

<h2 id="aktuelle-einstellungen" data-numberify>Aktuelle Einstellungen<a class="anchor ms-1" href="#aktuelle-einstellungen"></a></h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">v4l2-ctl --list-ctrls
</span></span></code></pre></div>
<h3 id="ausgabe-1" data-numberify>Ausgabe<a class="anchor ms-1" href="#ausgabe-1"></a></h3>
<pre><code>                         brightness 0x00980900 (int)    : min=0 max=255 step=1 default=128 value=128
                           contrast 0x00980901 (int)    : min=0 max=255 step=1 default=128 value=128
                         saturation 0x00980902 (int)    : min=0 max=255 step=1 default=128 value=128
     white_balance_temperature_auto 0x0098090c (bool)   : default=1 value=1
                               gain 0x00980913 (int)    : min=0 max=255 step=1 default=0 value=0
               power_line_frequency 0x00980918 (menu)   : min=0 max=2 default=2 value=2 (60 Hz)
          white_balance_temperature 0x0098091a (int)    : min=2000 max=6500 step=1 default=4000 value=4000 flags=inactive
                          sharpness 0x0098091b (int)    : min=0 max=255 step=1 default=128 value=128
             backlight_compensation 0x0098091c (int)    : min=0 max=1 step=1 default=0 value=0
                      exposure_auto 0x009a0901 (menu)   : min=0 max=3 default=3 value=3 (Aperture Priority Mode)
                  exposure_absolute 0x009a0902 (int)    : min=3 max=2047 step=1 default=250 value=250 flags=inactive
             exposure_auto_priority 0x009a0903 (bool)   : default=0 value=1
                       pan_absolute 0x009a0908 (int)    : min=-36000 max=36000 step=3600 default=0 value=0
                      tilt_absolute 0x009a0909 (int)    : min=-36000 max=36000 step=3600 default=0 value=0
                     focus_absolute 0x009a090a (int)    : min=0 max=250 step=5 default=0 value=0
                         focus_auto 0x009a090c (bool)   : default=1 value=0
                      zoom_absolute 0x009a090d (int)    : min=100 max=500 step=1 default=100 value=100
</code></pre>

<h2 id="auto-fokus-status-abfragen" data-numberify>Auto-Fokus Status abfragen<a class="anchor ms-1" href="#auto-fokus-status-abfragen"></a></h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">v4l2-ctl --get-ctrl focus_auto 
</span></span></code></pre></div>
<h3 id="ausgabe-2" data-numberify>Ausgabe<a class="anchor ms-1" href="#ausgabe-2"></a></h3>
<pre><code>focus_auto: 1
</code></pre>
<p>hier also an.</p>

<h2 id="auto-fokus-ausschalten" data-numberify>Auto-Fokus ausschalten<a class="anchor ms-1" href="#auto-fokus-ausschalten"></a></h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">v4l2-ctl --set-ctrl <span class="nv">focus_auto</span><span class="o">=</span><span class="m">0</span>
</span></span></code></pre></div>
<h2 id="parameter-änderungen" data-numberify>Parameter-Änderungen<a class="anchor ms-1" href="#parameter-änderungen"></a></h2>
<p>Aktuell (Stand irgendwann im Juni 2023) scheinen sich die o.g. Parameter etwas geändert zu haben. Den Parameter <code>focus_auto</code> gibt es nicht mehr.</p>
<p>Derzeit setze ich die Parameter folgendermaßen:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">v4l2-ctl --set-ctrl <span class="nv">focus_absolute</span><span class="o">=</span>0,focus_automatic_continuous<span class="o">=</span><span class="m">0</span>
</span></span></code></pre></div>
<h2 id="changelog" data-numberify>Changelog<a class="anchor ms-1" href="#changelog"></a></h2>
<table>
  <thead>
      <tr>
          <th>Datum</th>
          <th>Änderung</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>13.06.2023</td>
          <td>Parameter-Änderungen</td>
      </tr>
      <tr>
          <td>08.11.2023</td>
          <td>neuer Parameter &ndash;list-devices</td>
      </tr>
  </tbody>
</table>]]></content:encoded>
    </item>
    
    <item>
      <title>Theme Update Oktober&#39;23</title>
      <link>https://www.rainerrose.de/posts/theme-update-23-10/</link>
      <pubDate>Thu, 02 Nov 2023 22:50:30 +0100</pubDate>
      <guid>https://www.rainerrose.de/posts/theme-update-23-10/</guid>
      <description><![CDATA[<!-- Anreißer -->
<p>Die letzten Tage habe ich etwas unter der Haube der Homepage geschraubt.
Ich habe an Kleinigkeiten gearbeitet und ein paar Dinge im Hintergrund optimiert und verändert.</p>
<p>Was ich gemacht habe, bzw. was passiert ist:</p>]]></description>
      <content:encoded><![CDATA[<!-- Anreißer -->
<p>Die letzten Tage habe ich etwas unter der Haube der Homepage geschraubt.
Ich habe an Kleinigkeiten gearbeitet und ein paar Dinge im Hintergrund optimiert und verändert.</p>
<p>Was ich gemacht habe, bzw. was passiert ist:</p>
<p>Der RSS Feed zeigt jetzt den vollen Inhalt der jeweiligen Blog-Artikels. Wie es ausschaut, habe ich damit alle IDs neu generiert, so dass jetzt leider alle Lesenden auch die alten Artikel als ungelesen serviert bekommen haben.
Zumindest ist es so bei meinem RSS-Reader passiert, genauer debugged habe ich das aus Faulheit nicht.</p>
<p>Ich habe mich der Darstellungsproblematik im Archiv angenommen und das Problem gefixed.
Eine Kleinigkeit gibt es im Archiv noch zu korrigieren, aber da handelt es sich um einen Theme-Bug, der in der Zwischenzeit sogar schon behoben ist. \o/</p>
<p>Dies bedeutet, dass ich die nächsten Tage das Theme wieder auf die neueste Version hochziehen werde.</p>]]></content:encoded>
    <enclosure url="https://www.rainerrose.de/wallpaper/theme-update-sept-23.png" length="32247" type="image/.png" />
    </item>
    
    <item>
      <title>Discord-Bot</title>
      <link>https://www.rainerrose.de/posts/discord-bot/</link>
      <pubDate>Thu, 21 Sep 2023 22:28:30 +0200</pubDate>
      <guid>https://www.rainerrose.de/posts/discord-bot/</guid>
      <description><![CDATA[<!-- Anreißer -->
<p>Ich habe hier einige Backup-Scripte, die auch mal etwas länger laufen, wo ich eine Benachrichtigung haben wollte. Unter anderem muss nach einem Backup-Lauf die externe USB-Festplatte für mein Offsite-Backup wieder abgezogen werden.</p>]]></description>
      <content:encoded><![CDATA[<!-- Anreißer -->
<p>Ich habe hier einige Backup-Scripte, die auch mal etwas länger laufen, wo ich eine Benachrichtigung haben wollte. Unter anderem muss nach einem Backup-Lauf die externe USB-Festplatte für mein Offsite-Backup wieder abgezogen werden.</p>
<p>Da ich eh schon einen Discord-Account hatte, bot es sich an, per Webhook mir aus dem jeweiligen Script heraus eine Nachricht zu schicken.</p>

<h2 id="channel-anlegen" data-numberify>Channel anlegen<a class="anchor ms-1" href="#channel-anlegen"></a></h2>
<p>Es bietet sich an, einen extra Channel im Discord dafür anzulegen. Meiner heißt &ldquo;<em>bots</em>&rdquo;.</p>
<p><picture><img class="img-fluid " alt="Kanal des Bots bearbeiten" src="https://www.rainerrose.de/images/posts/discord/01-discord-text-channel-bearbeiten.png?v=cd0c707106a8448cba620e7d19b6c959" loading="lazy" width="470" height="236" />
</picture>

</p>

<h2 id="hook-anlegen" data-numberify>Hook anlegen<a class="anchor ms-1" href="#hook-anlegen"></a></h2>
<p>Um einen Webhook anzulegen, wählt man den gewünschten Channel aus, klickt auf das daneben stehende Rädchen, um den Kanal zu bearbeiten. Im folgenden Menü auf den Unterpunkt &ldquo;<em>Integrationen</em>&rdquo; klicken und als nächstes die Schaltfläche &ldquo;<em>Webhook erstellen</em>&rdquo; anklicken.</p>
<p><picture><img class="img-fluid " alt="Webhook erstellen" src="https://www.rainerrose.de/images/posts/discord/02_discord-webhook-erstellen.png?v=cd0c707106a8448cba620e7d19b6c959" loading="lazy" width="1370" height="371" />
</picture>

</p>
<p>Über den Pfeil, die weiteren Optionen aufklappen:</p>
<p><picture><img class="img-fluid " alt="Webhook bearbeiten" src="https://www.rainerrose.de/images/posts/discord/03_discord-webhook-bearbeiten.png?v=cd0c707106a8448cba620e7d19b6c959" loading="lazy" width="1013" height="201" />
</picture>

</p>
<p>Hier den Hook umbenennen oder doch noch einem anderen Channel zuweisen. Der Klick auf die Schaltfläche &ldquo;<em>WebHook-URL kopieren</em>&rdquo; bringt diesen in die Zwischenablage.</p>
<p><picture><img class="img-fluid " alt="Webhook URL" src="https://www.rainerrose.de/images/posts/discord/04_discord-webhook-url-copy.png?v=cd0c707106a8448cba620e7d19b6c959" loading="lazy" width="1018" height="443" />
</picture>

</p>

<h2 id="scripte" data-numberify>Scripte<a class="anchor ms-1" href="#scripte"></a></h2>
<p>Zuerst kam der Wunsch auf, sich bei Ende des Backup-Scriptes eine Meldung zuschicken zu lasssen, dass es fertig ist.
Entweder kann dann das nächste angeworfen werden oder es kann die externe USB-Festplatte abgekoppelt werden.
Später kam dann der Wunsch auf, dass ich auch bei Fehlern eine Benachrichtigung bekomme.
Weil ich keine große Lust hatte, da ein ordentliches Script mit einer Fall-Unterscheidung zu schreiben, habe ich es der Einfachheit halber dupliziert.</p>

<h3 id="ok-meldung" data-numberify>OK-Meldung<a class="anchor ms-1" href="#ok-meldung"></a></h3>
<p>Die Gut-Meldung hat einen grünen Balken an der Seite und meldet ein &ldquo;Backup fertig&rdquo;.</p>
<p><picture><img class="img-fluid " alt="Webhook Info-Meldung" src="https://www.rainerrose.de/images/posts/discord/05-info-meldung.png?v=cd0c707106a8448cba620e7d19b6c959" loading="lazy" width="700" height="270" />
</picture>

</p>
<p>Im Nachfolgenden Script <code>discord-bot.sh</code> muss die Webhook-URL noch durch den Inhalt der Variablen <code>discord_url</code> ersetzt werden.</p>
<div class="highlight" title="discord-bot.sh"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="cp">#!/bin/bash
</span></span></span><span class="line"><span class="ln"> 2</span><span class="cl"><span class="cp"></span><span class="c1"># Discord Webhook</span>
</span></span><span class="line"><span class="ln"> 3</span><span class="cl"><span class="nv">THE_SCRIPTNAME</span><span class="o">=</span><span class="s2">&#34;</span><span class="si">${</span><span class="nv">1</span><span class="si">}</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="nv">discord_url</span><span class="o">=</span><span class="s2">&#34;https://discord.com/api/webhooks/958845757975330887/wr21BPYs5jECw2OTAo86crAjGrAvbgaexvCAKqCFCgVDr5IFxQtrm5ON4CRAaBmP&#34;</span>
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">generate_post_data<span class="o">()</span> <span class="o">{</span>
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">  cat <span class="s">&lt;&lt;EOF
</span></span></span><span class="line"><span class="ln"> 8</span><span class="cl"><span class="s">{
</span></span></span><span class="line"><span class="ln"> 9</span><span class="cl"><span class="s">  &#34;content&#34;: &#34;Backup fertig&#34;,
</span></span></span><span class="line"><span class="ln">10</span><span class="cl"><span class="s">  &#34;embeds&#34;: [{
</span></span></span><span class="line"><span class="ln">11</span><span class="cl"><span class="s">    &#34;title&#34;: &#34;Backup Script ist fertig!&#34;,
</span></span></span><span class="line"><span class="ln">12</span><span class="cl"><span class="s">    &#34;description&#34;: &#34;Script ${1}&#34;,
</span></span></span><span class="line"><span class="ln">13</span><span class="cl"><span class="s">    &#34;color&#34;: &#34;45973&#34;
</span></span></span><span class="line"><span class="ln">14</span><span class="cl"><span class="s">  }]
</span></span></span><span class="line"><span class="ln">15</span><span class="cl"><span class="s">}
</span></span></span><span class="line"><span class="ln">16</span><span class="cl"><span class="s">EOF</span>
</span></span><span class="line"><span class="ln">17</span><span class="cl"><span class="o">}</span>
</span></span><span class="line"><span class="ln">18</span><span class="cl">
</span></span><span class="line"><span class="ln">19</span><span class="cl"><span class="c1"># POST request to Discord Webhook</span>
</span></span><span class="line"><span class="ln">20</span><span class="cl">curl -H <span class="s2">&#34;Content-Type: application/json&#34;</span> -X POST -d <span class="s2">&#34;</span><span class="k">$(</span>generate_post_data <span class="si">${</span><span class="nv">THE_SCRIPTNAME</span><span class="si">}</span> <span class="k">)</span><span class="s2">&#34;</span> <span class="nv">$discord_url</span>
</span></span></code></pre></div>
<h3 id="fehlermeldung" data-numberify>Fehlermeldung<a class="anchor ms-1" href="#fehlermeldung"></a></h3>
<p>Wenn ein Fehler passiert, gibt es einen roten Balken an der Seite. Zusätzlich habe ich dem Text einen Zeilenumbruch mit <code>\n</code> verpasst.</p>
<p><picture><img class="img-fluid " alt="Webhook Fehler-Meldung" src="https://www.rainerrose.de/images/posts/discord/05-info-error-meldung.png?v=cd0c707106a8448cba620e7d19b6c959" loading="lazy" width="789" height="249" />
</picture>

</p>
<p>Auch hier im nachfolgenden Script <code>discord-bot-error.sh</code> den Variablen-Inhalt <code>discord_url</code> wieder ersetzen.</p>
<div class="highlight" title="discord-bot-error.sh"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="cp">#!/bin/bash
</span></span></span><span class="line"><span class="ln"> 2</span><span class="cl"><span class="cp"></span><span class="c1"># Discord Webhook</span>
</span></span><span class="line"><span class="ln"> 3</span><span class="cl"><span class="nv">THE_SCRIPTNAME</span><span class="o">=</span><span class="s2">&#34;</span><span class="si">${</span><span class="nv">1</span><span class="si">}</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="nv">FEHLER_MELDUNG</span><span class="o">=</span><span class="s2">&#34;</span><span class="si">${</span><span class="nv">2</span><span class="si">}</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="ln"> 5</span><span class="cl"><span class="nv">discord_url</span><span class="o">=</span><span class="s2">&#34;https://discord.com/api/webhooks/958845757975330887/wr21BPYs5jECw2OTAo86crAjGrAvbgaexvCAKqCFCgVDr5IFxQtrm5ON4CRAaBmP&#34;</span>
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">generate_post_data<span class="o">()</span> <span class="o">{</span>
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">  cat <span class="s">&lt;&lt;EOF
</span></span></span><span class="line"><span class="ln"> 9</span><span class="cl"><span class="s">{
</span></span></span><span class="line"><span class="ln">10</span><span class="cl"><span class="s">  &#34;content&#34;: &#34;Backup Error&#34;,
</span></span></span><span class="line"><span class="ln">11</span><span class="cl"><span class="s">  &#34;embeds&#34;: [{
</span></span></span><span class="line"><span class="ln">12</span><span class="cl"><span class="s">    &#34;title&#34;: &#34;Backup Script wirft Fehler!&#34;,
</span></span></span><span class="line"><span class="ln">13</span><span class="cl"><span class="s">    &#34;description&#34;: &#34;Script ${1}\nIrgendwas ist bei diesem Script schiefgelaufen.&#34;,
</span></span></span><span class="line"><span class="ln">14</span><span class="cl"><span class="s">    &#34;color&#34;: &#34;15548997&#34;
</span></span></span><span class="line"><span class="ln">15</span><span class="cl"><span class="s">  }]
</span></span></span><span class="line"><span class="ln">16</span><span class="cl"><span class="s">}
</span></span></span><span class="line"><span class="ln">17</span><span class="cl"><span class="s">EOF</span>
</span></span><span class="line"><span class="ln">18</span><span class="cl"><span class="o">}</span>
</span></span><span class="line"><span class="ln">19</span><span class="cl">
</span></span><span class="line"><span class="ln">20</span><span class="cl"><span class="c1"># POST request to Discord Webhook</span>
</span></span><span class="line"><span class="ln">21</span><span class="cl">curl -H <span class="s2">&#34;Content-Type: application/json&#34;</span> -X POST -d <span class="s2">&#34;</span><span class="k">$(</span>generate_post_data <span class="si">${</span><span class="nv">THE_SCRIPTNAME</span><span class="si">}</span> <span class="si">${</span><span class="nv">FEHLER_MELDUNG</span><span class="si">}</span><span class="k">)</span><span class="s2">&#34;</span> <span class="nv">$discord_url</span>
</span></span></code></pre></div>
<h3 id="die-farbe-der-balken" data-numberify>Die Farbe der Balken<a class="anchor ms-1" href="#die-farbe-der-balken"></a></h3>
<p>Die Farbe der Balken lässt sich ändern. Weiter unten ist eine tabellarische Auflistung.</p>

<h2 id="verwendung-bzw-aufruf-im-backup-script" data-numberify>Verwendung bzw. Aufruf im Backup-Script<a class="anchor ms-1" href="#verwendung-bzw-aufruf-im-backup-script"></a></h2>
<p>Der Aufruf im Backup-Script ist dann simpel, hier das <code>discord-bot.sh</code> in der letzten Zeile aufrufen:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">discord-bot.sh <span class="s2">&#34;</span><span class="si">${</span><span class="nv">0</span><span class="si">}</span><span class="s2">&#34;</span>
</span></span></code></pre></div><p>Im Fehlerfall an entsprechender Stelle</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">discord-bot-error.sh <span class="s2">&#34;</span><span class="si">${</span><span class="nv">0</span><span class="si">}</span><span class="s2">&#34;</span>
</span></span></code></pre></div><p>Die beiden Bash-Dateien sollte natürlich ausführbar im Suchpfad von <code>$PATH</code> sein.</p>

<h2 id="farben-der-balken" data-numberify>Farben der Balken<a class="anchor ms-1" href="#farben-der-balken"></a></h2>
<p>Die erlaubten Farbwerte hatte ich irgendwo mal in diesem Internet gefunden, leider weiß ich nicht mehr wo.</p>
<table>
  <thead>
      <tr>
          <th>Name</th>
          <th style="text-align: right">Wert bei <code>color</code></th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>Aqua</code></td>
          <td style="text-align: right">1752220</td>
      </tr>
      <tr>
          <td><code>Blue</code></td>
          <td style="text-align: right">3447003</td>
      </tr>
      <tr>
          <td><code>DarkAqua</code></td>
          <td style="text-align: right">1146986</td>
      </tr>
      <tr>
          <td><code>DarkBlue</code></td>
          <td style="text-align: right">2123412</td>
      </tr>
      <tr>
          <td><code>DarkerGrey</code></td>
          <td style="text-align: right">8359053</td>
      </tr>
      <tr>
          <td><code>DarkGold</code></td>
          <td style="text-align: right">12745742</td>
      </tr>
      <tr>
          <td><code>DarkGreen</code></td>
          <td style="text-align: right">2067276</td>
      </tr>
      <tr>
          <td><code>DarkGrey</code></td>
          <td style="text-align: right">9936031</td>
      </tr>
      <tr>
          <td><code>DarkNavy</code></td>
          <td style="text-align: right">2899536</td>
      </tr>
      <tr>
          <td><code>DarkOrange</code></td>
          <td style="text-align: right">11027200</td>
      </tr>
      <tr>
          <td><code>DarkPurple</code></td>
          <td style="text-align: right">7419530</td>
      </tr>
      <tr>
          <td><code>DarkRed</code></td>
          <td style="text-align: right">10038562</td>
      </tr>
      <tr>
          <td><code>DarkVividPink</code></td>
          <td style="text-align: right">11342935</td>
      </tr>
      <tr>
          <td><code>Gold</code></td>
          <td style="text-align: right">15844367</td>
      </tr>
      <tr>
          <td><code>Green</code></td>
          <td style="text-align: right">5763719</td>
      </tr>
      <tr>
          <td><code>Grey</code></td>
          <td style="text-align: right">9807270</td>
      </tr>
      <tr>
          <td><code>LightGrey</code></td>
          <td style="text-align: right">12370112</td>
      </tr>
      <tr>
          <td><code>LuminousVividPink</code></td>
          <td style="text-align: right">15277667</td>
      </tr>
      <tr>
          <td><code>Navy</code></td>
          <td style="text-align: right">3426654</td>
      </tr>
      <tr>
          <td><code>Orange</code></td>
          <td style="text-align: right">15105570</td>
      </tr>
      <tr>
          <td><code>Purple</code></td>
          <td style="text-align: right">10181046</td>
      </tr>
      <tr>
          <td><code>Red</code></td>
          <td style="text-align: right">15548997</td>
      </tr>
      <tr>
          <td><code>Yellow</code></td>
          <td style="text-align: right">16776960</td>
      </tr>
  </tbody>
</table>

<h2 id="verbesserungsvorschläge" data-numberify>Verbesserungsvorschläge<a class="anchor ms-1" href="#verbesserungsvorschläge"></a></h2>
<p>Ihr könnt gerne auf <a href="https://gitlab.com/rainerrose/cli-tools" target="_blank" rel="noopener noreferrer">GitLab<i class="fas fa-external-link-square-alt ms-1"></i></a> einen Pull-Request einreichen.</p>]]></content:encoded>
    <enclosure url="https://www.rainerrose.de/images/posts/discord/05-info-meldung.png" length="27997" type="image/.png" />
    </item>
    
    <item>
      <title>Theme Update</title>
      <link>https://www.rainerrose.de/posts/theme-update-23-09/</link>
      <pubDate>Sat, 02 Sep 2023 23:20:20 +0200</pubDate>
      <guid>https://www.rainerrose.de/posts/theme-update-23-09/</guid>
      <description><![CDATA[<!-- Anreißer -->
<p>Für mein Hugo-Theme gab es ein Update.</p>]]></description>
      <content:encoded><![CDATA[<!-- Anreißer -->
<p>Für mein Hugo-Theme gab es ein Update.</p>
<p>Es war etwas schwieriger einzuspielen, weil sich ein paar Dinge geändert hatten und ich schon länger nicht mehr aktualisiert hatte. Ein paar neue Seiten-Parameter wollten gesetzt sein. Und auch die hugo-Version wollte mal wieder aktualisiert werden.</p>
<p>Die &ldquo;related posts&rdquo; fand ich optisch nicht gelungen, weil dies ein Artikel-Bild voraussetzt, was ich nicht habe. Um jetzt fehlende Bilder bzw. Dummy-Bilder zu vermeiden, habe ich aktuell die Funktion deaktiviert.</p>
<p>Es gibt hier und da kleine Veränderungen, z.B. sind die Icons den sozialen Netwerken jetzt in bunt.</p>
<p>Ich hoffe, ich habe keine Patzer übersehen und es gefällt.</p>]]></content:encoded>
    <enclosure url="https://www.rainerrose.de/wallpaper/theme-update-sept-23.png" length="32247" type="image/.png" />
    </item>
    
    <item>
      <title>sed</title>
      <link>https://www.rainerrose.de/docs/linux/sed/</link>
      <pubDate>Sat, 02 Sep 2023 23:14:31 +0200</pubDate>
      <guid>https://www.rainerrose.de/docs/linux/sed/</guid>
      <description><![CDATA[<!-- Anreißer -->
<p>Textersetzungswerkzeug <code>sed</code> Anwendungsbeispiele</p>

<h2 id="hinzufügen-einer-zeile" data-numberify>Hinzufügen einer Zeile<a class="anchor ms-1" href="#hinzufügen-einer-zeile"></a></h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">sed -i <span class="s1">&#39;8i Dies in Zeile 8 hinzufügen&#39;</span> FILE
</span></span></code></pre></div>]]></description>
      <content:encoded><![CDATA[<!-- Anreißer -->
<p>Textersetzungswerkzeug <code>sed</code> Anwendungsbeispiele</p>

<h2 id="hinzufügen-einer-zeile" data-numberify>Hinzufügen einer Zeile<a class="anchor ms-1" href="#hinzufügen-einer-zeile"></a></h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">sed -i <span class="s1">&#39;8i Dies in Zeile 8 hinzufügen&#39;</span> FILE
</span></span></code></pre></div>
<h2 id="mehrere-leerzeichen--spaces-ersetzen" data-numberify>Mehrere Leerzeichen / Spaces ersetzen<a class="anchor ms-1" href="#mehrere-leerzeichen--spaces-ersetzen"></a></h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;foo     bar baz&#34;</span> <span class="p">|</span> sed -e <span class="s1">&#39;s/  */ /g&#39;</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl">foo bar baz
</span></span></code></pre></div>
<h2 id="mehrere-leerzeichen--spaces-löschen" data-numberify>Mehrere Leerzeichen / Spaces löschen<a class="anchor ms-1" href="#mehrere-leerzeichen--spaces-löschen"></a></h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;foo     bar baz&#34;</span> <span class="p">|</span> sed <span class="s1">&#39;s/[[:space:]]//g&#39;</span>
</span></span></code></pre></div>
<h2 id="löschen-der-dritten-zeile-in-einer-datei" data-numberify>Löschen der dritten Zeile in einer Datei<a class="anchor ms-1" href="#löschen-der-dritten-zeile-in-einer-datei"></a></h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">sed <span class="s1">&#39;3d&#39;</span> &lt;datei&gt;
</span></span></code></pre></div>
<h2 id="löschen-einer-zeile-mit-pattern-matching" data-numberify>Löschen einer Zeile mit Pattern-Matching<a class="anchor ms-1" href="#löschen-einer-zeile-mit-pattern-matching"></a></h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">sed -i <span class="s1">&#39;/textpattern/d&#39;</span> <span class="s2">&#34;</span><span class="si">${</span><span class="nv">DATEI</span><span class="si">}</span><span class="s2">&#34;</span>
</span></span></code></pre></div>
<h2 id="in-einer-datei-ersetzen" data-numberify>in einer Datei ersetzen<a class="anchor ms-1" href="#in-einer-datei-ersetzen"></a></h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">sed -i <span class="s1">&#39;s/foo/bar/&#39;</span> &lt;datei&gt;
</span></span></code></pre></div>
<h2 id="in-einer-datei-ersetzen-mit-backup" data-numberify>in einer Datei ersetzen, mit Backup<a class="anchor ms-1" href="#in-einer-datei-ersetzen-mit-backup"></a></h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">sed -i.bak <span class="s1">&#39;s/foo/bar/&#39;</span> &lt;datei&gt;
</span></span></code></pre></div>
<h2 id="mit-umgebungsvariablen" data-numberify>mit Umgebungsvariablen<a class="anchor ms-1" href="#mit-umgebungsvariablen"></a></h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">sed <span class="s1">&#39;s/foo/&#39;</span><span class="s2">&#34;</span><span class="nv">$BAR</span><span class="s2">&#34;</span><span class="s1">&#39;/&#39;</span>
</span></span></code></pre></div>
<h2 id="changelog" data-numberify>Changelog<a class="anchor ms-1" href="#changelog"></a></h2>
<table>
  <thead>
      <tr>
          <th>Datum</th>
          <th>Änderung</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>12.03.2026</td>
          <td><code>[[:space:]]</code> Trick</td>
      </tr>
  </tbody>
</table>]]></content:encoded>
    </item>
    
    <item>
      <title>Powershell</title>
      <link>https://www.rainerrose.de/docs/howto/powershell/</link>
      <pubDate>Fri, 30 Jun 2023 16:24:51 +0200</pubDate>
      <guid>https://www.rainerrose.de/docs/howto/powershell/</guid>
      <description><![CDATA[<!-- Anreißer -->
<p>Ein paar Powershell-Helferlein, Einzeiler, Dinge, die ich ab und zu brauche.</p>]]></description>
      <content:encoded><![CDATA[<!-- Anreißer -->
<p>Ein paar Powershell-Helferlein, Einzeiler, Dinge, die ich ab und zu brauche.</p>

<h2 id="sowas-wie-netstat-bzw-lsof" data-numberify>sowas wie netstat bzw. lsof<a class="anchor ms-1" href="#sowas-wie-netstat-bzw-lsof"></a></h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-powershell" data-lang="powershell"><span class="line"><span class="ln">1</span><span class="cl"><span class="nb">Get-Process</span> <span class="n">-Id</span> <span class="p">(</span><span class="nb">Get-NetTCPConnection</span> <span class="n">-LocalPort</span> <span class="p">&lt;</span><span class="n">Port</span><span class="p">&gt;).</span><span class="py">OwningProcess</span>
</span></span></code></pre></div>]]></content:encoded>
    </item>
    
    <item>
      <title>SSL / TLS</title>
      <link>https://www.rainerrose.de/docs/howto/ssl/</link>
      <pubDate>Thu, 08 Jun 2023 17:42:10 +0200</pubDate>
      <guid>https://www.rainerrose.de/docs/howto/ssl/</guid>
      <description><![CDATA[<!-- Anreißer -->
<p>Ein paar Befehle, die ich immer wieder im Umfeld von TLS bzw. SSL benötige.</p>

<h2 id="selbst-signiertes-zertifikat" data-numberify>selbst signiertes Zertifikat<a class="anchor ms-1" href="#selbst-signiertes-zertifikat"></a></h2>
<p>Alles erstellen (CSR, private key, sign) in einem Schritt:</p>]]></description>
      <content:encoded><![CDATA[<!-- Anreißer -->
<p>Ein paar Befehle, die ich immer wieder im Umfeld von TLS bzw. SSL benötige.</p>

<h2 id="selbst-signiertes-zertifikat" data-numberify>selbst signiertes Zertifikat<a class="anchor ms-1" href="#selbst-signiertes-zertifikat"></a></h2>
<p>Alles erstellen (CSR, private key, sign) in einem Schritt:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">openssl req -new -days <span class="m">999</span> -newkey rsa:4096bits -sha512 -x509 -nodes -out server.crt -keyout server.key
</span></span></code></pre></div>
<blockquote class="alert alert-success" role="alert">
    <p class="alert-heading fw-bold">
      <i class="fas fa-lightbulb me-2"></i>Hinweis
    </p>
    <p>Die <code>999</code> Tage sollte man ggf. ändern. Dateien werden überschrieben, also Obacht!</p>
</blockquote>

<h2 id="öffentlichen--privaten-schlüssel-extrahieren-pkcs12" data-numberify>öffentlichen / privaten Schlüssel extrahieren (PKCS12)<a class="anchor ms-1" href="#öffentlichen--privaten-schlüssel-extrahieren-pkcs12"></a></h2>

<h3 id="privater-schlüssel" data-numberify>privater Schlüssel<a class="anchor ms-1" href="#privater-schlüssel"></a></h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">openssl pkcs12 -in P12Datei.pfx -nocerts -out privateKey.pem
</span></span></code></pre></div>
<h3 id="öffentlicher-schlüssel--zertifikat" data-numberify>öffentlicher Schlüssel / Zertifikat<a class="anchor ms-1" href="#öffentlicher-schlüssel--zertifikat"></a></h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">openssl pkcs12 -in P12Datei.pfx -clcerts -nokeys -out publicKey.pem
</span></span></code></pre></div>
<h3 id="zertifikat-als-plain-text-ausgeben--infos-anzeigen" data-numberify>Zertifikat als plain-text ausgeben / Infos anzeigen<a class="anchor ms-1" href="#zertifikat-als-plain-text-ausgeben--infos-anzeigen"></a></h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">openssl  x509 -noout -text -purpose -in Zertifikat.pem 
</span></span></code></pre></div>
<h3 id="aufbau-datei" data-numberify>Aufbau Datei<a class="anchor ms-1" href="#aufbau-datei"></a></h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="ln">1</span><span class="cl">-----BEGIN CERTIFICATE----
</span></span><span class="line"><span class="ln">2</span><span class="cl">... eigentliches Zertifikat ... 
</span></span><span class="line"><span class="ln">3</span><span class="cl">-----END CERTIFICATE-----
</span></span></code></pre></div>
<h2 id="konvertieren" data-numberify>Konvertieren<a class="anchor ms-1" href="#konvertieren"></a></h2>

<h3 id="pem-nach-der" data-numberify>PEM nach DER<a class="anchor ms-1" href="#pem-nach-der"></a></h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">openssl x509 -outform der -in Zertfikikat.pem -out Zertfikikat.der
</span></span></code></pre></div>
<h3 id="pem-nach-p7b" data-numberify>PEM nach P7B<a class="anchor ms-1" href="#pem-nach-p7b"></a></h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">openssl crl2pkcs7 -nocrl -certfile Zertfikikat.cer -out Zertfikikat.p7b -certfile CAZertifikat.cer
</span></span></code></pre></div>
<h3 id="pem-nach-pfx" data-numberify>PEM nach PFX<a class="anchor ms-1" href="#pem-nach-pfx"></a></h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">openssl pkcs12 -export -out Zertfikikat.pfx -inkey privateKey.key -in Zertfikikat.crt -certfile CAZertifikat.crt
</span></span></code></pre></div>
<h3 id="der-nach-pem" data-numberify>DER nach PEM<a class="anchor ms-1" href="#der-nach-pem"></a></h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">openssl x509 -inform der -in Zertfikikat.cer -out Zertfikikat.pem
</span></span></code></pre></div>
<h3 id="p7b-nach-pem" data-numberify>P7B nach PEM<a class="anchor ms-1" href="#p7b-nach-pem"></a></h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">openssl pkcs7 -print_certs -in Zertfikikat.p7b -out Zertfikikat.cer
</span></span></code></pre></div>
<h3 id="pfxpkcs12-nach-pem" data-numberify>PFX(PKCS#12) nach PEM<a class="anchor ms-1" href="#pfxpkcs12-nach-pem"></a></h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">openssl pkcs12 -in Zertfikikat.pfx -nodes -out Zertfikikat.cer
</span></span></code></pre></div>
<h2 id="dhparam-erzeugen" data-numberify>dhparam erzeugen<a class="anchor ms-1" href="#dhparam-erzeugen"></a></h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">openssl dhparam -out /etc/ssl/dhparam.pem <span class="m">4096</span>
</span></span></code></pre></div>
<h2 id="changelog" data-numberify>Changelog<a class="anchor ms-1" href="#changelog"></a></h2>
<table>
  <thead>
      <tr>
          <th>Datum</th>
          <th>Änderung</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>27.03.2025</td>
          <td>dhparam erzeugen</td>
      </tr>
  </tbody>
</table>]]></content:encoded>
    </item>
    
    <item>
      <title>vim</title>
      <link>https://www.rainerrose.de/docs/linux/vim/</link>
      <pubDate>Thu, 04 May 2023 17:39:42 +0200</pubDate>
      <guid>https://www.rainerrose.de/docs/linux/vim/</guid>
      <description><![CDATA[<!-- Anreißer -->
<p>Tipps und Tricks zum Editor vim.</p>]]></description>
      <content:encoded><![CDATA[<!-- Anreißer -->
<p>Tipps und Tricks zum Editor vim.</p>
<ul>
<li><code>set ignorecase</code> Groß-/Kleinschreibung egal</li>
<li><code>set smartcase</code> wenn Pattern kleingeschrieben: Groß-/Kleinschreibung egal, sonst <em>case sensitive</em></li>
<li><code>:set relativenumber</code> relative Zeilennummern</li>
<li><code>:set number</code> Zeilennummern ein</li>
</ul>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-vim" data-lang="vim"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="k">colorscheme</span> <span class="nx">darkblue</span>
</span></span><span class="line"><span class="ln"> 2</span><span class="cl"><span class="nx">nmap</span> <span class="p">&lt;</span><span class="nx">F8</span><span class="p">&gt;</span> :<span class="nx">TagbarToggle</span>
</span></span><span class="line"><span class="ln"> 3</span><span class="cl"><span class="nx">nmap</span> <span class="p">&lt;</span><span class="nx">F9</span><span class="p">&gt;</span> :<span class="p">!</span><span class="nx">ctags</span> *
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">
</span></span><span class="line"><span class="ln"> 5</span><span class="cl"><span class="k">set</span> <span class="nx">backup</span>
</span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="c">
</span></span></span><span class="line"><span class="ln"> 7</span><span class="cl"><span class="c">&#34; automatically indent lines (default)</span>
</span></span><span class="line"><span class="ln"> 8</span><span class="cl"><span class="c">&#34; set noautoindent</span>
</span></span><span class="line"><span class="ln"> 9</span><span class="cl"><span class="k">set</span> <span class="nx">autoindent</span>
</span></span><span class="line"><span class="ln">10</span><span class="cl"><span class="c">
</span></span></span><span class="line"><span class="ln">11</span><span class="cl"><span class="c">&#34; select case-insenitiv search (not default) set noignorecase</span>
</span></span><span class="line"><span class="ln">12</span><span class="cl"><span class="c">
</span></span></span><span class="line"><span class="ln">13</span><span class="cl"><span class="c">&#34; Suchergebnisse hervorheben</span>
</span></span><span class="line"><span class="ln">14</span><span class="cl"><span class="k">set</span> <span class="nx">hlsearch</span>
</span></span><span class="line"><span class="ln">15</span><span class="cl"><span class="c">
</span></span></span><span class="line"><span class="ln">16</span><span class="cl"><span class="c">&#34; show cursor line and column in the status line set ruler</span>
</span></span><span class="line"><span class="ln">17</span><span class="cl"><span class="c">
</span></span></span><span class="line"><span class="ln">18</span><span class="cl"><span class="c">&#34; show matching brackets</span>
</span></span><span class="line"><span class="ln">19</span><span class="cl"><span class="k">set</span> <span class="nx">showmatch</span>
</span></span><span class="line"><span class="ln">20</span><span class="cl"><span class="c">
</span></span></span><span class="line"><span class="ln">21</span><span class="cl"><span class="c">&#34; show existing tab with 4 spaces width</span>
</span></span><span class="line"><span class="ln">22</span><span class="cl"><span class="k">set</span> <span class="nx">tabstop</span><span class="p">=</span><span class="m">4</span>
</span></span><span class="line"><span class="ln">23</span><span class="cl"><span class="c">&#34; when indenting with &#39;&gt;&#39;, use 4 spaces width set shiftwidth=4 </span>
</span></span><span class="line"><span class="ln">24</span><span class="cl"><span class="c">&#34; On pressing tab, insert 4 spaces set expandtab</span>
</span></span><span class="line"><span class="ln">25</span><span class="cl"><span class="c">
</span></span></span><span class="line"><span class="ln">26</span><span class="cl"><span class="c">&#34; display mode INSERT/REPLACE/...</span>
</span></span><span class="line"><span class="ln">27</span><span class="cl"><span class="k">set</span> <span class="nx">showmode</span>
</span></span><span class="line"><span class="ln">28</span><span class="cl"><span class="c">
</span></span></span><span class="line"><span class="ln">29</span><span class="cl"><span class="c">&#34; changes special characters in search patterns (default)</span>
</span></span><span class="line"><span class="ln">30</span><span class="cl"><span class="c">&#34; set magic</span>
</span></span><span class="line"><span class="ln">31</span><span class="cl"><span class="c">
</span></span></span><span class="line"><span class="ln">32</span><span class="cl"><span class="c">&#34; Required to be able to use keypad keys and map missed escape sequences set esckeys</span>
</span></span><span class="line"><span class="ln">33</span><span class="cl">
</span></span><span class="line"><span class="ln">34</span><span class="cl">
</span></span><span class="line"><span class="ln">35</span><span class="cl"><span class="k">syntax</span> <span class="nx">on</span>
</span></span></code></pre></div>]]></content:encoded>
    </item>
    
    <item>
      <title>less ignore case in searches</title>
      <link>https://www.rainerrose.de/posts/less/</link>
      <pubDate>Thu, 04 May 2023 17:15:15 +0200</pubDate>
      <guid>https://www.rainerrose.de/posts/less/</guid>
      <description><![CDATA[<!-- Anreißer -->
<p>Kleiner Merkzettel, weil ich es immer wieder suche.</p>
<p>Wie ignoriere ich die Groß-/Kleinschreibung bei Suchen in Linux-CLI-Tool <code>less</code> ?</p>]]></description>
      <content:encoded><![CDATA[<!-- Anreißer -->
<p>Kleiner Merkzettel, weil ich es immer wieder suche.</p>
<p>Wie ignoriere ich die Groß-/Kleinschreibung bei Suchen in Linux-CLI-Tool <code>less</code> ?</p>
<p>Da ich mir es anscheinend nicht merken kann, notiere ich mir das jetzt hier.</p>

<h2 id="beispieldatei" data-numberify>Beispieldatei<a class="anchor ms-1" href="#beispieldatei"></a></h2>
<p>Folgende Datei habe ich:</p>
<pre><code>Groß-/Kleinschreibung bei Suchen in less ignorieren
groß-/kleinschreibung bei suchen in less ignorieren
</code></pre>

<h2 id="beispielsuche-case-senstive" data-numberify>Beispielsuche case senstive<a class="anchor ms-1" href="#beispielsuche-case-senstive"></a></h2>
<p>Suche ich jetzt nach <code>groß</code> erhalte ich einen Treffer in der zweiten Zeile:</p>
<p><picture><img class="img-fluid " alt="Beispielsuche für less mit case senstive suche " src="https://www.rainerrose.de/images/posts/less/nur_klein.png?v=fe5314156694cfcc715b7b57c795513e" loading="lazy" width="594" height="90" />
</picture>

</p>

<h2 id="möglichkeit-1-befehlsmodus" data-numberify>Möglichkeit 1: Befehlsmodus<a class="anchor ms-1" href="#möglichkeit-1-befehlsmodus"></a></h2>
<p>Hier den Befehl <code>-i</code> eingeben.</p>
<p>Dann gibt es in der unteren Zeile kurz die Meldung</p>
<pre><code>Ignore case in searches  (press RETURN)
</code></pre>
<p>und nach einer beherzten Druck auf die <code>RETURN</code>-Taste wird bei Suchen die Groß-/Kleinschreibung ignoriert.</p>

<h2 id="möglichkeit-2-direkt-beim-aufruf" data-numberify>Möglichkeit 2: direkt beim Aufruf<a class="anchor ms-1" href="#möglichkeit-2-direkt-beim-aufruf"></a></h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">less -i
</span></span></code></pre></div><p>dann sind sämtliche Suchen sofort <em>case insensitive</em>.</p>

<h2 id="beispielsuche-case-insenstive" data-numberify>Beispielsuche case insenstive<a class="anchor ms-1" href="#beispielsuche-case-insenstive"></a></h2>
<p>Jetzt erhalte ich bei beiden Zeilen einen Treffer:</p>
<p><picture><img class="img-fluid " alt="Beispielsuche für less mit case insenstive suche " src="https://www.rainerrose.de/images/posts/less/insensitive.png?v=533421c7f5097fc4794d45940234b66e" loading="lazy" width="560" height="88" />
</picture>

</p>
<p>Auf dass ich es mir merke oder jemand anderem hilft ;-)</p>]]></content:encoded>
    </item>
    
    <item>
      <title>DU - Disk Usage</title>
      <link>https://www.rainerrose.de/posts/disk-usage/</link>
      <pubDate>Tue, 18 Apr 2023 18:33:57 +0200</pubDate>
      <guid>https://www.rainerrose.de/posts/disk-usage/</guid>
      <description><![CDATA[<!-- Anreißer -->
<p>Jeder, der schon mal nach großen Platzverschwendern gesucht hat, kennt vermutlich das Tool <code>du</code> .</p>
<p>Dort lässt sich mit den Parametern <code>-s</code> und <code>-k</code> und einem Pipe nach <code>sort</code> sich nach Größe sortieren, aber mir fällt es immer etwas schwer zu erkennen, sind das noch MB oder schon GB?</p>]]></description>
      <content:encoded><![CDATA[<!-- Anreißer -->
<p>Jeder, der schon mal nach großen Platzverschwendern gesucht hat, kennt vermutlich das Tool <code>du</code> .</p>
<p>Dort lässt sich mit den Parametern <code>-s</code> und <code>-k</code> und einem Pipe nach <code>sort</code> sich nach Größe sortieren, aber mir fällt es immer etwas schwer zu erkennen, sind das noch MB oder schon GB?</p>

<h2 id="beispiel" data-numberify>Beispiel<a class="anchor ms-1" href="#beispiel"></a></h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">du -sk /usr/* 2&gt;/dev/null<span class="p">|</span> sort -n 
</span></span></code></pre></div>
<h3 id="ausgabe" data-numberify>Ausgabe<a class="anchor ms-1" href="#ausgabe"></a></h3>
<pre><code>0	/usr/lib64
0	/usr/sbin
40	/usr/local
96	/usr/src
393732	/usr/include
484820	/usr/lib32
1337084	/usr/bin
4228972	/usr/share
8205192	/usr/lib
</code></pre>

<h2 id="schönere-ausgabe" data-numberify>Schönere Ausgabe<a class="anchor ms-1" href="#schönere-ausgabe"></a></h2>
<p>Persönlich finde ich die obige Ausgabe nicht schön zu lesen. Mittels des Tools <code>numfmt</code> lässt sich das etwas hübsche aufbereiten.</p>
<p><strong>Wichtig</strong> hierbei ist, dass  der Parameter <code>-b</code> statt <code>-k</code> verwendet wird.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">du -sb /usr/* <span class="p">|</span> sort -n <span class="p">|</span> numfmt --to<span class="o">=</span>iec
</span></span></code></pre></div><pre><code>3 /usr/lib64
3 /usr/sbin
1,1K /usr/local
79K /usr/src
300M /usr/include
472M /usr/lib32
1,3G /usr/bin
3,5G /usr/share
7,6G /usr/lib
</code></pre>

<h2 id="in-spalten-bitte" data-numberify>In Spalten bitte<a class="anchor ms-1" href="#in-spalten-bitte"></a></h2>
<p>Mittels <code>column</code> lässt sich sogar noch eine Spaltigkeit herstellen</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">du -sb * <span class="p">|</span> sort -n <span class="p">|</span> numfmt --to<span class="o">=</span>iec <span class="p">|</span> column -t 
</span></span></code></pre></div><pre><code>3     /usr/lib64
3     /usr/sbin
1,1K  /usr/local
79K   /usr/src
300M  /usr/include
472M  /usr/lib32
1,3G  /usr/bin
3,5G  /usr/share
7,6G  /usr/lib
</code></pre>

<h2 id="in-alias-auslagern" data-numberify>In “alias” auslagern<a class="anchor ms-1" href="#in-alias-auslagern"></a></h2>
<p>Damit man sich den Befehl nicht merken muss, kann dies in ein bash-Alias ausgelagert werden, zum Beispiel so:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl"><span class="nb">alias</span> <span class="nv">sft</span><span class="o">=</span><span class="s2">&#34;sort -n | numfmt --to=iec | column -t&#34;</span>
</span></span></code></pre></div><p>Würde dann später so aussehen.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">du -sb /usr/* <span class="p">|</span> sft
</span></span></code></pre></div><pre><code>0     /usr/lib64
0     /usr/sbin
40    /usr/local
96    /usr/src
385K  /usr/include
474K  /usr/lib32
1,3M  /usr/bin
4,1M  /usr/share
7,9M  /usr/lib
</code></pre>
<p>Ewentewell lagert man das <code>du</code>-Kommando ebenfalls aus, da ich gerne den Parameter <code>-b</code></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl"><span class="k">function</span> sft<span class="o">()</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="o">{</span>
</span></span><span class="line"><span class="ln">3</span><span class="cl">    du -sb <span class="s2">&#34;</span><span class="nv">$@</span><span class="s2">&#34;</span> <span class="p">|</span> sort -n <span class="p">|</span> numfmt --to<span class="o">=</span>iec <span class="p">|</span> column -t
</span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="o">}</span>
</span></span></code></pre></div><p>Ja, ich weiß, es gibt <code>ncdu</code>; ggf. geht damit auch was; ewentewell sogar in Scripten.</p>
<p>Habe per Zufall <code>numfmt</code> entdeckt und brauchte es in einen anderen Kontext und wollte mal zeigen, was damit möglich ist.</p>]]></content:encoded>
    </item>
    
    <item>
      <title>AlmaLinux</title>
      <link>https://www.rainerrose.de/docs/linux/almalinux/</link>
      <pubDate>Mon, 17 Apr 2023 23:25:49 +0200</pubDate>
      <guid>https://www.rainerrose.de/docs/linux/almalinux/</guid>
      <description><![CDATA[<!-- Anreißer -->
<p>Ich sehe mir gerade eine weitere Linux-Distribution an: AlmaLinux.</p>
<p>Auf ein paar Stolpersteine bin ich schon gestoßen:</p>]]></description>
      <content:encoded><![CDATA[<!-- Anreißer -->
<p>Ich sehe mir gerade eine weitere Linux-Distribution an: AlmaLinux.</p>
<p>Auf ein paar Stolpersteine bin ich schon gestoßen:</p>

<h2 id="moreutils-package-broken" data-numberify>Moreutils package broken<a class="anchor ms-1" href="#moreutils-package-broken"></a></h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">dnf install -y moreutils
</span></span></code></pre></div><p>fällt auf die Nase.</p>

<h3 id="reparatur" data-numberify>Reparatur<a class="anchor ms-1" href="#reparatur"></a></h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">dnf install --enablerepo<span class="o">=</span>crb moreutils
</span></span></code></pre></div>]]></content:encoded>
    </item>
    
    <item>
      <title>OSI-Modell Layer 8 und 9</title>
      <link>https://www.rainerrose.de/posts/osi-modell-layer-8-und-9/</link>
      <pubDate>Sun, 12 Feb 2023 22:59:26 +0100</pubDate>
      <guid>https://www.rainerrose.de/posts/osi-modell-layer-8-und-9/</guid>
      <description><![CDATA[<!-- Anreißer -->
<p><em>+++ EIL ++++ EIL ++++ EIL +++</em></p>
<p>Es gibt neue Layer im OSI-Modell! Nummer Acht und Nummer Neun.</p>]]></description>
      <content:encoded><![CDATA[<!-- Anreißer -->
<p><em>+++ EIL ++++ EIL ++++ EIL +++</em></p>
<p>Es gibt neue Layer im OSI-Modell! Nummer Acht und Nummer Neun.</p>
<table>
  <thead>
      <tr>
          <th>Layer</th>
          <th>Type</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>9</td>
          <td>Organisation</td>
      </tr>
      <tr>
          <td>8</td>
          <td>People</td>
      </tr>
      <tr>
          <td>7</td>
          <td>Application</td>
      </tr>
      <tr>
          <td>6</td>
          <td>Presentation</td>
      </tr>
      <tr>
          <td>5</td>
          <td>Session</td>
      </tr>
      <tr>
          <td>4</td>
          <td>Transport</td>
      </tr>
      <tr>
          <td>3</td>
          <td>Network</td>
      </tr>
      <tr>
          <td>2</td>
          <td>Data Link</td>
      </tr>
      <tr>
          <td>1</td>
          <td>Physical</td>
      </tr>
  </tbody>
</table>]]></content:encoded>
    </item>
    
    <item>
      <title>Docker Registry</title>
      <link>https://www.rainerrose.de/docs/linux/docker-registry/</link>
      <pubDate>Sun, 05 Feb 2023 23:13:34 +0100</pubDate>
      <guid>https://www.rainerrose.de/docs/linux/docker-registry/</guid>
      <description><![CDATA[<!-- Anreißer -->
<p>Docker-Images lassen sich in verschiedene Registrys legen.</p>

<h2 id="beispiel-gitlab" data-numberify>Beispiel: GitLab<a class="anchor ms-1" href="#beispiel-gitlab"></a></h2>]]></description>
      <content:encoded><![CDATA[<!-- Anreißer -->
<p>Docker-Images lassen sich in verschiedene Registrys legen.</p>

<h2 id="beispiel-gitlab" data-numberify>Beispiel: GitLab<a class="anchor ms-1" href="#beispiel-gitlab"></a></h2>
<ol>
<li>Zuerst <a href="https://tools.rainerrose.de/redirect.php?id=16" target="_blank" rel="noopener noreferrer">Token erstellen<i class="fas fa-external-link-square-alt ms-1"></i></a> im Gitlab</li>
<li>Sinnvollen <em>token name</em> vergeben</li>
<li>Scopes ankreuzen
<ul>
<li><input checked="" disabled="" type="checkbox"> read_registry</li>
<li><input checked="" disabled="" type="checkbox"> write_registry</li>
</ul>
</li>
<li>Ablaufdatum wählen</li>
<li>Tocken erstellen</li>
<li>Eingabe-Box unterhalb <code>Your new personal access token</code> unbedingt kopieren und in einen Passwort-Manager ablegen</li>
</ol>

<h3 id="registry-login" data-numberify>Registry Login<a class="anchor ms-1" href="#registry-login"></a></h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">docker login registry.gitlab.com -u rainerrose
</span></span></code></pre></div><p>Das dann abgefrage Passwor entspricht dem generierte Tocken.</p>

<h2 id="image-bauen" data-numberify>Image bauen<a class="anchor ms-1" href="#image-bauen"></a></h2>

<h3 id="ohne-tag" data-numberify>Ohne Tag<a class="anchor ms-1" href="#ohne-tag"></a></h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">docker build -t registry.gitlab.com/rainerrose/&lt;projekt-name&gt; .
</span></span></code></pre></div>
<h3 id="mit-tag" data-numberify>Mit Tag<a class="anchor ms-1" href="#mit-tag"></a></h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">docker build -t registry.gitlab.com/rainerrose/&lt;projekt-name&gt;:1.1 .
</span></span></code></pre></div>
<h2 id="hochladen" data-numberify>Hochladen<a class="anchor ms-1" href="#hochladen"></a></h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">docker push <span class="o">[</span>OPTIONS<span class="o">]</span> NAME<span class="o">[</span>:TAG<span class="o">]</span>
</span></span></code></pre></div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">docker push registry.gitlab.com/rainerrose/&lt;projekt-name&gt; --all-tags
</span></span></code></pre></div>]]></content:encoded>
    </item>
    
    <item>
      <title>LVM</title>
      <link>https://www.rainerrose.de/docs/linux/lvm/</link>
      <pubDate>Sun, 05 Feb 2023 23:39:46 +0200</pubDate>
      <guid>https://www.rainerrose.de/docs/linux/lvm/</guid>
      <description><![CDATA[<!-- Anreißer -->
<p>HowTos zum Umgang des Logical Volume Manager (LVM)</p>]]></description>
      <content:encoded><![CDATA[<!-- Anreißer -->
<p>HowTos zum Umgang des Logical Volume Manager (LVM)</p>

<h2 id="vorwissen-und-ausführliche-doku" data-numberify>Vorwissen und ausführliche Doku<a class="anchor ms-1" href="#vorwissen-und-ausführliche-doku"></a></h2>
<p>Mehr Doku in c&rsquo;t 2005 Heft 25 Seiten 232-236 &ldquo;Teile und herrsche&rdquo; oder online
im <a href="https://tools.rainerrose.de/redirect.php?id=18" target="_blank" rel="noopener noreferrer">wiki.ubuntuusers.de<i class="fas fa-external-link-square-alt ms-1"></i></a>.</p>

<h2 id="partitionen" data-numberify>Partitionen<a class="anchor ms-1" href="#partitionen"></a></h2>

<blockquote class="alert alert-warning" role="alert">
    <p class="alert-heading fw-bold">
      <i class="fas fa-exclamation-circle me-2"></i>Tipp
    </p>
    <p>Vorher Gedanken machen wie erweitert werden soll.</p>
</blockquote>

<h3 id="a-platz-ranhängen" data-numberify>a) Platz ranhängen<a class="anchor ms-1" href="#a-platz-ranhängen"></a></h3>
<p>Platten unter ESX können &quot;physikalisch&quot; <strong>nur</strong> größer gemacht werden.
Drangehängt ist dran, geht auch nicht mehr weg.</p>
<ol>
<li>Platte rescan (siehe unten)</li>
<li>Partition erstellen mittels <code>parted</code></li>
<li>Volume Gruppe und / oder Logical Volume vergrößern</li>
</ol>

<blockquote class="alert alert-success" role="alert">
    <p class="alert-heading fw-bold">
      <i class="fas fa-lightbulb me-2"></i>Tipp
    </p>
    <p>Sind alle 4 Partitionen erstellt und keine weitere mehr möglich ?
<a href="https://tools.rainerrose.de/redirect.php?id=19" target="_blank" rel="noopener noreferrer">GParted-Live-CD<i class="fas fa-external-link-square-alt ms-1"></i></a> einlegen, ggf.
Boot-Reihenfolge umstellen, Distribution booten und Partition
vergrößern.</p>
</blockquote>

<h3 id="b-neue-platte" data-numberify>b) neue Platte<a class="anchor ms-1" href="#b-neue-platte"></a></h3>
<p>Ggf. &quot;<em>echte</em>&quot; <strong>zusätzliche</strong> ranhängen, z.B. bei max. 4 Partitionen
bei DOS-MBR-Format unter BIOS statt UEFI. Diese können dann als Physical
Volume in die Volume-Gruppe aufgenommen werden.</p>
<p>Hierbei entsteht ein neues Device z.B. <code>/dev/sdb</code>, welches dann wieder
partitioniert werden kann. Es entsteht unter ESX dann eine neue
VMDK-Datei.</p>

<h2 id="festplatte-rescan" data-numberify>Festplatte rescan<a class="anchor ms-1" href="#festplatte-rescan"></a></h2>
<p>Lässt sich easy online / live machen</p>

<blockquote class="alert alert-warning" role="alert">
    <p class="alert-heading fw-bold">
      <i class="fas fa-exclamation-circle me-2"></i>Warnung
    </p>
    <p>Entsprechendes Device setzen <code>sda</code> !</p>
</blockquote>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl"><span class="nb">echo</span> <span class="m">1</span> &gt; /sys/block/sda/device/rescan 
</span></span></code></pre></div><p>Alternativ (untested!)</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl"><span class="nb">echo</span> <span class="m">1</span> &gt; /sys/class/scsi_device/<span class="o">[</span>h:c:t:l<span class="o">]</span>/device/rescan
</span></span></code></pre></div><p>Dann sollte mit <code>parted -l</code></p>
<p>die neue Größe erkennbar sein</p>

<h2 id="physical-volume-initialisieren" data-numberify>Physical Volume initialisieren<a class="anchor ms-1" href="#physical-volume-initialisieren"></a></h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">sudo pvcreate /dev/PARTITION
</span></span></code></pre></div>
<h2 id="volume-gruppe-vergrößern" data-numberify>Volume Gruppe vergrößern<a class="anchor ms-1" href="#volume-gruppe-vergrößern"></a></h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">sudo vgextend GROUPNAME /dev/PARTITION
</span></span></code></pre></div>
<h2 id="logical-volume-vergrößern" data-numberify>Logical Volume vergrößern<a class="anchor ms-1" href="#logical-volume-vergrößern"></a></h2>

<h3 id="hinweis" data-numberify>Hinweis<a class="anchor ms-1" href="#hinweis"></a></h3>
<p>Bei <strong>Offline</strong>-Vergrößerungen vorher alle Prozesse beenden, die auf den
verwendeten Mountpoint (z.B. <code>/daten</code>) zugreifen (cronjobs nicht
vergessen).</p>

<blockquote class="alert alert-success" role="alert">
    <p class="alert-heading fw-bold">
      <i class="fas fa-lightbulb me-2"></i>Tipp
    </p>
    <p>Welche Dateisysteme kann ich wann vergrößern, siehe
<a href="https://tools.rainerrose.de/redirect.php?id=20" target="_blank" rel="noopener noreferrer">wiki.ubuntuusers.de<i class="fas fa-external-link-square-alt ms-1"></i></a></p>
</blockquote>

<h3 id="langer-weg" data-numberify>langer Weg<a class="anchor ms-1" href="#langer-weg"></a></h3>
<pre><code>$ lvs|grep daten
  daten   vg01 -wi-ao---- 600,00g
$ umount /daten
$ lvresize -v -L +200G /dev/vg01/daten
$ fsck.ext4 -f /dev/vg01/daten
$ lvs | grep daten
  daten   vg01 -wi-a----- 800,00g
$ resize2fs /dev/vg01/daten 800G
$ mount /daten
$ df -h /daten
Dateisystem            Größe Benutzt Verf. Verw% Eingehängt auf
/dev/mapper/vg01-daten  788G    540G  208G   73% /daten
</code></pre>

<h2 id="kurzer-weg" data-numberify>kurzer Weg<a class="anchor ms-1" href="#kurzer-weg"></a></h2>
<pre><code>$ lvs|grep daten
  daten   vg01 -wi-ao---- 600,00g
$ umount /daten
$ fsck.ext4 -f /dev/vg01/daten
$ lvextend --resizefs -v -L +200G /dev/vg01/daten
$ lvs | grep daten
  daten   vg01 -wi-a----- 800,00g
$ mount /daten
$ df -h /daten
Dateisystem            Größe Benutzt Verf. Verw% Eingehängt auf
/dev/mapper/vg01-daten  788G    540G  208G   73% /daten
</code></pre>

<h2 id="xfs-partition-mit-lvm-vergrößern" data-numberify>XFS-Partition mit LVM vergrößern<a class="anchor ms-1" href="#xfs-partition-mit-lvm-vergrößern"></a></h2>

<blockquote class="alert alert-success" role="alert">
    <p class="alert-heading fw-bold">
      <i class="fas fa-lightbulb me-2"></i>Tipp
    </p>
    <p>Geht online.</p>
</blockquote>
<pre><code># lvextend -L+40G /dev/vg0/var
# xfs_growfs /var
</code></pre>

<blockquote class="alert alert-warning" role="alert">
    <p class="alert-heading fw-bold">
      <i class="fas fa-question-circle me-2"></i>Achtung!
    </p>
    <p><code>XFS</code>-Filesysteme können nur <strong>vergrößert</strong>, nicht verkleinert werden.</p>
</blockquote>

<h2 id="logical-volume-erstellen" data-numberify>Logical Volume erstellen<a class="anchor ms-1" href="#logical-volume-erstellen"></a></h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">lvcreate -L 2G -n VOLUMENAME GROUPNAME
</span></span></code></pre></div><p>Formatieren nicht vergesssen!</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">mkfs.ext4 -f /dev/vg01/musik
</span></span></code></pre></div>]]></content:encoded>
    </item>
    
    <item>
      <title>AWK</title>
      <link>https://www.rainerrose.de/docs/linux/awk/</link>
      <pubDate>Thu, 08 Dec 2022 22:50:57 +0100</pubDate>
      <guid>https://www.rainerrose.de/docs/linux/awk/</guid>
      <description><![CDATA[<!-- Anreißer -->
<p>Tipps und Tricks zur Programmiersprache awk zur Bearbeitung oder Ausgabe von Textdateien</p>]]></description>
      <content:encoded><![CDATA[<!-- Anreißer -->
<p>Tipps und Tricks zur Programmiersprache awk zur Bearbeitung oder Ausgabe von Textdateien</p>

<h2 id="beispieldatei" data-numberify>Beispieldatei<a class="anchor ms-1" href="#beispieldatei"></a></h2>
<p>Inhalt von der Datei <code>t.txt</code>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-t.txt" data-lang="t.txt"><span class="line"><span class="ln">1</span><span class="cl">1 2 3 4
</span></span><span class="line"><span class="ln">2</span><span class="cl">a1 b1 c1 d1
</span></span><span class="line"><span class="ln">3</span><span class="cl">a2 b2 c2 d2
</span></span></code></pre></div>
<h2 id="klassiker-erste-drei-spalten" data-numberify>Klassiker: erste drei Spalten<a class="anchor ms-1" href="#klassiker-erste-drei-spalten"></a></h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">awk <span class="s1">&#39;{print $1,$2,$3}&#39;</span> t.txt
</span></span></code></pre></div>
<h3 id="ausgabe" data-numberify>Ausgabe<a class="anchor ms-1" href="#ausgabe"></a></h3>
<pre><code>1 2 3
a1 b1 c1
a2 b2 c2
</code></pre>

<h2 id="alle-spalten-bis-auf-die-letzte" data-numberify>Alle Spalten bis auf die letzte<a class="anchor ms-1" href="#alle-spalten-bis-auf-die-letzte"></a></h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">awk <span class="s1">&#39;{for(i=1;i&lt;=NF-1;i++) printf $i&#34; &#34;; print &#34;&#34;}&#39;</span> t.txt
</span></span></code></pre></div>
<h3 id="ausgabe-1" data-numberify>Ausgabe<a class="anchor ms-1" href="#ausgabe-1"></a></h3>
<pre><code>1 2 3
a1 b1 c1
a2 b2 c2
</code></pre>]]></content:encoded>
    </item>
    
    <item>
      <title>grub</title>
      <link>https://www.rainerrose.de/docs/linux/grub/</link>
      <pubDate>Thu, 01 Dec 2022 22:48:01 +0100</pubDate>
      <guid>https://www.rainerrose.de/docs/linux/grub/</guid>
      <description><![CDATA[<!-- Anreißer -->
<p>Tipps und Tricks zu Boot-Manager <code>grub2</code></p>]]></description>
      <content:encoded><![CDATA[<!-- Anreißer -->
<p>Tipps und Tricks zu Boot-Manager <code>grub2</code></p>

<h2 id="temporär-anderes-os-booten-beim-reboot" data-numberify>Temporär anderes OS booten beim Reboot<a class="anchor ms-1" href="#temporär-anderes-os-booten-beim-reboot"></a></h2>
<p>Ersten Eintrag beim nächsten Boot auswählen:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">grub-reboot <span class="m">0</span>
</span></span></code></pre></div>
<h2 id="boote-beim-nächsten-mal-ins-bios--efi-setup" data-numberify>Boote beim Nächsten mal ins BIOS / EFI-Setup<a class="anchor ms-1" href="#boote-beim-nächsten-mal-ins-bios--efi-setup"></a></h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">systemctl reboot --firmware-setup
</span></span></code></pre></div>
<h3 id="alternativ" data-numberify>Alternativ<a class="anchor ms-1" href="#alternativ"></a></h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">efibootmgr -n &lt;int&gt;
</span></span></code></pre></div><p>Meist ist der Integer <code>0</code>.</p>

<h3 id="original-doku" data-numberify>Original-Doku<a class="anchor ms-1" href="#original-doku"></a></h3>
<p>Findet sich auf <a href="https://tools.rainerrose.de/redirect.php?id=44" target="_blank" rel="noopener noreferrer">www.freedesktop.org<i class="fas fa-external-link-square-alt ms-1"></i></a>.</p>

<h2 id="update-grub-config" data-numberify>Update Grub-Config<a class="anchor ms-1" href="#update-grub-config"></a></h2>
<p><code>update-grub</code></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">grub-mkconfig -o /boot/grub/grub.cfg
</span></span></code></pre></div>
<h2 id="changelog" data-numberify>Changelog<a class="anchor ms-1" href="#changelog"></a></h2>
<table>
  <thead>
      <tr>
          <th>Datum</th>
          <th>Änderung</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>16.11.2024</td>
          <td>BIOS-EFI-Tipp und Doku-link hinzugefügt.</td>
      </tr>
      <tr>
          <td>23.12.2024</td>
          <td>Update Grub-Config</td>
      </tr>
  </tbody>
</table>]]></content:encoded>
    </item>
    
    <item>
      <title>XFCE</title>
      <link>https://www.rainerrose.de/docs/linux/xfce/</link>
      <pubDate>Thu, 01 Dec 2022 22:41:47 +0100</pubDate>
      <guid>https://www.rainerrose.de/docs/linux/xfce/</guid>
      <description><![CDATA[<!-- Anreißer -->
<p>Tipps und Tricks zu XFCE</p>]]></description>
      <content:encoded><![CDATA[<!-- Anreißer -->
<p>Tipps und Tricks zu XFCE</p>

<h2 id="bildschirmlupe--zoom" data-numberify>Bildschirmlupe / Zoom<a class="anchor ms-1" href="#bildschirmlupe--zoom"></a></h2>
<p>Zum  Zoom rein und raus in XFCE</p>
<p><code>ALT</code>-Taste gedrückt halten und Mausrad drehen.</p>]]></content:encoded>
    </item>
    
    <item>
      <title>Profil</title>
      <link>https://www.rainerrose.de/docs/howto/mastodon/profil/</link>
      <pubDate>Mon, 28 Nov 2022 17:43:22 +0200</pubDate>
      <guid>https://www.rainerrose.de/docs/howto/mastodon/profil/</guid>
      <description><![CDATA[<!-- Anreißer -->
<p>Die Liste wird immer mal wieder erweitert; dabei wird dann hier das Datum einfach aktualisiert.</p>]]></description>
      <content:encoded><![CDATA[<!-- Anreißer -->
<p>Die Liste wird immer mal wieder erweitert; dabei wird dann hier das Datum einfach aktualisiert.</p>

<h2 id="tabellenfelder" data-numberify>Tabellenfelder<a class="anchor ms-1" href="#tabellenfelder"></a></h2>
<p><code>Einstellungen</code> -&gt; <code>Profil</code> -&gt; <code>Erscheinungsbild</code></p>
<p>Z.B.</p>
<ul>
<li>Featured Hashtags (siehe oben)</li>
<li>Webseiten</li>
</ul>
<ul>
<li>Attribute, die einem wichtig sind oder prominent platziert werden sollen</li>
</ul>
<p>Hier kann auch der &ldquo;Grüne Haken&rdquo; gesetzt werden. Dazu muss auf dem Webseiten-Quellcode jedoch Zugriff bestehen.</p>

<h3 id="featuren-von-profilen" data-numberify>Featuren von Profilen<a class="anchor ms-1" href="#featuren-von-profilen"></a></h3>
<p>Im jeweiligen Profil auf die drei Punkte gehen und im Menü &ldquo;Im Profil hervorheben&rdquo; auswählen.</p>

<blockquote class="alert alert-success" role="alert">
    <p class="alert-heading fw-bold">
      <i class="fas fa-lightbulb me-2"></i>Info
    </p>
    <p>Bis zu vier Accounts werden angezeigt. Bei mehr werden daraus bei jedem Aufruf zufällig vier angezeigt.</p>
</blockquote>

<h2 id="featured-hashtags" data-numberify>Featured Hashtags<a class="anchor ms-1" href="#featured-hashtags"></a></h2>
<p>Man kann im Profil wichtige Hashtags anpinnen, unter denen man viel Tröötet.</p>

<h2 id="creds" data-numberify>Creds<a class="anchor ms-1" href="#creds"></a></h2>
<p>Das ist nicht alles auf meinem Mist gewachsen, sondern es ist ein Zusammenschrieb von unterschiedlichen Beiträgen (Toots bzw. Trööts).</p>
<p>Da ich die Loorberen nicht allein ernten will seien folgende Beiträge lobend erwähnt, wo ich schamlos geklaut habe:</p>
<ul>
<li><a href="https://tools.rainerrose.de/redirect.php?id=24" target="_blank" rel="noopener noreferrer">https://chaos.social/@Pertsch/109364783333410682<i class="fas fa-external-link-square-alt ms-1"></i></a></li>
<li><a href="https://tools.rainerrose.de/redirect.php?id=25" target="_blank" rel="noopener noreferrer">https://mastodon.social/@bkastl/109324608994865848<i class="fas fa-external-link-square-alt ms-1"></i></a></li>
<li><a href="https://tools.rainerrose.de/redirect.php?id=26" target="_blank" rel="noopener noreferrer">https://social.tchncs.de/@kaffeeringe/109318992205459828<i class="fas fa-external-link-square-alt ms-1"></i></a></li>
<li><a href="https://tools.rainerrose.de/redirect.php?id=27" target="_blank" rel="noopener noreferrer">https://www.mastodonien.de/einstiegshilfe/<i class="fas fa-external-link-square-alt ms-1"></i></a></li>
</ul>]]></content:encoded>
    </item>
    
    <item>
      <title>Posten / Trööten</title>
      <link>https://www.rainerrose.de/docs/howto/mastodon/posten/</link>
      <pubDate>Mon, 28 Nov 2022 17:42:22 +0200</pubDate>
      <guid>https://www.rainerrose.de/docs/howto/mastodon/posten/</guid>
      <description><![CDATA[<!-- Anreißer -->
<p>Kochrezepte, Tipps und Hinweise zu Mastodon als kleine Sammlung.</p>
<p>Die Liste wird immer mal wieder erweitert; dabei wird dann hier das Datum einfach aktualisiert.</p>]]></description>
      <content:encoded><![CDATA[<!-- Anreißer -->
<p>Kochrezepte, Tipps und Hinweise zu Mastodon als kleine Sammlung.</p>
<p>Die Liste wird immer mal wieder erweitert; dabei wird dann hier das Datum einfach aktualisiert.</p>

<h2 id="hashtags" data-numberify>Hashtags<a class="anchor ms-1" href="#hashtags"></a></h2>
<p>Unbedingt nutzen, da es (noch?) keine Volltext-Suche gibt und auch keine Algorithmen die Interessen auswerten und vorschlagen.
Beiträge die Tags verwenden lassen sich verfolgen und leichter finden im Fediverse.</p>
<p>Beispiel <tt style='color:blue;'>#hashtag</tt><tt>​s</tt></p>

<h3 id="mehrzahl--einzahl--grundform" data-numberify>Mehrzahl / Einzahl / Grundform<a class="anchor ms-1" href="#mehrzahl--einzahl--grundform"></a></h3>
<p>Wenn nur einen Teil eines Wortes als <code>#Hashtag</code> gesetzt werden soll  (z. B. für die Grundform), dann das <a href="https://tools.rainerrose.de/redirect.php?id=23" target="_blank" rel="noopener noreferrer">breitenlose Leerzeichen<i class="fas fa-external-link-square-alt ms-1"></i></a> einfügen für einen nahtlosen Übergang ein.</p>

<h2 id="creds" data-numberify>Creds<a class="anchor ms-1" href="#creds"></a></h2>
<p>Das ist nicht alles auf meinem Mist gewachsen, sondern es ist ein Zusammenschrieb von unterschiedlichen Beiträgen (Toots bzw. Trööts).</p>
<p>Da ich die Lorbeeren nicht allein ernten will seien folgende Beiträge lobend erwähnt, wo ich schamlos geklaut habe:</p>
<ul>
<li><a href="https://tools.rainerrose.de/redirect.php?id=24" target="_blank" rel="noopener noreferrer">https://chaos.social/@Pertsch/109364783333410682<i class="fas fa-external-link-square-alt ms-1"></i></a></li>
<li><a href="https://tools.rainerrose.de/redirect.php?id=25" target="_blank" rel="noopener noreferrer">https://mastodon.social/@bkastl/109324608994865848<i class="fas fa-external-link-square-alt ms-1"></i></a></li>
<li><a href="https://tools.rainerrose.de/redirect.php?id=26" target="_blank" rel="noopener noreferrer">https://social.tchncs.de/@kaffeeringe/109318992205459828<i class="fas fa-external-link-square-alt ms-1"></i></a></li>
<li><a href="https://tools.rainerrose.de/redirect.php?id=27" target="_blank" rel="noopener noreferrer">https://www.mastodonien.de/einstiegshilfe/<i class="fas fa-external-link-square-alt ms-1"></i></a></li>
</ul>]]></content:encoded>
    </item>
    
    <item>
      <title>Entdecken</title>
      <link>https://www.rainerrose.de/docs/howto/mastodon/entdecken/</link>
      <pubDate>Mon, 28 Nov 2022 17:41:22 +0200</pubDate>
      <guid>https://www.rainerrose.de/docs/howto/mastodon/entdecken/</guid>
      <description><![CDATA[<!-- Anreißer -->
<p>Die Liste wird immer mal wieder erweitert; dabei wird dann hier das Datum einfach aktualisiert.</p>]]></description>
      <content:encoded><![CDATA[<!-- Anreißer -->
<p>Die Liste wird immer mal wieder erweitert; dabei wird dann hier das Datum einfach aktualisiert.</p>

<h2 id="entdecken-ab-version-4" data-numberify>Entdecken ab Version 4<a class="anchor ms-1" href="#entdecken-ab-version-4"></a></h2>

<h3 id="profilverzeichnis" data-numberify>Profilverzeichnis<a class="anchor ms-1" href="#profilverzeichnis"></a></h3>
<p>Jede Instanz kann ein Profilverzeichnis haben, sonfern angegeben wurde, dass man gelistet werden möchte.</p>
<p>Beispiel: <a href="https://tools.rainerrose.de/redirect.php?id=21" target="_blank" rel="noopener noreferrer">https://norden.social/directory<i class="fas fa-external-link-square-alt ms-1"></i></a></p>
<p><picture><img class="img-fluid " alt="Auswahlmenü mit mehreren Optionen zum Profil durchsuchen. Kürzlich aktiv. Neue Profile. Nur von der Domain norden.social . Oder: Aus dem Fediverse" src="https://www.rainerrose.de/images/docs/profile-durchsuchen.png?v=c2f90ae1e77c30a722cf029b03dd4346" loading="lazy" width="450" height="278" />
</picture>

</p>
<p>Eingestellt wird dies unter den <code>Einstellungen</code> -&gt; <code>Profil</code> und dann dort den Haken setzen bei <code>Dieses Profil im Profilverzeichnis zeigen</code>, wenn man gelistet werden möchte.</p>

<h3 id="tags" data-numberify>Tags<a class="anchor ms-1" href="#tags"></a></h3>
<p>Trends in den Tags via <code>#Entdecken</code> -&gt; <code>Hashtags</code></p>
<p>Beispiel <a href="https://tools.rainerrose.de/redirect.php?id=22" target="_blank" rel="noopener noreferrer">https://norden.social/explore/tags<i class="fas fa-external-link-square-alt ms-1"></i></a></p>
<p><picture><img class="img-fluid " alt="tag liste mit Beschreibungen und einem kleinem Chart" src="https://www.rainerrose.de/images/docs/trends-hastags.png?v=13edcf3c7249e10210df15414843fc3c" loading="lazy" width="456" height="503" />
</picture>

</p>

<h2 id="rss" data-numberify>RSS<a class="anchor ms-1" href="#rss"></a></h2>
<p>Die Beiträge eines Kontos lassen sich als RSS-Feed abbonnieren. Es muss nur ein <code>.rss</code> an die URL des Profils rangehängt werden.</p>
<p><code>https://norden.social/@Kaffee_Junkie42</code> wird zu <code>https://norden.social/@Kaffee_Junkie42.rss</code></p>

<h2 id="eigene-beiträge" data-numberify>Eigene Beiträge<a class="anchor ms-1" href="#eigene-beiträge"></a></h2>
<p>Die eigenen Beiträge lassen sich anzeigen, in dem <code>from:me</code> in die Suchleiste angegeben wird.</p>

<h2 id="creds" data-numberify>Creds<a class="anchor ms-1" href="#creds"></a></h2>
<p>Das ist nicht alles auf meinem Mist gewachsen, sondern es ist ein Zusammenschrieb von unterschiedlichen Beiträgen (Toots bzw. Trööts).</p>
<p>Da ich die Lorbeeren nicht allein ernten will seien folgende Beiträge lobend erwähnt, wo ich schamlos geklaut habe:</p>
<ul>
<li><a href="https://tools.rainerrose.de/redirect.php?id=24" target="_blank" rel="noopener noreferrer">https://chaos.social/@Pertsch/109364783333410682<i class="fas fa-external-link-square-alt ms-1"></i></a></li>
<li><a href="https://tools.rainerrose.de/redirect.php?id=25" target="_blank" rel="noopener noreferrer">https://mastodon.social/@bkastl/109324608994865848<i class="fas fa-external-link-square-alt ms-1"></i></a></li>
<li><a href="https://tools.rainerrose.de/redirect.php?id=26" target="_blank" rel="noopener noreferrer">https://social.tchncs.de/@kaffeeringe/109318992205459828<i class="fas fa-external-link-square-alt ms-1"></i></a></li>
<li><a href="https://tools.rainerrose.de/redirect.php?id=27" target="_blank" rel="noopener noreferrer">https://www.mastodonien.de/einstiegshilfe/<i class="fas fa-external-link-square-alt ms-1"></i></a></li>
<li><a href="https://tools.rainerrose.de/redirect.php?id=52" target="_blank" rel="noopener noreferrer">https://social.tchncs.de/@cark/114796294158937637<i class="fas fa-external-link-square-alt ms-1"></i></a></li>
</ul>]]></content:encoded>
    </item>
    
    <item>
      <title>Backup</title>
      <link>https://www.rainerrose.de/docs/howto/mastodon/backup/</link>
      <pubDate>Mon, 28 Nov 2022 17:40:22 +0200</pubDate>
      <guid>https://www.rainerrose.de/docs/howto/mastodon/backup/</guid>
      <description><![CDATA[<!-- Anreißer -->
<p>Kochrezepte, Tipps und Hinweise zu Mastodon als kleine Sammlung.</p>
<p>Die Liste wird immer mal wieder erweitert; dabei wird dann hier das Datum einfach aktualisiert.</p>]]></description>
      <content:encoded><![CDATA[<!-- Anreißer -->
<p>Kochrezepte, Tipps und Hinweise zu Mastodon als kleine Sammlung.</p>
<p>Die Liste wird immer mal wieder erweitert; dabei wird dann hier das Datum einfach aktualisiert.</p>
<p>Unter <code>Einstel­lungen</code> -&gt; <code>Import und Export</code>  -&gt; <code>Export</code> können auch die anderen Daten­kate­gorien (außer Medien) im CSV-Format herun­terge­laden werden, wie Blockierte Accounts, Listen oder Lese­zei­chen. Und das nicht nur, um sie bei einem geplanten Umzug ins neue Konto zu impor­tieren.</p>
<p>Regel­mäßige Backups sind auch wichtig für den Fall, dass die Instanz, auf der man ange­meldet ist, einmal über­raschend abge­schaltet werden sollte. Alle Daten­kate­gorien inklu­sive Medi­enspei­cher können <strong>einmal wöchent­lich</strong> als Archiv herun­ter­geladen werden. Die Zusammenstellung dauert einen Moment und der Download-Link wird per E-Mail zugesendet.</p>]]></content:encoded>
    </item>
    
    <item>
      <title>Hinweis zur Aufteilung im neuen Layout</title>
      <link>https://www.rainerrose.de/posts/hinweis/</link>
      <pubDate>Wed, 16 Nov 2022 22:39:30 +0200</pubDate>
      <guid>https://www.rainerrose.de/posts/hinweis/</guid>
      <description><![CDATA[<!-- Anreißer -->
<p>Ein kleiner Hinweis zur Aufteilung. Es gibt <a href="/posts/">Blogposts</a>, als auch die alte Sammlung unter <a href="/docs/">/docs/</a>.</p>]]></description>
      <content:encoded><![CDATA[<!-- Anreißer -->
<p>Ein kleiner Hinweis zur Aufteilung. Es gibt <a href="/posts/">Blogposts</a>, als auch die alte Sammlung unter <a href="/docs/">/docs/</a>.</p>
<p>Nach der Umgestaltung meiner Homepage, habe ich jetzt zwei Bereiche.</p>
<ol>
<li>Sie untergliedert sich jetzt in einzelnen Post</li>
<li>Die Wiki-Artikel sind jetzt in einzele <a href="/docs/">Dokumente</a> mit z.T. neuer Sortierung.</li>
</ol>
<p>Die alten Bookmarks bzw. Lesezeichen funktionieren weiterhin, da eine Umleitung stattfindet.</p>]]></content:encoded>
    <enclosure url="https://www.rainerrose.de/wallpaper/neues-layout.png" length="12524" type="image/.png" />
    </item>
    
    <item>
      <title>Vertical Mouse</title>
      <link>https://www.rainerrose.de/docs/linux/evoluent-verticalmouse-3/</link>
      <pubDate>Mon, 04 Apr 2022 23:12:30 +0200</pubDate>
      <guid>https://www.rainerrose.de/docs/linux/evoluent-verticalmouse-3/</guid>
      <description><![CDATA[<!-- Anreißer -->
<p>Es ist etwas fummelig, aber ich habe die <em>Evoluent VerticalMouse 3</em> unter Linux zum Laufen bekommen.</p>]]></description>
      <content:encoded><![CDATA[<!-- Anreißer -->
<p>Es ist etwas fummelig, aber ich habe die <em>Evoluent VerticalMouse 3</em> unter Linux zum Laufen bekommen.</p>
<p>Für die ersten Konfigurationsschritte empfiehlt sich erstmal ein
Terminal, um die <code>Device-ID</code> herauszufinden.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">xinput list <span class="p">|</span> grep Evoluent
</span></span></code></pre></div><p>Beispiel-Ausgabe:</p>
<pre><code>Kingsis Peripherals Evoluent VerticalMouse 3 id=12 [slave pointer (2)]
</code></pre>
<p>Die ID <code>12</code> merken wir uns.</p>
<table>
  <thead>
      <tr>
          <th>Button</th>
          <th>ID</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Daumen</td>
          <td>9</td>
      </tr>
      <tr>
          <td>Zeigefinger</td>
          <td>1</td>
      </tr>
      <tr>
          <td>Mittelfinger</td>
          <td>8</td>
      </tr>
      <tr>
          <td>Ringfinger</td>
          <td>3</td>
      </tr>
      <tr>
          <td>Wheel Button</td>
          <td>2</td>
      </tr>
      <tr>
          <td>Wheel hoch</td>
          <td>4</td>
      </tr>
      <tr>
          <td>Wheel runter</td>
          <td>5</td>
      </tr>
      <tr>
          <td>Wheel links</td>
          <td>6</td>
      </tr>
      <tr>
          <td>Wheel rechts</td>
          <td>7</td>
      </tr>
  </tbody>
</table>
<table>
  <thead>
      <tr>
          <th>ID</th>
          <th>Button</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>1</td>
          <td>Links-Klick</td>
      </tr>
      <tr>
          <td>2</td>
          <td>Mittel-Klick</td>
      </tr>
      <tr>
          <td>3</td>
          <td>Rechts-Klick</td>
      </tr>
      <tr>
          <td>4</td>
          <td>Rad hoch</td>
      </tr>
      <tr>
          <td>5</td>
          <td>Rad runter</td>
      </tr>
      <tr>
          <td>6</td>
          <td>Rad links</td>
      </tr>
      <tr>
          <td>7</td>
          <td>Rad rechts</td>
      </tr>
      <tr>
          <td>8</td>
          <td>Daumen 1</td>
      </tr>
      <tr>
          <td>9</td>
          <td>Daumen 2</td>
      </tr>
      <tr>
          <td>10</td>
          <td>Extra Button 7</td>
      </tr>
      <tr>
          <td>11</td>
          <td>Extra Button 8</td>
      </tr>
  </tbody>
</table>
<p>Im Grunde zählt man stumpf die Buttons auf der Maus von links nach
rechts.</p>
<p>Ich habe es jetzt so gesetzt, dass der schmale Button, wo der Daumen
sitzt, der &ldquo;Zurück&rdquo;-Button ist.</p>
<p>Der Linksklick liegt auf dem Zeigefinger, Rechtsklick auf dem
Mittelfinger, das &ldquo;Maus-Rad drücken&rdquo; sowie der Ringfinger ist ein
Mittel-Klick. Den Rest habe ich beim Standard belassen (also Maus-Rad
rauf und runter belassen).</p>
<p>Jetzt erst einmal ausprobieren.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl"><span class="c1">#              input id: 1 2 3 4 5 6 7 8 9</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl">xinput set-button-map <span class="m">12</span> <span class="m">1</span> <span class="m">2</span> <span class="m">3</span> <span class="m">4</span> <span class="m">5</span> <span class="m">6</span> <span class="m">7</span> <span class="m">2</span> <span class="m">8</span>
</span></span></code></pre></div><p>Damit es den nächsten Reboot überlebt noch in die X11-Konfig übernehmen.</p>
<p>Zuerst einmal die USB-ID herausfinden</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">lsusb <span class="p">|</span> grep Evoluent
</span></span></code></pre></div><p><code>Bus 003 Device 005: ID 1a7c:0068 Evoluent VerticalMouse 3</code></p>
<p>Dieses jetzt festhalten:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">sudo touch /usr/share/X11/xorg.conf.d/90-evoluent.conf
</span></span><span class="line"><span class="ln">2</span><span class="cl">sudo vi /usr/share/X11/xorg.conf.d/90-evoluent.conf
</span></span></code></pre></div><p>Hierbei jeweils die ID <code>1a7c:0068</code> anpassen.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="ln">1</span><span class="cl">Section &#34;InputClass&#34;
</span></span><span class="line"><span class="ln">2</span><span class="cl">Identifier &#34;Evoluent&#34;
</span></span><span class="line"><span class="ln">3</span><span class="cl">MatchUSBID &#34;1a7c:0068&#34;
</span></span><span class="line"><span class="ln">4</span><span class="cl">Option &#34;ButtonMapping&#34; &#34;1 2 3 4 5 6 7 2 8&#34;
</span></span><span class="line"><span class="ln">5</span><span class="cl">EndSection
</span></span></code></pre></div><p>Fertig. Das war&rsquo;s. :-D</p>]]></content:encoded>
    </item>
    
    <item>
      <title>Ansible</title>
      <link>https://www.rainerrose.de/docs/linux/ansible/</link>
      <pubDate>Wed, 26 Jan 2022 17:22:53 +0100</pubDate>
      <guid>https://www.rainerrose.de/docs/linux/ansible/</guid>
      <description><![CDATA[<!-- Anreißer -->
<p>Ansible Notizen und Code-Stücke, die ich immer wieder brauche &amp; vergesse.</p>]]></description>
      <content:encoded><![CDATA[<!-- Anreißer -->
<p>Ansible Notizen und Code-Stücke, die ich immer wieder brauche &amp; vergesse.</p>

<h2 id="ansible-vault" data-numberify>Ansible-Vault<a class="anchor ms-1" href="#ansible-vault"></a></h2>
<p>Mit dem Tool können Passwörter verschlüsselt im Verzeichnis-Baum des
Ansible-Playbooks bzw. des Ansible-Inventories liegen.</p>
<p>Allerdings hat die Ansible-Yaml-Loading-Engine hat einen Detector, dass
alles was nach Vault aussieht, on-the-lfy decrypted wird - falls es den
Key hat. Danach sieht das Ansible nur noch den Klar-Text-YAML-Content
(ohne irgendein Crypto)</p>
<p>Sofern man in seiner <code>ansible.cfg</code> die Option</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ini" data-lang="ini"><span class="line"><span class="ln">1</span><span class="cl"><span class="na">log_path</span><span class="o">=</span><span class="s">~/log/ansible.log</span>
</span></span></code></pre></div><p>gesetzt hat, landen diese Klartext-Informationen sogar im Logfile -
unschön.</p>
<p>Um das zu vermeiden, kann die Option no_log: true gesetzt werden.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="ln">1</span><span class="cl"><span class="w">    </span>- <span class="nt">debug</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="w">        </span><span class="nt">msg</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;Geheim {{ansible_host}} &#34;</span><span class="w">
</span></span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="w">      </span><span class="nt">no_log</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span></code></pre></div><p>Danach sieht der Output nur noch folgendermaßen aus:</p>
<pre><code>PLAY RECAP *****************************************************************************************************************************************************
meinServerName              : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
</code></pre>
<p>Alternativ kann das Passwort auch während des Playbook-Laufs interaktiv
angefragt werden.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="ln">1</span><span class="cl"><span class="w">  </span><span class="nt">vars_prompt</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="w">    </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">api_key</span><span class="w">
</span></span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="w">      </span><span class="nt">prompt</span><span class="p">:</span><span class="w"> </span><span class="l">Enter the API key</span><span class="w">
</span></span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="w">  </span><span class="nt">tasks</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="ln">5</span><span class="cl"><span class="w">    </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Ensure API key is present in config file</span><span class="w">
</span></span></span><span class="line"><span class="ln">6</span><span class="cl"><span class="w">      </span><span class="nt">ansible.builtin.lineinfile</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="ln">7</span><span class="cl"><span class="w">        </span><span class="nt">path</span><span class="p">:</span><span class="w"> </span><span class="l">/etc/app/configuration.ini</span><span class="w">
</span></span></span><span class="line"><span class="ln">8</span><span class="cl"><span class="w">        </span><span class="nt">line</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;API_KEY={{ api_key }}&#34;</span><span class="w">
</span></span></span></code></pre></div><p>Überhaupt ist die interaktive Variante eine coole Sache, um z.B.
abzufragen, ob gewisse Dinge in Playbooks passieren sollen (z.B. Restart
j/n von $DINGEN nach Updates)</p>
<p>Mehr Doku wie z.B: die Einbindung von Passwort-Managern hier:
<a href="https://tools.rainerrose.de/redirect.php?id=17" target="_blank" rel="noopener noreferrer">https://www.redhat.com/sysadmin/ansible-playbooks-secrets<i class="fas fa-external-link-square-alt ms-1"></i></a></p>]]></content:encoded>
    </item>
    
    <item>
      <title>Screen</title>
      <link>https://www.rainerrose.de/docs/linux/screen/</link>
      <pubDate>Mon, 20 Dec 2021 23:03:55 +0100</pubDate>
      <guid>https://www.rainerrose.de/docs/linux/screen/</guid>
      <description><![CDATA[<!-- Anreißer -->
<p>Tipps zum Tool <code>screen</code>.</p>]]></description>
      <content:encoded><![CDATA[<!-- Anreißer -->
<p>Tipps zum Tool <code>screen</code>.</p>

<h2 id="starten-einer-neuen-sitzung" data-numberify>Starten einer neuen Sitzung<a class="anchor ms-1" href="#starten-einer-neuen-sitzung"></a></h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">screen -DRS sessionName
</span></span></code></pre></div><p>Credits: Die Parameter <code>-D</code> und <code>-R</code> habe ich in <a href="https://tools.rainerrose.de/redirect.php?id=43" target="_blank" rel="noopener noreferrer">Mariannes Blog-Artikel<i class="fas fa-external-link-square-alt ms-1"></i></a>  kennen gelernt.</p>

<h2 id="trennen" data-numberify>Trennen<a class="anchor ms-1" href="#trennen"></a></h2>
<p><code>Strg</code> + <code>A</code> + <code>D</code></p>

<h2 id="nimmt-die-sitzung-wieder-auf" data-numberify>Nimmt die Sitzung wieder auf<a class="anchor ms-1" href="#nimmt-die-sitzung-wieder-auf"></a></h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">screen -r &lt;sessionName&gt;
</span></span></code></pre></div>
<h2 id="auflisten" data-numberify>Auflisten<a class="anchor ms-1" href="#auflisten"></a></h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">screen -ls 
</span></span></code></pre></div>
<h2 id="trennen-wenn-hängen-geblieben" data-numberify>Trennen, wenn hängen geblieben<a class="anchor ms-1" href="#trennen-wenn-hängen-geblieben"></a></h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">screen -d sessionName 
</span></span></code></pre></div>
<h2 id="an-mehreren-computern-gleichzeitig-anzeigen" data-numberify>An mehreren Computern gleichzeitig anzeigen<a class="anchor ms-1" href="#an-mehreren-computern-gleichzeitig-anzeigen"></a></h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">screen -rx sessionName 
</span></span></code></pre></div>
<h2 id="navigieren" data-numberify>Navigieren<a class="anchor ms-1" href="#navigieren"></a></h2>
<p><strong>Zuerst</strong> den <code>Copy</code>-Mode betreten mit <code>CTRL-A</code> gefolgt von <code>[</code>.</p>
<table>
  <thead>
      <tr>
          <th>Kürzel</th>
          <th>Bedeutung</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>CTRL-u</code></td>
          <td>Bildschirmseite nach oben / <code>up</code> (Cursorposition beibehalten)</td>
      </tr>
      <tr>
          <td><code>CTRL-d</code></td>
          <td>Bildschirmseite nach unten / <code>down</code> (Cursorposition beibehalten)</td>
      </tr>
      <tr>
          <td><code>CTRL-b</code></td>
          <td>Bildschirmseite nach oben</td>
      </tr>
      <tr>
          <td><code>CTRL-f</code></td>
          <td>Bildschirmseite nach unten</td>
      </tr>
  </tbody>
</table>
<p>Ansonsten viel wie in <code>vi</code>:</p>
<table>
  <thead>
      <tr>
          <th>Kürzel</th>
          <th>Bedeutung</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>&lt;zahl&gt;%</code></td>
          <td>Springt zu <code>&lt;zahl&gt;</code> prozentual zum Buffer</td>
      </tr>
      <tr>
          <td><code>/&lt;pattern&gt;</code></td>
          <td>Sucht nach <code>&lt;Pattern&gt;</code></td>
      </tr>
      <tr>
          <td><code>/&lt;pattern&gt;</code></td>
          <td>Rückwärtssuche</td>
      </tr>
      <tr>
          <td><code>w</code></td>
          <td>Ein Wort <strong>w</strong>eiterspringen</td>
      </tr>
      <tr>
          <td><code>b</code></td>
          <td>Ein Wort zurück aka <code>back</code></td>
      </tr>
      <tr>
          <td><code>g</code></td>
          <td>Zum Be<strong>g</strong>inn des Buffers springen</td>
      </tr>
      <tr>
          <td><code>$</code></td>
          <td>Zum Zeilenende springen</td>
      </tr>
      <tr>
          <td><code>^</code></td>
          <td>Zum Zeilenanfang springen</td>
      </tr>
  </tbody>
</table>
<p>Gibt noch mehr, Rest kann sich eh keiner merken ;-)</p>

<h2 id="changelog" data-numberify>Changelog<a class="anchor ms-1" href="#changelog"></a></h2>
<table>
  <thead>
      <tr>
          <th>Datum</th>
          <th>Änderung</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>31.10.2024</td>
          <td>Parameter <code>-D</code> und <code>-R</code> hinzugefügt beim Abschnitt &ldquo;Starten einer neuen Sitzung&rdquo;</td>
      </tr>
      <tr>
          <td>27.03.2025</td>
          <td>Neuer Abschnitt: Navigation im Screen Copy-Mode</td>
      </tr>
  </tbody>
</table>]]></content:encoded>
    </item>
    
    <item>
      <title>jq</title>
      <link>https://www.rainerrose.de/docs/linux/jq/</link>
      <pubDate>Tue, 19 Oct 2021 21:22:30 +0200</pubDate>
      <guid>https://www.rainerrose.de/docs/linux/jq/</guid>
      <description><![CDATA[<!-- Anreißer -->
<p><code>jq</code> ist ein kleiner und flexibler command-line JSON processor.</p>]]></description>
      <content:encoded><![CDATA[<!-- Anreißer -->
<p><code>jq</code> ist ein kleiner und flexibler command-line JSON processor.</p>

<h2 id="beispiel" data-numberify>Beispiel<a class="anchor ms-1" href="#beispiel"></a></h2>

<h3 id="config-file-auslesen" data-numberify>Config-File auslesen<a class="anchor ms-1" href="#config-file-auslesen"></a></h3>
<p>Pro System ein Pfad. Unterschied zwischen Prod und Dev inkl.
Umgebungsvariablen auslesen.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl"><span class="cp">#!/usr/bin/bash
</span></span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="cp"></span><span class="nv">CONFIGFILE</span><span class="o">=</span><span class="s2">&#34;config.rc.json&#34;</span>
</span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="nv">ZIELSYTEM</span><span class="o">=</span><span class="s2">&#34;prodsysteme&#34;</span>
</span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="nv">ZIELSYTEM</span><span class="o">=</span><span class="s2">&#34;devsysteme&#34;</span>
</span></span><span class="line"><span class="ln">5</span><span class="cl"><span class="k">for</span> SystemArt in <span class="k">$(</span>jq -r <span class="s2">&#34;.</span><span class="nv">$ZIELSYTEM</span><span class="s2">[] | .name&#34;</span> <span class="si">${</span><span class="nv">CONFIGFILE</span><span class="si">}</span> <span class="k">)</span>
</span></span><span class="line"><span class="ln">6</span><span class="cl"><span class="k">do</span>
</span></span><span class="line"><span class="ln">7</span><span class="cl">    <span class="nv">PFAD</span><span class="o">=</span><span class="k">$(</span>jq -r --arg SystemArt <span class="s2">&#34;</span><span class="si">${</span><span class="nv">SystemArt</span><span class="si">}</span><span class="s2">&#34;</span> <span class="s2">&#34;.</span><span class="nv">$ZIELSYTEM</span><span class="s2">[] | select (.name==\&#34;</span><span class="nv">$SystemArt</span><span class="s2">\&#34;)| .pfad &#34;</span> <span class="nv">$CONFIGFILE</span> <span class="k">)</span>
</span></span><span class="line"><span class="ln">8</span><span class="cl">    <span class="nb">echo</span> <span class="s2">&#34;system </span><span class="nv">$SystemArt</span><span class="s2"> auf </span><span class="nv">$PFAD</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="ln">9</span><span class="cl"><span class="k">done</span>
</span></span></code></pre></div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">    <span class="nt">&#34;devsysteme&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">        <span class="p">{</span>
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">            <span class="nt">&#34;name&#34;</span><span class="p">:</span> <span class="s2">&#34;local&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">            <span class="nt">&#34;pfad&#34;</span><span class="p">:</span> <span class="s2">&#34;/mnt&#34;</span>
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">        <span class="p">},</span>
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">        <span class="p">{</span>
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">            <span class="nt">&#34;name&#34;</span><span class="p">:</span> <span class="s2">&#34;test1&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">            <span class="nt">&#34;pfad&#34;</span><span class="p">:</span> <span class="s2">&#34;/mnt_gibt_es_nicht&#34;</span>
</span></span><span class="line"><span class="ln">10</span><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="ln">11</span><span class="cl">    <span class="p">],</span>
</span></span><span class="line"><span class="ln">12</span><span class="cl">    <span class="nt">&#34;prodsysteme&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="ln">13</span><span class="cl">        <span class="p">{</span>
</span></span><span class="line"><span class="ln">14</span><span class="cl">            <span class="nt">&#34;name&#34;</span><span class="p">:</span> <span class="s2">&#34;prod&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="ln">15</span><span class="cl">            <span class="nt">&#34;pfad&#34;</span><span class="p">:</span> <span class="s2">&#34;/mnt&#34;</span>
</span></span><span class="line"><span class="ln">16</span><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="ln">17</span><span class="cl">    <span class="p">]</span>
</span></span><span class="line"><span class="ln">18</span><span class="cl"><span class="p">}</span>
</span></span></code></pre></div>]]></content:encoded>
    </item>
    
    <item>
      <title>Dokuwiki</title>
      <link>https://www.rainerrose.de/docs/howto/dokuwiki/</link>
      <pubDate>Tue, 05 Oct 2021 16:41:57 +0100</pubDate>
      <guid>https://www.rainerrose.de/docs/howto/dokuwiki/</guid>
      <description><![CDATA[<!-- Anreißer -->
<p>Notizen zur Webanwendung Dokuwiki.</p>]]></description>
      <content:encoded><![CDATA[<!-- Anreißer -->
<p>Notizen zur Webanwendung Dokuwiki.</p>

<h2 id="urls" data-numberify>URLs<a class="anchor ms-1" href="#urls"></a></h2>
<ul>
<li><a href="https://tools.rainerrose.de/redirect.php?id=4" target="_blank" rel="noopener noreferrer">https://www.dokuwiki.org/de:rewrite<i class="fas fa-external-link-square-alt ms-1"></i></a></li>
</ul>

<h2 id="plugins" data-numberify>Plugins<a class="anchor ms-1" href="#plugins"></a></h2>
<ul>
<li><a href="https://tools.rainerrose.de/redirect.php?id=5" target="_blank" rel="noopener noreferrer">https://www.dokuwiki.org/plugin:ifauthex<i class="fas fa-external-link-square-alt ms-1"></i></a></li>
<li>Backlinks</li>
<li>Bureaucracy Plugin</li>
<li><a href="https:*tools.rainerrose.de/redirect.php?id=6">catlist</a></li>
<li>ckgedit</li>
<li>Cloud Plugin</li>
<li>Color Plugin</li>
<li>Color Picker</li>
<li>Flowchartjs Plugin</li>
<li>include plugin</li>
<li>Indexmenu Plugin</li>
<li>keyboard</li>
<li>Lightbox for images</li>
<li>Move plugin</li>
<li>Note Plugin</li>
<li>Page Index</li>
<li>Pagelist Plugin</li>
<li>Inline Page Modifier</li>
<li>PageQuery Plugin</li>
<li>sortablejs</li>
<li>Tag Plugin</li>
<li>ToDo</li>
<li>widearea plugin</li>
<li>Wrap Plugin</li>
</ul>

<h2 id="sidebar" data-numberify>sidebar<a class="anchor ms-1" href="#sidebar"></a></h2>
<pre><code>{{indexmenu&gt;:#1|js#thread navbar context tsort}}
</code></pre>

<h2 id="edit-button" data-numberify>edit-Button<a class="anchor ms-1" href="#edit-button"></a></h2>
<pre><code>&lt;ifauth @user&gt;
[[:dokuwiki_doku.php?id=sidebar&amp;do=edit|{{:edit.png?nolink&amp;16}}]] [[:sidebar|Edit Sidebar]]
&lt;/ifauth&gt;
</code></pre>

<h2 id="tags-verwenden" data-numberify>TAGs verwenden<a class="anchor ms-1" href="#tags-verwenden"></a></h2>
<pre><code>{{tag&gt;[list of tags]}}
</code></pre>

<h2 id="auflistung-verwendeter-tags" data-numberify>Auflistung verwendeter TAGs<a class="anchor ms-1" href="#auflistung-verwendeter-tags"></a></h2>
<pre><code>{{searchtags}}
</code></pre>

<h2 id="tagcloud" data-numberify>TAGCLOUD<a class="anchor ms-1" href="#tagcloud"></a></h2>
<pre><code>~~TAGCLOUD~~
</code></pre>

<h2 id="sequenzdiagramme" data-numberify>Sequenzdiagramme<a class="anchor ms-1" href="#sequenzdiagramme"></a></h2>
<p>Basieren auf der Bibliothek
<a href="https://tools.rainerrose.de/redirect.php?id=7" target="_blank" rel="noopener noreferrer">js-sequence-diagrams<i class="fas fa-external-link-square-alt ms-1"></i></a>.</p>

<h2 id="code" data-numberify>Code<a class="anchor ms-1" href="#code"></a></h2>
<pre><code>&lt;sequencediagram&gt;
  Title: Der Titel
  A-&gt;B: Normale Linie
  B--&gt;C: Gestrichelte Linie
  C-&gt;&gt;D: Pfeilspitze offen
  Note right of D: Und wieder zurück
  D--&gt;&gt;A: Gestrichelte Linie Pfeilspitze offen
&lt;/sequencediagram&gt;
</code></pre>

<h2 id="tastenkürzel--tastenkombi" data-numberify>Tastenkürzel / Tastenkombi<a class="anchor ms-1" href="#tastenkürzel--tastenkombi"></a></h2>
<p>This displays the keys <code>ALT</code> + <code>H</code> .</p>
<pre><code>This displays the keys &lt;kbd&gt;ALT&lt;/kbd&gt; + &lt;kbd&gt;H&lt;/kbd&gt;.
</code></pre>
<p>Kürzer:</p>
<pre><code>This displays the keys &lt;kbd&gt;ALT+H&lt;/kbd&gt;.
</code></pre>
<p>Tipp: <code>ALT+-</code></p>
<pre><code>&lt;kbd&gt;ALT+-&lt;/kbd&gt;
</code></pre>

<h2 id="hinweisboxen-anlegen" data-numberify>Hinweisboxen anlegen<a class="anchor ms-1" href="#hinweisboxen-anlegen"></a></h2>

<h3 id="beispiele" data-numberify>Beispiele<a class="anchor ms-1" href="#beispiele"></a></h3>
<p>Classic</p>
<pre><code>&lt;note&gt; Classic &lt;/note&gt;
</code></pre>
<p>Important</p>
<pre><code>&lt;note important&gt; Important &lt;/note&gt;
</code></pre>
<p>Warning</p>
<pre><code>&lt;note warning&gt; Warning &lt;/note&gt;
</code></pre>
<p>Tip</p>
<pre><code>&lt;note tip&gt; Tip &lt;/note&gt;
</code></pre>

<h2 id="farben" data-numberify>Farben<a class="anchor ms-1" href="#farben"></a></h2>
<table>
  <thead>
      <tr>
          <th>Im Editor einzugeben</th>
          <th>Erläuterung</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>&lt;color green&gt;text&lt;/color&gt;</code></td>
          <td>Nur Textfarbe ändern</td>
      </tr>
      <tr>
          <td><code>&lt;color blue/lightgrey&gt;text&lt;/color&gt;</code></td>
          <td>Textfarbe und Texthintergrund ändern</td>
      </tr>
      <tr>
          <td><code>&lt;color /lightgrey&gt;text&lt;/color&gt;</code></td>
          <td>nur Texthintergrund ändern</td>
      </tr>
      <tr>
          <td><code>&lt;color #FF0000&gt;text&lt;/color&gt;</code></td>
          <td>Angabe in RGB-Notation</td>
      </tr>
      <tr>
          <td><code>&lt;color /#FFff00&gt;text&lt;/color&gt;</code></td>
          <td>Texthintergrund ändern in RGB-Notation</td>
      </tr>
  </tbody>
</table>

<h2 id="flowcharts" data-numberify>Flowcharts<a class="anchor ms-1" href="#flowcharts"></a></h2>
<p>Die Flowcharts basieren auf der Bibliothek
<a href="https://tools.rainerrose.de/redirect.php?id=8" target="_blank" rel="noopener noreferrer">http://flowchart.js.org<i class="fas fa-external-link-square-alt ms-1"></i></a></p>

<h3 id="code-1" data-numberify>Code<a class="anchor ms-1" href="#code-1"></a></h3>
<pre><code>&lt;flowchartjs default&gt;
  st=&gt;start: Start
  e=&gt;end: Ende
  con1=&gt;condition: Kennste 
  Flowcharts?
  con2=&gt;condition: Weißte wie
  es geht?
  op1=&gt;operation: Informieren (Klick):&gt;https://de.wikipedia.org/wiki/Programmablaufplan[blank]
  op2=&gt;operation: Informieren (Klick):&gt;http://flowchart.js.org[blank]
  io1=&gt;inputoutput: Flowchart tippen
  op3=&gt;operation: Freuen
  
  st-&gt;con1
  con1(no)-&gt;op1-&gt;con2
  con1(yes)-&gt;con2
  con2(no)-&gt;op2-&gt;io1-&gt;op3-&gt;e
  con2(yes)-&gt;io1
&lt;/flowchartjs&gt;
</code></pre>]]></content:encoded>
    </item>
    
    <item>
      <title>Liebe Headhunter*Innen</title>
      <link>https://www.rainerrose.de/posts/liebe-headhunter-innen/</link>
      <pubDate>Fri, 30 Apr 2021 23:13:18 +0100</pubDate>
      <guid>https://www.rainerrose.de/posts/liebe-headhunter-innen/</guid>
      <description><![CDATA[<!-- Anreißer -->
<p>Hallo Headhunter*in,</p>
<p>da es anscheinend üblich ist als Anrede das persönliche <em>Du</em> zu verwenden, mache ich das jetzt auch. Alle anderen mögen bitte eine adHoc-Transformation ins förmliche <em>Sie</em> beim Lesen durchführen.</p>
<p>Wenn Du einen Link auf diese Seite bekomme hast, dann treffen meist eine der folgenden Bedingungen zu (oder auch gerne alle):</p>
<ul>
<li>Mein Profil wurde nur grob gescannt</li>
<li>Keine inhaltliche Auseinandersetzung zu meinen Skills</li>
<li>Reines Keyword-Matching</li>
<li>Standard-Text-Blöcke</li>
<li>Ich habe gerade einen neuen Job</li>
</ul>
<p>Alles heißt: Du hast Dich nicht genug oder überhaupt nicht mit meinem Profil beschäftigt.
Wahrscheinlich ist wieder kurz vor Quartals-Ende? Und vielfach erhalte ich Anfragen, kurz nachdem ich meinen Job gewechselt habe. Guckt bitte mal in meinen Lebenslauf, dafür habe ich ihn gepflegt. Mal ehrlich: Warum sollte ich in meiner Probezeit wechseln? Oder nach 12 oder 24 Monaten? Stell Dir bitte die Frage „Ist der vorliegende Kandidat ein Nach-dem-Kalender-Wechsler-Typ?“ Mit einem Blick in den CV sollte die Frage selbst beantwortbar sein.</p>
<p>Wenn wirkliches Interesse an meiner Person, dann hier gerne weiter lesen.</p>]]></description>
      <content:encoded><![CDATA[<!-- Anreißer -->
<p>Hallo Headhunter*in,</p>
<p>da es anscheinend üblich ist als Anrede das persönliche <em>Du</em> zu verwenden, mache ich das jetzt auch. Alle anderen mögen bitte eine adHoc-Transformation ins förmliche <em>Sie</em> beim Lesen durchführen.</p>
<p>Wenn Du einen Link auf diese Seite bekomme hast, dann treffen meist eine der folgenden Bedingungen zu (oder auch gerne alle):</p>
<ul>
<li>Mein Profil wurde nur grob gescannt</li>
<li>Keine inhaltliche Auseinandersetzung zu meinen Skills</li>
<li>Reines Keyword-Matching</li>
<li>Standard-Text-Blöcke</li>
<li>Ich habe gerade einen neuen Job</li>
</ul>
<p>Alles heißt: Du hast Dich nicht genug oder überhaupt nicht mit meinem Profil beschäftigt.
Wahrscheinlich ist wieder kurz vor Quartals-Ende? Und vielfach erhalte ich Anfragen, kurz nachdem ich meinen Job gewechselt habe. Guckt bitte mal in meinen Lebenslauf, dafür habe ich ihn gepflegt. Mal ehrlich: Warum sollte ich in meiner Probezeit wechseln? Oder nach 12 oder 24 Monaten? Stell Dir bitte die Frage „Ist der vorliegende Kandidat ein Nach-dem-Kalender-Wechsler-Typ?“ Mit einem Blick in den CV sollte die Frage selbst beantwortbar sein.</p>
<p>Wenn wirkliches Interesse an meiner Person, dann hier gerne weiter lesen.</p>
<p>Ich suche keine Stelle, für die ich oder meine Familie ihre Heimat verlassen muss. Das bedeutet, wenn diese Stelle nicht in einer Stunde Weg um meinen aktuellen Wohnort herum liegt, würde für mich nur ein Remote Arbeitsplatz mit gelegentlichen Besuchen im Büro infrage kommen. Ein Umzug würde dafür sorgen, das sich meine Frau ebenfalls eine neue unbefristete Stelle suchen muss und meine Kinder eine gute Schule in der Nähe brauchen. Außerdem benötigen wir eine bezahlbare Bleibe mit guter Infrastruktur und öffentlichen Verkehrsmitteln sowie weiteren Anforderungen.
Eine Fernbeziehung bzw. Wochend-Papa ist für mich eigentlich kaum vorstellbar. Ein Umzug muss da schon sehr lukrativ sein, um andere familiären Bände zu verlängern.</p>
<p>Werde ich pendeln müssen, würde ich es begrüßen, wenn das Unternehmen sich zumindest daran beteiligt. Ebenfalls muss ich so flexibel sein, dass ich bei Krankheit oder sonstigen Umständen von zu Hause arbeiten kann. Die letzte bzw. aktuelle Pandemie hat es gezeigt, dass sogar monatelanges HomeOffice möglich sein muss (und damit meine ich kein mobiles Arbeiten!), das schließt einen Laptop, zwei Bildschirme und höhenverstellbaren Schreibtisch ein – zu Hause; im Büro gehe ich davon aus. Auf Großraumbüros habe ich keine Lust mehr; die aktuelle Pandemie zeigt es gerade: aus gesundheitlichen Gründen keine gute Idee.
Auch habe ich mir in der Pandemie 100%-Remote-Work angewöhnt und finde es ganz wunderbar.
(Work-Live-Balance)
Weiterhin möchte ich nicht dazu genötigt werden, bis übermorgen aktuelle Unterlagen einzureichen – erfahrungsgemäß steckt da nur der Quartals-Abschluss-Druck von dir oder der HR-Abteilung dahinter – Rückmeldungen gab es leider vielfach von Kolleg*Innen aus deiner Branche nicht.
Ich habe nichts dagegen Bereitschaft zu übernehmen, aber das sollte nicht als selbstverständlich angesehen werden. Hier sollte es faire und transparente Regeln zu geben und es muss sich auch finanziell bemerkbar machen.</p>
<p>Schlussendlich sollte die finanzielle Seite passen. Die aktuelle Rahmenbedingungen, wie auch Wochenarbeitsstunden und die tariflichen Sicherheiten meines Arbeitgebers sind kein Geheimnis und recherchierbar.</p>
<p>Prinzipiell habe ich immer Interesse daran von neuen Herausforderungen zu hören - aber du solltest etwas wissen. Erst wenn das alles matched und die aktuelle unbefristete Stelle übertrifft, dann freue ich mich ab einem Plus von 20% beim Salär über weitere Details.</p>
<p>Mit freundlichen Grüßen</p>
<p>Rainer Rose</p>]]></content:encoded>
    </item>
    
    <item>
      <title>RasPi/Kodi/LibreELEC</title>
      <link>https://www.rainerrose.de/docs/linux/kodi-raspi-libreelec/</link>
      <pubDate>Thu, 24 Sep 2020 23:20:43 +0200</pubDate>
      <guid>https://www.rainerrose.de/docs/linux/kodi-raspi-libreelec/</guid>
      <description><![CDATA[<!-- Anreißer -->
<p>Anleitungen, Kochrezepte und HowTos für RasPi / Kodi / LibreELEC</p>]]></description>
      <content:encoded><![CDATA[<!-- Anreißer -->
<p>Anleitungen, Kochrezepte und HowTos für RasPi / Kodi / LibreELEC</p>

<h2 id="permanenter-mount-vom-kodi-auf-das-nas" data-numberify>Permanenter Mount vom Kodi auf das NAS<a class="anchor ms-1" href="#permanenter-mount-vom-kodi-auf-das-nas"></a></h2>

<h3 id="hinzufügen" data-numberify>Hinzufügen<a class="anchor ms-1" href="#hinzufügen"></a></h3>
<p>Mount-point erstellen:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">mkdir /storage/mnt
</span></span></code></pre></div><p>Vorlagen liegen unter: <code>/storage/.config/system.d</code></p>
<p>Vorlage kopieren, wobei der verwendet Pfad sich im Namen der Start-Unit
wiederfinden muss. <code>/</code> sind durch <code>.</code> im Dateinamen zu ersetzen.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl"><span class="nb">cd</span> /storage/.config/system.d/
</span></span><span class="line"><span class="ln">2</span><span class="cl">cp cifs.mount.sample storage-mnt.mount
</span></span></code></pre></div><p>Anpassen mittels Texteditor:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ini" data-lang="ini"><span class="line"><span class="ln">1</span><span class="cl"><span class="na">Description</span><span class="o">=</span><span class="s">Hier noch eine kurze Beschreibung rein</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="na">What</span><span class="o">=</span><span class="s">//192.0.2.10/samba/backups</span>
</span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="na">Where</span><span class="o">=</span><span class="s">/storage/mnt</span>
</span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="na">Options</span><span class="o">=</span><span class="s">username=benutzer,password=passwort</span>
</span></span></code></pre></div><p>Start-Unit ggf. permanent beim Booten mitstarten lassen</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">systemctl <span class="nb">enable</span> storage-mnt.mount
</span></span></code></pre></div><p>Unit starten und Verzeichnis mounten:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">systemctl start storage-mnt.mount
</span></span></code></pre></div><p>Fertig.</p>

<h3 id="entfernen" data-numberify>Entfernen<a class="anchor ms-1" href="#entfernen"></a></h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">systemctl stop storage-mnt.mount
</span></span><span class="line"><span class="ln">2</span><span class="cl">systemctl disable storage-mnt.mount
</span></span></code></pre></div><p>ggf. noch Datei löschen.</p>

<h2 id="backup-des-raspberry-pi--kodi--im-laufenden-betrieb" data-numberify>Backup des Raspberry Pi / Kodi / im laufenden Betrieb<a class="anchor ms-1" href="#backup-des-raspberry-pi--kodi--im-laufenden-betrieb"></a></h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">dd <span class="k">if</span><span class="o">=</span>/dev/mmcblk0 <span class="nv">bs</span><span class="o">=</span>1MB <span class="p">|</span> gzip &gt;  /storage/mnt/kodi-backup-<span class="k">$(</span>date +%Y%m%d-%H%M%S<span class="k">)</span>.img.gz
</span></span></code></pre></div><p><code>dd</code> Parameter <code>status=progress</code> wird von LibreELEC derzeit leider nicht
unterstützt.</p>

<h2 id="restore" data-numberify>Restore<a class="anchor ms-1" href="#restore"></a></h2>
<p>Zurückspielen kann man das mit:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">gunzip -c  /storage/mnt/kodi-backup-&lt;datum&gt;.img.gz <span class="p">|</span> dd <span class="nv">of</span><span class="o">=</span>/dev/mmcblk0
</span></span></code></pre></div>]]></content:encoded>
    </item>
    
    <item>
      <title>Zufallszahlen</title>
      <link>https://www.rainerrose.de/docs/linux/zufallszahlen/</link>
      <pubDate>Fri, 21 Aug 2020 18:54:20 +0200</pubDate>
      <guid>https://www.rainerrose.de/docs/linux/zufallszahlen/</guid>
      <description><![CDATA[<!-- Anreißer -->
<p>Bessere Zufallszahlen erzeugen.</p>]]></description>
      <content:encoded><![CDATA[<!-- Anreißer -->
<p>Bessere Zufallszahlen erzeugen.</p>

<h2 id="problem" data-numberify>Problem<a class="anchor ms-1" href="#problem"></a></h2>
<p><code>/dev/random</code> erzeugt bekanntermaßen Zufallszahlen. Es bedient sich aus
den Block-Devices wie Tastatur, Maus, Festplatte. Bei einem Server ohne
diese Eingabegeräte oder auch bei virtuellen Server gibt's da wenig
Eingaben, mit der Folge, dass der Puffer recht schnell leer ist und dann
wieder gewartet werden muss (blockt).</p>
<p><code>/dev/urandom</code> liefert zwar schneller und kontinuierlicher
Zufallszahlen, ist aber nicht zu 100% sicher. Wenn dann Prozesse stehen,
weil auf Zufallszahlen gewartet wird, ist das blöd. Zudem saugt er erst
einmal den Pool von <code>/dev/random</code> leer - auch unschön.</p>

<h2 id="lösung" data-numberify>Lösung<a class="anchor ms-1" href="#lösung"></a></h2>
<p><code>Havege</code> (HArdware Volatile Entropy Gathering and Expansion) bedient
sich aus noch mehr Quellen (Caches, Pipelines, etc.) und damit konnte
ich für reichlich Zufallszahlen sorgen und der betroffene Prozess
wartete bisher nie wieder auf neue Zahlen - bisher habe ich gute
Erfahrungen damit gemacht.</p>
<p><code>Haveged</code> sollte sich in den Standard-Paket-Quellen der jeweiligen
Linux-Distribution finden lassen.</p>]]></content:encoded>
    </item>
    
    <item>
      <title>ezmlm-idx</title>
      <link>https://www.rainerrose.de/docs/linux/ezmlm/</link>
      <pubDate>Sun, 12 Jul 2020 23:16:41 +0200</pubDate>
      <guid>https://www.rainerrose.de/docs/linux/ezmlm/</guid>
      <description><![CDATA[<!-- Anreißer -->
<p>Bevor es weg ist, hier nochmal als Archiv-Dokumentation</p>]]></description>
      <content:encoded><![CDATA[<!-- Anreißer -->
<p>Bevor es weg ist, hier nochmal als Archiv-Dokumentation</p>
<p>Die Mailingliste verwaltet sich komplett über speziell zusammengesetzte E-Mail-Adressen oder über shell-Befehle.</p>

<h2 id="mailinglisten-manager-ezmlm-idx" data-numberify>Mailinglisten-Manager ezmlm-idx<a class="anchor ms-1" href="#mailinglisten-manager-ezmlm-idx"></a></h2>
<p>Die Installation durchführen wie im
<a href="https://tools.rainerrose.de/redirect.php?id=14" target="_blank" rel="noopener noreferrer">uberlab<i class="fas fa-external-link-square-alt ms-1"></i></a> beschrieben.</p>
<p>Die Mailingliste verwaltet sich komplett über speziell zusammengesetzte
E-Mail-Adressen oder über shell-Befehle.</p>

<h2 id="mailingliste-anlegen" data-numberify>Mailingliste anlegen<a class="anchor ms-1" href="#mailingliste-anlegen"></a></h2>
<p>Erst mal ein Verzeichnis anlegen, wo die Verwaltungsverzeichnisse
gesammelt werden sollen</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">mkdir ~/mailinglisten
</span></span></code></pre></div>
<h2 id="optionen-für-die-liste" data-numberify>Optionen für die Liste<a class="anchor ms-1" href="#optionen-für-die-liste"></a></h2>

<blockquote class="alert alert-success" role="alert">
    <p class="alert-heading fw-bold">
      <i class="fas fa-lightbulb me-2"></i>Tipp
    </p>
    <p>Mehrere Schalter können <strong>zusammengefasst</strong> werden!</p>
</blockquote>
<p>statt <code>-s</code> <code>-u</code> <code>-r</code> <code>-A</code> geht auch <code>-surA</code></p>
<p><strong>Grob:</strong></p>
<ul>
<li>Großschreibung aktiviert</li>
<li>Kleinschreibung deaktiviert.</li>
</ul>

<h3 id="option" data-numberify>Option<a class="anchor ms-1" href="#option"></a></h3>
<table>
  <thead>
      <tr>
          <th>Schalter</th>
          <th>Erklärung</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>-A</td>
          <td>kein Archiv.</td>
      </tr>
      <tr>
          <td>-a</td>
          <td>Archiv aufbauen (Default).</td>
      </tr>
      <tr>
          <td>-u</td>
          <td>private Liste; nur Listenteilnehmer dürfen an die Liste schreiben.</td>
      </tr>
  </tbody>
</table>

<h3 id="moderation" data-numberify>Moderation<a class="anchor ms-1" href="#moderation"></a></h3>
<table>
  <thead>
      <tr>
          <th>Schalter</th>
          <th>Erklärung</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>-s</td>
          <td>Jede <strong>Anmeldung</strong> geht erst an eine*n Moderator*in. Siehe unten!</td>
      </tr>
      <tr>
          <td>-m</td>
          <td>Jede <strong>Nachricht</strong> geht erst an eine*n Moderator*in. Siehe unten!</td>
      </tr>
  </tbody>
</table>

<h3 id="nachrichtensammlungen" data-numberify>Nachrichtensammlungen<a class="anchor ms-1" href="#nachrichtensammlungen"></a></h3>
<table>
  <thead>
      <tr>
          <th>Schalter</th>
          <th>Erklärung</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>-d</td>
          <td>Erstelle Sammlungen von Nachrichten für Digest-Abonnenten.</td>
      </tr>
  </tbody>
</table>

<h3 id="listeneigentümer" data-numberify>Listeneigentümer<a class="anchor ms-1" href="#listeneigentümer"></a></h3>
<table>
  <thead>
      <tr>
          <th>Schalter</th>
          <th>Erklärung</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>-5 user@domain</td>
          <td>Erstelle Sammlungen von Nachrichten für Digest-Abonnenten.</td>
      </tr>
  </tbody>
</table>

<h3 id="mehrsprachigkeit" data-numberify>Mehrsprachigkeit<a class="anchor ms-1" href="#mehrsprachigkeit"></a></h3>
<table>
  <thead>
      <tr>
          <th>Schalter</th>
          <th>Erklärung</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>-C ~/etc/ezmlm/de</td>
          <td>für die deutsche Spracheinstellung. Nur <strong>eine</strong> Sprache <strong>pro</strong> Mailingliste.</td>
      </tr>
  </tbody>
</table>

<h3 id="beispiel" data-numberify>Beispiel<a class="anchor ms-1" href="#beispiel"></a></h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">ezmlm-make -s -u -5 owner@domain -C ~/etc/ezmlm/de ~/mailinglisten/mylist ~/.qmail-mylist mylist domain
</span></span></code></pre></div>
<blockquote class="alert alert-danger" role="alert">
    <p class="alert-heading fw-bold">
      <i class="fas fa-exclamation-triangle me-2"></i>Achtung
    </p>
    <p>Jetzt noch ein*e Moderator*in hinzufügen, sonst geht&rsquo;s nicht!</p>
</blockquote>

<h2 id="moderationen" data-numberify>Moderationen<a class="anchor ms-1" href="#moderationen"></a></h2>
<p>Ist nur notwendig, wenn Schalter <code>-m</code> oder <code>-s</code> gesetzt sind. Ist
technisch ein Abo was unterhalb vom Unterverzeichnis <code>mod</code> verwaltet
wird.</p>

<h3 id="moderatorin-hinzufügen" data-numberify>Moderator*in hinzufügen<a class="anchor ms-1" href="#moderatorin-hinzufügen"></a></h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">ezmlm-sub ~/mailinglisten/mylist mod new_moderator@somedomain.tld
</span></span></code></pre></div>
<h3 id="moderatorin-löschen" data-numberify>Moderator*in löschen<a class="anchor ms-1" href="#moderatorin-löschen"></a></h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">ezmlm-unsub ~/mailinglisten/mylist mod retired_moderator@someotherdomain.tld
</span></span></code></pre></div>
<h3 id="moderatorin-hinweis" data-numberify>Moderator*in Hinweis<a class="anchor ms-1" href="#moderatorin-hinweis"></a></h3>
<p>Moderator*innen können sich nicht selbst aus der Liste austragen. Die
Steuerung und Kommunikation erfolgt grundsätzlich per E-Mail. Es werden
kryptografischer Einmal-Codes versendet. Die Mail enthält zusätzliche
Infos und zwei Antwort-Adressen, eine zum Ablehnen, eine zum Genehmigen.</p>

<h2 id="abonnentenverwaltung" data-numberify>Abonnentenverwaltung<a class="anchor ms-1" href="#abonnentenverwaltung"></a></h2>

<h3 id="abonnenten-entfernen" data-numberify>Abonnenten entfernen<a class="anchor ms-1" href="#abonnenten-entfernen"></a></h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">ezmlm-sub ~/mailinglisten/mylist user@otherdomain.org
</span></span></code></pre></div>
<h3 id="abonnenten-entfernen-1" data-numberify>Abonnenten entfernen<a class="anchor ms-1" href="#abonnenten-entfernen-1"></a></h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">ezmlm-unsub ~/mailinglisten/mylist user@otherdomain.org
</span></span></code></pre></div>
<h3 id="abonnenten-anzeigen" data-numberify>Abonnenten anzeigen<a class="anchor ms-1" href="#abonnenten-anzeigen"></a></h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">ezmlm-list ~/mailinglisten/mylist
</span></span></code></pre></div>
<h2 id="optionen-wieder-ändern" data-numberify>Optionen wieder ändern<a class="anchor ms-1" href="#optionen-wieder-ändern"></a></h2>
<p>Einstellungen können via <code>-+</code> hinzugefügt werden. Bestehende Optionen
bleiben erhalten! Soll die Moderation der Anmeldungen angeschaltet
werden:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">ezmlm-make -+ -s ~/mailinglisten/mylist ~/.qmail-mylist mylist domain
</span></span></code></pre></div>
<h2 id="anpassungen-der-einzelnen-mailingliste" data-numberify>Anpassungen der einzelnen Mailingliste<a class="anchor ms-1" href="#anpassungen-der-einzelnen-mailingliste"></a></h2>

<h3 id="sprachdateien-anpassen" data-numberify>Sprachdateien anpassen<a class="anchor ms-1" href="#sprachdateien-anpassen"></a></h3>
<p>Einzelne Texte aus der aktuellen Sprache, lassen sich überschreiben.
Kopiert man die <code>~/etc/ezmlm/de/text/info</code> in das jeweilige
Unterverzeichnis der Mailingliste <code>~/mailinglisten/mylist/text/info</code> und
passt sie individuell an, so wird diese Version verwendet in der
Mailingliste verwendet.</p>

<h3 id="betreff-zeilen-präfix" data-numberify>Betreff-Zeilen Präfix<a class="anchor ms-1" href="#betreff-zeilen-präfix"></a></h3>
<p>Unabhängig vom <code>Mailing-List:</code>-Header, lässt sich ein Präfix in der
Betreff-Zeile der Mail setzen</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl"><span class="nb">echo</span> <span class="s1">&#39;[Meine erste Mailingliste]&#39;</span> &gt; ~/mailinglisten/mylist/prefix
</span></span></code></pre></div>
<h3 id="info-text" data-numberify>Info-Text<a class="anchor ms-1" href="#info-text"></a></h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">vi ~/mailinglisten/fbw1a/text/info
</span></span></code></pre></div>
<h2 id="bedienung-für-abonnenten" data-numberify>Bedienung für Abonnenten<a class="anchor ms-1" href="#bedienung-für-abonnenten"></a></h2>
<p>Grundsätzlich per E-Mail:</p>
<table>
  <thead>
      <tr>
          <th>Befehl</th>
          <th>Erläuterung</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>listenname@host</code></td>
          <td>Mail an die Mailingliste senden</td>
      </tr>
      <tr>
          <td><code>listenname-subscribe@host</code></td>
          <td>Mailingliste abonnieren</td>
      </tr>
      <tr>
          <td><code>listenname-unsubscribe@host</code></td>
          <td>Mailingliste abbestellen</td>
      </tr>
      <tr>
          <td><code>listenname-help@host</code></td>
          <td>Detaillierte Hilfe abrufen</td>
      </tr>
      <tr>
          <td><code>listenname-owner@host</code></td>
          <td>Listeneigentümer persönlich kontaktieren</td>
      </tr>
  </tbody>
</table>
<p>Der Hilfetext passt sich automatisch den vorgenommen
Konfigurationsoptionen an. Nur wenn es ein Archiv gibt, wird der
dazugehörige Hilfetext ausgegeben. Gibt es kein Archiv, werden die Infos
im Text der Hilfe-E-Mail weggelassen.</p>

<h2 id="liste-wieder-löschen" data-numberify>Liste wieder löschen<a class="anchor ms-1" href="#liste-wieder-löschen"></a></h2>
<p>Soll die Mailingliste <code>mylist</code> gelöscht werden, löscht man zunächst alle
<code>.qmail</code>-Dateien und danach das Datenverzeichnis</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">rm -f ~/.qmail-mylist ~/.qmail-mylist-*
</span></span><span class="line"><span class="ln">2</span><span class="cl">rm -rf ~/mailinglisten/mylist
</span></span></code></pre></div>]]></content:encoded>
    </item>
    
    <item>
      <title>Alltagsrassismus in der IT</title>
      <link>https://www.rainerrose.de/posts/alltags-rassisums-in-der-it/</link>
      <pubDate>Sun, 14 Jun 2020 22:45:12 +0100</pubDate>
      <guid>https://www.rainerrose.de/posts/alltags-rassisums-in-der-it/</guid>
      <description><![CDATA[<!-- Anreißer -->
<p>Auch in der IT schleichen sich gerne mal unbewusst rassistische Denkmuster und Vokabeln ein. Es ist ein leichtes diese durch andere Wörter zu ersetzen, die sogar aussagekräftiger sein können.</p>]]></description>
      <content:encoded><![CDATA[<!-- Anreißer -->
<p>Auch in der IT schleichen sich gerne mal unbewusst rassistische Denkmuster und Vokabeln ein. Es ist ein leichtes diese durch andere Wörter zu ersetzen, die sogar aussagekräftiger sein können.</p>
<p>Es findet sich sogar ein <a href="https://tools.rainerrose.de/redirect.php?id=13" target="_blank" rel="noopener noreferrer">Entwurf für einen
IETF-Standard<i class="fas fa-external-link-square-alt ms-1"></i></a>, den ich
hier kurz zusammenfassen möchte:</p>

<h2 id="master-slave" data-numberify>Master-slave<a class="anchor ms-1" href="#master-slave"></a></h2>
<ul>
<li>Primary-Secondary</li>
<li>Leader-Follower</li>
<li>Active-Standby</li>
<li>Primary-Replica</li>
<li>Writer-Reader</li>
<li>Coordinator-Worker</li>
<li>Parent-Helper</li>
</ul>

<h2 id="git" data-numberify>GIT<a class="anchor ms-1" href="#git"></a></h2>
<p>Für <code>git</code> lässt sich der <code>master</code>-Zweig simpelst in einen <code>main</code>-Zweig
umbenennen. Eine kurzes HowTo habe ich <a href="/sammlung/linux/git">hier online [klick]</a>
gestellt.</p>

<h2 id="blacklist-whitelist" data-numberify>Blacklist-whitelist<a class="anchor ms-1" href="#blacklist-whitelist"></a></h2>
<ul>
<li>Blocklist-Allowlist</li>
<li>Block-Permit</li>
</ul>

<h2 id="blackbox" data-numberify>Blackbox<a class="anchor ms-1" href="#blackbox"></a></h2>
<ul>
<li>mysterious Box</li>
<li>myst-Box</li>
<li>Unfalldatenspeicher</li>
<li>Flugdatenschreiber</li>
</ul>]]></content:encoded>
    </item>
    
    <item>
      <title>qmail / netqmail</title>
      <link>https://www.rainerrose.de/docs/linux/qmail/</link>
      <pubDate>Thu, 28 May 2020 22:42:08 +0200</pubDate>
      <guid>https://www.rainerrose.de/docs/linux/qmail/</guid>
      <description><![CDATA[<!-- Anreißer -->
<p>Mails sortieren mit <code>qmail</code> auf Uberspace.de</p>]]></description>
      <content:encoded><![CDATA[<!-- Anreißer -->
<p>Mails sortieren mit <code>qmail</code> auf Uberspace.de</p>
<p>Ich nutze .qmail-Dateien auf meinem
<a href="https://tools.rainerrose.de/redirect.php?id=11" target="_blank" rel="noopener noreferrer">Uberspace<i class="fas fa-external-link-square-alt ms-1"></i></a>-Account.</p>
<p>Bei der Benutzung von <code>qmail</code> ist man nicht auf die einzelne Datei
festgelegt, sondern man kann weitere E-Mail-Adressen definieren. Trenner
ist hierbei das Minus <code>-</code> . Wird eine Datei mit Namen <code>.qmail-foo</code>
angelegt, so entspricht diese der E-Mail-Adresse
<code>foo@username.uberspace.de</code>.</p>
<p>Mail-Adressen sind so schnell angelegt: <code>.qmail-gewinnspiel</code> . Bei zu
viel Spam ist sie auch schnell wieder gelöscht.</p>
<p>Aufgeschaltete Domains bekommen dann dieselben Adressen verpasst;
allerdings gilt das für <strong>alle</strong> aufgeschalteten Domains:
<code>foo@&lt;aufgeschaltete-Domain-1&gt;</code> sowie
<code>foo@&lt;aufgeschaltete-Domain-Nummer-zwei&gt;</code></p>

<h2 id="stolperfallen" data-numberify>Stolperfallen<a class="anchor ms-1" href="#stolperfallen"></a></h2>
<div class="alert alert-warning" role="alert"><i class="alert-icon fas fa-fw fa-exclamation-triangle me-1"></i>

  Folgende Dinge sollten beachtet werden, um sich nicht das Leben schwer zu machen.
</div>

<ul>
<li><strong>Punkte</strong> als Trenner in E-Mail-Adressen sind aus
Sicherheitsgründen nicht erlaubt. Einfach im Dateinamen durch
Doppelpunkte ersetzen und es geht trotzdem. <code>.qmail-foo:bar</code> hört
also auf <code>foo.bar@username.uberspace.de</code></li>
<li>Dateinamen <strong>klein</strong> schreiben. <code>qmail-info</code> hört also nicht nur
<code>info@...</code>, sondern auch <code>INFO@...</code> ebenso wie <code>iNfO@...</code> usw.</li>
</ul>

<h2 id="lizenzhinweis" data-numberify>Lizenzhinweis<a class="anchor ms-1" href="#lizenzhinweis"></a></h2>
<p>Das Wissen hierzu ist schamlos aus dem
<a href="https://tools.rainerrose.de/redirect.php?id=12" target="_blank" rel="noopener noreferrer">Wiki<i class="fas fa-external-link-square-alt ms-1"></i></a> der
<a href="https://tools.rainerrose.de/redirect.php?id=11" target="_blank" rel="noopener noreferrer">Ubernauten<i class="fas fa-external-link-square-alt ms-1"></i></a> entnommen.
Aufgrund einer Produkteinstellung auf deren Seite, wird es dieses
vermutlich (Stand Mai 2020) nicht mehr lange geben und daher konserviere
ich hier Teile davon, die ich selbst öfters brauche, da qmail immer noch
auf U7 funktioniert, nur eben nicht dokumentiert ist.</p>]]></content:encoded>
    </item>
    
    <item>
      <title>Thunderbird</title>
      <link>https://www.rainerrose.de/docs/howto/thunderbird/</link>
      <pubDate>Sat, 09 May 2020 15:02:34 +0200</pubDate>
      <guid>https://www.rainerrose.de/docs/howto/thunderbird/</guid>
      <description><![CDATA[<!-- Anreißer -->
<p>Tipps und Tricks zum Mail-Programm Thunderbird</p>]]></description>
      <content:encoded><![CDATA[<!-- Anreißer -->
<p>Tipps und Tricks zum Mail-Programm Thunderbird</p>

<h2 id="konto-reihenfolge-bzw-position-ändern" data-numberify>Konto-Reihenfolge bzw. Position ändern<a class="anchor ms-1" href="#konto-reihenfolge-bzw-position-ändern"></a></h2>
<p>Die <code>prefs.js-Datei</code> muss geändert werden; sie liegt im jeweiligen
Profil-Pfad von Thunderbird.</p>
<p><code>${HOME}/.thunderbird/&lt;profil-id&gt;.default/prefs.js</code></p>
<pre><code>user_pref(&quot;mail.accountmanager.accounts&quot;, &quot;account3,account1,account2&quot;);
</code></pre>
<p>Hier kann die Reihenfolge der Kontendarstellung festgelegt werden. Es
muss nur die Account-Bezeichnung an die gewünschte Stelle gesetzt
werden. Der &quot;Lokale Ordner&quot; hat ebenfalls eine Account-Nummer. Mit
grep und co findet man die richtige Account-Nummer raus. Getestet mit
Thunderbird 68.7.0 :!:</p>

<blockquote class="alert alert-danger" role="alert">
    <p class="alert-heading fw-bold">
      <i class="fas fa-exclamation-triangle me-2"></i>Wichtig!
    </p>
    <p>Thunderbird <strong>vorher schließen</strong>!</p>
</blockquote>
<p>Während der Änderung muss <strong>Thunderbird geschlossen</strong> sein, ansonsten werden die Änderungen wieder
überschrieben.</p>
<p>Am einfachsten geht es, wenn der Benutzername zum Anmelden am Server
genommen wird:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">$ grep &lt;benutzername&gt; prefs.js<span class="p">|</span> grep userName
</span></span><span class="line"><span class="ln">2</span><span class="cl">user_pref<span class="o">(</span><span class="s2">&#34;mail.server.server5.userName&#34;</span>, <span class="s2">&#34;&lt;benutzername&gt;&#34;</span><span class="o">)</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">3</span><span class="cl">$ grep &lt;benutzername&gt; prefs.js<span class="p">|</span> grep userName  <span class="p">|</span> cut -d <span class="s2">&#34;.&#34;</span> -f <span class="m">3</span>
</span></span><span class="line"><span class="ln">4</span><span class="cl">server5
</span></span></code></pre></div><p>Mit der Angabe geht's weiter, hier beim Suchen einen <strong>Punkt hinten
anfügen</strong>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">$ grep server5. prefs.js  <span class="p">|</span> grep account
</span></span><span class="line"><span class="ln">2</span><span class="cl"> user_pref<span class="o">(</span><span class="s2">&#34;mail.account.account5.server&#34;</span>, <span class="s2">&#34;server5&#34;</span><span class="o">)</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">3</span><span class="cl">$ grep server5. prefs.js  <span class="p">|</span> grep account <span class="p">|</span> cut -d <span class="s2">&#34;.&#34;</span> -f <span class="m">3</span>
</span></span><span class="line"><span class="ln">4</span><span class="cl">account5
</span></span></code></pre></div><p><code>account5</code> jetzt merken.</p>
<p>Jetzt den anderen Account:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">$ grep &lt;benutzername-der-umsortiert-werden-soll&gt; prefs.js<span class="p">|</span> grep userName <span class="p">|</span> cut -d <span class="s2">&#34;.&#34;</span> -f <span class="m">3</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl">server11
</span></span></code></pre></div><p>Jetzt noch die Account-Nummer rausfinden:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">$ grep server11. prefs.js  <span class="p">|</span> grep account <span class="p">|</span> cut -d <span class="s2">&#34;.&#34;</span> -f <span class="m">3</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl">account11
</span></span></code></pre></div><p>jetzt geht's ans Tauschen. Sieht vorher so aus:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">$ grep mail.accountmanager.accounts prefs.js
</span></span><span class="line"><span class="ln">2</span><span class="cl">user_pref<span class="o">(</span><span class="s2">&#34;mail.accountmanager.accounts&#34;</span>, <span class="s2">&#34;account1,account2,account3,account4,account5,account6,account7,account8,account9,account10,account11&#34;</span><span class="o">)</span><span class="p">;</span>
</span></span></code></pre></div><p>und nach dem Editieren mit einem beliebigen Text-Editor so</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">$ grep mail.accountmanager.accounts prefs.js
</span></span><span class="line"><span class="ln">2</span><span class="cl">user_pref<span class="o">(</span><span class="s2">&#34;mail.accountmanager.accounts&#34;</span>, <span class="s2">&#34;account1,account2,account3,account4,account5,account11,account6,account7,account8,account9,account10&#34;</span><span class="o">)</span><span class="p">;</span>
</span></span></code></pre></div>]]></content:encoded>
    <enclosure url="https://www.rainerrose.de/wallpaper/thunderbird.png" length="25860" type="image/.png" />
    </item>
    
    <item>
      <title>E-Mail-Guide</title>
      <link>https://www.rainerrose.de/docs/kontakt/e-mail-guide/</link>
      <pubDate>Sat, 02 May 2020 19:15:26 +0100</pubDate>
      <guid>https://www.rainerrose.de/docs/kontakt/e-mail-guide/</guid>
      <description><![CDATA[<!-- Anreißer -->
<p>Liebe*r Leser*in, ich empfange täglich einige hundert E-Mails. Möglicherweise können Sie sich vorstellen, dass die Welt unter dieser Vorbedingung etwas anders auszusehen beginnt, wenn 80% der eingehenden E-Mails falsch adressiert, fehlerhaft oder einfach nur nutzlos, unpassend und nervig sind.</p>]]></description>
      <content:encoded><![CDATA[<!-- Anreißer -->
<p>Liebe*r Leser*in, ich empfange täglich einige hundert E-Mails. Möglicherweise können Sie sich vorstellen, dass die Welt unter dieser Vorbedingung etwas anders auszusehen beginnt, wenn 80% der eingehenden E-Mails falsch adressiert, fehlerhaft oder einfach nur nutzlos, unpassend und nervig sind.</p>

<h2 id="e-mail-knigge" data-numberify>E-Mail-Knigge<a class="anchor ms-1" href="#e-mail-knigge"></a></h2>

<h2 id="allgemeines" data-numberify>Allgemeines<a class="anchor ms-1" href="#allgemeines"></a></h2>
<p>Eine E-Mail ist schnell geschrieben, aber genauso schnell abgeschickt.
Da können sich schnell mal ein paar Schnitzer einschleichen und der
Gegenüber schnell auf den Schlips treten. Zudem haben sich einige Regeln
und Verhaltensweisen eingebürgert, die nicht nur der Höflichkeit halber
befolgt werden sollten, sondern auch ein Maß an Effizienz bieten.</p>
<p>Denn wie in allen gesellschaftlichen Bereichen existiert auch im
Internet eine Übereinkunft darüber, was als gutes Benehmen gilt und was
nicht. Diese ungeschriebenen Höflichkeits- und Verhaltensformen fasst
man im Internet gemeinhin unter dem Titel &ldquo;Netiquette&rdquo; zusammen, einem
Kunstwort aus den Begriffen Net und Etiquette.</p>
<p>Daher gilt:</p>
<p>Eine E-Mail ist genauso wie ein Brief. Man sollte also nicht allzu
schnell in ein persönliches Du verfallen. Ebenso gilt es die allgemeinen
Höflichkeitsprotokolle einzuhalten, die es auch in der Papierwelt
einzuhalten gilt. Persönliche Anrede und höflicher Ton u.s.w. Greifen
Sie ruhig auf die altbewährte Anrede &ldquo;Sehr geehrte Damen und Herren&rdquo;
zurück, wenn Sie den Empfänger Ihrer E-Mail nicht namentlich kennen.</p>

<h2 id="tippfehler" data-numberify>Tippfehler<a class="anchor ms-1" href="#tippfehler"></a></h2>
<p>Tippfehler werden in Mailinglisten, Disskussionsforen und privater Mail
werden im Gegensatz zur Snail-Mail (Brief per Post) meist toleriert. Bei
gehobener und geschäftlicher Korrespondenz jedoch sollten Sie Tipp- und
Rechtschreibfehler vermeiden! Ein fehlerhafter Text ist nämlich
suboptimal und damit nur schlecht lesbar &ndash; und somit unhöflich.</p>

<h2 id="die-oft-vergessene-betreff-zeile" data-numberify>Die oft vergessene Betreff-Zeile<a class="anchor ms-1" href="#die-oft-vergessene-betreff-zeile"></a></h2>
<p>Bitte denken Sie immer daran, die Betreffzeile auszufüllen!</p>
<p>Gern unterschätzt; und doch so wichtig: Der Betreff Ihrer Nachricht ist
die erste Information, die dem Empfänger beim Öffnen seiner Mailbox
angezeigt wird, und liefert damit den ersten Anhaltspunkt über den
Inhalt Ihrer E-Mail. Und: Ein aussagekräftiges &ldquo;Subject&rdquo; lässt sich
auch in einer Mailbox mit regem Durchgangsverkehr leichter wieder
auffinden als eine Allerwelts-Floskel.</p>

<h2 id="zititeren" data-numberify>Zititeren<a class="anchor ms-1" href="#zititeren"></a></h2>

<h3 id="quoting" data-numberify>quoting<a class="anchor ms-1" href="#quoting"></a></h3>
<p>Es gibt das System des &ldquo;Quotings&rdquo; (Zitierens).</p>
<p>Es ist eine äussert praktische Methode, um zum vorher geschriebenen
Bezug zu nehmen. Dabei wird dem vorher geschrieben Text, zu dem man
Bezug nimmt, eine spitze Klammer (<code>&gt;</code>) vorangestellt.</p>
<p>Beispiel:</p>
<pre><code>&gt;&gt; Wieviel kostet Produkt X ?
&gt; 50 Euro.
Geht das nicht billiger ?
</code></pre>
<p>Vielfach visuelle Darstellung:</p>
<hr>
<blockquote>
<blockquote>
<p>Wieviel kostet Produkt X ?</p>
</blockquote>
<p>50 Euro.</p>
</blockquote>
<p>Geht das nicht billiger ?</p>
<hr>

<h3 id="erklärung" data-numberify>Erklärung<a class="anchor ms-1" href="#erklärung"></a></h3>
<p>Der erste Satz stammt aus der ersten Mail und ging somit schon dreimal
durch das Internet. Würde man nur den letzten Satz in der Mail erwähnen,
wüsste die Gesprächspartner*in den Kontext des vorhergegangenen nicht mehr.
Gerade bei etwas längeren Diskussionen ist das von Vorteil. Einige
E-Mail-Programme beherrschen sogar die unterschiedliche Einfärbung der
Quotings.</p>
<p>Auf Quotings zu verzichten empfiehlt sich nicht, da die Gesprächspartner*in
bei längeren Konversationen die unterschiedlichen Gesprächsfetzen nicht
mehr auseinander halten kann. Auch die Zuordnung der zugehörigen Autor*innen
wird erschwert. Gerade bei länger unterbrochener Kommunikation, oder
wenn der Gesprächspartner*innen mehrere 100 Mails pro Tag empfängt, wie z.B.
Hotlines, ist ein Einstieg in die Diskussion einfacher.</p>
<p>Und jetzt mal ehrlich: sieht das nicht auch ein wenig wunderlich aus,
wenn man erst die Antwort erhält und dann die Frage gestellt bekommt?
(Mal abgesehen von irgendwelchen Gameshows, wo das üblich ist.)</p>
<p>Daher ist es angebracht, die bezugnehmende Antwort <strong>unter</strong> den
zitierten Text zu schreiben. Dann kann sich der Gegenüber nochmals den
vorhergehenden Schriftverlauf durchlesen und somit leichter in die
Kommunikation einzusteigen. Auch empfiehlt es sich die E-Mail zu kürzen
und nur den wirklich wichtigen Teil der E-Mail zu zitieren. Eine
Leerzeile wirkt Wunder und ein [...] für ausgelassen Text versteht aus meiner Erfahrung heraus
auch jede*r. Da die meisten mobilen Internet-Benutzer*innen noch hinter einem langsamen
Mobilfunknetz sitzen mit wenig Datenvolumen oder geriner Datenrate, erfordert es schon die Höflichkeit nicht einen ganzen
Rattenschwanz an E-Mail mit der gesamten Kommunikation, Datei-Anhängen
etc. zu versenden, sondern sich auf das Wesentliche zu beschränken.</p>

<h3 id="originalartikel-am-ende" data-numberify>Originalartikel am Ende?<a class="anchor ms-1" href="#originalartikel-am-ende"></a></h3>
<p>Warum soll ich den Originalartikel nicht am Ende anhängen?</p>
<p>Die meisten Menschen lesen einen Artikel von <strong>oben</strong> nach <strong>unten</strong>.
Wer nicht? Oft ist das Ende eines Artikels nicht auf dem Bildschirm oder
im Fenster zu sehen. Wenn Sie den kompletten Artikel Ihres Vorredners am
Ende Deines Postings anhängen, können viele Leute nicht abschätzen, ob
Sie noch etwas dazu schreiben oder nicht. Deshalb müssen sie erst bis
zum Ende durchblättern, um festzustellen, dass da doch nichts neues mehr
kommt. Das ist gerade für Vielleser ärgerlich. Bitte bedenken: auch das
Überfliegen eines Artikels bis zum Ende kostet Zeit, und nicht nur der
einzelne, sondern <strong>alle</strong> Artikel zählen.</p>
<p>Ausserdem widerspricht das Anhängen des kompletten Vorgängerartikels dem
Prinzip, nur das zu zitieren, worauf man sich bezieht. Abgesehen davon
muss ja nicht jeder Artikel x-mal (nämlich in jeder Antwort und jeder
darauf folgenden Antwort usw.) neu verbreitet werden; die Übertragungs-
und Speicherkosten würden innerhalb kürzester Zeit explodieren.</p>
<p>Und nicht jeder hat eine große Internet-Leitung, eine gute
Mobilfunkversorgung jederzeit verfügbar. Auch das Datenvolumen ist bei
vielen begrenzt.</p>

<h2 id="größe-der-e-mail" data-numberify>Größe der E-Mail<a class="anchor ms-1" href="#größe-der-e-mail"></a></h2>
<p>Die meisten Personen möchten nicht 5 Minuten auf das Herunterladen eine
E-Mail warten. Dateinanhängsel (=Attachments) sollten Sie somit nur nach
Aufforderung mitsenden. Der Geldbeutel dank&rsquo;s. Viele lesen E-Mails
unterwegs und auch hier verbraucht jede E-Mail mit Anhang das ggf.
knappe Datenvolumen. Auch unaufgeforderte Werbe-E-Mails (sogenannter
Spam) wird verachtet.</p>
<p>Das E-Mail-Protokoll ist alt. Es war nur für Text-EMails gedacht und nicht für riesengroße Anhänge. Alles was nicht Text ist, muss umgewandelt werden. Die Umwandlung macht den Anhang um ca. den <strong>Faktor 1,4 größer</strong>.</p>

<blockquote class="alert alert-warning" role="alert">
    <p class="alert-heading fw-bold">
      <i class="fas fa-exclamation-circle me-2"></i>Maximalgröße einer E-Mail
    </p>
    <p>Aus einer Maximalgröße einer E-Mail (inkl. Anhang) von <code>25 MB</code> <strong>Brutto</strong> sind dies <code>Nettogröße : 1,4 = 17,8 MB</code></p>
</blockquote>
<p>Und in <strong>D</strong>auernd-<strong>E</strong>dge-Land ist es auch nicht erbaulich sich große Attachments herunterzuladen.</p>
<p>Die Nutzer*innen und Provider wehren sich mit unterschiedlichen Maßnahmen.
Falls man zu sehr auffällt, wird man in eine Blockier-Liste geschrieben
und die Mailserver des Providers des Gegenüber nehmen keine Mails mehr
von einem an. Manchmal schicken sie die Mail postwendend zurück; einige entsorgen sie aber auch unkommentiert im digtialen Mülleimer. Evtl. richten die
Nutzer selber einen Filter ein und sämtliche Mails werden nicht mehr
gelesen, sondern wandern gleich ins digitale Nirwana. Daher sollte
man Schlagwörter wie <em>SEX und earn more money</em> gleich vermeiden. (Auch
wenn <em>sex</em> im Englischen <em>Geschlecht</em> bezeichnet und somit medizinische
Fach-Artikel ebenfalls rausfallen).</p>
<p>Auch sollte man beachten, dass einige Surfer*innen noch Ihr geliebtes
veraltetes Mailprogramm benutzen oder auf einem kleinen Handybildschirm
arbeiten, der nur 80 Spalten anbietet. Ein großer Softwarehersteller hat
diese berühmte Eigenschaft, dass sie die E-Mail in einer Zeile
schreiben. Mann kann verstehen, wenn die Surfer*innen verärgert ist, weil sie
beim Erhalt der E-Mail nur eine einzige Zeile erhält. Das macht das
Lesen und Beantworten der E-Mail schwerer. Daher sollte man eine
automatischen Zeilensprung nach 72 Spalten bei seinem
Lieblings-E-Mail-Programm einstellen. Dann kann man immer noch quoten.
Gerade bei Mailing-Listen stößt so etwas sonst auf wenig Verständnis;
evtl. wird die Mail gar nicht erst gelesen. Man sollte Vorsicht walten
lassen und die Mitleser nicht gleich bei der ersten Mail zu verärgern.
Daher empfiehlt es sich die ersten Tage nur mitzulesen und die
allgemeine Umgangsformen, Philosophien und Schreibweisen kennenzulernen.
(Meist gibt es aber ein lockeres &ldquo;Du&rdquo;). Vielleicht gibt es ja auch
eine gepflegte FAQ (Oft gestellte Fragen), in die man erst hineinschauen
sollte, um nervende Anfängerfragen zu vermeiden.</p>

<h2 id="formatierung-html-mails-javascript" data-numberify>Formatierung (HTML-Mails, Javascript)<a class="anchor ms-1" href="#formatierung-html-mails-javascript"></a></h2>
<p>Aber eine E-Mail ist noch mehr. Sie kann auch Gefühle und Emotionen
überbringen. Eine Möglichkeit ist mit Emoctions (Emotions + Icons) zu
arbeiten. Das sind um 90° Grad gedrehte Smilies.</p>
<p>Im Netz gibt es tausende solcher Sammlungen. Ein einfaches Beispiel ist
der lachende Smilie <code>:-)</code> oder der verärgerte <code>:-(</code></p>
<p>Grundsätzlich verzichten sollten Sie auf GROSSGESCHRIEBENE und G E S P E
R R T E Wörter, da diese als schreien interpretiert werden. Schließlich
möchte man ja etwas von seinem Gegenüber.</p>
<p>Auch sollte man mit Spielerein wie HTML-Mails, Javascript vorsichtig
sein. Ersten sind es potentielle Sicherheitslöcher und meistens
unerwünscht. Ältere E-Mail-Programme können diesen Schnick-Schnak zudem
nicht interpretieren und zeigen dann nur den reinen HTML-Code an. Dort
den eigentlichen Informationsgehalt herauszufiltern ist für den
Gesprächspartner meist recht mühselig. Auch hat jeder ein anderes
Farbempfinden. Jede Zeile in einer anderen Schriftart und einer anderen
Farbe zu verfassen, ist für das lesende Gegenüber meist nur nervtötend.</p>

<h2 id="dateianhänge-attachments" data-numberify>Dateianhänge (Attachments)<a class="anchor ms-1" href="#dateianhänge-attachments"></a></h2>
<p>Dann wären wir auch schon bei den Attachments, den sogenannten
Datei-Anhängen. Nicht nur, dass sie potentiell Viren enthalten können,
man muss auch noch davon ausgehen, dass der Gegenüber auch das jeweilige
Format anzeigen und somit lesen kann.</p>
<p>Größere Datei-Anhänge sollte man grundsätzlich komprimieren. Das
<code>zip</code>-Format hat sich hier als Standard herauskristallisiert. Falls die E-Mail
größer als 100kb wird, sollte man sich mit dem Gesprächspartner
absprechen. Dann kann er sich darauf einstellen und die E-Mails im
günstigeren WLAN abholen. Auch beachten sollte man, dass die meisten
E-Mail-Postfächer in ihrer Größe begrenzt sind.</p>
<p>Wenn es Textdokumente sind, sollte man sie gleich in eigenen Mail-Text
mit einfügen. Wenn es denn unbedingt mit Formatierung sein muss, dann
sollten Sie das RichTextFormat (Endung <code>.rtf</code>) verwenden. Dieses Format
versteht eigentlich jedes Textverarbeitungs-Programm.</p>
<p>Langsam setzt sich auch das <em>portableDocumentFormat</em> durch
(Endung <code>.pdf</code>). Dieses Format kann zudem keine Makro-Viren enthalten
und die Lese-Software ist für nahezu jedes Betriebs-System kostenlos
verfügbar. Jedoch sollte man sicher sein, den jeweils aktuellste
Software installiert zu haben. Eine spezielle Formatierung erlaubt bei
alten Versionen einen Pufferüberlauf, der im günstigsten Fall nur ein
Abstürzen der Lese-Software zur Folge hat. So manche Bewerbung ist
gleich im Mülleimer gelandet, nur weil der zukünftige Chef in spe gerade
kein Word installiert hatte (Kein Zeit, kein Lust, Unvermögen). Bei
Bildern sollte man sich an Standards halten und nur Bilder im
jpeg-Format (<code>.jpg</code> bzw. <code>.jpeg</code>) oder im <code>.gif</code>-Format. Nicht jeder hat
die Präsentationssoftware vom Software-Monopolisten auf der Festplatte.
Eine recht gute kostenlose Alternative bietet hier OpenOffice und
LibreOffice, welches schon in vielen Sprachen und den vielen
Betriebssystem-Plattformen verfügbar ist. Die Importfilter sind
inzwischen sehr gut.</p>
<p>Aktelle Diskussionen zeigen, dass man zudem nicht unüberlegt jedes
Attachment öffnen sollte. (Siehe I-LOVE-YOU-Virus, Emotet, Crypto-Trojaner, Verschlüsselungs-Trojaner) Grundsätzlich
sollte man aufpassen, wenn man von einer Bekannte*n unaufgefordert eine
E-Mail mit Anhang zugeschickt bekommt. Dann sollte man vorher noch mal
rückfragen, ob die E-Mail wirklich von der Absender*in versandt wurde. Wenn
der Bekannte*r dann auch noch in englisch schreibt, obwohl die
vorhergehenden immer in deutsch waren oder die Absender*in unbekannt ist,
sollten spätestens jetzt alle Alarmglocken läuten. Dann empfiehlt es
sich nur, die E-Mail schnellstens zu löschen und einen aktuellen
Virenscanner zu besorgen.</p>

<h2 id="beantwortungszeit" data-numberify>Beantwortungszeit<a class="anchor ms-1" href="#beantwortungszeit"></a></h2>
<p>Ich lese E-Mails meist regelmäßig, d.h. aber nicht dass ich sie sofort
beantworte. Entweder habe ich gerade viel zu tun, muss über die Antwort
noch einmal nachdenken, evtl. keine Lust oder ich habe schlicht keine
Zeit sie sofort zu beantworten - selbiges gilt für andere
Kommunikationsformen wie z.B. Messenger und soziale Medien.</p>

<h2 id="anrufbeantworter" data-numberify>Anrufbeantworter<a class="anchor ms-1" href="#anrufbeantworter"></a></h2>
<p>Ein sehr umstrittenes und mein letztes Thema:</p>
<p>Wenn Sie urlaubsbedingt oder aus anderen Gründen mehrere Tage nicht an
Ihre Mails denken möchten:</p>
<p>Schalten Sie doch einfach Ihren &ldquo;Anrufbeantworter&rdquo; für E-Mails, die
Abwesenheitsschaltung, ein. Wer Ihnen dann eine E-Mail schickt, erfährt
postwendend, dass und wie lange er auf eine Antwort warten muss.</p>
<p>Eine Netzies stören sich hingegen an der zusätzlichen und Ihrer Meinung
nach unnötigen Mail.</p>
<p>Es ist wie im richtigen Leben. Einige verabscheuen die &ldquo;Eiserne Emma&rdquo;
einige lieben sie.</p>
<p>Für E-Mail-Listen gilt:</p>
<p>Kein Anrufbeantworter. Unbedingt für die Zeit der Abwesenheit aus der
Liste austragen, falls man einen Anrufbeantworter verwendet. Bei
hochfrequentierten Listen macht es keinen guten Eindruck, wenn jede Mail
auf der Liste vom eigenen Anrufbeantworter beantwortet wird, die dann ja
wieder durch die gesamte Liste geht; somit auch an einen selber, die
dann wieder per Anrufbeantworter beantwortet wird &hellip;</p>

<h2 id="zu-guter-letzt" data-numberify>Zu guter Letzt<a class="anchor ms-1" href="#zu-guter-letzt"></a></h2>
<p>Wenn die E-Mail geschrieben ist, empfiehlt es sich, die E-Mail nochmals
durchzulesen, ggf. zu korrigieren und dann erst abzuschicken.</p>]]></content:encoded>
    </item>
    
    <item>
      <title>Das /etc-Verzeichnis</title>
      <link>https://www.rainerrose.de/docs/linux/das-etc-verzeichnis/</link>
      <pubDate>Sat, 02 May 2020 15:26:59 +0100</pubDate>
      <guid>https://www.rainerrose.de/docs/linux/das-etc-verzeichnis/</guid>
      <description><![CDATA[<!-- Anreißer -->
<p>Notizen zum <code>/etc</code>-Verzeichnis.</p>]]></description>
      <content:encoded><![CDATA[<!-- Anreißer -->
<p>Notizen zum <code>/etc</code>-Verzeichnis.</p>

<h2 id="issue" data-numberify>issue<a class="anchor ms-1" href="#issue"></a></h2>
<p>In diese Datei kann man einen Begrüßungstext schreiben, der bei jedem Konsolen-Login erscheint. Dort schreibt SuSE auch seinen Text:</p>
<p>Welcome to SuSE 6.1&hellip;</p>
<p>In der Datei <code>issue.net</code> steht hingegen der Text, der bei einem <code>telnet</code>, <code>ssh</code> etc. erscheinen soll.
inetd.conf</p>
<p>Dort kann man Dienste, die nicht nach außen angeboten werden einfach sperren. Wie z.B. <code>finger</code>, <code>ftp</code>, <code>telnet</code>, &hellip;</p>

<h2 id="mothd" data-numberify>mothd<a class="anchor ms-1" href="#mothd"></a></h2>
<p>Message of the Day</p>
<p>Dieser Text wird nach dem Login auf einer Konsole ausgegeben. Auch unter X gibt es so etwas: <code>xmessage</code>.</p>

<h2 id="syslogd-syslog-demon" data-numberify>syslogd (Syslog-Demon)<a class="anchor ms-1" href="#syslogd-syslog-demon"></a></h2>
<p>Der <code>syslogd</code> ist doch meist so nervtötend vorkonfiguriert, dass er andauernd ins Logfile schreibt, dass es nichts zu melden gibt!?</p>
<p>Mit der Option <code>-m 0</code> kann das abschalten werden.</p>]]></content:encoded>
    </item>
    
    <item>
      <title>Subdomains</title>
      <link>https://www.rainerrose.de/docs/kontakt/subdomains/</link>
      <pubDate>Sat, 02 May 2020 15:26:36 +0100</pubDate>
      <guid>https://www.rainerrose.de/docs/kontakt/subdomains/</guid>
      <description><![CDATA[<!-- Anreißer -->
<p>Erläuterungen zu den verwendeten Subdomains.</p>]]></description>
      <content:encoded><![CDATA[<!-- Anreißer -->
<p>Erläuterungen zu den verwendeten Subdomains.</p>

<h1 id="subdomains" data-numberify>Subdomains<a class="anchor ms-1" href="#subdomains"></a></h1>
<div class="alert alert-warning" role="alert"><i class="alert-icon fas fa-fw fa-exclamation-triangle me-1"></i>

  Ein paar Domains sind nur zu Kommunikations-Zwecken gedacht und werden bei mir nur zur Generierung von E-Mail-Adressen gebraucht.
</div>


<h2 id="no-spamrainerrosede--keine-werbungrainerrosede" data-numberify>no-spam.rainerrose.de / keine-werbung.rainerrose.de<a class="anchor ms-1" href="#no-spamrainerrosede--keine-werbungrainerrosede"></a></h2>
<p>Wie die Sub-Domains schon aussagen, verbitte ich mir über die Aliase
(der Teil vor dem <code>@</code>) dieser Domain jeglichen Spam, Werbemüll,
Kettenbriefe, übergroße Anhänge und sonstige Nerv-Mails.</p>
<p>Die <strong>Filter</strong> dieser Domain sind normalerweise <strong>recht restriktiv
eingestellt</strong>, so dass z.B. IP-Blacklists oder andere Wegwerf-Regeln
recht früh zuschlagen. [Benutzen Sie bitte den zugewiesen
Alias]{.underline} mit Ihrer gewohnten E-Mail-Adresse. <strong>Beachten</strong> Sie
auch bitte meinen <strong><a href="../e-mail-guide">E-Mail-Guide</a></strong>.</p>
<p><strong>Beispiele für Müll:</strong></p>
<ul>
<li>Kaputte E-Mails (kein Betreff, falsche Message-ID's),</li>
<li>E-Mails an Aliases dürfen nur von bestimmten E-Mail-Adressen
angeschrieben werden</li>
<li>einige bekannte Spam-Domains sind generell gesperrt</li>
</ul>
<p><strong>Fühlt sich ein Filter</strong>, der auf dem E-Mail-Server arbeitet, zuständig,
schlägt er sofort zu und schiebt die Mail sofort in den digitalen
Mülleimer. Achten Sie also im eigenen Interesse drauf, dass
Ihr Provider, Computer oder E-Mail-Account keine Spams versendet und die
E-Mail allgemein gültigen Spezifikationen und Kommunikationsregeln (z.B.
kein leeren Betreff) entspricht, da ich solche E-Mails werde ich nie zu
Gesicht bekommen werde, weil sie vorher schon entsorgt werden. Die
nächste Hürde, die die E-Mails nehmen müssen sind meine
Filtereinstellungen meines E-Mail Programms. Auch hier wird fleißig
aussortiert und in Unterordner verschoben. Teilweise rufe ich gewisse
E-Mail-Konten auch nur recht unregelmäßig ab.</p>

<h2 id="keine-antwort-erhalten" data-numberify>Keine Antwort erhalten?<a class="anchor ms-1" href="#keine-antwort-erhalten"></a></h2>
<p>Siehe Artikel &ldquo;<a href="../keine-antwort">Keine Antwort?</a>&rdquo;.</p>]]></content:encoded>
    </item>
    
    <item>
      <title>Nostalgie-Script</title>
      <link>https://www.rainerrose.de/docs/linux/nostalgie-script/</link>
      <pubDate>Sat, 02 May 2020 15:25:17 +0100</pubDate>
      <guid>https://www.rainerrose.de/docs/linux/nostalgie-script/</guid>
      <description><![CDATA[<!-- Anreißer -->
<p>Nach diesem Script habe ich mich in den Anfängen meiner Linux-Zeit[^1) dumm und dämlich gesucht. Aus Nostalgie-Gründen (und vielleicht braucht man es ja doch noch mal, paste ich es hier nochmal rein. Alles andere kommt inzwischen ins git.</p>]]></description>
      <content:encoded><![CDATA[<!-- Anreißer -->
<p>Nach diesem Script habe ich mich in den Anfängen meiner Linux-Zeit[^1) dumm und dämlich gesucht. Aus Nostalgie-Gründen (und vielleicht braucht man es ja doch noch mal, paste ich es hier nochmal rein. Alles andere kommt inzwischen ins git.</p>

<h2 id="aufgabe" data-numberify>Aufgabe<a class="anchor ms-1" href="#aufgabe"></a></h2>
<p>Es ersetzt in allen Dateien der angegebenen Verzeichnisse, das per
Parameter angegebene Suchmuster.</p>
<p>Gebraucht habe ich es mal für meinen HTML-Seiten wo ich &quot;EUR&quot; durch
&quot;€&quot; ersetzen wollte.</p>

<h2 id="anwendung" data-numberify>Anwendung<a class="anchor ms-1" href="#anwendung"></a></h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">usage: gsed sed-command <span class="o">[</span>dir ...<span class="o">]</span>
</span></span></code></pre></div><p><code>sed-command</code> entspricht dabei den normalen <code>sed</code> Parameter. Siehe man-Page.</p>

<h3 id="einige-anwendungsbeispiele" data-numberify>Einige Anwendungsbeispiele:<a class="anchor ms-1" href="#einige-anwendungsbeispiele"></a></h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">gsub s/EUR/<span class="se">\\\&amp;</span>euro<span class="se">\;</span>/g <span class="c1"># ====&gt; EUR =&gt; &amp;euro;</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl">gsub s/<span class="se">\Ä</span>/<span class="se">\\\&amp;</span>Auml<span class="se">\;</span>/g <span class="c1"># ====&gt; Ä =&gt; &amp;Auml; (Groß- Kleinschreibung beachten !)</span>
</span></span><span class="line"><span class="ln">3</span><span class="cl">gsub s/<span class="se">\Ä</span>/<span class="se">\\\&amp;</span>Auml<span class="se">\;</span>/gi <span class="c1"># ====&gt; Ä =&gt; &amp;Auml; (Groß- Kleinschreibung egal !)</span>
</span></span><span class="line"><span class="ln">4</span><span class="cl">gsub s/<span class="se">\
</span></span></span><span class="line"><span class="ln">5</span><span class="cl"><span class="se">\&lt;\\\/</span>td<span class="se">\&gt;</span>/<span class="se">\&lt;\\\/</span>td<span class="se">\&gt;</span>/g <span class="c1"># =====&gt; &lt;br&gt;&lt;/td&gt; =&gt; &lt;/td&gt;</span>
</span></span><span class="line"><span class="ln">6</span><span class="cl">gsub s/http<span class="se">\:\\</span>/<span class="se">\\</span>/www./..<span class="se">\\</span>/img/g <span class="c1"># ====&gt; http://www. =&gt; /img</span>
</span></span></code></pre></div>
<h3 id="prinzip" data-numberify>Prinzip:<a class="anchor ms-1" href="#prinzip"></a></h3>
<p><code>s/raus/rein/g</code></p>

<h3 id="weiterer-tipp" data-numberify>Weiterer Tipp<a class="anchor ms-1" href="#weiterer-tipp"></a></h3>
<p>Und wenn das ersetzen nicht klappt ruhig mal öfters ein \ setzen, wie
bei:</p>
<ul>
<li><code>\\\&amp;</code></li>
<li><code>\\/</code></li>
</ul>

<h2 id="quell-code" data-numberify>Quell-Code<a class="anchor ms-1" href="#quell-code"></a></h2>
<div class="highlight" title="gsub.sh"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln"> 1</span><span class="cl">    <span class="c1">#!/bin/sh</span>
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">    <span class="c1">#</span>
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">    <span class="c1"># Global sed on all files contained in a list of directories.</span>
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">    <span class="c1"># The command</span>
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">    <span class="c1"># gsub cmd dir1 dir2 ...</span>
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">    <span class="c1"># will do</span>
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">     
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">    <span class="c1"># sed -e cmd</span>
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">    <span class="c1"># on each file found in dir1, dir2, ...</span>
</span></span><span class="line"><span class="ln">10</span><span class="cl">    <span class="c1">#</span>
</span></span><span class="line"><span class="ln">11</span><span class="cl">    <span class="c1"># If a file is changed, a backup copy is created.</span>
</span></span><span class="line"><span class="ln">12</span><span class="cl">    <span class="c1"># Files .*.swp and CVS directories are skipped.</span>
</span></span><span class="line"><span class="ln">13</span><span class="cl">     
</span></span><span class="line"><span class="ln">14</span><span class="cl">     
</span></span><span class="line"><span class="ln">15</span><span class="cl">    usage<span class="o">()</span> <span class="o">{</span>
</span></span><span class="line"><span class="ln">16</span><span class="cl">    <span class="nb">echo</span> <span class="s2">&#34;usage: gsed sed-command [dir ...]&#34;</span> &gt;<span class="p">&amp;</span> <span class="m">2</span>
</span></span><span class="line"><span class="ln">17</span><span class="cl">    <span class="nb">exit</span> <span class="m">1</span>
</span></span><span class="line"><span class="ln">18</span><span class="cl">    <span class="o">}</span>
</span></span><span class="line"><span class="ln">19</span><span class="cl">     
</span></span><span class="line"><span class="ln">20</span><span class="cl">    <span class="nv">tmp</span><span class="o">=</span>/var/tmp/gsub.<span class="nv">$$</span>
</span></span><span class="line"><span class="ln">21</span><span class="cl">     
</span></span><span class="line"><span class="ln">22</span><span class="cl">     
</span></span><span class="line"><span class="ln">23</span><span class="cl">    <span class="nb">trap</span> <span class="s2">&#34;rm -f </span><span class="nv">$tmp</span><span class="s2">&#34;</span> <span class="m">0</span> <span class="m">1</span> <span class="m">2</span> <span class="m">3</span> <span class="m">15</span>
</span></span><span class="line"><span class="ln">24</span><span class="cl">     
</span></span><span class="line"><span class="ln">25</span><span class="cl">    <span class="k">if</span> <span class="o">[</span> <span class="nv">$#</span> -lt <span class="m">1</span> <span class="o">]</span><span class="p">;</span> <span class="k">then</span>
</span></span><span class="line"><span class="ln">26</span><span class="cl">    usage
</span></span><span class="line"><span class="ln">27</span><span class="cl">    <span class="k">fi</span>
</span></span><span class="line"><span class="ln">28</span><span class="cl">     
</span></span><span class="line"><span class="ln">29</span><span class="cl">     
</span></span><span class="line"><span class="ln">30</span><span class="cl">    <span class="nv">cmd</span><span class="o">=</span><span class="s2">&#34;</span><span class="nv">$1</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="ln">31</span><span class="cl">     
</span></span><span class="line"><span class="ln">32</span><span class="cl">    <span class="nb">shift</span>
</span></span><span class="line"><span class="ln">33</span><span class="cl">     
</span></span><span class="line"><span class="ln">34</span><span class="cl">    <span class="k">if</span> <span class="o">[</span> <span class="nv">$#</span> <span class="o">=</span> <span class="m">0</span> <span class="o">]</span><span class="p">;</span> <span class="k">then</span>
</span></span><span class="line"><span class="ln">35</span><span class="cl">    <span class="nb">set</span> .
</span></span><span class="line"><span class="ln">36</span><span class="cl">    <span class="k">fi</span>
</span></span><span class="line"><span class="ln">37</span><span class="cl">     
</span></span><span class="line"><span class="ln">38</span><span class="cl">     
</span></span><span class="line"><span class="ln">39</span><span class="cl">    find <span class="nv">$*</span> -name CVS -prune -o <span class="se">\(</span> -type f ! -name <span class="s1">&#39;*~&#39;</span> ! -name <span class="s1">&#39;.*.swp&#39;</span> -print <span class="se">\)</span> <span class="p">|</span>
</span></span><span class="line"><span class="ln">40</span><span class="cl">    <span class="k">while</span> <span class="nb">read</span> file<span class="p">;</span> <span class="k">do</span>
</span></span><span class="line"><span class="ln">41</span><span class="cl">    sed -e <span class="s2">&#34;</span><span class="nv">$cmd</span><span class="s2">&#34;</span> <span class="s2">&#34;</span><span class="nv">$file</span><span class="s2">&#34;</span> &gt; <span class="s2">&#34;</span><span class="nv">$tmp</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="ln">42</span><span class="cl">    <span class="k">if</span> cmp -s <span class="s2">&#34;</span><span class="nv">$file</span><span class="s2">&#34;</span> <span class="s2">&#34;</span><span class="nv">$tmp</span><span class="s2">&#34;</span><span class="p">;</span> <span class="k">then</span>
</span></span><span class="line"><span class="ln">43</span><span class="cl">    :
</span></span><span class="line"><span class="ln">44</span><span class="cl">     
</span></span><span class="line"><span class="ln">45</span><span class="cl">    <span class="k">else</span>
</span></span><span class="line"><span class="ln">46</span><span class="cl">    <span class="nb">echo</span> <span class="s2">&#34;</span><span class="nv">$file</span><span class="s2">: patched&#34;</span> &gt;<span class="p">&amp;</span> <span class="m">2</span>
</span></span><span class="line"><span class="ln">47</span><span class="cl">    mv <span class="s2">&#34;</span><span class="nv">$file</span><span class="s2">&#34;</span> <span class="s2">&#34;</span><span class="nv">$file</span><span class="s2">~&#34;</span>
</span></span><span class="line"><span class="ln">48</span><span class="cl">    cp <span class="s2">&#34;</span><span class="nv">$tmp</span><span class="s2">&#34;</span> <span class="s2">&#34;</span><span class="nv">$file</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="ln">49</span><span class="cl">    <span class="k">fi</span>
</span></span><span class="line"><span class="ln">50</span><span class="cl">     
</span></span><span class="line"><span class="ln">51</span><span class="cl">    <span class="k">done</span>
</span></span></code></pre></div>
<h2 id="dank" data-numberify>Dank<a class="anchor ms-1" href="#dank"></a></h2>
<p><strong>Dank an Matthias Kilian von der LUG-Braunschweig</strong> :!:</p>
<p>Original-Ton aus seiner Mail:</p>
<blockquote>
<p>Bitte nach Bedarf tunen. [Ja, ich weiß, dass es böse ist, das
temporäre Verzeichnis fest zu verdrahten. Wer das nicht mag, kann ja
zusätzliche TMPDIR auswerten.]</p>
<p>Das Script ist sogar so nett, nur Dateien, die sich wirklich geändert
haben, zu überschreiben, bei unmodifizierten Dateien bleibt also die
Modificationtime unverändert. Außerdem wird bei modifizierten Dateien
eine Backupdatei angelegt.</p>
<p>Würde ich es heute noch mal schreiben, dann würde ich aber wohl statt
sed(1) den ed(1) nehmen, um mir den ganzen Kram mit temporären Dateien
zu ersparen.</p>
</blockquote>]]></content:encoded>
    </item>
    
    <item>
      <title>Seriell und PCI</title>
      <link>https://www.rainerrose.de/docs/linux/seriell-und-pci/</link>
      <pubDate>Sat, 02 May 2020 15:25:05 +0200</pubDate>
      <guid>https://www.rainerrose.de/docs/linux/seriell-und-pci/</guid>
      <description><![CDATA[<!-- Anreißer -->
<p>Serielle Schnittstelle, es gibt sie immer noch.</p>]]></description>
      <content:encoded><![CDATA[<!-- Anreißer -->
<p>Serielle Schnittstelle, es gibt sie immer noch.</p>

<h2 id="kernel" data-numberify>Kernel<a class="anchor ms-1" href="#kernel"></a></h2>
<p>Ab dem <strong>2.2.5-Kernel</strong> wird die <strong>serielle Port-Unterstützung</strong>
automatisch als Modul geladen. Das macht bei einem selbstgebastelten
Kernel Probleme.</p>
<p>Die Lösung sah bei SuSE 6.1 so aus:</p>
<p>Die Datei <code>/lib/modules/2.2.5/misc/serial.o</code> muss gelöscht werden, dann
kann das Modul nicht mehr geladen werden.</p>
<p>In der Datei <code>/etc/conf.modules</code> die Zeile:</p>
<pre><code>  alias char-major-4 serial
</code></pre>
<p>nach:</p>
<pre><code>  alias char-major-4 off
</code></pre>
<p>ändern, um zu verhindern, dass der Kernel versucht das Modul
nachzuladen.</p>

<h2 id="pci-geräte" data-numberify>PCI-Geräte<a class="anchor ms-1" href="#pci-geräte"></a></h2>
<p>Beim Konfigurieren von PCI-Geräten wie z.B. ISDN-Karten dürfen keine
IRQ- und Adresse-Parameter angeben werden.</p>

<h2 id="ps2-maus" data-numberify>PS/2-Maus<a class="anchor ms-1" href="#ps2-maus"></a></h2>
<p>Besitzt man eine PS/2-Maus und man bekommt die Maus nicht konfiguriert,
sollte man als Protokoll <code>Mouseman</code> ausprobieren.</p>]]></content:encoded>
    </item>
    
    <item>
      <title>Kontakt-Infos</title>
      <link>https://www.rainerrose.de/docs/kontakt/start/</link>
      <pubDate>Sun, 19 Apr 2020 17:23:04 +0100</pubDate>
      <guid>https://www.rainerrose.de/docs/kontakt/start/</guid>
      <description><![CDATA[<!-- Anreißer -->
<p>Bitte beachten, dass für manche betreuungsintensive Projekte eigene E-Mail Kontaktadressen und Telefonnummern eingerichtet wurden.</p>]]></description>
      <content:encoded><![CDATA[<!-- Anreißer -->
<p>Bitte beachten, dass für manche betreuungsintensive Projekte eigene E-Mail Kontaktadressen und Telefonnummern eingerichtet wurden.</p>

<h2 id="kontaktmöglichkeiten" data-numberify>Kontaktmöglichkeiten<a class="anchor ms-1" href="#kontaktmöglichkeiten"></a></h2>
<p>Solche speziellen Kontaktmöglichkeiten sind in der Regel zu bevorzugen. Falls
Kontaktinformationen im Rahmen eines Projekts veröffentlicht oder
anderweitig weitergereicht werden sollen, bitte ich um vorherige Absprache.</p>

<h2 id="keine-antwort-erhalten" data-numberify>Keine Antwort erhalten?<a class="anchor ms-1" href="#keine-antwort-erhalten"></a></h2>
<p>Dann <a href="/kontakt/keine-antwort/">diesen Post</a> lesen.</p>

<h2 id="antwort-auf-e-mails-erwünscht" data-numberify>Antwort auf E-Mails erwünscht?<a class="anchor ms-1" href="#antwort-auf-e-mails-erwünscht"></a></h2>
<p>Dann bitte den
<a href="/kontakt/emailknigge">E-Mail-Guide</a> beachten.</p>]]></content:encoded>
    </item>
    
    <item>
      <title>Schon gewusst?</title>
      <link>https://www.rainerrose.de/posts/schon_gewusst/</link>
      <pubDate>Sun, 19 Apr 2020 13:22:44 +0200</pubDate>
      <guid>https://www.rainerrose.de/posts/schon_gewusst/</guid>
      <description><![CDATA[<!-- Anreißer -->
<p>Eine muntere Ansammlung von unnützen Wissen.</p>]]></description>
      <content:encoded><![CDATA[<!-- Anreißer -->
<p>Eine muntere Ansammlung von unnützen Wissen.</p>
<ul>
<li>Eine Apfelsine enthält den gesamten Vitamingehalt einer Orange !</li>
<li>Die Raupe ist entlarvt, es ist ein Schmetterling !</li>
<li>Tränen ist die einzige Körperflüssigkeit vor der man sich nicht ekeln kann.<sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup></li>
<li>Schadenfreude ist die ehrlichste Form von Mitleid.</li>
</ul>
<div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p>Alles andere ist angeboren, wie Maden im Essen, oder angelernt, wie z.B. keinen Spinat mögen. Warum? Es ist eine Schutzfunktion, die sich im Laufe der Evolution entwickelt hat. Das erklärt auch, warum meist Frauen mehr Ekel empfinden als Männer. Frauen haben früher traditionell den Nachwuchs beschützt.&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
</ol>
</div>]]></content:encoded>
    </item>
    
    <item>
      <title>Team bzw. Teamwork</title>
      <link>https://www.rainerrose.de/posts/teamwork-team_-_definition/</link>
      <pubDate>Sun, 19 Apr 2020 00:19:47 +0200</pubDate>
      <guid>https://www.rainerrose.de/posts/teamwork-team_-_definition/</guid>
      <description><![CDATA[<!-- Anreißer -->
<p>Defintion von Team bzw. Teamwork</p>]]></description>
      <content:encoded><![CDATA[<!-- Anreißer -->
<p>Defintion von Team bzw. Teamwork</p>

<h2 id="teamwork" data-numberify>Teamwork<a class="anchor ms-1" href="#teamwork"></a></h2>
<div class="alert alert-Info" role="alert"><i class="alert-icon fas fa-fw fa-info-circle me-1"></i>

  Teamwork ist - wenn alle dasselbe wollen wie ich.
</div>


<h2 id="was-heisst-team" data-numberify>Was heisst TEAM?<a class="anchor ms-1" href="#was-heisst-team"></a></h2>
<p><strong>T</strong>oll <strong>E</strong>in <strong>A</strong>nderer <strong>M</strong>acht´s</p>]]></content:encoded>
    </item>
    
    <item>
      <title>Fragen, auf die ich keine Antwort weiß</title>
      <link>https://www.rainerrose.de/posts/fragen-auf-die-ich-keine-antwort-weiss/</link>
      <pubDate>Sun, 19 Apr 2020 00:17:40 +0200</pubDate>
      <guid>https://www.rainerrose.de/posts/fragen-auf-die-ich-keine-antwort-weiss/</guid>
      <description><![CDATA[<!-- Anreißer -->
<p>Es treiben mich manchmal Dinge um und dann stelle ich mir Fragen, auf die ich keine Antwort weiß, aber die bisher auch sonst noch niemand beantworten konnte.</p>]]></description>
      <content:encoded><![CDATA[<!-- Anreißer -->
<p>Es treiben mich manchmal Dinge um und dann stelle ich mir Fragen, auf die ich keine Antwort weiß, aber die bisher auch sonst noch niemand beantworten konnte.</p>
<ol>
<li>Aus welchem Material besteht eine Holz-eisen-bahn?</li>
<li>Was zählen Schafe, wenn sie nicht einschlafen können?</li>
<li>Herr Rose, warum wischen Sie den Flur immer nie? Hä?</li>
<li>Wie soll ich der Aufforderung nachkommen:<br>
Fahr mal langsam schneller.</li>
<li>Was versteht man unter einer Doppelhaushälfte?</li>
<li>Was ist ein eingefleischter Vegetarier?</li>
<li>Welche Farbe bekommt ein Schlumpf, wenn man ihn würgt?</li>
<li>Wie soll ich reagieren, wenn jemand zu mir sagt:<br>
Komm geh´ weg.</li>
<li>Wenn schwimmen schlank macht, was macht ein Blauwal falsch?</li>
<li>Warum halten die Fäden, die die Socken zusammenhalten, besser als die Socken selbst?</li>
<li>Warum ist Abkürzung so ein langes Wort?</li>
<li>Dürfen Vegetarier fleischfressende Pflanzen essen?</li>
<li>Bleibt man trocken, wenn man in geschmolzenen Trockeneis schwimmt?</li>
<li>Was fühlt ein Schmetterling, wenn er verliebt ist?</li>
<li>Was tat der Mensch eigentlich, als er entdeckte, dass die Kuh Milch gibt?</li>
<li>Warum musste Noah eigentlich die beiden Tse-Tse Fliegen retten?</li>
<li>Was ist eigentlich das Gegenteil von Schokoladenseite?</li>
<li>Wenn Katholiken auf eine Demo gehen, sind sie dann Protestanten?</li>
<li>Gibt es ein anderes Wort für Synonym?</li>
<li>Leiden kabellose Tastaturen unter Bindungsangst?</li>
<li>Kann ein Pantomime die Schallmauer durchbrechen?</li>
<li>Wenn nichts an Teflon haftet, wie haftet Teflon an der Pfanne?</li>
<li>Wenn in Flugzeugen Schwimmwesten sind, gibt es auf Schiffen dann Fallschirme?</li>
<li>Warum ist einsilbig dreisilbig?</li>
<li>Gibt es in einer Teefabrik Kaffeepausen?</li>
<li>Was passiert nachdem man sich zweimal mal halb tot gelacht hat?</li>
<li>Wenn ein Schäfer seine Schafe verhaut, ist er dann ein Mähdrescher?</li>
<li>Wer hatte bloß die Idee, ein &ldquo;S&rdquo; in das Wort &ldquo;lispeln&rdquo; zu stecken?</li>
<li>Was ist besser: Drei Vierkornbrötchen oder vier Dreikornbrötchen?</li>
<li>Ist ein Keks, der unter einem Baum liegt, nicht ein wunderbar schattiges Plätzchen?</li>
<li>Wenn Superkleber wirklich überall klebt, warum nicht an der Innenseite der Tube?</li>
<li>Warum werden Rundschreiben in einem eckigen Umschlag verschickt?</li>
<li>Ist eine Gesichtscreme, die 20 Jahre jünger macht lebensgefährlich, wenn man erst 19 Jahre alt ist?</li>
<li>Sind nymphomane Hündinnen eigentlich zwangsläufig?</li>
<li>Wie lange muss eine Katze trainieren, um ein Muskelkater zu werden?</li>
<li>Können Einzelgänger auch alleinstehend sein?</li>
<li>Darf man mit Hosen zu einem Rockkonzert?</li>
<li>Darf sich jemand, der sich im Ruhestand befindet, nachts hinlegen?</li>
<li>Warum ist ein Kreiskrankenhaus nicht rund?</li>
<li>Woher kommt eigentlich die Aggressivität der Menschen, die ein Rad schlagen?</li>
<li>Darf man eine Tagesdecke auch nachts benutzen?</li>
<li>Ist ein Raumschiff, das ausschließlich mit Frauen besetzt, ist eigentlich Unbemannt?</li>
<li>Geht der Meeresspiegel kaputt, wenn man in See sticht?</li>
<li>Wie lange kriegt man für einen Wintereinbruch, oder gibt es darauf Bewährung?</li>
<li>Wo wachsen eigentlich Purzelbäume?</li>
<li>Warum haben 24 Stunden Tankstellen ein Schloss an der Tür?</li>
<li>Darf man in einem Schaltjahr auch Automatik fahren?</li>
<li>Wie kommt eigentlich das &ldquo;Rasen betreten verboten&rdquo;-Schild immer mitten auf den Rasen?</li>
<li>Warum muß man beim Hellseher Termine machen?</li>
<li>Warum gibt es kein Katzenfutter mit Mäusegeschmack?</li>
<li>Ernäheren sich Lichtesser (Lichternahrung) mit Energiesparlampen besonders kalorienarm ?</li>
<li>Ist jemand, der ständig aus dem Fenster guckt, wenn es aus Eimern gießt, eigentlich ein Regenschauer?</li>
<li>Warum heißt es Auto-Bahn?</li>
</ol>
<p>Wer mehr Fragen weiß, die die Welt bewegen, kontaktiere mich bitte. Auch Antworten sind gerne gesehen.</p>]]></content:encoded>
    </item>
    
    <item>
      <title>English for awaystep - Englisch für Fortgeschrittene</title>
      <link>https://www.rainerrose.de/posts/english-for-awaystep_-_englisch-fuer-fortgeschrittene/</link>
      <pubDate>Sun, 19 Apr 2020 00:14:28 +0200</pubDate>
      <guid>https://www.rainerrose.de/posts/english-for-awaystep_-_englisch-fuer-fortgeschrittene/</guid>
      <description><![CDATA[<!-- Anreißer -->]]></description>
      <content:encoded><![CDATA[<!-- Anreißer -->
<table>
  <thead>
      <tr>
          <th>Englisch</th>
          <th>Deutsch</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>I just understand train-station</td>
          <td>ich versteh nur Bahnhof</td>
      </tr>
      <tr>
          <td>sorry, my englisch is under all pig</td>
          <td>entschuldige, mein englisch ist unter aller Sau</td>
      </tr>
      <tr>
          <td>I think I spider</td>
          <td>ich glaub ich spinne</td>
      </tr>
      <tr>
          <td>the devil will i do</td>
          <td>den Teufel werd ich tun</td>
      </tr>
      <tr>
          <td>my lovely mister singing club</td>
          <td>mein lieber Herr Gesangsverein</td>
      </tr>
      <tr>
          <td>come on...jump over your shadow</td>
          <td>komm schon...spring über deinen Schatten</td>
      </tr>
      <tr>
          <td>you walk me animally on the cookie</td>
          <td>du gehst mir tierisch auf den Keks</td>
      </tr>
      <tr>
          <td>there my hairs stand up to the mountain</td>
          <td>da stehen mir die Haare zu Berge</td>
      </tr>
      <tr>
          <td>tell me nothing from the horse</td>
          <td>erzähl mir keinen vom Pferd</td>
      </tr>
      <tr>
          <td>don't ask after sunshine</td>
          <td>frag nicht nach Sonnenschein</td>
      </tr>
      <tr>
          <td>it's not good cherry-eating with you</td>
          <td>es ist nicht gut Kirschenessen mit dir</td>
      </tr>
      <tr>
          <td>now it goes around the sausage</td>
          <td>jetzt geht's um die Wurst</td>
      </tr>
      <tr>
          <td>there you on the woodway</td>
          <td>da bist du auf dem Holzweg</td>
      </tr>
      <tr>
          <td>holla the woodfairy</td>
          <td>holla die Waldfee</td>
      </tr>
      <tr>
          <td>I hold it in head not out</td>
          <td>ich halt's im Kopf nicht aus</td>
      </tr>
      <tr>
          <td>now butter by the fishes</td>
          <td>jetzt mal Butter bei die Fische</td>
      </tr>
      <tr>
          <td>I see black for you</td>
          <td>ich seh schwarz für dich</td>
      </tr>
      <tr>
          <td>your are so a fear-rabbit</td>
          <td>du bist so ein Angsthase</td>
      </tr>
      <tr>
          <td>known home luck alone</td>
          <td>trautes heim, glück allein</td>
      </tr>
      <tr>
          <td>are you save?</td>
          <td>bist du sicher?</td>
      </tr>
      <tr>
          <td>give not so on</td>
          <td>gib nicht so an</td>
      </tr>
      <tr>
          <td>heaven, ass and thread!</td>
          <td>Himmel, Arsch und Zwirn!</td>
      </tr>
      <tr>
          <td>Human Meier</td>
          <td>Mensch Meier</td>
      </tr>
      <tr>
          <td>you have not more all cups in the board</td>
          <td>du hast nicht mehr alle Tassen im Schrank</td>
      </tr>
      <tr>
          <td>she had a circleroundbreakdown</td>
          <td>sie hatte einen Kreislaufzusammenbruch</td>
      </tr>
      <tr>
          <td>I know me here out</td>
          <td>ich kenn mich hier aus</td>
      </tr>
      <tr>
          <td>I fall from all clouds</td>
          <td>ich falle aus allen Wolken</td>
      </tr>
      <tr>
          <td>no one can reach me the water</td>
          <td>niemand kann mir das Wasser reichen</td>
      </tr>
      <tr>
          <td>not the yellow of the egg</td>
          <td>nicht das gelbe vom Ei</td>
      </tr>
      <tr>
          <td>everything in the green area</td>
          <td>alles im grünen Bereich</td>
      </tr>
      <tr>
          <td>I die for Blackforrestcherrycake</td>
          <td>Ich sterbe für Schwarzwälderkirschtorte</td>
      </tr>
      <tr>
          <td>it walks me icecold the back down</td>
          <td>es läuft mir eiskalt den Rücken runter</td>
      </tr>
      <tr>
          <td>I'm foxdevilswild</td>
          <td>ich bin fuchsteufelswild</td>
      </tr>
      <tr>
          <td>And now we have the salat</td>
          <td>Und nun haben wir den Salat</td>
      </tr>
      <tr>
          <td>I break together</td>
          <td>Ich brech zusammen</td>
      </tr>
      <tr>
          <td>I believe me kicks a horse</td>
          <td>Ich glaub mich tritt ein Pferd.</td>
      </tr>
      <tr>
          <td>I tell you now something</td>
          <td>Ich erzähl Dir jetzt was.</td>
      </tr>
      <tr>
          <td>She has hairs on her tooth</td>
          <td>Sie hat Haare auf den Zähnen.</td>
      </tr>
      <tr>
          <td>I am heavy on wire</td>
          <td>Ich bin schwer auf Draht.</td>
      </tr>
      <tr>
          <td>I delete me.</td>
          <td>Ich entferne mich.</td>
      </tr>
      <tr>
          <td>I feel my pig is whistling.</td>
          <td>Ich glaube mein Schwein pfeift.</td>
      </tr>
  </tbody>
</table>]]></content:encoded>
    </item>
    
    <item>
      <title>Das Ampere</title>
      <link>https://www.rainerrose.de/posts/das-ampere/</link>
      <pubDate>Sun, 19 Apr 2020 00:06:04 +0200</pubDate>
      <guid>https://www.rainerrose.de/posts/das-ampere/</guid>
      <description><![CDATA[<!-- Anreißer -->
<p>Das Ampere (A) ist die Stärke eines konstanten elektrischen Stromes, der,</p>]]></description>
      <content:encoded><![CDATA[<!-- Anreißer -->
<p>Das Ampere (A) ist die Stärke eines konstanten elektrischen Stromes, der,</p>
<p>durch zwei parallele, geradlinige, unendlich lange und im Vakuum im Abstand der Länge der Strecke, die Licht im Vakuum während der mit dem Quotienten von 9'192'631'770 und 299'792'458 multiplizierten Periodendauer, der dem Übergang zwischen den beiden Hyperfeinstrukturenniveaus des Grundzustandes von Atomen des Nuklids 133Cs entsprechenden Strahlung durchläuft vonaneinander angeordneten Leitern von vernachlässigbar kleinen kreisförmigen Querschnitt fließend, zwischen diesen Leitern auf jedem der Länge des Leiterabstandes entsprechendem Abschnitt eine Kraft von 2*10-7 Newton hervorrufen würde.</p>]]></content:encoded>
    </item>
    
    <item>
      <title>Impressum</title>
      <link>https://www.rainerrose.de/posts/impressum/</link>
      <pubDate>Fri, 03 Apr 2015 22:22:45 +0100</pubDate>
      <guid>https://www.rainerrose.de/posts/impressum/</guid>
      <description><![CDATA[<!-- Anreißer -->
<p>Die obligatorischen Nutzungsbedingungen, Datenschutzerklärungen und sonstigen Hinweise.</p>]]></description>
      <content:encoded><![CDATA[<!-- Anreißer -->
<p>Die obligatorischen Nutzungsbedingungen, Datenschutzerklärungen und sonstigen Hinweise.</p>

<h2 id="keine-kiaiml-klausel" data-numberify>Keine KI/AI/ML Klausel<a class="anchor ms-1" href="#keine-kiaiml-klausel"></a></h2>
<p>Es ist untersagt, Daten oder Inhalte von dieser Website für das Training oder die Entwicklung von Modellen der künstlichen Intelligenz oder des maschinellen Lernens zu verwenden, ohne die ausdrückliche Zustimmung meinerseits einzuholen.
Jede unbefugte Nutzung von Daten oder Inhalten für KI/AI/ML-Zwecke wird als Verstoß gegen das Urheberrecht betrachtet und kann rechtliche Schritte nach sich ziehen.</p>

<h2 id="nutzungsbedingungen" data-numberify>Nutzungsbedingungen<a class="anchor ms-1" href="#nutzungsbedingungen"></a></h2>
<p>Dies ist eine privat betriebene Homepage von Rainer Rose. Der gesamte
Auftritt basiert auf dem Recht auf freier Meinungsäußerung. Nur weil die
Texte hier online stehen, sind sie nicht frei von Urheberrechten. Alle
Texte sind entweder frei verfügbar gewesen, ich habe sie selber verfasst
oder konnte den Autor nicht ausfindig machen.</p>
<p><em>Linux</em> ist ein eingetragenes Warenzeichen von Linus Torvalds. <em>Windows</em>
ist ein eingetragenes Warenzeichen der <em>Mircosoft Corporation</em>. <em>UNIX</em>
ist ein eingetragenes Warenzeichen von <em>X/Open Company Limited</em>.
<em>WinZip</em> ist ein eingetragenes Warenzeichen der <em>WinZip International
LLC</em>. <em>PKWARE</em> ist ein eingetragene Handelsmarke der <em>PKWARE, Inc. -
Trusted ZIP Solutions</em>. Alle Warennamen werden ohne Gewährleistung der
freien Verwendbarkeit benutzt und sind möglicherweise eingetragene
Warenzeichen. Ich richte mich im wesentlichen nach den Schreibweisen der
Hersteller. Andere hier genannte Produkte können Warenzeichen des
jeweiligen Hersteller sein.</p>
<p>Software, die ich hier evtl. bereitstelle, ist <strong>weitestgehend</strong> auf
Viren überprüft. Ich gebe jedoch <strong>keine Garantie</strong>, dass sie auch
virenfrei sind. Der Einfachheit-halber habe ich die Software im
ZIP-Archiv ins WWW gestellt. Spart erstens Download-Zeit und zweitens
hat es sich durchgesetzt. Wer damit nichts anfangen bzw. entpacken kann,
sollte mal bei
<a href="https://tools.rainerrose.de/redirect.php?id=1" target="_blank" rel="noopener noreferrer">www.7-zip.org<i class="fas fa-external-link-square-alt ms-1"></i></a>
vorbeisurfen.</p>
<p>Ich akzeptiere alle eingetragenen Warenzeichen und benutze sie ohne
Rücksichtnahme auf Namensrechte. <strong>Wo benötigt</strong> oder der reinen
<strong>Höflichkeit</strong> halber, habe ich eine <strong>Erlaubnis</strong> des Autors der
jeweiligen Seite oder Datei <strong>geholt</strong>. Wenn jemand berechtigte Einwände
dagegen hat, mag er mir dieses mitteilen und ich <strong>entferne</strong> die
Datei(en) bzw. den/die Link/s vom Server bzw. meiner Internet-Seite. Und
ja, das Internet lebt von Links, das ist der Grundgedanke. Die Seiten
dahinter unterstehen nicht meiner Kontrolle. Zudem ist das Internet
schnelllebig und schon morgen kann sich hinter dem ursprünglichen Link
ein ganz anderer Inhalt verbergen. Dies alles liegt außerhalb meiner
Wirkungszone und Kontrolle. Daher bitte auch nicht für verlinkten
Inhalte verantwortlich machen. Ebensowenig kann ich alle paar Tage dort
die Inhalte überprüfen. Und das abschreiben irgendwelcher, vermutlich
nutzloser juristischer Texte spare ich mir auch. Wer Angst hat auf
dubiosen Seiten zu landen, oder wem die Links nicht gefallen, klickt sie
einfach nicht an. Sollen irgendwelche Verweise nicht mehr den geltenden
deutschen Gesetzen entsprechen, bin ich natürlich für Hinweise dankbar.</p>
<p><strong>Alle Scripte und Programme</strong> habe ich der <a href="https://tools.rainerrose.de/redirect.php?id=2" target="_blank" rel="noopener noreferrer">GNU General Public
License<i class="fas fa-external-link-square-alt ms-1"></i></a> der Free
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
unterstellt. Näheres siehe im jeweiligen ReadMe bzw. online bei der
<a href="https://tools.rainerrose.de/redirect.php?id=3" target="_blank" rel="noopener noreferrer">Free Software
Foundation<i class="fas fa-external-link-square-alt ms-1"></i></a>. Die auf
dieser Website wiedergegebenen Verfahren und Programme werden ohne
Rücksicht auf die Patentlage mitgeteilt. <strong>Sie sind für Amateur- und
Lehrzwecke bestimmt</strong>.</p>
<p>Die Informationen auf dieser Website wurden mit größter Sorgfalt
erarbeitet und unter Einschaltung wirksamer Kontrollmaßnahmen
reproduziert. Dennoch können Fehler nicht vollständig ausgeschlossen
werden.</p>
<p>Ich übernehme weder eine Garantie noch die juristische Verantwortung
oder irgendeine Haftung für Folgen, die auf fehlerhafte Angaben,
zurückgehen. Für die Mitteilung eventueller Fehler bin ich jederzeit
dankbar.</p>
<p>Haben Sie nicht genügend Erfahrung, lassen Sie lieber die Finger davon!
<strong>Herunterladen und benutzen auf eigene Gefahr!</strong> Für Beschwerden oder
Fragen, richten Sie sich bitte an die Autorin oder den Autor der
jeweiligen Software!</p>
<p>Viel Spaß beim Download und nicht vergessen:</p>
<p><strong>Jeder nur ein Kreuz!</strong></p>

<h2 id="datenschutzerklärung" data-numberify>Datenschutzerklärung<a class="anchor ms-1" href="#datenschutzerklärung"></a></h2>

<h3 id="geltungsbereich" data-numberify>Geltungsbereich<a class="anchor ms-1" href="#geltungsbereich"></a></h3>
<p>Diese Datenschutzerklärung klärt Nutzende über die Art, den Umfang und
Zwecke der Erhebung und Verwendung personenbezogener Daten durch den
verantwortlichen Anbieter (Kontakt-Daten finden Sie auf der
Kontak-Seite) auf dieser Website (im folgenden &ldquo;Angebot&rdquo;) auf.</p>
<p>Die rechtlichen Grundlagen des Datenschutzes finden sich im
Bundesdatenschutzgesetz (BDSG) und dem Telemediengesetz (TMG).</p>

<h3 id="cookies" data-numberify>Cookies<a class="anchor ms-1" href="#cookies"></a></h3>
<p>Ja, werden hier auch genutzt, um sich z.B. besuchte Seiten zu merken.
Wer das nicht mag löscht sie einfach oder verweigert die Annahme. Die
Webseite funktioniert auch so.</p>

<h3 id="zugriffsdaten--server-logfiles" data-numberify>Zugriffsdaten / Server-Logfiles<a class="anchor ms-1" href="#zugriffsdaten--server-logfiles"></a></h3>
<p>Der Anbieter (beziehungsweise sein Webspace-Provider) erhebt Daten über
jeden Zugriff auf das Angebot (so genannte Serverlogfiles). Zu den
Zugriffsdaten gehören:</p>
<p>Name der abgerufenen Webseite, Datei, Datum und Uhrzeit des Abrufs,
übertragene Datenmenge, Meldung über erfolgreichen Abruf, Browsertyp
nebst Version, das Betriebssystem des Nutzendes, Referrer URL (die zuvor
besuchte Seite), IP-Adresse und der anfragende Provider.</p>
<p>Der Anbieter verwendet die Protokolldaten nur für statistische
Auswertungen zum Zweck des Betriebs, der Sicherheit und der Optimierung
des Angebotes. Der Anbieter behält sich jedoch vor, die Protokolldaten
nachträglich zu überprüfen, wenn aufgrund konkreter Anhaltspunkte der
berechtigte Verdacht einer rechtswidrigen Nutzung besteht.</p>

<h3 id="kontaktaufnahme" data-numberify>Kontaktaufnahme<a class="anchor ms-1" href="#kontaktaufnahme"></a></h3>
<p>Bei der Kontaktaufnahme mit dem Anbieter (zum Beispiel per
Kontaktformular oder E-Mail) werden die Angaben des Nutzendes zwecks
Bearbeitung der Anfrage sowie für den Fall, dass Anschlussfragen
entstehen, gespeichert.</p>

<h3 id="widerruf-änderungen-berichtigungen-und-aktualisierungen" data-numberify>Widerruf, Änderungen, Berichtigungen und Aktualisierungen<a class="anchor ms-1" href="#widerruf-änderungen-berichtigungen-und-aktualisierungen"></a></h3>
<p>Der Nutzende hat das Recht, auf Antrag unentgeltlich Auskunft zu
erhalten über die personenbezogenen Daten, die über ihn gespeichert
wurden. Zusätzlich hat der Nutzende das Recht auf Berichtigung
unrichtiger Daten, Sperrung und Löschung seiner personenbezogenen Daten,
soweit dem keine gesetzliche Aufbewahrungspflicht entgegensteht.</p>

<h2 id="impressum" data-numberify>Impressum<a class="anchor ms-1" href="#impressum"></a></h2>
<p>Dieser Webauftritt dient rein privaten Zwecken.</p>
<p>Rainer Rose<br>
<a href="https://www.RainerRose.de" target="_blank" rel="noopener noreferrer">www.RainerRose.de<i class="fas fa-external-link-square-alt ms-1"></i></a></p>
<p>Ich widerspreche ausdrücklich jegliche Verwendung meiner Daten für Werbezwecke oder sonstige grundsätzlich unerwünschte Belästigungen.</p>

<h2 id="bildrechte" data-numberify>Bildrechte<a class="anchor ms-1" href="#bildrechte"></a></h2>
<p>Die Bildrechte liegen bei mir, sofern nicht anders angegeben.</p>]]></content:encoded>
    </item>
    
    <item>
      <title>Die fünf Lebenslügen</title>
      <link>https://www.rainerrose.de/posts/die-5-lebensluegen/</link>
      <pubDate>Tue, 29 Dec 2009 22:27:11 +0200</pubDate>
      <guid>https://www.rainerrose.de/posts/die-5-lebensluegen/</guid>
      <description><![CDATA[<!-- Anreißer -->]]></description>
      <content:encoded><![CDATA[<!-- Anreißer -->
<ol>
<li>Ich habe schon viel gutes von Dir gehört.</li>
<li>Wir werden immer Freunde bleiben.</li>
<li>Siehst Du aber gut aus.</li>
<li>Alles wird gut.</li>
<li>Du hast Dich überhaupt nicht verändert.</li>
</ol>]]></content:encoded>
    </item>
    
    <item>
      <title>Eastereggs</title>
      <link>https://www.rainerrose.de/posts/eastereggs/</link>
      <pubDate>Sat, 26 Aug 2006 16:19:36 +0100</pubDate>
      <guid>https://www.rainerrose.de/posts/eastereggs/</guid>
      <description><![CDATA[<!-- Anreißer -->
<p>Eastereggs sind undokumentiert verstecke Programmteile.</p>]]></description>
      <content:encoded><![CDATA[<!-- Anreißer -->
<p>Eastereggs sind undokumentiert verstecke Programmteile.</p>
<p>Meist dienen sie nur der Belustigung der Benutzers und stellen überwiegend eine reine Bestätigung des Programmierenden dar. Man bezeichnet sie auch als Unterschrift des Programmierenden.</p>

<h2 id="vim" data-numberify>vim<a class="anchor ms-1" href="#vim"></a></h2>
<ul>
<li><code>:help 42</code></li>
<li><code>:help holy-grail</code></li>
</ul>]]></content:encoded>
    </item>
    
    <item>
      <title>Keine Antwort?</title>
      <link>https://www.rainerrose.de/docs/kontakt/keine-antwort/</link>
      <pubDate>Sun, 21 May 2006 23:27:30 +0100</pubDate>
      <guid>https://www.rainerrose.de/docs/kontakt/keine-antwort/</guid>
      <description><![CDATA[<p>Sie haben mir eine Nachricht geschickt und keine Antwort bekommen oder
einen Link zu dieser Seite ?</p>]]></description>
      <content:encoded><![CDATA[<p>Sie haben mir eine Nachricht geschickt und keine Antwort bekommen oder
einen Link zu dieser Seite ?</p>
<p>Folgendes gilt für <strong>alle</strong> Nachrichten via</p>
<ul>
<li>E-Mail</li>
<li>Anrufbeantworter / Mailbox</li>
<li>Nachrichten aus Messengern</li>
<li>Nachrichten in sozialen Netzwerken</li>
<li>Briefe</li>
</ul>

<h2 id="dafür-kann-es-drei-gründe-geben" data-numberify>Dafür kann es drei Gründe geben:<a class="anchor ms-1" href="#dafür-kann-es-drei-gründe-geben"></a></h2>
<ol>
<li>Ich bin gerade zu beschäftigt.</li>
<li>Ich muss für die Antwort erst noch ein paar Dinge recherchieren.</li>
<li>Möglicherweise erfordert die Antwort eine Abstimmung mit anderen
Personen.</li>
<li>Ich habe gerade keine Lust zu antworten.</li>
<li>Ich muss mir erst eine Antwort überlegen oder mich entscheiden, was
ich antworte.</li>
<li>Die E-Mail kommt von einer Domain, die E-Mail-Spam versendet.<br>
E-Mails von diesen Domains werden automatisch und sofort gelöscht<br>
Ich werde sie nicht beachten.<br>
Benutzen Sie bitte einen anderen ISP / Zugangsprovider !</li>
<li>Ihre E-Mail beinhaltet Elemente, die oft in SPAM E-Mails vorkommen.
Zum Beispiel HTML Body, gefaked Addressen, ungültige Message-ID,
ungültiges Reverse-Lookup.<br>
Die meisten dieser SPAM- und SPAM-like E-Mails werden automatisch
gelöscht, einige werden in spezielle Ordner gespeichert, die ich nur
unregelmäßig durchsehe.</li>
</ol>
<div class="alert alert-success" role="alert"><i class="alert-icon fas fa-fw fa-check-circle me-1"></i>

  Bitte lesen sie meinen E-Mail-Guide.
</div>


<h2 id="zusammengefasst-für-e-mails" data-numberify>Zusammengefasst für E-Mails<a class="anchor ms-1" href="#zusammengefasst-für-e-mails"></a></h2>
<div class="alert alert-warning" role="alert"><i class="alert-icon fas fa-fw fa-exclamation-triangle me-1"></i>

  Nur Plain Text, keine VCards, kein HTML, keine übergrossen Attachments, keine Word Dokumente, benutze gültige Adressen, gültige Messsage-ID und respektiere die Netiquette.
</div>


<h2 id="blocklist" data-numberify>Blocklist<a class="anchor ms-1" href="#blocklist"></a></h2>
<p>Diese E-Mails werden noch nicht mal angenommen, ich werde sie also nie
sehen!</p>
<ul>
<li>ungültiges Reverse-Lookup</li>
<li><a href="https://www.spamhaus.org/sbl" target="_blank" rel="noopener noreferrer">www.spamhaus.org/sbl<i class="fas fa-external-link-square-alt ms-1"></i></a></li>
</ul>
<div class="alert alert-danger" role="alert"><i class="alert-icon fas fa-fw fa-skull-crossbones me-1"></i>

  Ich werde keine E-Mails lesen, die mindestens eine der u.g. Regeln erfüllt:
</div>

<ul>
<li>blocked Domains: siehe Blocklist (Bitte einen anderen ISP benutzen!)</li>
<li>blocked From-Addressen: (Bitte einen anderen Account benutzen!)</li>
<li>blocked to-Addressen: no_reply@Domain (Bitte gültige Adresse
benutzen)</li>
<li>blocked Spam-Elemente: (MASSIG
GROSSCHREIBUNG,HTML,SPAM-likely-Inhalt vermeiden)</li>
</ul>]]></content:encoded>
    </item>
    
  </channel>
</rss>

