<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <title>Zero to Hero - shell-scripting</title>
    <link rel="self" type="application/atom+xml" href="https://zerotohero.dev/tags/shell-scripting/atom.xml"/>
    <link rel="alternate" type="text/html" href="https://zerotohero.dev"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2025-07-13T00:00:00+00:00</updated>
    <id>https://zerotohero.dev/tags/shell-scripting/atom.xml</id>
    <entry xml:lang="en">
        <title>Snippet&#x2F;Draft: systemd-networkd-wait-online.service Waits Too Long During Ubuntu Startup</title>
        <published>2025-07-13T00:00:00+00:00</published>
        <updated>2025-07-13T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Volkan Özçelik
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://zerotohero.dev/inbox/snippet-systemd-network-wait-online-too-long/"/>
        <id>https://zerotohero.dev/inbox/snippet-systemd-network-wait-online-too-long/</id>
        
        <content type="html" xml:base="https://zerotohero.dev/inbox/snippet-systemd-network-wait-online-too-long/">&lt;p&gt;Quick fix: Disable the service (if you don’t need to wait for network at boot):&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;sudo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; systemctl disable systemd-networkd-wait-online.service&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Better fixes:&lt;&#x2F;p&gt;
&lt;p&gt;Configure it to wait only for specific interfaces:&lt;&#x2F;p&gt;
&lt;p&gt;Edit the service:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;sudo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; systemctl edit systemd-networkd-wait-online.service&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Add:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ini[Service]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ExecStart=&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ExecStart=&#x2F;lib&#x2F;systemd&#x2F;systemd-networkd-wait-online --interface=eth0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Reduce the timeout:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;ini&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;Service&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;ExecStart&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;=&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;ExecStart&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;&#x2F;lib&#x2F;systemd&#x2F;systemd-networkd-wait-online --&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;timeout&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;10&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Check which interfaces are causing delays:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;hnetworkctl&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; status&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Look for interfaces that are “configuring” or “pending”.&lt;&#x2F;p&gt;
&lt;p&gt;If you’re using NetworkManager instead of &lt;code&gt;systemd-networkd&lt;&#x2F;code&gt;, you can disable
this service and enable the NetworkManager equivalent:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;sudo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; systemctl disable systemd-networkd-wait-online.service&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;sudo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; systemctl enable NetworkManager-wait-online.service&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The most common cause is having network interfaces defined in &lt;code&gt;&#x2F;etc&#x2F;netplan&#x2F;&lt;&#x2F;code&gt; or
&lt;code&gt;&#x2F;etc&#x2F;network&#x2F;interfaces&lt;&#x2F;code&gt; that aren’t actually connected, causing the service
to wait for them unnecessarily.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Bulk Import Bookmarks to Shiori: A Simple Bash Script Solution</title>
        <published>2025-06-22T00:00:00+00:00</published>
        <updated>2025-06-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Volkan Özçelik
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://zerotohero.dev/inbox/shiori/"/>
        <id>https://zerotohero.dev/inbox/shiori/</id>
        
        <content type="html" xml:base="https://zerotohero.dev/inbox/shiori/">&lt;p&gt;If you’re like me and have accumulated hundreds of bookmarks across various
services, migrating them to a self-hosted solution like
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;go-shiori&#x2F;shiori&quot;&gt;&lt;strong&gt;Shiori&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; can feel daunting. While
&lt;strong&gt;Shiori&lt;&#x2F;strong&gt;’s simplicity is one of its strengths, importing bookmarks one by one
through the web UI or CLI can be time-consuming.&lt;&#x2F;p&gt;
&lt;p&gt;In this post, I’ll share a bash script that automates the bulk import process,
making it easy to migrate your entire bookmark collection to &lt;strong&gt;Shiori&lt;&#x2F;strong&gt; in
minutes and finally break free from the “social” bookmarking ecosystem.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-is-shiori&quot;&gt;What is Shiori?&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;go-shiori&#x2F;shiori&quot;&gt;Shiori&lt;&#x2F;a&gt; is a simple, self-hosted bookmark
manager written in &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;go.dev&#x2F;&quot;&gt;Go&lt;&#x2F;a&gt;. I like to call it my
“&lt;em&gt;antisocial bookmark manager&lt;&#x2F;em&gt;” because it’s the complete opposite of modern,
social-media-influenced bookmarking services. There are no social features,
no “trending” sections, no algorithmic recommendations, and definitely
no tracking.&lt;&#x2F;p&gt;
&lt;p&gt;It’s just you and your bookmarks, exactly how it should be.&lt;&#x2F;p&gt;
&lt;p&gt;Think of Shiori as your personal library: A quiet, private space where you can
save and organize content that matters to you, without the noise and
distractions of the modern web.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;why-i-chose-shiori-over-traditional-services&quot;&gt;Why I Chose Shiori Over Traditional Services&lt;&#x2F;h2&gt;
&lt;p&gt;After years of using various “&lt;em&gt;as a service&lt;&#x2F;em&gt;” bookmark managers
(Pocket, Instapaper, Pinboard, and others), I made the switch to &lt;strong&gt;Shiori&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Here is “why” in a nutshell:&lt;&#x2F;p&gt;
&lt;h3 id=&quot;complete-privacy-and-control&quot;&gt;Complete Privacy and Control&lt;&#x2F;h3&gt;
&lt;p&gt;Your bookmarks reveal a lot about your interests, research, and thought
processes. With Shiori being self-hosted, your data never leaves your server,
or your laptop, if you prefer to host your bookmarks locally.&lt;&#x2F;p&gt;
&lt;p&gt;No company is analyzing your reading habits, selling your data, or using it to
train AI models.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;true-offline-access&quot;&gt;True Offline Access&lt;&#x2F;h3&gt;
&lt;p&gt;Shiori doesn’t just save links - it creates full offline archives of web pages.&lt;&#x2F;p&gt;
&lt;p&gt;This means:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Content remains accessible even if the original site goes down&lt;&#x2F;li&gt;
&lt;li&gt;No more “404 Page Not Found” disappointments&lt;&#x2F;li&gt;
&lt;li&gt;Read your saved articles without an internet connection
*Protection against content changes or removals&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;no-vendor-lock-in&quot;&gt;No Vendor Lock-in&lt;&#x2F;h3&gt;
&lt;p&gt;With traditional services, you’re at the mercy of:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Pricing changes (&lt;em&gt;remember when Pocket introduced Pocket Premium?&lt;&#x2F;em&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;Feature removals (&lt;em&gt;RIP Google Reader&lt;&#x2F;em&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;Service shutdowns (&lt;em&gt;Delicious, anyone?&lt;&#x2F;em&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;API restrictions and rate limits&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;With &lt;strong&gt;Shiori&lt;&#x2F;strong&gt;, you own your data and the software. It’s open source, so even
if development stops, your bookmarks remain accessible.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;clean-distraction-free-interface&quot;&gt;Clean, Distraction-Free Interface&lt;&#x2F;h3&gt;
&lt;p&gt;Unlike modern services that push “recommended content” or “what’s trending,”
&lt;strong&gt;Shiori&lt;&#x2F;strong&gt; presents only what you’ve saved. No algorithmic feed, no social
features trying to increase engagement—just a clean, searchable list of
your bookmarks.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;lightweight-and-fast&quot;&gt;Lightweight and Fast&lt;&#x2F;h3&gt;
&lt;p&gt;Running on a simple SQLite database (&lt;em&gt;or, PostgreSQL&#x2F;MySQL, if you prefer&lt;&#x2F;em&gt;),
&lt;strong&gt;Shiori&lt;&#x2F;strong&gt; is incredibly lightweight. It runs comfortably on a
Raspberry Pi, doesn’t require complex infrastructure, and starts up in seconds.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;developer-friendly&quot;&gt;Developer-Friendly&lt;&#x2F;h3&gt;
&lt;p&gt;With a proper CLI interface and straightforward database schema, &lt;strong&gt;Shiori&lt;&#x2F;strong&gt;
plays well with scripts and automation. You can easily:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Bulk import&#x2F;export bookmarks&lt;&#x2F;li&gt;
&lt;li&gt;Integrate with other tools&lt;&#x2F;li&gt;
&lt;li&gt;Create custom workflows&lt;&#x2F;li&gt;
&lt;li&gt;Automate bookmark management&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;the-migration-challenge&quot;&gt;The Migration Challenge&lt;&#x2F;h2&gt;
&lt;p&gt;Shiori provides several ways to add bookmarks:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Through the web interface (&lt;em&gt;one at a time&lt;&#x2F;em&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;Using the CLI command &lt;code&gt;shiori add &amp;lt;url&amp;gt;&lt;&#x2F;code&gt; (&lt;em&gt;also one at a time&lt;&#x2F;em&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;Importing from browsers (&lt;em&gt;limited format support&lt;&#x2F;em&gt;)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;But what if you have a simple text file with hundreds of URLs? Or what if
you’re migrating from another service that exports to a basic list format?&lt;&#x2F;p&gt;
&lt;p&gt;That’s where automation comes in handy.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-solution-a-bulk-import-script&quot;&gt;The Solution: A Bulk Import Script&lt;&#x2F;h2&gt;
&lt;p&gt;I’ve created a bash script that:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Reads URLs from a text file (&lt;em&gt;one URL per line&lt;&#x2F;em&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;Adds each bookmark to Shiori automatically&lt;&#x2F;li&gt;
&lt;li&gt;Tracks success&#x2F;failure statistics&lt;&#x2F;li&gt;
&lt;li&gt;Logs errors for troubleshooting&lt;&#x2F;li&gt;
&lt;li&gt;Provides progress feedback during import&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Here’s the complete script:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;#!&#x2F;bin&#x2F;bash&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;# Script to bulk import links to Shiori&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;# Usage: .&#x2F;import.sh &amp;lt;links_file.txt&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;LINKS_FILE&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;.&#x2F;links.txt&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt; [&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; $#&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; -eq&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt; ]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; then&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;  echo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;Usage: &lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;$0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; &amp;lt;links_file.txt&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;  echo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;Defaulting to .&#x2F;links.txt&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;else&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;  LINKS_FILE&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;$1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;fi&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;# Check if the file exists&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt; [&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; ! -f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;$LINKS_FILE&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt; ]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; then&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;  echo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;Error: File &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;$LINKS_FILE&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;&amp;#39; not found!&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;  exit&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;fi&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;# Check if shiori is in PATH&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; !&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt; command&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; -v&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; shiori&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; &#x2F;dev&#x2F;null&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; then&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;  echo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;Error: shiori command not found in PATH!&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;  echo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;Please ensure shiori binary is accessible&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;  exit&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;fi&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;# Counter variables&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;total&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;success&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;failed&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;# Log file for errors&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;ERROR_LOG&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;shiori_import_errors_&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;$(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;date&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; +%Y%m%d_%H%M%S&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;.log&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;echo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;Starting Shiori import from: &lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;$LINKS_FILE&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;echo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;Errors will be logged to: &lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;$ERROR_LOG&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;echo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;----------------------------------------&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;# Read the file line by line&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;while&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; IFS&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt; read&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; -r&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; url&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; ||&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt; [&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; -n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;$url&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt; ]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; do&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;  # Skip empty lines and lines starting with #&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;  if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt; [[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; -z&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;$url&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt; ]]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; ||&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt; [[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;$url&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; =~&lt;&#x2F;span&gt;&lt;span&gt; ^&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;[[&lt;&#x2F;span&gt;&lt;span&gt;:space:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;]]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt;# &lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;]]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; then&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;    continue&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;  fi&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;  # Trim whitespace&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;  url&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;$(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;echo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;$url&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; |&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; xargs&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;  ((&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;total&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;++&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;  echo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; -n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;$total&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;] Adding: &lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;$url&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; ... &lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;  # Add bookmark to Shiori&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;  if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; output&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;$(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;shiori&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; add&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;$url&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; 2&amp;gt;&amp;amp;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;);&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; then&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;    echo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;SUCCESS&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;    ((&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;success&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;++&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;    # Extract bookmark ID from output (macOS compatible)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;    bookmark_id&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;$(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;echo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;$output&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; |&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;      grep&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; -o&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;ID:[[:space:]]*[0-9]*&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; |&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; grep&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; -o&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;[0-9]*&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; ||&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;      echo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;$output&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; |&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; grep&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; -o&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;Added bookmark with ID [0-9]*&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; |&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;      grep&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; -o&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;[0-9]*$&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; ||&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;      echo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;$output&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; |&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; grep&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; -o&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;[0-9]\+&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; |&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; head&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; -1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt; [&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; -n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;$bookmark_id&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt; ]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; then&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;      echo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;   → Bookmark ID: &lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;$bookmark_id&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;    fi&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;  else&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;    echo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;FAILED&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;    ((&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;failed&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;++&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;    echo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;$total&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;] Failed to add: &lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;$url&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; &amp;gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;$ERROR_LOG&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;    echo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;Error: &lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;$output&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; &amp;gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;$ERROR_LOG&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;    echo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;----------------------------------------&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; &amp;gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;$ERROR_LOG&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;  fi&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;  # Small delay to avoid overwhelming the server&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;  sleep&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 0.5&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;done&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;$LINKS_FILE&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;echo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;----------------------------------------&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;echo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;Import completed!&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;echo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;Total processed: &lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;$total&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;echo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;Successful: &lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;$success&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;echo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;Failed: &lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;$failed&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt; [&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; $failed&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; -gt&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt; ]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; then&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;  echo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;  echo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;Check &lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;$ERROR_LOG&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; for details on failed imports&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;fi&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;how-to-use-the-script&quot;&gt;How to Use the Script&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;1-prerequisites&quot;&gt;1. Prerequisites&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Shiori&lt;&#x2F;strong&gt; installed and accessible in your &lt;code&gt;$PATH&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;A text file containing URLs (&lt;em&gt;one per line&lt;&#x2F;em&gt;).&lt;&#x2F;li&gt;
&lt;li&gt;Bash shell (&lt;em&gt;works on Linux, macOS, and WSL&lt;&#x2F;em&gt;)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;2-prepare-your-url-list&quot;&gt;2. Prepare Your URL List&lt;&#x2F;h3&gt;
&lt;p&gt;Create a file called &lt;code&gt;links.txt&lt;&#x2F;code&gt; with your bookmarks:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;https:&#x2F;&#x2F;github.com&#x2F;go-shiori&#x2F;shiori&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;https:&#x2F;&#x2F;news.ycombinator.com&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;https:&#x2F;&#x2F;example.com&#x2F;article&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# This is a comment - it will be skipped&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;https:&#x2F;&#x2F;another-site.com&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# Empty lines are also skipped&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;https:&#x2F;&#x2F;final-url.com&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;3-run-the-script&quot;&gt;3. Run the Script&lt;&#x2F;h3&gt;
&lt;p&gt;Save the script as &lt;code&gt;import.sh&lt;&#x2F;code&gt;, make it executable, and run:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;chmod&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; +x import.sh&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;.&#x2F;import.sh&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; links.txt&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Or use the default &lt;code&gt;links.txt&lt;&#x2F;code&gt; file:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;.&#x2F;import.sh&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;4-monitor-progress&quot;&gt;4. Monitor Progress&lt;&#x2F;h3&gt;
&lt;p&gt;The script provides real-time feedback:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Starting Shiori import from: .&#x2F;links.txt&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Errors will be logged to: shiori_import_errors_20250622_184441.log&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;----------------------------------------&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[1] Adding: https:&#x2F;&#x2F;github.com&#x2F;go-shiori&#x2F;shiori ... SUCCESS&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   → Bookmark ID: 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[2] Adding: https:&#x2F;&#x2F;news.ycombinator.com&#x2F; ... SUCCESS&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   → Bookmark ID: 2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[3] Adding: https:&#x2F;&#x2F;invalid-url ... FAILED&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;----------------------------------------&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Import completed!&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Total processed: 3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Successful: 2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Failed: 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Check shiori_import_errors_20250622_184441.log \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  for details on failed imports&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;key-features&quot;&gt;Key Features&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;error-handling&quot;&gt;Error Handling&lt;&#x2F;h3&gt;
&lt;p&gt;The script creates a timestamped log file for any failures, making it easy to
identify and retry problematic URLs.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;progress-tracking&quot;&gt;Progress Tracking&lt;&#x2F;h3&gt;
&lt;p&gt;Real-time feedback shows exactly which URLs are being processed and their
import status.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;comment-support&quot;&gt;Comment Support&lt;&#x2F;h3&gt;
&lt;p&gt;Lines starting with &lt;code&gt;#&lt;&#x2F;code&gt; are treated as comments and skipped, allowing you to
annotate your URL list.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;rate-limiting&quot;&gt;Rate Limiting&lt;&#x2F;h3&gt;
&lt;p&gt;A 0.5-second delay between imports prevents overwhelming your Shiori instance.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;cross-platform-compatibility&quot;&gt;Cross-Platform Compatibility&lt;&#x2F;h3&gt;
&lt;p&gt;The script uses POSIX-compliant commands and works on Linux, macOS,
and Windows (&lt;em&gt;via WSL&lt;&#x2F;em&gt;).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;extending-the-script&quot;&gt;Extending the Script&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;adding-tags&quot;&gt;Adding Tags&lt;&#x2F;h3&gt;
&lt;p&gt;To add tags during import, modify the shiori command:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;shiori&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; add&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;$url&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; -t&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;imported,to-read&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; 2&amp;gt;&amp;amp;1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;creating-offline-archives&quot;&gt;Creating Offline Archives&lt;&#x2F;h3&gt;
&lt;p&gt;Depending on your Shiori version, you might be able to create offline 4
archives during import. Check available options with:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;shiori&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; add&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; --help&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;shiori&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; update&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; --help&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;parallel-processing&quot;&gt;Parallel Processing&lt;&#x2F;h3&gt;
&lt;p&gt;For faster imports with large lists, you could modify the script to use
GNU parallel:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;cat&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; links.txt&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; |&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; parallel&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; -j 4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; shiori add {}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;troubleshooting&quot;&gt;Troubleshooting&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;command-not-found&quot;&gt;Command Not Found&lt;&#x2F;h3&gt;
&lt;p&gt;If you get “shiori: command not found”, ensure Shiori is in your &lt;code&gt;$PATH&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;which&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; shiori&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;# Should output something like: &#x2F;usr&#x2F;local&#x2F;bin&#x2F;shiori&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;permission-denied&quot;&gt;Permission Denied&lt;&#x2F;h3&gt;
&lt;p&gt;Make sure the script is executable:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;chmod&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; +x import.sh&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;special-characters-in-urls&quot;&gt;Special Characters in URLs&lt;&#x2F;h3&gt;
&lt;p&gt;The script handles most URLs correctly, but if you have URLs with special
characters, ensure they’re properly encoded.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;&#x2F;h2&gt;
&lt;p&gt;This simple bash script has saved me hours of manual work when migrating
bookmarks to Shiori. It’s a great example of how a little automation can
streamline repetitive tasks.&lt;&#x2F;p&gt;
&lt;p&gt;The script is intentionally kept simple and focused on the core functionality.
Feel free to modify it for your specific needs - perhaps adding custom titles,
excerpts, or integrating with other tools in your workflow.&lt;&#x2F;p&gt;
&lt;p&gt;Happy bookmarking 🔖.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Establishing SPIFFE Federation Between Kubernetes Clusters</title>
        <published>2024-12-16T00:00:00+00:00</published>
        <updated>2024-12-16T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Volkan Özçelik
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://zerotohero.dev/inbox/spiffe-federation/"/>
        <id>https://zerotohero.dev/inbox/spiffe-federation/</id>
        
        <content type="html" xml:base="https://zerotohero.dev/inbox/spiffe-federation/">&lt;p&gt;SPIFFE (Secure Production Identity Framework For Everyone) provides a robust framework for service identity across distributed systems. When using SPIFFE with SPIRE (SPIFFE Runtime Environment) in Kubernetes clusters, it’s common to have multiple trust domains. To enable secure communication between these domains, you need to establish SPIFFE federation by exchanging and trusting each other’s trust bundles.&lt;&#x2F;p&gt;
&lt;p&gt;In this blog post, we’ll walk through the steps to establish SPIFFE federation between two Kubernetes clusters with separate trust domains.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;scenario-overview&quot;&gt;Scenario Overview&lt;&#x2F;h2&gt;
&lt;p&gt;Assume you have:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Server A with a trust domain &lt;code&gt;trustdomainA&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Server B with a trust domain &lt;code&gt;trustdomainB&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Both servers are running SPIRE to manage identities. To enable federation, the servers need to exchange and trust each other’s trust bundles.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;step-1-export-the-trust-bundle&quot;&gt;Step 1: Export the Trust Bundle&lt;&#x2F;h2&gt;
&lt;p&gt;Each SPIRE server has its own trust bundle, which includes the root CA certificate for its trust domain. Start by exporting the trust bundle from Server B:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;spire-server&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; bundle show&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; -format&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; spiffe&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This command will output the trust bundle for &lt;code&gt;trustdomainB&lt;&#x2F;code&gt; in SPIFFE format. Save this output to a file (e.g., &lt;code&gt;trust-bundleB.pem&lt;&#x2F;code&gt;).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;step-2-configure-federation-in-server-a&quot;&gt;Step 2: Configure Federation in Server A&lt;&#x2F;h2&gt;
&lt;p&gt;Next, configure Server A to trust &lt;code&gt;trustdomainB&lt;&#x2F;code&gt;. To do this, you’ll use the exported trust bundle from Server B.&lt;&#x2F;p&gt;
&lt;p&gt;Add the trust bundle to Server A’s configuration:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;spire-server&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; bundle set&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; -format&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; spiffe&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; -id&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; spiffe:&#x2F;&#x2F;trustdomainB&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; -path&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; &#x2F;path&#x2F;to&#x2F;trust-bundleB.pem&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This command tells Server A to trust the root CA from &lt;code&gt;trustdomainB&lt;&#x2F;code&gt;. Update Server A’s &lt;code&gt;spire-server.conf&lt;&#x2F;code&gt; file if needed to reflect the federation relationship with &lt;code&gt;trustdomainB&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;step-3-validate-the-trust-relationship&quot;&gt;Step 3: Validate the Trust Relationship&lt;&#x2F;h2&gt;
&lt;p&gt;After configuration, Server A will validate any SPIFFE identity (SVID) from &lt;code&gt;trustdomainB&lt;&#x2F;code&gt; by checking its signature against the root CA in the trust bundle.&lt;&#x2F;p&gt;
&lt;p&gt;When Server A encounters an identity from &lt;code&gt;trustdomainB&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;It verifies the SVID’s signature&lt;&#x2F;li&gt;
&lt;li&gt;If the signature is valid and matches the root CA from &lt;code&gt;trustdomainB&lt;&#x2F;code&gt;, the identity is trusted&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;step-4-establish-bi-directional-trust-optional&quot;&gt;Step 4: Establish Bi-Directional Trust (Optional)&lt;&#x2F;h2&gt;
&lt;p&gt;If you want Server B to trust identities from &lt;code&gt;trustdomainA&lt;&#x2F;code&gt;, repeat the process in reverse:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Export the trust bundle from Server A:&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;spire-server&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; bundle show&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; -format&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; spiffe&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ol start=&quot;2&quot;&gt;
&lt;li&gt;Configure Server B to trust the exported bundle by adding it to &lt;code&gt;trustdomainA&lt;&#x2F;code&gt;:&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;spire-server&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; bundle set&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; -format&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; spiffe&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; -id&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; spiffe:&#x2F;&#x2F;trustdomainA&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; -path&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; &#x2F;path&#x2F;to&#x2F;trust-bundleA.pem&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now, both servers trust each other’s identities, enabling mutual federation.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;key-considerations&quot;&gt;Key Considerations&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;bundle-rotation&quot;&gt;Bundle Rotation&lt;&#x2F;h3&gt;
&lt;p&gt;If the root CA in a trust domain is rotated, the updated trust bundle must be shared with the other server to maintain trust.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;unique-spiffe-ids&quot;&gt;Unique SPIFFE IDs&lt;&#x2F;h3&gt;
&lt;p&gt;Ensure that SPIFFE IDs are unique across trust domains to avoid collisions.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;secure-transport&quot;&gt;Secure Transport&lt;&#x2F;h3&gt;
&lt;p&gt;Always exchange trust bundles securely to prevent tampering.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;&#x2F;h2&gt;
&lt;p&gt;By following these steps, you can establish SPIFFE federation between two Kubernetes clusters with distinct trust domains. This enables secure identity-based communication across distributed systems, a critical component for modern cloud-native applications.&lt;&#x2F;p&gt;
&lt;p&gt;SPIFFE federation simplifies the management of service identity across multiple clusters and trust domains, allowing you to focus on building secure and scalable applications.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Understanding Docker&#x27;s 6MB Memory Limit: A Deep Dive</title>
        <published>2024-12-12T00:00:00+00:00</published>
        <updated>2024-12-12T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Volkan Özçelik
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://zerotohero.dev/inbox/docker-memory-limits/"/>
        <id>https://zerotohero.dev/inbox/docker-memory-limits/</id>
        
        <content type="html" xml:base="https://zerotohero.dev/inbox/docker-memory-limits/">&lt;p&gt;Have you ever encountered this puzzling error message while working with Docker containers?&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Warning Failed 89s (x12 over 3m44s) kubelet Error: Error response from daemon: Minimum memory limit allowed is 6MB&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If you’re like many developers, your first instinct might be to check Kubernetes’ LimitRange resources:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; kubectl get limitrange&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; -A&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;No&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; resources found&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;But wait - if there are no LimitRange resources defined, where is this 6MB limit coming from? Let’s dive deep into this common containerization puzzle.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-mystery-of-the-6mb-limit&quot;&gt;The Mystery of the 6MB Limit&lt;&#x2F;h2&gt;
&lt;p&gt;The key to understanding this issue lies in recognizing that this limit isn’t coming from Kubernetes at all - it’s actually a built-in restriction in Docker itself. This often surprises developers because it’s not documented prominently in Docker’s documentation.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;why-does-this-limit-exist&quot;&gt;Why Does This Limit Exist?&lt;&#x2F;h3&gt;
&lt;p&gt;The 6MB minimum memory limit serves as a critical safeguard in Docker’s architecture. It’s designed to prevent containers from being started with dangerously low memory limits that could lead to:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Immediate Out-of-Memory (OOM) kills&lt;&#x2F;li&gt;
&lt;li&gt;Unstable container behavior&lt;&#x2F;li&gt;
&lt;li&gt;System resource exhaustion&lt;&#x2F;li&gt;
&lt;li&gt;Cascading failures in container orchestration&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;configuration-options-what-can-you-do&quot;&gt;Configuration Options: What Can You Do?&lt;&#x2F;h2&gt;
&lt;p&gt;While this limit is hardcoded into Docker’s engine, you’re not entirely without options. Here are several approaches to dealing with this limitation:&lt;&#x2F;p&gt;
&lt;h3 id=&quot;1-adjust-your-resource-allocation&quot;&gt;1. Adjust Your Resource Allocation&lt;&#x2F;h3&gt;
&lt;p&gt;The most straightforward solution is to ensure your containers have adequate memory allocation. If you’re hitting this limit, it’s worth questioning whether running with such minimal memory is truly optimal for your application.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;2-alternative-approaches&quot;&gt;2. Alternative Approaches&lt;&#x2F;h3&gt;
&lt;p&gt;If you absolutely need to work with very low memory limits, consider these options:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Use Docker Swarm with Compatibility Mode&lt;&#x2F;strong&gt;: Running Docker Swarm with the &lt;code&gt;--compatibility&lt;&#x2F;code&gt; flag can alter how memory limits are interpreted&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Switch Container Runtimes&lt;&#x2F;strong&gt;: Consider using containerd or another container runtime that doesn’t impose this limitation&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Custom Docker Build&lt;&#x2F;strong&gt;: Though not recommended for production, you could technically modify Docker’s source code to adjust this limit&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;best-practices-and-recommendations&quot;&gt;Best Practices and Recommendations&lt;&#x2F;h2&gt;
&lt;p&gt;When working with container memory limits, consider these best practices:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Right-size Your Containers&lt;&#x2F;strong&gt;: Instead of trying to run with minimal memory, focus on appropriate sizing based on actual application needs&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Monitor Memory Usage&lt;&#x2F;strong&gt;: Use tools like cAdvisor or Prometheus to understand your actual memory usage patterns&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Test Thoroughly&lt;&#x2F;strong&gt;: Always test your containers under load to ensure memory limits are appropriate&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Document Your Settings&lt;&#x2F;strong&gt;: Make memory requirements and limits explicit in your deployment documentation&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;&#x2F;h2&gt;
&lt;p&gt;While Docker’s 6MB memory limit might seem restrictive at first, it’s actually a thoughtful safeguard that helps prevent potentially problematic container configurations. Understanding this limit - and working with it rather than against it - will help you build more reliable containerized applications.&lt;&#x2F;p&gt;
&lt;p&gt;Remember: Just because you can run a container with minimal memory doesn’t always mean you should. Focus on stability and reliability over minimal resource usage unless you have a compelling reason to do otherwise.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;additional-resources&quot;&gt;Additional Resources&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Docker Documentation on Resource Constraints&lt;&#x2F;li&gt;
&lt;li&gt;Kubernetes Memory Management Documentation&lt;&#x2F;li&gt;
&lt;li&gt;Container Runtime Comparisons&lt;&#x2F;li&gt;
&lt;li&gt;Memory Optimization Strategies for Containers&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Happy containerizing!&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Installing VMware vCenter Server Appliance (vCSA): Stage 1 Deployment Guide</title>
        <published>2024-12-12T00:00:00+00:00</published>
        <updated>2024-12-12T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Volkan Özçelik
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://zerotohero.dev/inbox/installing-vcsa-stage-1/"/>
        <id>https://zerotohero.dev/inbox/installing-vcsa-stage-1/</id>
        
        <content type="html" xml:base="https://zerotohero.dev/inbox/installing-vcsa-stage-1/">&lt;p&gt;This guide walks through the first stage of deploying vCenter Server Appliance (vCSA) on an ESXi host. Like any critical infrastructure deployment, proper preparation and verification at each step is essential for success.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;prerequisites-verification&quot;&gt;Prerequisites Verification&lt;&#x2F;h2&gt;
&lt;p&gt;Before beginning the installation:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Verify DNS resolution for target ESXi host:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;nslookup&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; esxi-4.zerotohero.dev&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;# Should resolve to 192.168.1.104&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Verify DNS resolution for vCSA FQDN:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;nslookup&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; vcsa.zerotohero.dev&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;# Should resolve to 192.168.1.111&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;installation-process&quot;&gt;Installation Process&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;1-launch-installer&quot;&gt;1. Launch Installer&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Navigate to mounted vCSA ISO&lt;&#x2F;li&gt;
&lt;li&gt;Go to &lt;code&gt;&#x2F;vcsa-ui-installer&#x2F;Win32&#x2F;&lt;&#x2F;code&gt; directory&lt;&#x2F;li&gt;
&lt;li&gt;Double-click installer executable&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;2-initial-setup&quot;&gt;2. Initial Setup&lt;&#x2F;h3&gt;
&lt;ol&gt;
&lt;li&gt;Select “Install” from the main menu&lt;&#x2F;li&gt;
&lt;li&gt;Acknowledge two-stage installation process&lt;&#x2F;li&gt;
&lt;li&gt;Accept End User License Agreement (EULA)&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h3 id=&quot;3-target-host-configuration&quot;&gt;3. Target Host Configuration&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;ESXi Host: esxi-4.zerotohero.dev&lt;&#x2F;li&gt;
&lt;li&gt;Username: root&lt;&#x2F;li&gt;
&lt;li&gt;Password: (lab password)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Security Tip&lt;&#x2F;strong&gt;: Verify host SSL thumbprint matches ESXi DCUI (F2 &amp;gt; View Support Information)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;4-vcsa-vm-configuration&quot;&gt;4. vCSA VM Configuration&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;VM Name: vCSA&lt;&#x2F;li&gt;
&lt;li&gt;Root Password: (set secure password)&lt;&#x2F;li&gt;
&lt;li&gt;Deployment Size: Tiny (suitable for managing up to 10 hosts)&lt;&#x2F;li&gt;
&lt;li&gt;Storage Size: Default&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;5-storage-configuration&quot;&gt;5. Storage Configuration&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Select datastore: esxi-4&lt;&#x2F;li&gt;
&lt;li&gt;Enable thin disk mode for efficient storage utilization&lt;&#x2F;li&gt;
&lt;li&gt;Note: vSAN configuration (if needed) comes later&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;6-network-configuration&quot;&gt;6. Network Configuration&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;network-selection&quot;&gt;Network Selection&lt;&#x2F;h4&gt;
&lt;ul&gt;
&lt;li&gt;Select “VM Network” port group&lt;&#x2F;li&gt;
&lt;li&gt;Connects to vSwitch0 on management network&lt;&#x2F;li&gt;
&lt;li&gt;Verify network connectivity via ESXi host client:
&lt;ul&gt;
&lt;li&gt;Navigate to Networking &amp;gt; Virtual Switches&lt;&#x2F;li&gt;
&lt;li&gt;Confirm vSwitch0 configuration with VM Network port group&lt;&#x2F;li&gt;
&lt;li&gt;Verify physical uplink (vmnic0) connectivity&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;network-settings&quot;&gt;Network Settings&lt;&#x2F;h4&gt;
&lt;ul&gt;
&lt;li&gt;FQDN: vcsa.zerotohero.dev&lt;&#x2F;li&gt;
&lt;li&gt;IP Address: 192.168.1.111&lt;&#x2F;li&gt;
&lt;li&gt;Subnet Mask: 255.255.255.0&lt;&#x2F;li&gt;
&lt;li&gt;Gateway: 192.168.1.1&lt;&#x2F;li&gt;
&lt;li&gt;DNS Server: 192.168.1.100&lt;&#x2F;li&gt;
&lt;li&gt;Default Ports:
&lt;ul&gt;
&lt;li&gt;HTTP: 80&lt;&#x2F;li&gt;
&lt;li&gt;HTTPS: 443&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;important-notes&quot;&gt;Important Notes&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;dns-configuration&quot;&gt;DNS Configuration&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Proper DNS setup is critical for vCSA deployment&lt;&#x2F;li&gt;
&lt;li&gt;Both forward and reverse DNS resolution must work correctly&lt;&#x2F;li&gt;
&lt;li&gt;DNS issues are a common source of deployment problems&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;network-connectivity&quot;&gt;Network Connectivity&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;vCSA requires reliable network connectivity&lt;&#x2F;li&gt;
&lt;li&gt;Management network access is essential&lt;&#x2F;li&gt;
&lt;li&gt;Verify all network settings before proceeding&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;time-synchronization&quot;&gt;Time Synchronization&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Accurate time settings are crucial&lt;&#x2F;li&gt;
&lt;li&gt;NTP configuration follows in Stage 2&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;next-steps&quot;&gt;Next Steps&lt;&#x2F;h2&gt;
&lt;p&gt;After Stage 1 completes (approximately 3-8 minutes):&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Verify VM deployment on ESXi host&lt;&#x2F;li&gt;
&lt;li&gt;Proceed to Stage 2 configuration&lt;&#x2F;li&gt;
&lt;li&gt;Configure SSO domain&lt;&#x2F;li&gt;
&lt;li&gt;Set up initial vSphere environment&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Remember: This is just Stage 1 of the deployment. Stage 2 will handle the configuration of the appliance, including SSO setup, time synchronization, and initial vSphere environment configuration.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>How to Export Kubernetes Secrets as JSON: A Complete Guide</title>
        <published>2024-12-12T00:00:00+00:00</published>
        <updated>2024-12-12T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Volkan Özçelik
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://zerotohero.dev/inbox/secret-export/"/>
        <id>https://zerotohero.dev/inbox/secret-export/</id>
        
        <content type="html" xml:base="https://zerotohero.dev/inbox/secret-export/">&lt;p&gt;When working with Kubernetes secrets, you may need to export them in a format that can be version controlled or transferred between clusters. This guide will show you how to export Kubernetes secrets as JSON while preserving important metadata like labels and annotations.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-basic-approach&quot;&gt;The Basic Approach&lt;&#x2F;h2&gt;
&lt;p&gt;The fundamental command to export a secret in JSON format is straightforward:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;kubectl&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; get secret&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;secret-nam&lt;&#x2F;span&gt;&lt;span&gt;e&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; -o&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; json&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;However, this raw output includes cluster-specific information that you typically don’t want to include when exporting secrets for reuse. Let’s look at how to clean this up.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;cleaning-up-cluster-specific-information&quot;&gt;Cleaning Up Cluster-Specific Information&lt;&#x2F;h2&gt;
&lt;p&gt;To create a clean export that removes cluster-specific metadata, we can use &lt;code&gt;jq&lt;&#x2F;code&gt; to process the JSON output. Here’s the recommended approach:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;kubectl&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; get secret&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;secret-nam&lt;&#x2F;span&gt;&lt;span&gt;e&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; -o&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; json&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; |&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;jq&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;del(.metadata.creationTimestamp,.metadata.resourceVersion,.metadata.selfLink,.metadata.uid,.metadata.namespace,.metadata.ownerReferences)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This command removes the following fields:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;creationTimestamp&lt;&#x2F;code&gt;: When the secret was created in the source cluster&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;resourceVersion&lt;&#x2F;code&gt;: The internal version number used by Kubernetes&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;selfLink&lt;&#x2F;code&gt;: The API URL for this resource&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;uid&lt;&#x2F;code&gt;: The unique identifier in the source cluster&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;namespace&lt;&#x2F;code&gt;: The namespace in the source cluster&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;ownerReferences&lt;&#x2F;code&gt;: References to parent resources&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;working-with-multiple-secrets&quot;&gt;Working with Multiple Secrets&lt;&#x2F;h2&gt;
&lt;p&gt;If you need to export all secrets from a namespace, you can modify the command slightly:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;kubectl&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; get secrets&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; -o&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; json&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; |&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;jq&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;.items[] | del(.metadata.creationTimestamp,.metadata.resourceVersion,.metadata.selfLink,.metadata.uid,.metadata.namespace,.metadata.ownerReferences)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;example-output&quot;&gt;Example Output&lt;&#x2F;h2&gt;
&lt;p&gt;Here’s what a cleaned export might look like:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;json&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #689D6A;&quot;&gt;apiVersion&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;: &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;v1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #689D6A;&quot;&gt;kind&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;: &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;Secret&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #689D6A;&quot;&gt;metadata&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #689D6A;&quot;&gt;labels&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #689D6A;&quot;&gt;app&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;: &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;myapp&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #689D6A;&quot;&gt;environment&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;: &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;production&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;    },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #689D6A;&quot;&gt;annotations&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #689D6A;&quot;&gt;kubernetes.io&#x2F;description&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;: &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;Application credentials&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;    },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #689D6A;&quot;&gt;name&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;: &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;mysecret&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;  },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #689D6A;&quot;&gt;type&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;: &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;Opaque&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #689D6A;&quot;&gt;data&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #689D6A;&quot;&gt;username&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;: &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;YWRtaW4=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #689D6A;&quot;&gt;password&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;: &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;MWYyZDFlMmU2N2Rm&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;best-practices&quot;&gt;Best Practices&lt;&#x2F;h2&gt;
&lt;p&gt;When working with exported secrets, keep these tips in mind:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Always verify the exported secret contains all necessary metadata (labels and annotations) before using it in a new environment&lt;&#x2F;li&gt;
&lt;li&gt;Consider using tools like &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;mozilla&#x2F;sops&quot;&gt;SOPS&lt;&#x2F;a&gt; or &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;bitnami-labs&#x2F;sealed-secrets&quot;&gt;sealed-secrets&lt;&#x2F;a&gt; for encrypting secrets before storing them in version control&lt;&#x2F;li&gt;
&lt;li&gt;Document any environment-specific values that might need to be modified when importing the secret into a new cluster&lt;&#x2F;li&gt;
&lt;li&gt;Use meaningful labels and annotations to make secrets self-documenting&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;&#x2F;h2&gt;
&lt;p&gt;Exporting Kubernetes secrets as JSON is a common task in cluster management and application deployment. By following this guide, you can ensure your exported secrets are clean, portable, and ready for use in other environments while maintaining important metadata like labels and annotations.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Parsing JWT Claims in Go: A Practical Guide</title>
        <published>2024-12-10T00:00:00+00:00</published>
        <updated>2024-12-10T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Volkan Özçelik
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://zerotohero.dev/go/jwt-parsing/"/>
        <id>https://zerotohero.dev/go/jwt-parsing/</id>
        
        <content type="html" xml:base="https://zerotohero.dev/go/jwt-parsing/">&lt;p&gt;When working with JWTs in Go, you’ll often need to extract and validate claims from the payload section. Let’s walk through how to do this effectively using the popular &lt;code&gt;github.com&#x2F;golang-jwt&#x2F;jwt&lt;&#x2F;code&gt; package.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;basic-jwt-structure&quot;&gt;Basic JWT Structure&lt;&#x2F;h2&gt;
&lt;p&gt;First, let’s understand what we’re parsing. A JWT consists of three parts:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Header (algorithm and token type)&lt;&#x2F;li&gt;
&lt;li&gt;Payload (claims)&lt;&#x2F;li&gt;
&lt;li&gt;Signature&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;setting-up-your-project&quot;&gt;Setting Up Your Project&lt;&#x2F;h2&gt;
&lt;p&gt;Start by installing the required package:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;go&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; get&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; -u&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; github.com&#x2F;golang-jwt&#x2F;jwt&#x2F;v5&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;creating-a-claims-structure&quot;&gt;Creating a Claims Structure&lt;&#x2F;h2&gt;
&lt;p&gt;Let’s define a structure to hold our claims:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;go&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;type&lt;&#x2F;span&gt;&lt;span&gt; CustomClaims&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;    Issuer&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;    string&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; `&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;json:&amp;quot;iss&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;    Subject&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;   string&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; `&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;json:&amp;quot;sub&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;    ExpiresAt&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; int64&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;  `&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;json:&amp;quot;exp&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;    NotBefore&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; int64&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;  `&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;json:&amp;quot;nbf&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;    IssuedAt&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;  int64&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;  `&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;json:&amp;quot;iat&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    jwt&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;RegisteredClaims&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;parsing-the-token&quot;&gt;Parsing the Token&lt;&#x2F;h2&gt;
&lt;p&gt;Here’s a complete example showing how to parse a JWT and extract its claims:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;go&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;package&lt;&#x2F;span&gt;&lt;span&gt; main&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; (&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;fmt&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;log&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;time&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;github.com&#x2F;golang-jwt&#x2F;jwt&#x2F;v5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;func&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; parseToken&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;tokenString&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; string&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;) (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt;CustomClaims&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; error&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;    &#x2F;&#x2F; Parse the token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;    token&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; err&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; jwt&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;ParseWithClaims&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;tokenString&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;CustomClaims&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;{},&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; func&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;token&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;jwt&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;Token&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;) (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;{},&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; error&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;        &#x2F;&#x2F; Replace this with your actual secret key&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; []&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;byte&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;your-secret-key&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;),&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; nil&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;    })&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; err&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; nil&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; nil&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; fmt&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;Errorf&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;error parsing token: &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;%v&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; err&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;    &#x2F;&#x2F; Type assert the claims&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; claims&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; ok&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; token&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;Claims&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt;CustomClaims&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;);&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; ok&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; token&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;Valid&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; claims&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; nil&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; nil&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; fmt&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;Errorf&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;invalid token claims&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;func&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; main&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;    &#x2F;&#x2F; Example JWT string - replace with your actual token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;    tokenString&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;your.jwt.token&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;    claims&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; err&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; parseToken&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;tokenString&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; err&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; nil&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;        log&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;Fatalf&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;Error: &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;%v&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; err&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;    &#x2F;&#x2F; Access the claims&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;    fmt&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;Printf&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;Issuer: &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;%s\n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; claims&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;Issuer&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;    fmt&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;Printf&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;Subject: &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;%s\n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; claims&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;Subject&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;    fmt&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;Printf&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;Expires At: &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;%v\n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; time&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;Unix&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;claims&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;ExpiresAt&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;    fmt&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;Printf&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;Not Before: &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;%v\n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; time&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;Unix&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;claims&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;NotBefore&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;    fmt&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;Printf&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;Issued At: &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;%v\n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; time&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;Unix&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;claims&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;IssuedAt&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;validation&quot;&gt;Validation&lt;&#x2F;h2&gt;
&lt;p&gt;The JWT library automatically validates:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Token structure&lt;&#x2F;li&gt;
&lt;li&gt;Signature&lt;&#x2F;li&gt;
&lt;li&gt;Expiration time (exp)&lt;&#x2F;li&gt;
&lt;li&gt;Not Before time (nbf)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;However, you might want to add custom validation:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;go&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;func&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; validateClaims&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;claims&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;CustomClaims&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; error&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;    &#x2F;&#x2F; Example: Validate issuer&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; claims&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;Issuer&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;spike-nexus&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; fmt&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;Errorf&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;invalid issuer&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;    &#x2F;&#x2F; Example: Validate subject&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; claims&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;Subject&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;spike-admin&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; fmt&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;Errorf&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;invalid subject&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; nil&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;error-handling&quot;&gt;Error Handling&lt;&#x2F;h2&gt;
&lt;p&gt;Here’s how to handle common JWT errors:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;go&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;func&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; handleJWTError&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;err&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; error&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; string&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;    switch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;    case&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; errors&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;Is&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;err&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; jwt&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;ErrTokenMalformed&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;Token is malformed&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;    case&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; errors&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;Is&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;err&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; jwt&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;ErrTokenExpired&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;Token has expired&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;    case&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; errors&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;Is&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;err&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; jwt&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;ErrTokenNotValidYet&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;Token is not valid yet&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;    default&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;Invalid token&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;best-practices&quot;&gt;Best Practices&lt;&#x2F;h2&gt;
&lt;ol&gt;
&lt;li&gt;Always validate the token signature using a secure key&lt;&#x2F;li&gt;
&lt;li&gt;Check expiration and not-before claims&lt;&#x2F;li&gt;
&lt;li&gt;Verify the issuer and subject claims match expected values&lt;&#x2F;li&gt;
&lt;li&gt;Use proper error handling&lt;&#x2F;li&gt;
&lt;li&gt;Consider using environment variables for sensitive values like secret keys&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;testing&quot;&gt;Testing&lt;&#x2F;h2&gt;
&lt;p&gt;Here’s a simple test case:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;go&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;func&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; TestTokenParsing&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;t&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;testing&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;T&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;    tokenString&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;your.test.token&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;    claims&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; err&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; parseToken&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;tokenString&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; err&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; nil&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;        t&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;Errorf&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;Failed to parse token: &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;%v&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; err&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; claims&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;Issuer&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;spike-nexus&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;        t&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;Errorf&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;Expected issuer &amp;#39;spike-nexus&amp;#39;, got &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;%s&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; claims&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;Issuer&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;&#x2F;h2&gt;
&lt;p&gt;Parsing JWT claims in Go is straightforward with the &lt;code&gt;jwt-go&lt;&#x2F;code&gt; package. The key is to:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Define a proper claims structure&lt;&#x2F;li&gt;
&lt;li&gt;Use appropriate parsing methods&lt;&#x2F;li&gt;
&lt;li&gt;Implement proper validation&lt;&#x2F;li&gt;
&lt;li&gt;Handle errors gracefully&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Remember to always validate tokens server-side and never trust client-provided tokens without verification.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>How to Decrypt Files Using age - A Quick Guide</title>
        <published>2024-12-03T00:00:00+00:00</published>
        <updated>2024-12-03T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Volkan Özçelik
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://zerotohero.dev/inbox/age-decryption-guide/"/>
        <id>https://zerotohero.dev/inbox/age-decryption-guide/</id>
        
        <content type="html" xml:base="https://zerotohero.dev/inbox/age-decryption-guide/">&lt;p&gt;Age is a modern file encryption tool that’s simple yet powerful. Here’s how to decrypt age-encrypted files using a secret key.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;prerequisites&quot;&gt;Prerequisites&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;age installed on your system&lt;&#x2F;li&gt;
&lt;li&gt;An encrypted file (base64 encoded)&lt;&#x2F;li&gt;
&lt;li&gt;A secret key (starting with AGE-SECRET-KEY-)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;step-by-step-decryption&quot;&gt;Step-by-Step Decryption&lt;&#x2F;h2&gt;
&lt;ol&gt;
&lt;li&gt;First, decode the base64 content to a file:&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;echo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;YOUR-BASE64-CONTENT&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; |&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; base64&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; -d&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; encrypted.age&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ol start=&quot;2&quot;&gt;
&lt;li&gt;Save the secret key to a file:&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;echo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;AGE-SECRET-KEY-YOUR-KEY&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; key.txt&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;chmod&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 600&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; key.txt&lt;&#x2F;span&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;  # Set proper permissions&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ol start=&quot;3&quot;&gt;
&lt;li&gt;Decrypt the file:&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;age&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; --decrypt -i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; key.txt encrypted.age&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;installing-age&quot;&gt;Installing age&lt;&#x2F;h2&gt;
&lt;p&gt;Choose your platform:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;macOS: &lt;code&gt;brew install age&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Ubuntu&#x2F;Debian: &lt;code&gt;apt install age&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Other systems: Download from the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;FiloSottile&#x2F;age&quot;&gt;age GitHub repository&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;common-issues&quot;&gt;Common Issues&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Ensure you’re using only the AGE-SECRET-KEY line for decryption&lt;&#x2F;li&gt;
&lt;li&gt;Verify the base64 content is complete and properly formatted&lt;&#x2F;li&gt;
&lt;li&gt;Check file permissions on the key file (should be readable only by you)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;security-best-practices&quot;&gt;Security Best Practices&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Never share your secret key&lt;&#x2F;li&gt;
&lt;li&gt;Delete key files after use&lt;&#x2F;li&gt;
&lt;li&gt;Store encrypted files and keys separately&lt;&#x2F;li&gt;
&lt;li&gt;Use secure channels when transferring encrypted files&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Computing File Hashes in Unix Systems: A Complete Guide</title>
        <published>2024-12-02T00:00:00+00:00</published>
        <updated>2024-12-02T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Volkan Özçelik
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://zerotohero.dev/inbox/file-hashing/"/>
        <id>https://zerotohero.dev/inbox/file-hashing/</id>
        
        <content type="html" xml:base="https://zerotohero.dev/inbox/file-hashing/">&lt;p&gt;File hashing is an essential operation in software development, system administration, and security verification. This guide will walk you through the process of computing file hashes in Unix-like systems, with a focus on generating formatted SHA-256 hashes.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;basic-hash-computation&quot;&gt;Basic Hash Computation&lt;&#x2F;h2&gt;
&lt;p&gt;The most straightforward way to compute a SHA-256 hash in Unix systems is using the &lt;code&gt;sha256sum&lt;&#x2F;code&gt; command:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;sha256sum&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; filename&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This produces output in the format:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;hash_value filename&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;formatted-hash-output&quot;&gt;Formatted Hash Output&lt;&#x2F;h2&gt;
&lt;p&gt;Sometimes you need to format the hash output in a specific way, particularly when working with systems that expect a certain structure. Here’s how to generate a hash in this format:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;type:&amp;quot;unix&amp;quot;  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;value:&amp;quot;sha256:HASH_VALUE&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;command-construction&quot;&gt;Command Construction&lt;&#x2F;h3&gt;
&lt;p&gt;To achieve this format, we can combine several Unix commands:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;echo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;type:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;\&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;unix&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;\&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;value:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;\&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;sha256:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;$(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;sha256sum&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; .&#x2F;keeper&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; |&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; cut&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; -d&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;#39; &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; -f1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;\&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Let’s break down this command:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;sha256sum .&#x2F;keeper&lt;&#x2F;code&gt;: Computes the SHA-256 hash of the file&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;cut -d&#x27; &#x27; -f1&lt;&#x2F;code&gt;: Extracts just the hash value, removing the filename&lt;&#x2F;li&gt;
&lt;li&gt;Command substitution &lt;code&gt;$()&lt;&#x2F;code&gt;: Embeds the hash into our formatted string&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;echo&lt;&#x2F;code&gt;: Outputs the final formatted result&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h3 id=&quot;use-cases&quot;&gt;Use Cases&lt;&#x2F;h3&gt;
&lt;p&gt;This formatting is particularly useful for:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Configuration management systems&lt;&#x2F;li&gt;
&lt;li&gt;Version control systems&lt;&#x2F;li&gt;
&lt;li&gt;Security verification processes&lt;&#x2F;li&gt;
&lt;li&gt;Automated build systems&lt;&#x2F;li&gt;
&lt;li&gt;Documentation purposes&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;alternative-hash-algorithms&quot;&gt;Alternative Hash Algorithms&lt;&#x2F;h2&gt;
&lt;p&gt;While SHA-256 is commonly used, Unix systems support various other hashing algorithms:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;MD5 (using &lt;code&gt;md5sum&lt;&#x2F;code&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;SHA-1 (using &lt;code&gt;sha1sum&lt;&#x2F;code&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;SHA-224 (using &lt;code&gt;sha224sum&lt;&#x2F;code&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;SHA-384 (using &lt;code&gt;sha384sum&lt;&#x2F;code&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;SHA-512 (using &lt;code&gt;sha512sum&lt;&#x2F;code&gt;)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;best-practices&quot;&gt;Best Practices&lt;&#x2F;h2&gt;
&lt;p&gt;When working with file hashes:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Always verify the file path before computing the hash&lt;&#x2F;li&gt;
&lt;li&gt;Use appropriate hash algorithms for your security requirements&lt;&#x2F;li&gt;
&lt;li&gt;Consider using multiple hash algorithms for critical files&lt;&#x2F;li&gt;
&lt;li&gt;Document the hashing process in your system documentation&lt;&#x2F;li&gt;
&lt;li&gt;Implement verification steps in your deployment pipeline&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;error-handling&quot;&gt;Error Handling&lt;&#x2F;h2&gt;
&lt;p&gt;When implementing hash computation in scripts, consider handling these common issues:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;File not found&lt;&#x2F;li&gt;
&lt;li&gt;Insufficient permissions&lt;&#x2F;li&gt;
&lt;li&gt;Corrupted files&lt;&#x2F;li&gt;
&lt;li&gt;System command availability&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Example error handling in a shell script:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;#!&#x2F;bin&#x2F;bash&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;file&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;.&#x2F;keeper&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt; [&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; ! -f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;$file&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt; ]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; then&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;    echo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;Error: File not found&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;    exit&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;fi&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt; [&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; ! -r&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;$file&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt; ]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; then&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;    echo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;Error: Cannot read file (check permissions)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;    exit&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;fi&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;hash_output&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;$(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;sha256sum&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;$file&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; 2&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;&#x2F;dev&#x2F;null&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt; [&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; $?&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; -ne&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt; ]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; then&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;    echo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;Error: Hash computation failed&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;    exit&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;fi&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;echo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;type:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;\&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;unix&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;\&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;value:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;\&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;sha256:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;$(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;echo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;$hash_output&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; |&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; cut&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; -d&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;#39; &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; -f1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;\&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;&#x2F;h2&gt;
&lt;p&gt;File hashing is a critical operation in many systems. By understanding how to compute and format hashes correctly, you can ensure your systems maintain security and integrity while meeting specific format requirements.&lt;&#x2F;p&gt;
&lt;p&gt;Remember to always validate your hash computations and keep your hashing tools updated to maintain security standards.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Securely Generating and Storing SPIRE Agent Tokens</title>
        <published>2024-12-02T00:00:00+00:00</published>
        <updated>2024-12-02T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Volkan Özçelik
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://zerotohero.dev/inbox/spire-agent-token-generation/"/>
        <id>https://zerotohero.dev/inbox/spire-agent-token-generation/</id>
        
        <content type="html" xml:base="https://zerotohero.dev/inbox/spire-agent-token-generation/">&lt;p&gt;SPIRE (the SPIFFE Runtime Environment) requires tokens for agent authentication. Here’s a secure way to generate and store these tokens using bash scripting.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-problem&quot;&gt;The Problem&lt;&#x2F;h2&gt;
&lt;p&gt;When working with SPIRE, we often need to generate agent tokens and store them for later use. The default &lt;code&gt;spire-server token generate&lt;&#x2F;code&gt; command outputs tokens with a “Token: “ prefix, which isn’t always ideal for automation or direct use in configuration files.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-solution&quot;&gt;The Solution&lt;&#x2F;h2&gt;
&lt;p&gt;Here’s a bash script that generates a SPIRE agent token, strips unnecessary prefixes, and stores it securely:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;#!&#x2F;usr&#x2F;bin&#x2F;env bash&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;#    \\ SPIKE: Keep your secrets secret with SPIFFE.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;#  \\\\\ Copyright 2024-present SPIKE contributors.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;# \\\\\\\ SPDX-License-Identifier: Apache-2.0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;TOKEN_FILE&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;agent-token.txt&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;# Generate token and strip the &amp;quot;Token: &amp;quot; prefix&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; !&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; spire-server&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; token generate&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; -spiffeID&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; spiffe:&#x2F;&#x2F;spike.ist&#x2F;spire-agent&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; |&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; sed&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;s&#x2F;^Token: &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;$TOKEN_FILE&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; then&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;    echo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;Error: Failed to generate token&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; &amp;gt;&amp;amp;2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;    exit&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;fi&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;# Verify file was created and is not empty&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt; [&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; ! -s&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;$TOKEN_FILE&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt; ]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; then&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;    echo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;Error: Token file is empty or was not created&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; &amp;gt;&amp;amp;2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;    exit&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;fi&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;# Set restrictive permissions&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;chmod&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 600&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;$TOKEN_FILE&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;echo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;Token successfully generated and saved to &lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;$TOKEN_FILE&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;how-it-works&quot;&gt;How It Works&lt;&#x2F;h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Token Generation&lt;&#x2F;strong&gt;: The script uses &lt;code&gt;spire-server token generate&lt;&#x2F;code&gt; to create a new token with a specific SPIFFE ID.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Text Processing&lt;&#x2F;strong&gt;: A &lt;code&gt;sed&lt;&#x2F;code&gt; command strips the “Token: “ prefix from the output:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;&#x27;s&#x2F;^Token: &#x2F;&#x2F;&#x27;&lt;&#x2F;code&gt; replaces “Token: “ at the start of the line with nothing&lt;&#x2F;li&gt;
&lt;li&gt;The clean token is then redirected to the output file&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Error Handling&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Checks if token generation succeeded&lt;&#x2F;li&gt;
&lt;li&gt;Verifies the output file exists and isn’t empty&lt;&#x2F;li&gt;
&lt;li&gt;Returns meaningful error messages&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Security&lt;&#x2F;strong&gt;: Sets file permissions to 600 (read&#x2F;write for owner only) to protect the token&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;usage&quot;&gt;Usage&lt;&#x2F;h2&gt;
&lt;ol&gt;
&lt;li&gt;Save the script as &lt;code&gt;generate-agent-token.sh&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Make it executable: &lt;code&gt;chmod +x generate-agent-token.sh&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Run it: &lt;code&gt;.&#x2F;generate-agent-token.sh&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;The token will be saved in &lt;code&gt;agent-token.txt&lt;&#x2F;code&gt; in the current directory.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;best-practices&quot;&gt;Best Practices&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Always use restrictive file permissions for token files&lt;&#x2F;li&gt;
&lt;li&gt;Store tokens in a secure location&lt;&#x2F;li&gt;
&lt;li&gt;Never commit tokens to version control&lt;&#x2F;li&gt;
&lt;li&gt;Consider using environment variables or secure vaults for production environments&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;&#x2F;h2&gt;
&lt;p&gt;This script provides a secure and automated way to generate and store SPIRE agent tokens. By removing the prefix and implementing proper error handling, it makes token management more reliable and automation-friendly.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Cross-Compiling Go Applications on M3 Macs: A Practical Guide</title>
        <published>2024-11-27T00:00:00+00:00</published>
        <updated>2024-11-27T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Volkan Özçelik
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://zerotohero.dev/go/cross-compilation/"/>
        <id>https://zerotohero.dev/go/cross-compilation/</id>
        
        <content type="html" xml:base="https://zerotohero.dev/go/cross-compilation/">&lt;p&gt;Cross-compiling Go applications on Apple Silicon (M-series) Macs can be tricky, especially when dealing with CGO dependencies. In this guide, we’ll explore different approaches to building Go applications for multiple architectures, specifically targeting Linux (AMD64 and ARM64) and macOS (ARM64).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-challenge&quot;&gt;The Challenge&lt;&#x2F;h2&gt;
&lt;p&gt;When working with Go applications that use CGO, simple cross-compilation commands like &lt;code&gt;GOOS=linux GOARCH=amd64 go build&lt;&#x2F;code&gt; might not be sufficient. This is particularly true when:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Your application uses CGO-dependent packages&lt;&#x2F;li&gt;
&lt;li&gt;You need to build for multiple architectures&lt;&#x2F;li&gt;
&lt;li&gt;You’re working on an M-series Mac&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;initial-approach-local-cross-compilation&quot;&gt;Initial Approach: Local Cross-Compilation&lt;&#x2F;h2&gt;
&lt;p&gt;My first attempt involved using traditional cross-compilation tools. Here’s what I initially tried:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;# Linux ARM64&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;CGO_ENABLED&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; GOEXPERIMENT&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;boringcrypto&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; go&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; build&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; -o&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; keeper .&#x2F;app&#x2F;keeper&#x2F;cmd&#x2F;main.go&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;CGO_ENABLED&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; GOEXPERIMENT&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;boringcrypto&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; go&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; build&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; -o&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; nexus .&#x2F;app&#x2F;nexus&#x2F;cmd&#x2F;main.go&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;CGO_ENABLED&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; GOEXPERIMENT&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;boringcrypto&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; go&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; build&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; -o&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; spike .&#x2F;app&#x2F;spike&#x2F;cmd&#x2F;main.go&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;However, when trying to cross-compile for different architectures, I ran into issues:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;GOOS&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;linux&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; GOARCH&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;amd64&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; CGO_ENABLED&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; GOEXPERIMENT&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;boringcrypto&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; go&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; build&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; -o&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; nexus-linux-amd64 .&#x2F;app&#x2F;nexus&#x2F;cmd&#x2F;main.go&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This approach failed because it needed proper cross-compilation toolchains.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-solution-docker-based-cross-compilation&quot;&gt;The Solution: Docker-Based Cross-Compilation&lt;&#x2F;h2&gt;
&lt;p&gt;After exploring various options, I found that using Docker for cross-compilation provides the most reliable and reproducible solution. Here’s how to implement it:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;First, create a Dockerfile:&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;docker&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;FROM&lt;&#x2F;span&gt;&lt;span&gt; golang:1.21-alpine &lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;AS&lt;&#x2F;span&gt;&lt;span&gt; builder&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;# Install build tools&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;RUN&lt;&#x2F;span&gt;&lt;span&gt; apk add --no-cache gcc musl-dev&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;# Set working directory&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;WORKDIR&lt;&#x2F;span&gt;&lt;span&gt; &#x2F;app&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;# Copy go mod files&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;COPY&lt;&#x2F;span&gt;&lt;span&gt; go.mod go.sum .&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;RUN&lt;&#x2F;span&gt;&lt;span&gt; go mod download&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;# Copy source code&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;COPY&lt;&#x2F;span&gt;&lt;span&gt; . .&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;# Build for different platforms&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;RUN&lt;&#x2F;span&gt;&lt;span&gt; GOOS=linux GOARCH=amd64 CGO_ENABLED=0 GOEXPERIMENT=boringcrypto go build -o keeper-linux-amd64 .&#x2F;app&#x2F;keeper&#x2F;cmd&#x2F;main.go &amp;amp;&amp;amp; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    GOOS=linux GOARCH=amd64 CGO_ENABLED=1 GOEXPERIMENT=boringcrypto go build -o nexus-linux-amd64 .&#x2F;app&#x2F;nexus&#x2F;cmd&#x2F;main.go &amp;amp;&amp;amp; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    GOOS=linux GOARCH=amd64 CGO_ENABLED=0 GOEXPERIMENT=boringcrypto go build -o spike-linux-amd64 .&#x2F;app&#x2F;spike&#x2F;cmd&#x2F;main.go &amp;amp;&amp;amp; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    GOOS=linux GOARCH=arm64 CGO_ENABLED=0 GOEXPERIMENT=boringcrypto go build -o keeper-linux-arm64 .&#x2F;app&#x2F;keeper&#x2F;cmd&#x2F;main.go &amp;amp;&amp;amp; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    GOOS=linux GOARCH=arm64 CGO_ENABLED=1 GOEXPERIMENT=boringcrypto go build -o nexus-linux-arm64 .&#x2F;app&#x2F;nexus&#x2F;cmd&#x2F;main.go &amp;amp;&amp;amp; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    GOOS=linux GOARCH=arm64 CGO_ENABLED=0 GOEXPERIMENT=boringcrypto go build -o spike-linux-arm64 .&#x2F;app&#x2F;spike&#x2F;cmd&#x2F;main.go&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ol start=&quot;2&quot;&gt;
&lt;li&gt;Create a build script:&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;#!&#x2F;bin&#x2F;bash&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;# Build the Docker image&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;docker&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; build&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; -t&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; go-cross-compiler .&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;# Create a container and copy the binaries&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;docker&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; create&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; --name&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; temp-container go-cross-compiler&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;docker&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; cp temp-container:&#x2F;app&#x2F;keeper-linux-amd64 .&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;docker&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; cp temp-container:&#x2F;app&#x2F;nexus-linux-amd64 .&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;docker&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; cp temp-container:&#x2F;app&#x2F;spike-linux-amd64 .&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;docker&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; cp temp-container:&#x2F;app&#x2F;keeper-linux-arm64 .&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;docker&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; cp temp-container:&#x2F;app&#x2F;nexus-linux-arm64 .&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;docker&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; cp temp-container:&#x2F;app&#x2F;spike-linux-arm64 .&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;# Clean up&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;docker&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; rm temp-container&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;advantages-of-the-docker-approach&quot;&gt;Advantages of the Docker Approach&lt;&#x2F;h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Reproducibility&lt;&#x2F;strong&gt;: The build environment is consistent across different development machines&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;No Local Dependencies&lt;&#x2F;strong&gt;: No need to install cross-compilation tools locally&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Simplified Process&lt;&#x2F;strong&gt;: One command builds all targets&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Consistent Results&lt;&#x2F;strong&gt;: Binaries are built in a controlled environment&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Easy CI&#x2F;CD Integration&lt;&#x2F;strong&gt;: The Docker-based approach works well in automated pipelines&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;building-for-macos-arm64&quot;&gt;Building for macOS ARM64&lt;&#x2F;h2&gt;
&lt;p&gt;For macOS ARM64 builds, you can still build natively on your M-series Mac:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;GOOS&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;darwin&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; GOARCH&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;arm64&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; CGO_ENABLED&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; GOEXPERIMENT&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;boringcrypto&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; go&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; build&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; -o&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; keeper-darwin-arm64 .&#x2F;app&#x2F;keeper&#x2F;cmd&#x2F;main.go&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;GOOS&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;darwin&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; GOARCH&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;arm64&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; CGO_ENABLED&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; GOEXPERIMENT&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;boringcrypto&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; go&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; build&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; -o&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; nexus-darwin-arm64 .&#x2F;app&#x2F;nexus&#x2F;cmd&#x2F;main.go&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;GOOS&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;darwin&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; GOARCH&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;arm64&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; CGO_ENABLED&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; GOEXPERIMENT&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;boringcrypto&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; go&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; build&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; -o&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; spike-darwin-arm64 .&#x2F;app&#x2F;spike&#x2F;cmd&#x2F;main.go&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;common-pitfalls-and-solutions&quot;&gt;Common Pitfalls and Solutions&lt;&#x2F;h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;CGO Dependencies&lt;&#x2F;strong&gt;: When &lt;code&gt;CGO_ENABLED=1&lt;&#x2F;code&gt;, ensure your Docker container has the necessary build tools installed&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Architecture Mismatch&lt;&#x2F;strong&gt;: Double-check &lt;code&gt;GOOS&lt;&#x2F;code&gt; and &lt;code&gt;GOARCH&lt;&#x2F;code&gt; values match your target platforms&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Build Tags&lt;&#x2F;strong&gt;: Consider using build tags for platform-specific code&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Static Linking&lt;&#x2F;strong&gt;: For better portability, use &lt;code&gt;CGO_ENABLED=0&lt;&#x2F;code&gt; when possible&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;&#x2F;h2&gt;
&lt;p&gt;While cross-compilation on M-series Macs presents some challenges, using Docker provides a robust and maintainable solution. This approach simplifies the build process and ensures consistent results across different architectures.&lt;&#x2F;p&gt;
&lt;p&gt;For projects that don’t require CGO, you might still use direct cross-compilation. However, for complex projects with CGO dependencies, the Docker-based approach is recommended.&lt;&#x2F;p&gt;
&lt;p&gt;Remember to version your build scripts and Dockerfile alongside your project code to maintain build reproducibility across your team.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Implementing Secure Password Input in Go CLI Applications</title>
        <published>2024-11-27T00:00:00+00:00</published>
        <updated>2024-11-27T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Volkan Özçelik
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://zerotohero.dev/go/secure-password-input/"/>
        <id>https://zerotohero.dev/go/secure-password-input/</id>
        
        <content type="html" xml:base="https://zerotohero.dev/go/secure-password-input/">&lt;p&gt;When building command-line applications in Go, there often comes a time when you need to securely collect sensitive information from users, such as passwords. In this post, we’ll explore how to implement secure password input in a Go CLI application using best practices.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-challenge&quot;&gt;The Challenge&lt;&#x2F;h2&gt;
&lt;p&gt;Consider a typical CLI initialization command where you need to collect an admin password:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;go&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;func&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; NewInitCommand&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;source&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;workloadapi&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;X509Source&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;cobra&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;Command&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;    var&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; initCmd&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; = &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;cobra&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;Command&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;        Use&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;:   &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;init&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;        Short&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;: &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;Initialize spike configuration&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;        Run&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; func&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;cmd&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;cobra&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;Command&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; args&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; []&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;string&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;            &#x2F;&#x2F; How do we securely get the password?&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;        },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; initCmd&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Simply using &lt;code&gt;fmt.Scanln()&lt;&#x2F;code&gt; or similar methods would display the password in plain text as the user types - a significant security risk. We need a better solution.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-solution-using-term-readpassword&quot;&gt;The Solution: Using term.ReadPassword&lt;&#x2F;h2&gt;
&lt;p&gt;Go’s &lt;code&gt;golang.org&#x2F;x&#x2F;term&lt;&#x2F;code&gt; package provides a secure way to read passwords from the terminal. Here’s how to implement it:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;First, install the required dependency:&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;go&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; get golang.org&#x2F;x&#x2F;term&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ol start=&quot;2&quot;&gt;
&lt;li&gt;Import the necessary packages:&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;go&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; (&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;golang.org&#x2F;x&#x2F;term&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;syscall&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;fmt&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ol start=&quot;3&quot;&gt;
&lt;li&gt;Implement the password collection:&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;go&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;func&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; NewInitCommand&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;source&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;workloadapi&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;X509Source&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;cobra&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;Command&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;    var&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; initCmd&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; = &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;cobra&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;Command&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;        Use&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;:   &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;init&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;        Short&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;: &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;Initialize spike configuration&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;        Run&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; func&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;cmd&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;cobra&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;Command&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; args&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; []&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;string&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;            &#x2F;&#x2F; Check initialization state&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;            state&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; err&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; net&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;CheckInitState&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;source&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; err&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; nil&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;                fmt&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;Println&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;Failed to check init state:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;                fmt&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;Println&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;err&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;Error&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;())&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;                return&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;            }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; state&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; data&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;AlreadyInitialized&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;                fmt&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;Println&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;SPIKE is already initialized.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;                fmt&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;Println&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;Nothing to do.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;                return&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;            }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;            &#x2F;&#x2F; Collect password securely&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;            fmt&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;Print&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;Enter admin password: &lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;            password&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; err&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; term&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;ReadPassword&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;syscall&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;Stdin&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; err&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; nil&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;                fmt&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;Println&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;Failed to read password:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;                fmt&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;Println&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;err&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;Error&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;())&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;                return&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;            }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;            fmt&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;Println&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; &#x2F;&#x2F; Add newline after password input&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;            &#x2F;&#x2F; Convert to string if needed&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;            passwordStr&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; string&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;password&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;            &#x2F;&#x2F; Use the password...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;            fmt&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;Println&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&amp;quot;&amp;quot;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;            fmt&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;Println&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;    SPIKE system initialization completed.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;            fmt&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;Println&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;      Generated admin token and saved it to&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;            fmt&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;Println&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;        .&#x2F;.spike-admin-token for future use.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;            fmt&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;Println&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&amp;quot;&amp;quot;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;        },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; initCmd&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;why-this-approach-works&quot;&gt;Why This Approach Works&lt;&#x2F;h2&gt;
&lt;p&gt;This implementation offers several security benefits:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Hidden Input&lt;&#x2F;strong&gt;: The password isn’t displayed on screen as the user types&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Memory Security&lt;&#x2F;strong&gt;: Password is initially stored as a byte slice (&lt;code&gt;[]byte&lt;&#x2F;code&gt;), which can be securely wiped from memory&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Clean User Experience&lt;&#x2F;strong&gt;: The interface is professional and familiar to users&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Error Handling&lt;&#x2F;strong&gt;: Robust error handling for input failures&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Cross-Platform&lt;&#x2F;strong&gt;: Works across different operating systems&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;best-practices&quot;&gt;Best Practices&lt;&#x2F;h2&gt;
&lt;p&gt;When implementing password input in your CLI applications:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Clear Memory&lt;&#x2F;strong&gt;: If possible, clear the password from memory after use&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Validate Input&lt;&#x2F;strong&gt;: Add password strength requirements if needed&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Confirmation&lt;&#x2F;strong&gt;: For new passwords, consider asking users to type twice&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Clear Prompts&lt;&#x2F;strong&gt;: Use clear prompts to indicate what’s expected&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Error Messages&lt;&#x2F;strong&gt;: Provide helpful error messages without revealing sensitive information&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;example-adding-password-confirmation&quot;&gt;Example: Adding Password Confirmation&lt;&#x2F;h2&gt;
&lt;p&gt;For cases where users are setting a new password, here’s how to add confirmation:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;go&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;func&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; getPasswordWithConfirmation&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;() (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;string&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; error&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;    fmt&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;Print&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;Enter new password: &lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;    password1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; err&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; term&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;ReadPassword&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;syscall&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;Stdin&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; err&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; nil&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&amp;quot;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; err&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;    fmt&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;Println&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;    fmt&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;Print&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;Confirm password: &lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;    password2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; err&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; :=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; term&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;ReadPassword&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;syscall&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;Stdin&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; err&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; nil&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&amp;quot;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; err&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;    fmt&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;Println&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; string&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;password1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; string&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;password2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&amp;quot;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; fmt&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;Errorf&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;passwords do not match&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; string&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;password1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;),&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; nil&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;&#x2F;h2&gt;
&lt;p&gt;Implementing secure password input in Go CLI applications is straightforward with the right tools. The &lt;code&gt;golang.org&#x2F;x&#x2F;term&lt;&#x2F;code&gt; package provides a robust solution that works across platforms and follows security best practices. By following these patterns, you can ensure your CLI applications handle sensitive information securely and professionally.&lt;&#x2F;p&gt;
&lt;p&gt;Remember to always consider security implications when handling passwords and other sensitive data, and make sure to follow your organization’s security requirements and best practices.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>How to Count Lines in Your Source Code Projects: A Comprehensive Guide</title>
        <published>2024-11-27T00:00:00+00:00</published>
        <updated>2024-11-27T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Volkan Özçelik
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://zerotohero.dev/inbox/counting-lines-of-code/"/>
        <id>https://zerotohero.dev/inbox/counting-lines-of-code/</id>
        
        <content type="html" xml:base="https://zerotohero.dev/inbox/counting-lines-of-code/">&lt;p&gt;As software projects grow, tracking their size becomes increasingly important for maintenance, documentation, and planning. One fundamental metric is the line count of your source code. In this article, we’ll explore different methods to count lines in your codebase, from quick command-line solutions to more sophisticated tools.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-quick-and-simple-using-wc&quot;&gt;The Quick and Simple: Using &lt;code&gt;wc&lt;&#x2F;code&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;For Unix-like systems (Linux, macOS), the &lt;code&gt;wc&lt;&#x2F;code&gt; (word count) command provides a straightforward way to count lines. Here’s how you can use it:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;# Count lines in a single file&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;wc&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; -l&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; file.py&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;To count lines across multiple files, you can combine &lt;code&gt;wc&lt;&#x2F;code&gt; with other Unix commands:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;# Count lines in all Python files in a directory&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;find&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; .&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; -type&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; -name&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;*.py&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; |&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; xargs&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; wc&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; -l&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;# Count lines recursively for all files&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;find&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; .&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; -type&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; -exec&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; wc&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; -l&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; {}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; \;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;While &lt;code&gt;wc&lt;&#x2F;code&gt; is fast and readily available, it’s rather basic - it counts all lines, including empty lines and comments.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-professional-solution-cloc&quot;&gt;The Professional Solution: CLOC&lt;&#x2F;h2&gt;
&lt;p&gt;CLOC (Count Lines of Code) is a specialized tool that provides detailed statistics about your codebase. It’s more intelligent than &lt;code&gt;wc&lt;&#x2F;code&gt; as it can:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Exclude blank lines and comments&lt;&#x2F;li&gt;
&lt;li&gt;Recognize dozens of programming languages&lt;&#x2F;li&gt;
&lt;li&gt;Provide detailed breakdowns by language&lt;&#x2F;li&gt;
&lt;li&gt;Generate reports in various formats&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;installing-cloc&quot;&gt;Installing CLOC&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;# Ubuntu&#x2F;Debian&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;sudo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; apt install cloc&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;# macOS via Homebrew&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;brew&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; install cloc&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;# Windows via Chocolatey&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;choco&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; install cloc&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;using-cloc&quot;&gt;Using CLOC&lt;&#x2F;h3&gt;
&lt;p&gt;Basic usage is as simple as:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;cloc&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; .&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This will scan your current directory and provide a detailed breakdown. For more specific analysis:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;# Count specific languages&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;cloc&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; --include-lang=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;Python,JavaScript&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; .&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;# Generate XML report&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;cloc&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; --xml --out=results.xml&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; .&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;# Count lines in a Git repository&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;git&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; clone&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; --depth 1&lt;&#x2F;span&gt;&lt;span&gt; [repository-url]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;cloc&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; .&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;custom-python-solution&quot;&gt;Custom Python Solution&lt;&#x2F;h2&gt;
&lt;p&gt;Sometimes you need more control over what and how you count. Here’s a Python script that you can customize for your specific needs:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; os&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;from&lt;&#x2F;span&gt;&lt;span&gt; pathlib&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; import&lt;&#x2F;span&gt;&lt;span&gt; Path&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; count_lines&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;directory&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; extensions&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;None&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;    &amp;quot;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;    Count lines in files within a directory, optionally filtering by extension.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;    Args:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;        directory (str): Path to the directory to scan&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;        extensions (list): List of file extensions to include (e.g., [&amp;#39;.py&amp;#39;, &amp;#39;.js&amp;#39;])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;    Returns:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;        dict: Dictionary containing line counts and file statistics&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;    &amp;quot;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    stats&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;        &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;total_lines&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;#39;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;        &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;total_files&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;#39;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;        &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;files_by_extension&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;#39;: {}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; path&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; Path&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;directory&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;).&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;rglob&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;#39;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; path&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;is_file&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;():&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span&gt; extensions&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; and not&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt; any&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;str&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;path&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;).&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;endswith&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;ext&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; for&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; ext&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; extensions&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;                continue&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            ext&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; path&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;suffix&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;            try&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;                with&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt; open&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt;path&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;, &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;r&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;#39;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; encoding&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;utf-8&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;#39;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; as&lt;&#x2F;span&gt;&lt;span&gt; f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    line_count&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt; sum&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; for&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; _&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D5C4A1;&quot;&gt; f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                stats&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;[&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;total_lines&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;#39;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span&gt; line_count&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                stats&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;[&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;total_files&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;#39;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;                if&lt;&#x2F;span&gt;&lt;span&gt; ext&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; not in&lt;&#x2F;span&gt;&lt;span&gt; stats&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;[&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;files_by_extension&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;#39;]:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    stats&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;[&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;files_by_extension&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;#39;][&lt;&#x2F;span&gt;&lt;span&gt;ext&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;                        &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;files&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;#39;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;                        &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;lines&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;#39;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;                    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                stats&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;[&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;files_by_extension&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;#39;][&lt;&#x2F;span&gt;&lt;span&gt;ext&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;][&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;files&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;#39;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                stats&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;[&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;files_by_extension&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;#39;][&lt;&#x2F;span&gt;&lt;span&gt;ext&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;][&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;lines&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;#39;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span&gt; line_count&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;            except&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;UnicodeDecodeError&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt; PermissionError&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;                continue&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; stats&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This script provides more detailed statistics and can be easily modified to:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Exclude certain directories (like &lt;code&gt;node_modules&lt;&#x2F;code&gt; or &lt;code&gt;.git&lt;&#x2F;code&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;Count only specific types of lines&lt;&#x2F;li&gt;
&lt;li&gt;Generate custom reports&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;best-practices&quot;&gt;Best Practices&lt;&#x2F;h2&gt;
&lt;p&gt;When counting lines in your source code, consider:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Consistency&lt;&#x2F;strong&gt;: Use the same tool and settings across your project for meaningful comparisons over time.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Documentation&lt;&#x2F;strong&gt;: Document which tool and settings you use for line counting in your project documentation.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Automation&lt;&#x2F;strong&gt;: Integrate line counting into your CI&#x2F;CD pipeline to track changes over time.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Context&lt;&#x2F;strong&gt;: Remember that line count is just one metric - it doesn’t necessarily correlate with complexity or quality.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;&#x2F;h2&gt;
&lt;p&gt;While line count isn’t a perfect metric for code complexity or project size, it’s a useful baseline metric that’s easy to track. Whether you choose the simple &lt;code&gt;wc&lt;&#x2F;code&gt; command, the comprehensive CLOC tool, or a custom solution depends on your specific needs:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Use &lt;code&gt;wc&lt;&#x2F;code&gt; for quick, rough estimates&lt;&#x2F;li&gt;
&lt;li&gt;Use CLOC for detailed analysis and reporting&lt;&#x2F;li&gt;
&lt;li&gt;Create a custom solution when you need specific features or integration with your workflow&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Remember that the goal isn’t just to count lines, but to gain insights that help you better understand and manage your codebase.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Debugging Git GPG Signing Issuese</title>
        <published>2024-11-27T00:00:00+00:00</published>
        <updated>2024-11-27T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Volkan Özçelik
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://zerotohero.dev/inbox/git-gpg-sign/"/>
        <id>https://zerotohero.dev/inbox/git-gpg-sign/</id>
        
        <content type="html" xml:base="https://zerotohero.dev/inbox/git-gpg-sign/">&lt;p&gt;When working with signed Git commits, you might encounter this error:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;error:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; gpg failed to sign the data:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;gpg:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; skipped&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;[EMAIL]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;: No secret key&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;GNUPG:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;]&lt;&#x2F;span&gt;&lt;span&gt; INV_SGNR 9 &lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;USER&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;GNUPG:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;]&lt;&#x2F;span&gt;&lt;span&gt; FAILURE sign 17&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;gpg:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; signing failed: No secret key&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;fatal:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; failed to write commit object&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This error occurs when you try to create a signed Git commit (using the &lt;code&gt;-S&lt;&#x2F;code&gt; flag) but GPG can’t find the corresponding secret key for your email address. Let’s walk through how to diagnose and fix this issue.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;checking-your-gpg-keys&quot;&gt;Checking Your GPG Keys&lt;&#x2F;h2&gt;
&lt;p&gt;First, check if you have any GPG keys installed:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;gpg&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; --list-secret-keys --keyid-format=long&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This command will show output similar to:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;&#x2F;home&#x2F;user&#x2F;.gnupg&#x2F;pubring.kbx&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;-------------------------------&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;sec&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;   ed25519&#x2F;KEYID 2024-11-06&lt;&#x2F;span&gt;&lt;span&gt; [SC]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;      FULL_KEYID&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;uid&lt;&#x2F;span&gt;&lt;span&gt;                 [ultimate] User Name &lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt;email@example.com&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;ssb&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;   cv25519&#x2F;SUBKEY 2024-11-06&lt;&#x2F;span&gt;&lt;span&gt; [E]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;if-you-have-a-key&quot;&gt;If You Have a Key&lt;&#x2F;h2&gt;
&lt;p&gt;If you see output like above, you already have a GPG key. The key ID is the string after “ed25519&#x2F;” in the &lt;code&gt;sec&lt;&#x2F;code&gt; line. You’ll need to configure Git to use this key:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;git&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; config&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; --global&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; user.signingkey YOUR_KEY_ID&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Also ensure your Git email matches the GPG key email:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;git&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; config&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; --global&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; user.email&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;your.email@example.com&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;if-you-don-t-have-a-key&quot;&gt;If You Don’t Have a Key&lt;&#x2F;h2&gt;
&lt;p&gt;If no keys are listed, you’ll need to generate a new one:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;gpg&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; --full-generate-key&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Follow the prompts to create your key. Make sure to use the same email address that you use with Git.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;additional-configuration&quot;&gt;Additional Configuration&lt;&#x2F;h2&gt;
&lt;p&gt;Sometimes, you might need to explicitly tell Git which GPG program to use:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;git&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; config&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; --global&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; gpg.program&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; $(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;which&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; gpg&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;testing-your-configuration&quot;&gt;Testing Your Configuration&lt;&#x2F;h2&gt;
&lt;p&gt;After setting everything up, try creating a signed commit:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;git&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; commit&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; -S -m&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;Your commit message&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;troubleshooting-tips&quot;&gt;Troubleshooting Tips&lt;&#x2F;h2&gt;
&lt;p&gt;If you’re still having issues:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Verify your GPG key email matches your Git email&lt;&#x2F;li&gt;
&lt;li&gt;Ensure your GPG key hasn’t expired&lt;&#x2F;li&gt;
&lt;li&gt;Check if your key has signing capability (look for [S] in the key capabilities)&lt;&#x2F;li&gt;
&lt;li&gt;Make sure you’re using the correct key ID&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;alternative-unsigned-commits&quot;&gt;Alternative: Unsigned Commits&lt;&#x2F;h2&gt;
&lt;p&gt;If you need to make a commit without signing (assuming your repository allows it), you can simply omit the &lt;code&gt;-S&lt;&#x2F;code&gt; flag:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;git&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; commit&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; -m&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;Your commit message&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;security-note&quot;&gt;Security Note&lt;&#x2F;h2&gt;
&lt;p&gt;Signing your Git commits adds an extra layer of security by verifying that commits actually came from you. It’s especially important for open-source projects or when working in larger teams. However, make sure to keep your GPG private key secure and never share it with others.&lt;&#x2F;p&gt;
&lt;p&gt;Remember that you can also configure Git to sign all commits by default:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;git&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; config&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; --global&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; commit.gpgsign&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This way, you won’t need to add the &lt;code&gt;-S&lt;&#x2F;code&gt; flag to every commit command.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;&#x2F;h2&gt;
&lt;p&gt;GPG signing issues in Git are usually straightforward to fix once you understand the relationship between your GPG keys and Git configuration. The key is to ensure that Git knows which GPG key to use and that the key is properly set up with your correct email address.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Computing SHA256 Hashes for Binary Files: A Quick Guide</title>
        <published>2024-11-27T00:00:00+00:00</published>
        <updated>2024-11-27T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Volkan Özçelik
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://zerotohero.dev/inbox/sha256-guide/"/>
        <id>https://zerotohero.dev/inbox/sha256-guide/</id>
        
        <content type="html" xml:base="https://zerotohero.dev/inbox/sha256-guide/">&lt;p&gt;When distributing binary files, it’s crucial to provide cryptographic hashes so users can verify the integrity of their downloads. This guide shows how to generate SHA256 hashes for multiple binary files across different platforms.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-problem&quot;&gt;The Problem&lt;&#x2F;h2&gt;
&lt;p&gt;Let’s say you have a set of binary files for different platforms and architectures:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;keeper-darwin-arm64&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;keeper-linux-amd64&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;keeper-linux-arm64&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;nexus-darwin-arm64&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;nexus-linux-amd64&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;nexus-linux-arm64&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;spike-darwin-arm64&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;spike-linux-amd64&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;spike-linux-arm64&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;You want to generate SHA256 hash files for each binary, with each hash saved in its own file next to the binary.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;platform-specific-solutions&quot;&gt;Platform-Specific Solutions&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;on-macos&quot;&gt;On macOS&lt;&#x2F;h3&gt;
&lt;p&gt;On macOS, we use the &lt;code&gt;shasum&lt;&#x2F;code&gt; command with the &lt;code&gt;-a 256&lt;&#x2F;code&gt; flag to specify SHA256:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;for&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; file&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; keeper-* nexus-* spike-*&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; do&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;    shasum&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; -a 256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;$file&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;$file&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;.sum.txt&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;done&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;on-linux&quot;&gt;On Linux&lt;&#x2F;h3&gt;
&lt;p&gt;Linux systems typically use &lt;code&gt;sha256sum&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;for&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; file&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; keeper-* nexus-* spike-*&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; do&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;    sha256sum&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;$file&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;$file&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;.sum.txt&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;done&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;what-this-does&quot;&gt;What This Does&lt;&#x2F;h2&gt;
&lt;p&gt;The script will:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Loop through all files matching the patterns &lt;code&gt;keeper-*&lt;&#x2F;code&gt;, &lt;code&gt;nexus-*&lt;&#x2F;code&gt;, and &lt;code&gt;spike-*&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;For each file, compute its SHA256 hash&lt;&#x2F;li&gt;
&lt;li&gt;Save the hash and filename in a corresponding &lt;code&gt;.sum.txt&lt;&#x2F;code&gt; file&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;For example, if you have a file named &lt;code&gt;keeper-darwin-arm64&lt;&#x2F;code&gt;, it will create &lt;code&gt;keeper-darwin-arm64.sum.txt&lt;&#x2F;code&gt; containing something like:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855  keeper-darwin-arm64&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;verifying-hashes&quot;&gt;Verifying Hashes&lt;&#x2F;h2&gt;
&lt;p&gt;Users can verify the files using:&lt;&#x2F;p&gt;
&lt;p&gt;On macOS:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;shasum&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; -a 256 -c&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; filename.sum.txt&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;On Linux:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;sha256sum&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; -c&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; filename.sum.txt&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;best-practices&quot;&gt;Best Practices&lt;&#x2F;h2&gt;
&lt;ol&gt;
&lt;li&gt;Always use quotation marks around filenames in scripts to handle spaces and special characters&lt;&#x2F;li&gt;
&lt;li&gt;Keep hash files alongside binaries for easy reference&lt;&#x2F;li&gt;
&lt;li&gt;Consider also creating a single file containing all hashes for batch verification&lt;&#x2F;li&gt;
&lt;li&gt;Document which hashing algorithm was used (in this case, SHA256)&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;This approach provides a secure way to distribute binaries while allowing users to verify their integrity through cryptographic hashes.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>SQLite Security: Understanding Authentication and Protectio</title>
        <published>2024-11-27T00:00:00+00:00</published>
        <updated>2024-11-27T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Volkan Özçelik
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://zerotohero.dev/inbox/sqlite-security/"/>
        <id>https://zerotohero.dev/inbox/sqlite-security/</id>
        
        <content type="html" xml:base="https://zerotohero.dev/inbox/sqlite-security/">&lt;p&gt;SQLite is unique among database management systems in that it doesn’t come with built-in password protection or user authentication. This might seem strange at first, especially if you’re familiar with other databases like MySQL or PostgreSQL. However, understanding how SQLite handles security is crucial for developers building applications with this popular database.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;why-doesn-t-sqlite-have-passwords&quot;&gt;Why Doesn’t SQLite Have Passwords?&lt;&#x2F;h2&gt;
&lt;p&gt;SQLite is a serverless database, which means it operates quite differently from client-server database systems. Instead of running as a separate service that accepts connections from multiple clients, SQLite directly reads and writes to a single file on your disk. This fundamental architectural difference explains the absence of traditional authentication mechanisms.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;how-to-secure-your-sqlite-database&quot;&gt;How to Secure Your SQLite Database&lt;&#x2F;h2&gt;
&lt;p&gt;Despite not having built-in password protection, there are several effective ways to secure your SQLite database:&lt;&#x2F;p&gt;
&lt;h3 id=&quot;1-file-system-permissions&quot;&gt;1. File System Permissions&lt;&#x2F;h3&gt;
&lt;p&gt;The most basic and often most effective way to protect your SQLite database is through your operating system’s file permissions. Here’s how you can implement this:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;On Unix-like systems (Linux, macOS):&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;chmod&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 600&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; mydatabase.db&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This command restricts read and write access to only the file owner.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;On Windows:
Use the file properties dialog or NTFS permissions to restrict access to specific users or groups.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;2-file-encryption&quot;&gt;2. File Encryption&lt;&#x2F;h3&gt;
&lt;p&gt;For enhanced security, you can encrypt your entire SQLite database file. There are several approaches:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Use SQLite Encryption Extension (SEE)&lt;&#x2F;li&gt;
&lt;li&gt;Implement transparent disk encryption&lt;&#x2F;li&gt;
&lt;li&gt;Use third-party encryption tools&lt;&#x2F;li&gt;
&lt;li&gt;Create your own encryption wrapper&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;3-application-level-authentication&quot;&gt;3. Application-Level Authentication&lt;&#x2F;h3&gt;
&lt;p&gt;Many developers implement security at the application level. This approach involves:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Building a user authentication system in your application&lt;&#x2F;li&gt;
&lt;li&gt;Managing access control through your application’s code&lt;&#x2F;li&gt;
&lt;li&gt;Creating middleware that checks user credentials before allowing database access&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;best-practices-for-sqlite-security&quot;&gt;Best Practices for SQLite Security&lt;&#x2F;h2&gt;
&lt;p&gt;To maintain a secure SQLite implementation:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Never store your database file in a publicly accessible directory&lt;&#x2F;li&gt;
&lt;li&gt;Regularly backup your database file&lt;&#x2F;li&gt;
&lt;li&gt;Implement proper input validation to prevent SQL injection attacks&lt;&#x2F;li&gt;
&lt;li&gt;Consider using prepared statements for all database queries&lt;&#x2F;li&gt;
&lt;li&gt;Monitor file system permissions regularly&lt;&#x2F;li&gt;
&lt;li&gt;Keep your SQLite library updated to the latest version&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;when-to-consider-alternative-databases&quot;&gt;When to Consider Alternative Databases&lt;&#x2F;h2&gt;
&lt;p&gt;While SQLite’s security model works well for many use cases, you might want to consider a different database system if you need:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Built-in user authentication&lt;&#x2F;li&gt;
&lt;li&gt;Fine-grained access control&lt;&#x2F;li&gt;
&lt;li&gt;Multiple concurrent users with different permission levels&lt;&#x2F;li&gt;
&lt;li&gt;Network-based access control&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;&#x2F;h2&gt;
&lt;p&gt;SQLite’s approach to security might be different from what you’re used to, but it’s not inherently less secure. By understanding its serverless nature and implementing appropriate security measures at the file system and application levels, you can build robust and secure applications with SQLite. The key is choosing the right security measures for your specific use case and implementing them correctly.&lt;&#x2F;p&gt;
&lt;p&gt;Remember: security is only as strong as its weakest link. Always consider your entire application’s security architecture, not just database access control.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Managing Background Processes in Bash: A Complete Guide</title>
        <published>2024-11-24T00:00:00+00:00</published>
        <updated>2024-11-24T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Volkan Özçelik
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://zerotohero.dev/inbox/background-processes/"/>
        <id>https://zerotohero.dev/inbox/background-processes/</id>
        
        <content type="html" xml:base="https://zerotohero.dev/inbox/background-processes/">&lt;p&gt;When developing applications or running multiple services locally, you often need to run several scripts simultaneously. While you could open multiple terminal windows, a more elegant solution is to manage these processes programmatically. In this post, I’ll show you how to create a robust script that can run multiple processes in the background, manage their logs, and clean up properly when shutting down.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-challenge&quot;&gt;The Challenge&lt;&#x2F;h2&gt;
&lt;p&gt;Common scenarios where you might need this approach include:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Running multiple microservices locally for development&lt;&#x2F;li&gt;
&lt;li&gt;Starting various components of a distributed system&lt;&#x2F;li&gt;
&lt;li&gt;Running long-running tasks that need to be monitored&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The key requirements for our solution are:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Run multiple scripts in the background&lt;&#x2F;li&gt;
&lt;li&gt;Capture logs from each process&lt;&#x2F;li&gt;
&lt;li&gt;Clean up processes properly when the main script exits&lt;&#x2F;li&gt;
&lt;li&gt;Handle interrupts gracefully&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;the-solution&quot;&gt;The Solution&lt;&#x2F;h2&gt;
&lt;p&gt;Here’s a complete script that handles all these requirements:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;#!&#x2F;bin&#x2F;bash&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;declare&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; -a&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; BG_PIDS&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;LOG_DIR&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;logs&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;cleanup&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;    echo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;Cleaning up background processes...&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; pid&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;${&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;BG_PIDS&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;@&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;]}&amp;quot;;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; do&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt; kill&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; -0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;$pid&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; 2&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;&#x2F;dev&#x2F;null&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; then&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;            echo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;Killing process &lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;$pid&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;            kill&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;$pid&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;            wait&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;$pid&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; 2&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;&#x2F;dev&#x2F;null&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;        fi&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;    done&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;    exit&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;trap&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; cleanup EXIT INT TERM&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;mkdir&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; -p&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;$LOG_DIR&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;run_background&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;    local&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; script&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;$1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;    local&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; logfile&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;$LOG_DIR&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;$(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;basename&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;$script&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;.log&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt; [&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; ! -x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;$script&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt; ]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; then&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;        echo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;Error: &lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;$script&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; is not executable&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;    fi&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;$script&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;$logfile&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; 2&amp;gt;&amp;amp;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;    local&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; pid&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;$!&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;    BG_PIDS&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;+=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;$pid&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;    echo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;Started &lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;$script&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; with PID &lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;$pid&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;, logging to &lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;$logfile&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;run_background&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;.&#x2F;hack&#x2F;spike-agent-starter.sh&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;# run_background &amp;quot;.&#x2F;path&#x2F;to&#x2F;another&#x2F;script.sh&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;echo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;Scripts running in background. Logs in &lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;$LOG_DIR&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;. Press Ctrl+C to stop all processes.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;wait&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;how-it-works&quot;&gt;How It Works&lt;&#x2F;h2&gt;
&lt;p&gt;Let’s break down the key components:&lt;&#x2F;p&gt;
&lt;h3 id=&quot;process-management&quot;&gt;Process Management&lt;&#x2F;h3&gt;
&lt;p&gt;The script uses an array (&lt;code&gt;BG_PIDS&lt;&#x2F;code&gt;) to keep track of all background processes. This is crucial for proper cleanup later.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;declare&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; -a&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; BG_PIDS&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;log-management&quot;&gt;Log Management&lt;&#x2F;h3&gt;
&lt;p&gt;Each process gets its own log file in a dedicated logs directory:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;LOG_DIR&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;logs&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;mkdir&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; -p&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;$LOG_DIR&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;the-cleanup-function&quot;&gt;The Cleanup Function&lt;&#x2F;h3&gt;
&lt;p&gt;The cleanup function is responsible for gracefully shutting down all background processes:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;cleanup&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;    echo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;Cleaning up background processes...&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; pid&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;${&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;BG_PIDS&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;@&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;]}&amp;quot;;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; do&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt; kill&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; -0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;$pid&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; 2&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;&#x2F;dev&#x2F;null&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; then&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;            echo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;Killing process &lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;$pid&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;            kill&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;$pid&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;            wait&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;$pid&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; 2&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;&#x2F;dev&#x2F;null&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;        fi&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;    done&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;    exit&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;signal-handling&quot;&gt;Signal Handling&lt;&#x2F;h3&gt;
&lt;p&gt;The script uses &lt;code&gt;trap&lt;&#x2F;code&gt; to ensure cleanup happens in all exit scenarios:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;trap&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; cleanup EXIT INT TERM&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This catches:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Normal script exit (EXIT)&lt;&#x2F;li&gt;
&lt;li&gt;Ctrl+C interrupts (INT)&lt;&#x2F;li&gt;
&lt;li&gt;Termination signals (TERM)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;running-background-processes&quot;&gt;Running Background Processes&lt;&#x2F;h3&gt;
&lt;p&gt;The &lt;code&gt;run_background&lt;&#x2F;code&gt; function handles starting processes and setting up their logs:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;run_background&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;    local&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; script&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;$1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;    local&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; logfile&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;$LOG_DIR&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;$(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;basename&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;$script&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;.log&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt; [&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; ! -x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;$script&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt; ]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt; then&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;        echo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;Error: &lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;$script&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; is not executable&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FB4934;&quot;&gt;    fi&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;$script&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;$logfile&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt; 2&amp;gt;&amp;amp;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;    local&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt; pid&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;$!&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;    BG_PIDS&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;+=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;$pid&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;    echo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;Started &lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;$script&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; with PID &lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;$pid&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;, logging to &lt;&#x2F;span&gt;&lt;span style=&quot;color: #83A598;&quot;&gt;$logfile&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;usage&quot;&gt;Usage&lt;&#x2F;h2&gt;
&lt;ol&gt;
&lt;li&gt;Save the script as &lt;code&gt;run-background.sh&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Make it executable:&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;chmod&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; +x run-background.sh&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Add your scripts to the main execution section:&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;run_background&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;.&#x2F;your-script.sh&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Run it:&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;.&#x2F;run-background.sh&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;best-practices&quot;&gt;Best Practices&lt;&#x2F;h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Always check executability&lt;&#x2F;strong&gt;: The script verifies that each program is executable before attempting to run it.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Proper signal handling&lt;&#x2F;strong&gt;: Using &lt;code&gt;trap&lt;&#x2F;code&gt; ensures no processes are left running.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Organized logging&lt;&#x2F;strong&gt;: Each process gets its own log file, making debugging easier.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Clean exit handling&lt;&#x2F;strong&gt;: The cleanup function verifies each process exists before attempting to kill it.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;common-issues-and-solutions&quot;&gt;Common Issues and Solutions&lt;&#x2F;h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Zombie Processes&lt;&#x2F;strong&gt;: The script uses &lt;code&gt;wait&lt;&#x2F;code&gt; to properly reap child processes.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Log Management&lt;&#x2F;strong&gt;: Logs are automatically organized by script name in the logs directory.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Permission Issues&lt;&#x2F;strong&gt;: The script checks for executable permissions before running each program.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;&#x2F;h2&gt;
&lt;p&gt;This script provides a robust foundation for managing background processes in a development environment. It’s particularly useful for microservices development, where you need to run multiple services simultaneously.&lt;&#x2F;p&gt;
&lt;p&gt;Remember to modify the script paths and add any specific error handling your use case might require. The modular nature of the script makes it easy to extend with additional functionality like log rotation or process monitoring.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Understanding Unix Directory Permissions: A Common Pitfall</title>
        <published>2024-11-24T00:00:00+00:00</published>
        <updated>2024-11-24T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Volkan Özçelik
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://zerotohero.dev/inbox/file-permission/"/>
        <id>https://zerotohero.dev/inbox/file-permission/</id>
        
        <content type="html" xml:base="https://zerotohero.dev/inbox/file-permission/">&lt;p&gt;When working with Unix-like systems, you might occasionally encounter situations where you can’t create files in a directory even though you own it. This usually happens because of a common misunderstanding about how directory permissions work in Unix systems.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-problem&quot;&gt;The Problem&lt;&#x2F;h2&gt;
&lt;p&gt;Let’s look at a real-world example. Consider this output from &lt;code&gt;ls -al&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;drw-------&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;  2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; volkan volkan&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;  4096&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; Nov&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 15&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; 15:22 .spike&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;At first glance, this might seem fine - the owner has read and write permissions (&lt;code&gt;rw-&lt;&#x2F;code&gt;). However, trying to create a file in this directory will fail. Why?&lt;&#x2F;p&gt;
&lt;h2 id=&quot;understanding-directory-permissions&quot;&gt;Understanding Directory Permissions&lt;&#x2F;h2&gt;
&lt;p&gt;In Unix systems, directory permissions work differently than file permissions. The permission bits have different meanings when applied to directories:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Read (r)&lt;&#x2F;strong&gt;: Allows listing directory contents&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Write (w)&lt;&#x2F;strong&gt;: Allows creating and deleting files within the directory&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Execute (x)&lt;&#x2F;strong&gt;: Allows accessing the directory and its contents&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The crucial detail here is that the &lt;strong&gt;execute&lt;&#x2F;strong&gt; permission is required to use a directory effectively. Without it, you can’t:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Enter the directory (&lt;code&gt;cd&lt;&#x2F;code&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;Access files within it&lt;&#x2F;li&gt;
&lt;li&gt;Create new files&lt;&#x2F;li&gt;
&lt;li&gt;Delete existing files&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;breaking-down-the-permission-string&quot;&gt;Breaking Down the Permission String&lt;&#x2F;h2&gt;
&lt;p&gt;Let’s decode &lt;code&gt;drw-------&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;d&lt;&#x2F;code&gt;: This is a directory&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;rw-&lt;&#x2F;code&gt;: Owner has read and write permissions, but no execute&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;---&lt;&#x2F;code&gt;: Group has no permissions&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;---&lt;&#x2F;code&gt;: Others have no permissions&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;This translates to mode &lt;code&gt;600&lt;&#x2F;code&gt; in octal notation. However, this is rarely what you want for a directory.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-solution&quot;&gt;The Solution&lt;&#x2F;h2&gt;
&lt;p&gt;To fix this, you need to add the execute permission for the owner. There are two ways to do this:&lt;&#x2F;p&gt;
&lt;p&gt;Using symbolic mode:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;chmod&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; u+x ~&#x2F;.spike&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Or using octal mode (more common):&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;chmod&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 700&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; ~&#x2F;.spike&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;After this change, the permission string will show as &lt;code&gt;drwx------&lt;&#x2F;code&gt;, giving you full control over the directory.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;best-practices&quot;&gt;Best Practices&lt;&#x2F;h2&gt;
&lt;p&gt;For private directories that only you should access:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Use mode &lt;code&gt;700&lt;&#x2F;code&gt; (&lt;code&gt;rwx------&lt;&#x2F;code&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;This gives you full permissions while keeping the directory private&lt;&#x2F;li&gt;
&lt;li&gt;It’s more secure than &lt;code&gt;777&lt;&#x2F;code&gt; which would allow anyone to access the directory&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;For shared directories:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Consider who needs access and adjust group permissions accordingly&lt;&#x2F;li&gt;
&lt;li&gt;Common modes include &lt;code&gt;750&lt;&#x2F;code&gt; (&lt;code&gt;rwxr-x---&lt;&#x2F;code&gt;) for group-readable directories&lt;&#x2F;li&gt;
&lt;li&gt;Always be cautious with world-readable&#x2F;writable permissions&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;command-reference&quot;&gt;Command Reference&lt;&#x2F;h2&gt;
&lt;p&gt;Useful commands for managing directory permissions:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;# View permissions in human-readable format&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;ls&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; -al&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; directory_name&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;# View permissions in numeric format&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FE8019;&quot;&gt;stat&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; -c&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;%a&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A89984;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; directory_name&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;# Change permissions using symbolic notation&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;chmod&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; u+x directory_name&lt;&#x2F;span&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;  # Add execute for user&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;chmod&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; g+rx directory_name&lt;&#x2F;span&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt; # Add read and execute for group&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;# Change permissions using octal notation&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;chmod&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 700&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; directory_name&lt;&#x2F;span&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;  # rwx------ (private)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;chmod&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 750&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; directory_name&lt;&#x2F;span&gt;&lt;span style=&quot;color: #928374;font-style: italic;&quot;&gt;  # rwxr-x--- (group readable)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Remember: when working with directories, the execute permission is essential for basic operations. Always ensure it’s set appropriately for your use case.&lt;&#x2F;p&gt;
&lt;p&gt;Happy permissions managing! 🐧&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>A Glossary of Mostly Developer-Related Things</title>
        <published>2021-11-27T00:00:00+00:00</published>
        <updated>2021-11-27T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Volkan Özçelik
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://zerotohero.dev/roadmap/glossary/"/>
        <id>https://zerotohero.dev/roadmap/glossary/</id>
        
        <content type="html" xml:base="https://zerotohero.dev/roadmap/glossary/">
&lt;div class=&quot;z2h-image&quot;&gt;
    &lt;p class=&quot;img&quot;&gt;&lt;img src=&quot;&amp;#x2F;images&amp;#x2F;size&amp;#x2F;w1200&amp;#x2F;2024&amp;#x2F;03&amp;#x2F;acronym.png&quot; alt=&quot;The tech industry loves its TLAs.&quot;&#x2F;&gt;&lt;&#x2F;p&gt;
    &lt;p class=&quot;alt&quot; style=&quot;text-align: center; font-style: italic;
      margin-top: -1.125em;
      font-size: 1em;&quot;&gt;The tech industry loves its TLAs.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;We love our terms and acronyms, don’t we? They help us communicate complex
notions with just a few characters; however, they can also be an obstacle when
you are learning new stuff. This page covers a list of mostly developer-related
terms and acronyms with links to further explanations about them.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;A&#x2F;B_testing&quot;&gt;A&#x2F;B Testing&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Application_programming_interface&quot;&gt;API&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.interaction-design.org&#x2F;literature&#x2F;topics&#x2F;adaptive-design&quot;&gt;Adaptive Design&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Agile_software_development&quot;&gt;Agile Software Development&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Algorithm&quot;&gt;Algorithm&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Automation&quot;&gt;Automation&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Scrum_(software_development)#Product_backlog&quot;&gt;Backlog&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Bash_(Unix_shell)&quot;&gt;bash&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Behavior-driven_development&quot;&gt;BDD (&lt;em&gt;Behavior-Driven
Development&lt;&#x2F;em&gt;)&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Big_data&quot;&gt;Big Data&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;cloud.google.com&#x2F;bigquery&quot;&gt;Big Query&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.mozilla.org&#x2F;en-US&#x2F;firefox&#x2F;browsers&#x2F;what-is-a-browser&#x2F;&quot;&gt;Browser&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Software_bug&quot;&gt;Bug&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;dev.to&#x2F;tanhauhau&#x2F;what-is-module-bundler-and-how-does-it-work-3gp2&quot;&gt;Bundling&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Burn_rate&quot;&gt;Burn Rate&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;C_Sharp_(programming_language)&quot;&gt;C#&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;C%2B%2B&quot;&gt;C++&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Content_management_system&quot;&gt;CMS (&lt;em&gt;Content Management
System&lt;&#x2F;em&gt;)&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.cncf.io&#x2F;&quot;&gt;CNCF (&lt;em&gt;Cloud Native Computing Foundation&lt;&#x2F;em&gt;)&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Central_processing_unit&quot;&gt;CPU (&lt;em&gt;Central Processing
Unit&lt;&#x2F;em&gt;)&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;crm.org&#x2F;crmland&#x2F;what-is-a-crm&quot;&gt;CRM (&lt;em&gt;Customer Relationship
Management&lt;&#x2F;em&gt;)&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Cascading_Style_Sheets&quot;&gt;CSS (&lt;em&gt;Cascading Style
Sheet&lt;&#x2F;em&gt;)&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Call_to_action_(marketing)&quot;&gt;CTA (&lt;em&gt;Call to
Action&lt;&#x2F;em&gt;)&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;C_(programming_language)&quot;&gt;C&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Cache_(computing)&quot;&gt;Cache&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Churn_rate&quot;&gt;Churn Rate&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Source-code_editor&quot;&gt;Code Editor&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;CommonJS&quot;&gt;CommonJS&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;OS-level_virtualization&quot;&gt;Container&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Continuous_integration&quot;&gt;CI (&lt;em&gt;Continuous
Integration&lt;&#x2F;em&gt;)&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Cookie&quot;&gt;Cookie&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Web_crawler&quot;&gt;Crawl&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Domain_Name_System&quot;&gt;DNS (&lt;em&gt;Domain Name System&lt;&#x2F;em&gt;)&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;List_of_DNS_record_types&quot;&gt;DNS Record Types&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Dots_per_inch&quot;&gt;DPI (&lt;em&gt;Dots Per Inch&lt;&#x2F;em&gt;)&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Data_structure&quot;&gt;Data Structure&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Debugging&quot;&gt;Debugging&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Software_deployment&quot;&gt;Deployment&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Design&quot;&gt;Design&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;DevOps&quot;&gt;DevOps&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.docker.com&#x2F;&quot;&gt;Docker&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Domain_name&quot;&gt;Domain&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;ECMAScript&quot;&gt;ECMAScript&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.erlang.org&#x2F;&quot;&gt;Erlang&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;web.dev&#x2F;first-meaningful-paint&#x2F;&quot;&gt;FMP (&lt;em&gt;First Meaningful Paint&lt;&#x2F;em&gt;)&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Functional_programming&quot;&gt;FP (&lt;em&gt;Functional
Programming&lt;&#x2F;em&gt;)&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;File_Transfer_Protocol&quot;&gt;FTP (&lt;em&gt;File Transfer
Protocol&lt;&#x2F;em&gt;)&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Function_as_a_service&quot;&gt;FaaS&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Favicon&quot;&gt;Favicon&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Software_framework&quot;&gt;Framework&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Front_end_and_back_end&quot;&gt;Front End and Back End&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;stackoverflow.blog&#x2F;2019&#x2F;10&#x2F;17&#x2F;imho-the-mythical-fullstack-engineer&#x2F;&quot;&gt;Full-Stack&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Graphical_user_interface&quot;&gt;GUI (&lt;em&gt;Graphical User
Interface&lt;&#x2F;em&gt;)&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;&quot;&gt;GitHub&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;git-scm.com&#x2F;&quot;&gt;Git&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;golang.org&#x2F;&quot;&gt;Go&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;graphql.org&#x2F;&quot;&gt;GraphQL&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.haskell.org&#x2F;&quot;&gt;Haskell&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;HTML&quot;&gt;HTML (&lt;em&gt;Hypertext Markup Language&lt;&#x2F;em&gt;)&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;developer.mozilla.org&#x2F;en-US&#x2F;docs&#x2F;Web&#x2F;HTTP&#x2F;Status&quot;&gt;HTTP Response Status Codes&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;developer.mozilla.org&#x2F;en-US&#x2F;docs&#x2F;Web&#x2F;HTTP&quot;&gt;HTTP (&lt;em&gt;Hypertext Transfer
Protocol&lt;&#x2F;em&gt;)&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;humanstxt.org&#x2F;&quot;&gt;humans.txt&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;ionicframework.com&#x2F;resources&#x2F;articles&#x2F;what-is-hybrid-app-development&quot;&gt;Hybrid App&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Hypervisor&quot;&gt;Hypervisor&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Infrastructure_as_a_service&quot;&gt;IaaS (&lt;em&gt;Infrastructure as a
Service&lt;&#x2F;em&gt;)&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Inbound_marketing&quot;&gt;Inbound Marketing&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Information_architecture&quot;&gt;Information Architecture&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Integration_testing&quot;&gt;Integration Testing&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;jamstack.org&#x2F;&quot;&gt;JAM Stack&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;developer.mozilla.org&#x2F;en-US&#x2F;docs&#x2F;Learn&#x2F;JavaScript&#x2F;First_steps&#x2F;What_is_JavaScript&quot;&gt;JavaScript&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;go.java&#x2F;&quot;&gt;Java&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Kaizen&quot;&gt;Kaizen&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Kanban_(development)&quot;&gt;Kanban&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;kubernetes.io&#x2F;&quot;&gt;Kubernetes&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;LAMP_(software_bundle)&quot;&gt;LAMP Stack&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Library_(computing)&quot;&gt;Library&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Lisp_(programming_language)&quot;&gt;Lisp&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;developer.mozilla.org&#x2F;en-US&#x2F;docs&#x2F;Web&#x2F;API&#x2F;Window&#x2F;localStorage&quot;&gt;Local Storage&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;MEAN_(solution_stack)&quot;&gt;MEAN Stack&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.educative.io&#x2F;edpresso&#x2F;what-is-mern-stack&quot;&gt;MERN Stack&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Mock_object&quot;&gt;Mocking&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;mqtt.org&#x2F;&quot;&gt;MQTT (&lt;em&gt;Message Queue Telemetry Transport&lt;&#x2F;em&gt;)&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Mean_time_to_repair&quot;&gt;MTTR (&lt;em&gt;Mean Time to
Repair&lt;&#x2F;em&gt;)&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Minimum_viable_product&quot;&gt;MVP (&lt;em&gt;Minimum Viable
Product&lt;&#x2F;em&gt;)&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Machine_learning&quot;&gt;Machine Learning&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Minification_(programming)&quot;&gt;Minification&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Mobile_app&quot;&gt;Mobile App&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Mockup#Software_engineering&quot;&gt;Mockup&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Modular_design&quot;&gt;Module&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Web_navigation&quot;&gt;Navigation&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Not_invented_here&quot;&gt;NIH (&lt;em&gt;Not Invented Here&lt;&#x2F;em&gt;)&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;NoSQL&quot;&gt;NoSQL&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;nodejs.org&#x2F;en&#x2F;&quot;&gt;Node.js&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Orchestration_(computing)&quot;&gt;Orchestration&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Object-oriented_programming&quot;&gt;OOP (&lt;em&gt;Object-Oriented
Programming&lt;&#x2F;em&gt;)&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Out_of_the_box_(feature)&quot;&gt;OOTB (&lt;em&gt;Out of the
Box&lt;&#x2F;em&gt;)&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;OSI_model&quot;&gt;OSI Model&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;owasp.org&#x2F;&quot;&gt;OWASP (&lt;em&gt;Open Web Application Security Project&lt;&#x2F;em&gt;)&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Operating_system&quot;&gt;Operating System&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Platform_as_a_service&quot;&gt;PaaS &lt;em&gt;_Platform as a
Service&lt;&#x2F;em&gt;)&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Plug-in_(computing)&quot;&gt;Plugin&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;kubernetes.io&#x2F;docs&#x2F;concepts&#x2F;workloads&#x2F;pods&#x2F;pod&#x2F;&quot;&gt;Pod&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;dev.to&#x2F;flippedcoding&#x2F;difference-between-development-stage-and-production-d0p&quot;&gt;Production&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;developers.google.com&#x2F;protocol-buffers&quot;&gt;Protocol Buffers&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Prototype&quot;&gt;Prototype&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.python.org&#x2F;&quot;&gt;Python&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Random-access_memory&quot;&gt;RAM (&lt;em&gt;Random-Access
Memory&lt;&#x2F;em&gt;)&lt;&#x2F;a&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Representational_state_transfer&quot;&gt;REST (&lt;em&gt;Representational State
Transfer&lt;&#x2F;em&gt;)&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;URL_redirection&quot;&gt;Redirect&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Registrar&quot;&gt;Registrar&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Image_resolution&quot;&gt;Resolution&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.smashingmagazine.com&#x2F;2011&#x2F;01&#x2F;guidelines-for-responsive-web-design&#x2F;&quot;&gt;Responsive Design&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Technology_roadmap&quot;&gt;Roadmap&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;support.google.com&#x2F;webmasters&#x2F;answer&#x2F;6062608&quot;&gt;robots.txt&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.ruby-lang.org&#x2F;en&#x2F;&quot;&gt;Ruby&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.rust-lang.org&#x2F;&quot;&gt;Rust&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Simple_Mail_Transfer_Protocol&quot;&gt;SMTP (&lt;em&gt;Simple Mail Transfer
Protocol&lt;&#x2F;em&gt;)&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;SQL&quot;&gt;SQL (&lt;em&gt;Structured Query Language&lt;&#x2F;em&gt;)&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Solid-state_drive&quot;&gt;SSD (&lt;em&gt;Solid-State Drive&lt;&#x2F;em&gt;)&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Secure_Shell&quot;&gt;SSH (&lt;em&gt;Secure Shell&lt;&#x2F;em&gt;)&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Software_as_a_service&quot;&gt;SaaS (&lt;em&gt;Software as a
Service&lt;&#x2F;em&gt;)&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Scheme_(programming_language)&quot;&gt;Scheme&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Web_scraping&quot;&gt;Scrape&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Scrum_(software_development)&quot;&gt;Scrum&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Server_(computing)&quot;&gt;Server&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Separation_of_concerns&quot;&gt;Separation of Concerns&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;thoughtbot.com&#x2F;blog&#x2F;a-closer-look-at-test-spies&quot;&gt;Spying&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Serverless_computing&quot;&gt;Serverless&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;developer.mozilla.org&#x2F;en-US&#x2F;docs&#x2F;Web&#x2F;API&#x2F;Window&#x2F;sessionStorage&quot;&gt;Session Storage&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Site_map&quot;&gt;Sitemap&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Smalltalk&quot;&gt;Smalltalk&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Solution_stack&quot;&gt;Software Stack&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Version_control&quot;&gt;Source Control&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;SOLID&quot;&gt;SOLID&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.atlassian.com&#x2F;agile&#x2F;scrum&#x2F;sprints&quot;&gt;Sprint&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Test-driven_development&quot;&gt;TDD (&lt;em&gt;Test-Driven
Development&lt;&#x2F;em&gt;)&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Transport_Layer_Security&quot;&gt;TLS&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Time_to_first_byte&quot;&gt;TTFB (&lt;em&gt;Time to First
Byte&lt;&#x2F;em&gt;)&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Tag_(metadata)&quot;&gt;Tags&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Web_template_system&quot;&gt;Template&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Test_stub&quot;&gt;Test Stub&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Text_editor&quot;&gt;Text Editor&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Acceptance_testing&quot;&gt;UAT (&lt;em&gt;User Acceptance
Testing&lt;&#x2F;em&gt;)&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;User_interface_design&quot;&gt;UI Design&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;User_interface&quot;&gt;UI (&lt;em&gt;User Interface&lt;&#x2F;em&gt;)&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;User_experience_design&quot;&gt;UX Design&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;User_experience&quot;&gt;UX (&lt;em&gt;User Experience&lt;&#x2F;em&gt;)&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Unit_testing&quot;&gt;Unit Testing&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.usability.gov&#x2F;how-to-and-tools&#x2F;methods&#x2F;usability-testing.html&quot;&gt;Usability Testing&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;User_agent&quot;&gt;User Agent&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.interaction-design.org&#x2F;literature&#x2F;topics&#x2F;user-research&quot;&gt;User Research&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;WYSIWYG&quot;&gt;WYSIWYG (&lt;em&gt;What You See Is What You
Get&lt;&#x2F;em&gt;)&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Waterfall_model&quot;&gt;Waterfall&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Web_application&quot;&gt;Web App&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Graphical_widget&quot;&gt;Widget&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.usability.gov&#x2F;how-to-and-tools&#x2F;methods&#x2F;wireframing.html&quot;&gt;Wireframe&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;You_aren%27t_gonna_need_it&quot;&gt;YAGNI&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Z_shell&quot;&gt;zsh&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Until next time… May the source be with you 🦄.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;section-contents&quot;&gt;Section Contents&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;zerotohero.dev&#x2F;roadmap&#x2F;roadmap&#x2F;&quot;&gt;Be the Next Version of Yourself&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;zerotohero.dev&#x2F;roadmap&#x2F;hack-the-system&#x2F;&quot;&gt;Who Else is Ready to Hack?&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;zerotohero.dev&#x2F;roadmap&#x2F;chisel&#x2F;&quot;&gt;Grab Your Chisel and Start Pounding&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;zerotohero.dev&#x2F;roadmap&#x2F;learn-fast-remember-more&#x2F;&quot;&gt;Unlock Your Brain’s Power: Learn Fast, Remember More&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;zerotohero.dev&#x2F;roadmap&#x2F;the-art-of-learning&#x2F;&quot;&gt;Master Your Mind: Unleash the Power of Learning&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;zerotohero.dev&#x2F;roadmap&#x2F;bedtime-reading&#x2F;&quot;&gt;Resources Every Developer Must Read: No Exceptions&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;zerotohero.dev&#x2F;roadmap&#x2F;knowing-javascript-is-not-good-enough&#x2F;&quot;&gt;Knowing JavaScript Is Not Good Enough&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;zerotohero.dev&#x2F;roadmap&#x2F;learn-javascript-the-unconventional-way&#x2F;&quot;&gt;Learn JavaScript the Unconventional Way&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;zerotohero.dev&#x2F;roadmap&#x2F;learn-haskell&#x2F;&quot;&gt;Want to Learn JavaScript? Learn Haskell First&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;▶ A Glossary of Mostly Developer-Related Things&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;zerotohero.dev&#x2F;roadmap&#x2F;git&#x2F;&quot;&gt;Git Comfortable&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;zerotohero.dev&#x2F;roadmap&#x2F;vim&#x2F;&quot;&gt;Master Your Vim-Fu&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;zerotohero.dev&#x2F;roadmap&#x2F;one-does-not-simply-terminal&#x2F;&quot;&gt;One Does Not Simply Terminal 👌&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;zerotohero.dev&#x2F;roadmap&#x2F;design-patterns&#x2F;&quot;&gt;Paint Me Like One of Your French Design Patterns&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;zerotohero.dev&#x2F;roadmap&#x2F;regexp&#x2F;&quot;&gt;Tame Your Regular Expressions&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;zerotohero.dev&#x2F;roadmap&#x2F;security&#x2F;&quot;&gt;Security Is Not Optional&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;zerotohero.dev&#x2F;roadmap&#x2F;you-need-testing&#x2F;&quot;&gt;You Need Testing&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;zerotohero.dev&#x2F;roadmap&#x2F;a-startup-founders-bedtime-reading-list&#x2F;&quot;&gt;A Startup Founder’s Bedtime Reading List&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;zerotohero.dev&#x2F;roadmap&#x2F;color-theory&#x2F;&quot;&gt;Orange Is the New Purple&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;zerotohero.dev&#x2F;roadmap&#x2F;ramp-up-in-user-experience-design&#x2F;&quot;&gt;Ramp Up in User Experience Design&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;zerotohero.dev&#x2F;roadmap&#x2F;typography&#x2F;&quot;&gt;Get Better at Typography&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;zerotohero.dev&#x2F;roadmap&#x2F;what-the-junior-actually-needs&#x2F;&quot;&gt;The Bottleneck Moved. The Work Did Not.&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>One Does Not Simply &quot;Terminal&quot; 👌</title>
        <published>2021-11-07T00:00:00+00:00</published>
        <updated>2021-11-07T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Volkan Özçelik
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://zerotohero.dev/roadmap/one-does-not-simply-terminal/"/>
        <id>https://zerotohero.dev/roadmap/one-does-not-simply-terminal/</id>
        
        <content type="html" xml:base="https://zerotohero.dev/roadmap/one-does-not-simply-terminal/">
&lt;div class=&quot;z2h-image&quot;&gt;
    &lt;p class=&quot;img&quot;&gt;&lt;img src=&quot;&amp;#x2F;images&amp;#x2F;size&amp;#x2F;w1200&amp;#x2F;2024&amp;#x2F;03&amp;#x2F;one-does-not.png&quot; alt=&quot;One does not simply...&quot;&#x2F;&gt;&lt;&#x2F;p&gt;
    &lt;p class=&quot;alt&quot; style=&quot;text-align: center; font-style: italic;
      margin-top: -1.125em;
      font-size: 1em;&quot;&gt;One does not simply...&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;h2 id=&quot;getting-comfortable-with-the-linux-terminal&quot;&gt;Getting Comfortable With the Linux Terminal&lt;&#x2F;h2&gt;
&lt;p&gt;Here are some articles you can read to get more intimate with the command line:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.digitalocean.com&#x2F;community&#x2F;tutorials&#x2F;an-introduction-to-the-linux-terminal&quot;&gt;An introduction to the Linux Terminal&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;help.ubuntu.com&#x2F;community&#x2F;UsingTheTerminal&quot;&gt;Using the Terminal&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;tldr.sh&#x2F;&quot;&gt;tldr Pages&lt;&#x2F;a&gt; (&lt;em&gt;easier to scan than&lt;&#x2F;em&gt; &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.kernel.org&#x2F;doc&#x2F;man-pages&#x2F;&quot;&gt;&lt;em&gt;man pages&lt;&#x2F;em&gt;&lt;&#x2F;a&gt;&lt;em&gt;, more practical&lt;&#x2F;em&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;explainshell.com&#x2F;&quot;&gt;Explain Shell&lt;&#x2F;a&gt; (&lt;em&gt;paste your command, and let explain shell… well… explain it&lt;&#x2F;em&gt;)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;commands-that-you-ll-use-frequently&quot;&gt;Commands That You’ll Use Frequently&lt;&#x2F;h2&gt;
&lt;p&gt;The more terminal you know, the more power you’ll have. Yet, here is a list of
common commands that you might want to start familiarizing yourself with:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;man.he.net&#x2F;?topic=awk&amp;amp;section=all&quot;&gt;&lt;code&gt;awk&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;,
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;man.he.net&#x2F;?topic=sed&amp;amp;section=all&quot;&gt;&lt;code&gt;sed&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;,
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;man.he.net&#x2F;?topic=grep&amp;amp;section=all&quot;&gt;&lt;code&gt;grep&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;,
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;man.he.net&#x2F;?topic=sort&amp;amp;section=all&quot;&gt;&lt;code&gt;sort&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;,
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;man.he.net&#x2F;?topic=uniq&amp;amp;section=all&quot;&gt;&lt;code&gt;uniq&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;,
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;man.he.net&#x2F;?topic=cat&amp;amp;section=all&quot;&gt;&lt;code&gt;cat&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;,
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;man.he.net&#x2F;?topic=cut&amp;amp;section=all&quot;&gt;&lt;code&gt;cut&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;,
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;man.he.net&#x2F;?topic=echo&amp;amp;section=all&quot;&gt;&lt;code&gt;echo&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;,
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;man.he.net&#x2F;?topic=egrep&amp;amp;section=all&quot;&gt;&lt;code&gt;egrep&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;,
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;man.he.net&#x2F;?topic=fgrep&amp;amp;section=all&quot;&gt;&lt;code&gt;fgrep&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;,
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;man.he.net&#x2F;?topic=wc&amp;amp;section=all&quot;&gt;&lt;code&gt;wc&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;,
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;man.he.net&#x2F;?topic=less&amp;amp;section=all&quot;&gt;&lt;code&gt;less&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;,
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;man.he.net&#x2F;?topic=more&amp;amp;section=all&quot;&gt;&lt;code&gt;more&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;,
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;man.he.net&#x2F;?topic=ps&amp;amp;section=all&quot;&gt;&lt;code&gt;ps&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;,
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;man.he.net&#x2F;?topic=top&amp;amp;section=all&quot;&gt;&lt;code&gt;top&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;,
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;man.he.net&#x2F;?topic=htop&amp;amp;section=all&quot;&gt;&lt;code&gt;htop&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;,
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;linux.die.net&#x2F;man&#x2F;1&#x2F;atop&quot;&gt;&lt;code&gt;atop&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;,
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;nmon.sourceforge.net&#x2F;pmwiki.php&quot;&gt;&lt;code&gt;nmon&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;,
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;man.he.net&#x2F;?topic=iostat&amp;amp;section=all&quot;&gt;&lt;code&gt;iostat&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;,
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;man.he.net&#x2F;?topic=vmstat&amp;amp;section=all&quot;&gt;&lt;code&gt;vmstat&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;,
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;man.he.net&#x2F;?topic=ifconfig&amp;amp;section=all&quot;&gt;&lt;code&gt;ifconfig&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;,
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;linux.die.net&#x2F;man&#x2F;1&#x2F;nmap&quot;&gt;&lt;code&gt;nmap&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;,
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;man.he.net&#x2F;?topic=tcpdump&amp;amp;section=all&quot;&gt;&lt;code&gt;tcpdump&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;,
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;man.he.net&#x2F;?topic=ping&amp;amp;section=all&quot;&gt;&lt;code&gt;ping&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;,
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;man.he.net&#x2F;?topic=ping&amp;amp;section=all&quot;&gt;&lt;code&gt;traceroute&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;👆 These are the ones that you might use frequently. Obviously, there are more
that you might want to look into.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;know-enough-shell-scripting-to-be-dangerous&quot;&gt;Know Enough Shell Scripting to Be Dangerous&lt;&#x2F;h2&gt;
&lt;p&gt;Here are a few guides on the topic:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.tldp.org&#x2F;LDP&#x2F;Bash-Beginners-Guide&#x2F;html&#x2F;&quot;&gt;Bash Guide for Beginners&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;ryanstutorials.net&#x2F;bash-scripting-tutorial&#x2F;&quot;&gt;Bash Scripting Tutorial&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.bashoneliners.com&#x2F;&quot;&gt;Bash One-Liners&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.tldp.org&#x2F;LDP&#x2F;abs&#x2F;html&#x2F;&quot;&gt;Advanced Bash Scripting Guide&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.goodreads.com&#x2F;book&#x2F;show&#x2F;1130902.Bash_Cookbook&quot;&gt;Bash Cookbook&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;Idnan&#x2F;bash-guide&quot;&gt;Bash Guide&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.goodreads.com&#x2F;book&#x2F;show&#x2F;27112374-bash-pocket-reference&quot;&gt;Bash Pocket Reference&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;tldp.org&#x2F;HOWTO&#x2F;Bash-Prog-Intro-HOWTO.html&quot;&gt;Bash Programming Intro&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.gnu.org&#x2F;software&#x2F;bash&#x2F;manual&#x2F;bash.pdf&quot;&gt;Bash Reference Manual&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;devhints.io&#x2F;bash&quot;&gt;Bash Scripting Cheatsheet&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikibooks.org&#x2F;wiki&#x2F;Bash_Shell_Scripting&quot;&gt;Bash Shell Scripting&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;wiki.bash-hackers.org&#x2F;&quot;&gt;Bash Wiki&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.learnshell.org&#x2F;&quot;&gt;Learn Shell&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;learnxinyminutes.com&#x2F;docs&#x2F;bash&#x2F;&quot;&gt;Learn X in Y Minutes Where X is Bash&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;google.github.io&#x2F;styleguide&#x2F;shellguide.html&quot;&gt;Shell Guide&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;jlevy&#x2F;the-art-of-command-line&quot;&gt;The Art of Command Line&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;jlevy&#x2F;the-art-of-command-line&quot;&gt;The Art of Command Line&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;connecting-to-a-remote-server&quot;&gt;Connecting to a Remote Server&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.digitalocean.com&#x2F;community&#x2F;tutorials&#x2F;how-to-use-ssh-to-connect-to-a-remote-server-in-ubuntu&quot;&gt;Connecting a remote server via
&lt;strong&gt;SSH&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt;
is something you’ll have to do sooner or later.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Explore Community Docs&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;If you need more than connecting to a server. Like, for example, if you need
to install and configure applications, services, proxies, firewalls,
databases,
containers, and the like, then &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.digitalocean.com&#x2F;community&#x2F;tutorials&quot;&gt;&lt;strong&gt;DigitalOcean&lt;&#x2F;strong&gt;’s community tutorials&lt;&#x2F;a&gt; is
one of the best resources that you can have; closely followed by &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.linode.com&#x2F;docs&#x2F;&quot;&gt;&lt;strong&gt;Linode&lt;&#x2F;strong&gt;’s helpful articles&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;The only commands you need to master probably
are &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;man.openbsd.org&#x2F;ssh&quot;&gt;&lt;code&gt;ssh&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;
and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;man.openbsd.org&#x2F;ssh&quot;&gt;&lt;code&gt;ssh-copy-id&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Below, I’ll list some terminal emulators that you might want to try out too;
however, most of the time, the default terminal emulator on your operating
system will be sufficient for your needs.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Windows and Terminal&lt;&#x2F;strong&gt;&lt;br &#x2F;&gt;
If you have a Windows development machine and you are planning to work on
Linux-like environments, do yourself a favor and give
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.microsoft.com&#x2F;en-us&#x2F;windows&#x2F;wsl&#x2F;install&quot;&gt;Windows Subsystem for Linux&lt;&#x2F;a&gt;
a go. You’ll thank me later.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h2 id=&quot;cross-platform-terminal-emulators&quot;&gt;Cross-Platform Terminal Emulators&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;alacritty&quot;&gt;Alacritty&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;alacritty&#x2F;alacritty&quot;&gt;&lt;strong&gt;Alacritty&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; is the &lt;strong&gt;fastest&lt;&#x2F;strong&gt;
terminal emulator that you can find around. It’s fast, lightweight, based on
OpenGL.&lt;&#x2F;p&gt;
&lt;p&gt;However, when I say &lt;strong&gt;lightweight&lt;&#x2F;strong&gt;, it truly &lt;strong&gt;is&lt;&#x2F;strong&gt; lightweight. You cannot
find tabs, split windows, and other fancy add-ons that other terminal emulators
provide.&lt;&#x2F;p&gt;
&lt;p&gt;To be productive with &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;alacritty&#x2F;alacritty&quot;&gt;&lt;strong&gt;alacritty&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt;,
you’ll have to learn &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.hamvocke.com&#x2F;blog&#x2F;a-quick-and-easy-guide-to-tmux&#x2F;&quot;&gt;&lt;strong&gt;tmux&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt;
too, so that you’ll have an equivalent tabbed user interface experience that you might be
used to from other terminal emulators.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;💁‍&lt;&#x2F;p&gt;
&lt;p&gt;Here’s &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.hamvocke.com&#x2F;blog&#x2F;a-quick-and-easy-guide-to-tmux&#x2F;&quot;&gt;a quick and easy guide to &lt;strong&gt;tmux&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h3 id=&quot;kitty&quot;&gt;Kitty&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;sw.kovidgoyal.net&#x2F;kitty&#x2F;&quot;&gt;&lt;strong&gt;Kitty&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; is another fast, GPU-based
terminal. So what makes it different than,
say &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;alacritty&#x2F;alacritty&quot;&gt;alacritty&lt;&#x2F;a&gt;? It is feature-rich,
scriptable, and composable while still being fast and minimalistic.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;hyper&quot;&gt;Hyper&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;hyper.is&#x2F;&quot;&gt;&lt;strong&gt;Hyper&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; is an
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;electron&#x2F;electron&quot;&gt;electron&lt;&#x2F;a&gt;-based terminal emulator. It
is built on HTML&#x2F;CSS&#x2F;JS. Fully extensible, absolutely hackable. If you want
something customizable, with &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;hyper.is&#x2F;&quot;&gt;hyper&lt;&#x2F;a&gt; sky is the limit.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;mosh&quot;&gt;Mosh&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;mosh.org&#x2F;&quot;&gt;&lt;strong&gt;Mosh&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; is especially useful when you are, say, using your
terminal on a train, where connectivity is intermittent and unreliable.&lt;&#x2F;p&gt;
&lt;p&gt;It is a replacement for interactive SSH terminals. It works wonders, especially
over Wi-Fi, cellular, and long-distance links.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;terminus&quot;&gt;Terminus&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eugeny.github.io&#x2F;terminus&#x2F;&quot;&gt;&lt;strong&gt;Terminus&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; boast to be a customizable
terminal for the modern age, and it does look pretty slick if you ask me.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;linux-terminal-emulators&quot;&gt;Linux Terminal Emulators&lt;&#x2F;h2&gt;
&lt;p&gt;For the Linux UI fans out there, here are a few terminal emulators that you can
try.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;guake-project.org&#x2F;&quot;&gt;&lt;strong&gt;Guake&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt;, is my preferred terminal on my
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;ubuntu.com&#x2F;&quot;&gt;&lt;strong&gt;Ubuntu&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt;, mostly because I’m so used to
the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Quake_(video_game)&quot;&gt;Quake&lt;&#x2F;a&gt;-style keyboard
shortcuts to show and hide it. If you are a gamer, it becomes second nature to
use it.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;gnometerminator.blogspot.com&#x2F;&quot;&gt;&lt;strong&gt;Terminator&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; is really useful if
you find yourself needing to split your window horizontally and vertically to
see multiple terminal sessions simultaneously.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;konsole.kde.org&#x2F;&quot;&gt;&lt;strong&gt;Konsole&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; is another popular option to try out.&lt;&#x2F;li&gt;
&lt;li&gt;So is &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;lanoxx&#x2F;tilda&quot;&gt;&lt;strong&gt;Tilda&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;mac-terminal-emulators&quot;&gt;Mac Terminal Emulators&lt;&#x2F;h2&gt;
&lt;p&gt;Mac Terminal emulators come and go all the time, yet there’s only a single one
that stays and gets better year after year: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.iterm2.com&#x2F;&quot;&gt;&lt;strong&gt;iTerm2&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;While the default Terminal app is more than enough for your programming needs,
in case you want to spice things up a bit, you can try out
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.iterm2.com&#x2F;&quot;&gt;&lt;strong&gt;iTerm2&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt;. It provides a split window view similar
to &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;gnometerminator.blogspot.com&#x2F;&quot;&gt;terminator&lt;&#x2F;a&gt;, so if you come from the
Unix world and seek a similar experience, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.iterm2.com&#x2F;&quot;&gt;iTerm2&lt;&#x2F;a&gt; can
be your ally.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;windows-terminal-emulators&quot;&gt;Windows Terminal Emulators&lt;&#x2F;h3&gt;
&lt;p&gt;To be honest, I don’t use Terminal on Windows too much; however, the following
are the terminal emulators I’ve used and liked over time. Pick your own poison
🙂.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.microsoft.com&#x2F;en-us&#x2F;p&#x2F;windows-terminal&#x2F;9n0dx20hk701&quot;&gt;&lt;strong&gt;Windows Terminal&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;conemu.github.io&#x2F;&quot;&gt;&lt;strong&gt;Conemu&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;felixse&#x2F;FluentTerminal&quot;&gt;&lt;strong&gt;Fluent Terminal&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.microsoft.com&#x2F;en-us&#x2F;powershell&#x2F;scripting&#x2F;overview&quot;&gt;&lt;strong&gt;Powershell&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt;
(&lt;em&gt;it’s a shell, not a terminal, but still &lt;strong&gt;very&lt;&#x2F;strong&gt; useful&lt;&#x2F;em&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.putty.org&#x2F;&quot;&gt;&lt;strong&gt;PuTTY&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.emtec.com&#x2F;zoc&#x2F;index.html&quot;&gt;&lt;strong&gt;ZOC Terminal&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;cmder.net&#x2F;&quot;&gt;&lt;strong&gt;Cmder&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;shells&quot;&gt;Shells&lt;&#x2F;h2&gt;
&lt;p&gt;Picking a terminal emulator is the first step in the journey of making your
terminal experience better. Next up is &lt;strong&gt;picking up a shell&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Z_shell&quot;&gt;&lt;strong&gt;Z-shell&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; is popular nowadays, and
whoever uses &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Z_shell&quot;&gt;Z-shell&lt;&#x2F;a&gt; also installs
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;ohmyz.sh&#x2F;&quot;&gt;&lt;strong&gt;Oh My Zsh&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; as a sane starting point in customizing their
shell.&lt;&#x2F;p&gt;
&lt;p&gt;There is a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;unixorn&#x2F;zsh-quickstart-kit&quot;&gt;zsh Quickstart Kit&lt;&#x2F;a&gt;
that you might want to look at too.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;fishshell.com&#x2F;&quot;&gt;&lt;strong&gt;Fish&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; is another popular shell that is famous for
its autocomplete support.&lt;&#x2F;p&gt;
&lt;p&gt;Ah, there is also &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;oh-my-fish&#x2F;oh-my-fish&quot;&gt;&lt;strong&gt;oh my fish&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; to
set up your fish 🐠.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;terminal-utilities&quot;&gt;Terminal Utilities&lt;&#x2F;h2&gt;
&lt;p&gt;Here I’m listing terminal tools and utilities I’ve found useful over the course
of years.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;find-search-filter-files-folders-and-streams&quot;&gt;Find; Search; Filter Files, Folders and Streams&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;beyondgrep.com&#x2F;&quot;&gt;&lt;strong&gt;ack&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; (&lt;em&gt;this is a must-learn, especially if you
search source code a lot&lt;&#x2F;em&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;junegunn&#x2F;fzf&quot;&gt;&lt;strong&gt;fzf&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; (&lt;em&gt;Fuzzy Finder: Another finder
utility that you’d question how you lived without it&lt;&#x2F;em&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;ss64.com&#x2F;bash&#x2F;grep.html&quot;&gt;&lt;strong&gt;grep&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; (&lt;em&gt;must be in your toolbox&lt;&#x2F;em&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;peco&#x2F;peco&quot;&gt;&lt;strong&gt;peco&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; (&lt;strong&gt;peco&lt;&#x2F;strong&gt; is a simplistic,
interactive filtering tool)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;ripgrep&lt;&#x2F;strong&gt; (&lt;em&gt;&lt;strong&gt;ripgrep&lt;&#x2F;strong&gt; recursively searches your directories&lt;&#x2F;em&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;geoff.greer.fm&#x2F;ag&#x2F;&quot;&gt;&lt;strong&gt;The Silver Searcher&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; (&lt;em&gt;a code searching tool
similar to &lt;strong&gt;ack&lt;&#x2F;strong&gt;&lt;&#x2F;em&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;antonmedv&#x2F;fx&quot;&gt;&lt;strong&gt;fx&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; (&lt;em&gt;a utility to view JSON in
terminal&lt;&#x2F;em&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;stedolan.github.io&#x2F;jq&#x2F;&quot;&gt;&lt;strong&gt;jq&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; (&lt;em&gt;so as this one&lt;&#x2F;em&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.gnu.org&#x2F;software&#x2F;sed&#x2F;manual&#x2F;sed.html&quot;&gt;&lt;strong&gt;sed&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; (Stream
Editor—another powerful tool to learn)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ajeetdsouza&#x2F;zoxide&quot;&gt;&lt;strong&gt;zoxide&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; (&lt;em&gt;alias cd zoxide&lt;&#x2F;em&gt;)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;help&quot;&gt;Help&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;explainshell.com&#x2F;&quot;&gt;&lt;strong&gt;ExplainShell&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; is a web app to explain the
shell command you paste in.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;nvbn&#x2F;thefuck&quot;&gt;&lt;strong&gt;fuck&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; is a command-line utility that
recovers you from your mistakes.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;santinic&#x2F;how2&quot;&gt;&lt;strong&gt;how2&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; finds the simplest way to do
something in a Unix shell.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;gleitz&#x2F;howdoi&quot;&gt;&lt;strong&gt;howdoi&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; provides instant coding answers
via the command line.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;tldr-pages&#x2F;tldr&quot;&gt;&lt;strong&gt;tldr-pages&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; is for those who are
tired of reading the full manual.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;tldr.sh&#x2F;&quot;&gt;&lt;strong&gt;tldr.sh&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; is the website for &lt;code&gt;tldr-pages&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;terminal-multiplexing&quot;&gt;Terminal Multiplexing&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.gnu.org&#x2F;software&#x2F;screen&#x2F;&quot;&gt;&lt;strong&gt;screen&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;tmux&#x2F;tmux&quot;&gt;&lt;strong&gt;tmux&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;tmuxinator&#x2F;tmuxinator&quot;&gt;&lt;strong&gt;tmuxinator&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;file-and-folder-management&quot;&gt;File and Folder Management&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ogham&#x2F;exa&quot;&gt;&lt;strong&gt;exa&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; (&lt;em&gt;alias ls exa&lt;&#x2F;em&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;sindresorhus&#x2F;trash&quot;&gt;&lt;strong&gt;trash&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; (&lt;em&gt;moves files and
directories to trash&lt;&#x2F;em&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;gsamokovarov&#x2F;jump&quot;&gt;&lt;strong&gt;jump&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; (&lt;em&gt;jump helps you navigate
faster by learning your habits&lt;&#x2F;em&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;wting&#x2F;autojump&quot;&gt;&lt;strong&gt;autojump&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; (&lt;em&gt;similar to &lt;strong&gt;jump&lt;&#x2F;strong&gt;&lt;&#x2F;em&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;pedramamini&#x2F;lazy-cd&quot;&gt;&lt;strong&gt;lazy-cd&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; (&lt;em&gt;path bookmarking for
bash&lt;&#x2F;em&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;Jintin&#x2F;aliasme&quot;&gt;&lt;strong&gt;aliasme&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; (&lt;em&gt;a shell script to organize
your aliases&lt;&#x2F;em&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;sindresorhus&#x2F;fkill-cli&quot;&gt;&lt;strong&gt;fkill-cli&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; (&lt;em&gt;fabulously kill
processes with extreme prejudice&lt;&#x2F;em&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;direnv.net&#x2F;&quot;&gt;&lt;strong&gt;direnv&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; (&lt;em&gt;unclutter your &lt;code&gt;.profile&lt;&#x2F;code&gt;&lt;&#x2F;em&gt;)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;monitoring-and-system-info&quot;&gt;Monitoring and System Info&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;hisham.hm&#x2F;htop&#x2F;&quot;&gt;&lt;strong&gt;htop&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; (&lt;em&gt;better&lt;&#x2F;em&gt; &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;man7.org&#x2F;linux&#x2F;man-pages&#x2F;man1&#x2F;top.1.html&quot;&gt;
&lt;em&gt;&lt;code&gt;top&lt;&#x2F;code&gt;&lt;&#x2F;em&gt;&lt;&#x2F;a&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;MrRio&#x2F;vtop&quot;&gt;&lt;strong&gt;vtop&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; (&lt;em&gt;similar to &lt;strong&gt;htop&lt;&#x2F;strong&gt;, but
graphical&lt;&#x2F;em&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;nicolargo&#x2F;glances&quot;&gt;&lt;strong&gt;glances&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; (&lt;em&gt;better &lt;strong&gt;htop&lt;&#x2F;strong&gt; 🙂&lt;&#x2F;em&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;dylanaraps&#x2F;neofetch&quot;&gt;&lt;strong&gt;neofetch&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; (&lt;em&gt;a command-line system
information tool&lt;&#x2F;em&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;Xfennec&#x2F;progress&quot;&gt;&lt;strong&gt;progress&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; (shows the progress
of &lt;code&gt;cp&lt;&#x2F;code&gt;, &lt;code&gt;mv&lt;&#x2F;code&gt;, &lt;code&gt;dd&lt;&#x2F;code&gt;, etc.)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;getting-done&quot;&gt;Getting $#!% Done&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;todotxt.org&#x2F;&quot;&gt;&lt;strong&gt;todo.txt&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; (&lt;em&gt;a future-proof task tracking tool&lt;&#x2F;em&gt;)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;mac-specific&quot;&gt;Mac-Specific&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;mas-cli&#x2F;mas&quot;&gt;&lt;strong&gt;mas&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; (&lt;em&gt;Mac AppStore command-line
interface because why not 🤷‍♂️&lt;&#x2F;em&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;brew.sh&#x2F;&quot;&gt;&lt;strong&gt;homebrew&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; (&lt;em&gt;the closest you can get to a package
manager for Mac OS&lt;&#x2F;em&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.macports.org&#x2F;&quot;&gt;&lt;strong&gt;macports&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; (&lt;em&gt;similar to &lt;strong&gt;homebrew&lt;&#x2F;strong&gt;&lt;&#x2F;em&gt;)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;&#x2F;h2&gt;
&lt;p&gt;That’s a lot of tools and utilities to get you started with the terminal. I
hope you find them useful.&lt;&#x2F;p&gt;
&lt;p&gt;Until next time… May the source be with you 🦄.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;section-contents&quot;&gt;Section Contents&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;zerotohero.dev&#x2F;roadmap&#x2F;roadmap&#x2F;&quot;&gt;Be the Next Version of Yourself&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;zerotohero.dev&#x2F;roadmap&#x2F;hack-the-system&#x2F;&quot;&gt;Who Else is Ready to Hack?&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;zerotohero.dev&#x2F;roadmap&#x2F;chisel&#x2F;&quot;&gt;Grab Your Chisel and Start Pounding&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;zerotohero.dev&#x2F;roadmap&#x2F;learn-fast-remember-more&#x2F;&quot;&gt;Unlock Your Brain’s Power: Learn Fast, Remember More&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;zerotohero.dev&#x2F;roadmap&#x2F;the-art-of-learning&#x2F;&quot;&gt;Master Your Mind: Unleash the Power of Learning&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;zerotohero.dev&#x2F;roadmap&#x2F;bedtime-reading&#x2F;&quot;&gt;Resources Every Developer Must Read: No Exceptions&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;zerotohero.dev&#x2F;roadmap&#x2F;knowing-javascript-is-not-good-enough&#x2F;&quot;&gt;Knowing JavaScript Is Not Good Enough&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;zerotohero.dev&#x2F;roadmap&#x2F;learn-javascript-the-unconventional-way&#x2F;&quot;&gt;Learn JavaScript the Unconventional Way&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;zerotohero.dev&#x2F;roadmap&#x2F;learn-haskell&#x2F;&quot;&gt;Want to Learn JavaScript? Learn Haskell First&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;zerotohero.dev&#x2F;roadmap&#x2F;glossary&#x2F;&quot;&gt;A Glossary of Mostly Developer-Related Things&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;zerotohero.dev&#x2F;roadmap&#x2F;git&#x2F;&quot;&gt;Git Comfortable&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;zerotohero.dev&#x2F;roadmap&#x2F;vim&#x2F;&quot;&gt;Master Your Vim-Fu&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;▶ One Does Not Simply Terminal 👌&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;zerotohero.dev&#x2F;roadmap&#x2F;design-patterns&#x2F;&quot;&gt;Paint Me Like One of Your French Design Patterns&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;zerotohero.dev&#x2F;roadmap&#x2F;regexp&#x2F;&quot;&gt;Tame Your Regular Expressions&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;zerotohero.dev&#x2F;roadmap&#x2F;security&#x2F;&quot;&gt;Security Is Not Optional&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;zerotohero.dev&#x2F;roadmap&#x2F;you-need-testing&#x2F;&quot;&gt;You Need Testing&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;zerotohero.dev&#x2F;roadmap&#x2F;a-startup-founders-bedtime-reading-list&#x2F;&quot;&gt;A Startup Founder’s Bedtime Reading List&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;zerotohero.dev&#x2F;roadmap&#x2F;color-theory&#x2F;&quot;&gt;Orange Is the New Purple&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;zerotohero.dev&#x2F;roadmap&#x2F;ramp-up-in-user-experience-design&#x2F;&quot;&gt;Ramp Up in User Experience Design&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;zerotohero.dev&#x2F;roadmap&#x2F;typography&#x2F;&quot;&gt;Get Better at Typography&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;zerotohero.dev&#x2F;roadmap&#x2F;what-the-junior-actually-needs&#x2F;&quot;&gt;The Bottleneck Moved. The Work Did Not.&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>mTLS With SPIRE: Part 2: Creating the Server App</title>
        <published>2021-10-19T00:00:00+00:00</published>
        <updated>2021-10-19T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Volkan Özçelik
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://zerotohero.dev/spire/mtls/server-app/"/>
        <id>https://zerotohero.dev/spire/mtls/server-app/</id>
        
        <content type="html" xml:base="https://zerotohero.dev/spire/mtls/server-app/">&lt;h2 id=&quot;mtls-with-spire-part-2-creating-the-server-app&quot;&gt;mTLS With SPIRE: Part 2 — Creating the Server App&lt;&#x2F;h2&gt;

&lt;div class=&quot;z2h-image&quot;&gt;
    &lt;p class=&quot;img&quot;&gt;&lt;img src=&quot;&amp;#x2F;images&amp;#x2F;size&amp;#x2F;w1200&amp;#x2F;2024&amp;#x2F;03&amp;#x2F;server-app.png&quot; alt=&quot;mTLS With SPIRE: Part 2: Creating the Server App&quot;&#x2F;&gt;&lt;&#x2F;p&gt;
    &lt;p class=&quot;alt&quot; style=&quot;text-align: center; font-style: italic;
      margin-top: -1.125em;
      font-size: 1em;&quot;&gt;mTLS With SPIRE: Part 2: Creating the Server App&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;We’ll start by creating a server application. Once the server is ready, we’ll
continue with the client application on the next video.&lt;&#x2F;p&gt;
&lt;div style=&quot;padding:56.25% 0 0 0;position:relative;&quot;&gt;
  &lt;iframe src=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;embed&#x2F;sNqJxFE7eR8?si=hFxATeHr6n1_OGPx&quot;
    frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; 
    encrypted-media; gyroscope; picture-in-picture; web-share&quot;
    referrerpolicy=&quot;strict-origin-when-cross-origin&quot;
    allowfullscreen
    style=&quot;position:absolute;top:0;left:0;width:100%;height:100%;&quot;
    title=&quot;mTLS With SPIRE: Part 2: Creating the Server App&quot;&gt;&lt;&#x2F;iframe&gt;
&lt;&#x2F;div&gt;
&lt;p style=&quot;text-align: center;&quot;&gt;mTLS With SPIRE: Part 2: Creating the Server App&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;playlist&quot;&gt;Playlist&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;zerotohero.dev&#x2F;spire&#x2F;mtls&#x2F;intro&#x2F;&quot;&gt;mTLS With SPIRE: Part 1: Introduction&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;▶ mTLS With SPIRE: Part 2: Creating the Server App&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;zerotohero.dev&#x2F;spire&#x2F;mtls&#x2F;client-app&#x2F;&quot;&gt;mTLS With SPIRE: Part 3: Creating the Client App&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;zerotohero.dev&#x2F;spire&#x2F;mtls&#x2F;bundle-server&#x2F;&quot;&gt;mTLS With SPIRE: Part 4: Containerizing the Server App&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;zerotohero.dev&#x2F;spire&#x2F;mtls&#x2F;bundle-client&#x2F;&quot;&gt;mTLS With SPIRE: Part 5: Containerizing the Client App&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;zerotohero.dev&#x2F;spire&#x2F;mtls&#x2F;rollout&#x2F;&quot;&gt;mTLS With SPIRE: Part 6: Rolling Out SPIRE to the Cluster&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;zerotohero.dev&#x2F;spire&#x2F;mtls&#x2F;register&#x2F;&quot;&gt;mTLS With SPIRE: Part 7: Registering Nodes and Workloads to SPIRE&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;zerotohero.dev&#x2F;spire&#x2F;mtls&#x2F;setup-server&#x2F;&quot;&gt;mTLS With SPIRE: Part 8: Configuring the Server to Use SPIRE mTLS&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;zerotohero.dev&#x2F;spire&#x2F;mtls&#x2F;setup-client&#x2F;&quot;&gt;mTLS With SPIRE: Part 9: Configuring the Client to Use SPIRE mTLS&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;zerotohero.dev&#x2F;spire&#x2F;mtls&#x2F;end-to-end&#x2F;&quot;&gt;mTLS With SPIRE: Part 10: Establishing Cross-Cluster mTLS&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;tools-and-technologies-mentioned&quot;&gt;Tools and Technologies Mentioned&lt;&#x2F;h2&gt;
&lt;p&gt;Here are the tools and technologies that were mentioned in the video, along with
related articles and other helpful links.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;go.dev&#x2F;&quot;&gt;&lt;strong&gt;Go&lt;&#x2F;strong&gt; Programming Language&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;go.dev&#x2F;blog&#x2F;using-go-modules&quot;&gt;Using &lt;strong&gt;Go&lt;&#x2F;strong&gt; Modules&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Bash_(Unix_shell)&quot;&gt;&lt;strong&gt;Bash&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;grpc.io&#x2F;&quot;&gt;&lt;strong&gt;gRPC&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;read-the-source&quot;&gt;Read the Source&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;zerotohero-dev&#x2F;spire-mtls&quot;&gt;Access the source code and other related assets from &lt;strong&gt;Zero to Hero&lt;&#x2F;strong&gt; GitHub&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Assemble Your Personal Board of Advisors</title>
        <published>2021-07-31T00:00:00+00:00</published>
        <updated>2021-07-31T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Volkan Özçelik
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://zerotohero.dev/highlights/issue-0011/"/>
        <id>https://zerotohero.dev/highlights/issue-0011/</id>
        
        <content type="html" xml:base="https://zerotohero.dev/highlights/issue-0011/">
&lt;div class=&quot;z2h-image&quot;&gt;
    &lt;p class=&quot;img&quot;&gt;&lt;img src=&quot;&amp;#x2F;images&amp;#x2F;size&amp;#x2F;w1200&amp;#x2F;2024&amp;#x2F;03&amp;#x2F;board.png&quot; alt=&quot;Your personal board of advisors will help you navigate the tough times.&quot;&#x2F;&gt;&lt;&#x2F;p&gt;
    &lt;p class=&quot;alt&quot; style=&quot;text-align: center; font-style: italic;
      margin-top: -1.125em;
      font-size: 1em;&quot;&gt;Your personal board of advisors will help you navigate the tough times.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;Welcome to the eleventh issue of &lt;strong&gt;Zero to Hero&lt;&#x2F;strong&gt; Highlights.&lt;&#x2F;p&gt;
&lt;p&gt;We had quite a ride in the last week. Let’s take a look at a few highlights.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;fizzbuzz-pro-kubernetes-cluster-is-up-and-running-metal&quot;&gt;FizzBuzz Pro** Kubernetes Cluster is Up and Running 🤘&lt;&#x2F;h2&gt;
&lt;p&gt;Well, it’s up, running; and there’s still a lot to implement, but at least I can
get a list of pods and deployments. Also, the critical services
like &lt;code&gt;idm&lt;&#x2F;code&gt;, &lt;code&gt;mailer&lt;&#x2F;code&gt;, &lt;code&gt;crypto&lt;&#x2F;code&gt; are &lt;strong&gt;mostly&lt;&#x2F;strong&gt; complete.&lt;&#x2F;p&gt;
&lt;p&gt;Here’s what I see when I query the cluster:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #EBDBB2; background-color: #1D2021;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; kubectl get deployment&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;NAME&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;        READY   UP-TO-DATE   AVAILABLE   AGE&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;crypto&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;      1&#x2F;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;     1            1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;           3d&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;idm&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;         1&#x2F;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;     1            1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;           3d21h&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;mailer&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;      1&#x2F;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;     1            1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;           4d2h&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;questions&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;   1&#x2F;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;     1            1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;           4d2h&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;store&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;       1&#x2F;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;     1            1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;           4d2h&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt; kubectl get po&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;NAME&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;                         READY   STATUS      RESTARTS   AGE&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;crypto-84f64dc7bf-qnj8l&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;      1&#x2F;1     Running&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;     0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;          3d&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;idm-844969c6dd-pzmks&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;         1&#x2F;1     Running&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;     0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;          3d21h&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;mailer-67fcf8b5dc-zc8lp&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;      1&#x2F;1     Running&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;     0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;          4d2h&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;questions-7f5ccd5b84-2tmdp&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;   1&#x2F;1     Running&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;     0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;          4d2h&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;store-5f8b66f949-tsc42&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;       1&#x2F;1     Running&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt;     0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;          4d2h&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;  kubectl get ingress&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;NAME&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;       CLASS    HOSTS              ADDRESS&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FABD2F;&quot;&gt;cerberus&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;   &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;non&lt;&#x2F;span&gt;&lt;span&gt;e&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EC07C;&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;   api.fizzbuzz.pro   k8s-...amazonaws.com&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D3869B;&quot;&gt; 80&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B8BB26;&quot;&gt;   10d&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;So nothing has been broken for days! Everything is healthy as a horse. Progress!&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;I’ll be writing more articles and creating more videos about how these
services all tie together. Stay tuned.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h2 id=&quot;deploying-a-microservice-to-kubernetes&quot;&gt;Deploying a Microservice to Kubernetes&lt;&#x2F;h2&gt;
&lt;p&gt;While on the topic of videos, &lt;a href=&quot;https:&#x2F;&#x2F;zerotohero.dev&#x2F;spire&#x2F;&quot;&gt;I published a video about how you can deploy a
microservice to an AWS EKS Kubernetes cluster&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;In the video, I start from the source code:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Build the code.&lt;&#x2F;li&gt;
&lt;li&gt;Containerize it.&lt;&#x2F;li&gt;
&lt;li&gt;Push it to a registry.&lt;&#x2F;li&gt;
&lt;li&gt;Link the registry image to Kubernetes Deployments, Services, and Pods.&lt;&#x2F;li&gt;
&lt;li&gt;And more.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;It’s an excellent overview of how everything ties together.&lt;&#x2F;p&gt;
&lt;p&gt;Note that this is just the &lt;strong&gt;video&lt;&#x2F;strong&gt; part of the content. There will be an
accompanying article on &lt;a href=&quot;https:&#x2F;&#x2F;zerotohero.dev&#x2F;&quot;&gt;&lt;strong&gt;Zero to Hero&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; that will dive deeper and
provide you with additional &lt;em&gt;bedtime reading material&lt;&#x2F;em&gt; to dig in.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;installing-an-aws-eks-kubernetes-cluster-using-eksctl&quot;&gt;Installing an AWS EKS Kubernetes Cluster Using &lt;code&gt;eksctl&lt;&#x2F;code&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;The above video talks about deploying to &lt;strong&gt;Kubernetes,&lt;&#x2F;strong&gt; but how do we create a
&lt;strong&gt;Kubernetes&lt;&#x2F;strong&gt; cluster in the first place.&lt;&#x2F;p&gt;
&lt;p&gt;There are many ways but
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eksctl.io&#x2F;&quot;&gt;eksctl&lt;&#x2F;a&gt; is the preferred way.
As always, there’s more than mere instructions; I discuss the pros and cons of
things, and there are further reference material for the interested to do a
deeper dive.&lt;&#x2F;p&gt;
&lt;p&gt;That’s more or less this week in a nutshell. So what’s coming up next?&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-s-on-the-horizon-woman-fried-egg&quot;&gt;What’s on the Horizon 👩‍🍳&lt;&#x2F;h2&gt;
&lt;p&gt;I have a couple of [&lt;strong&gt;Zero to Hero Twitch Screencasts&lt;&#x2F;strong&gt;][twitch] that I
haven’t published yet.&lt;&#x2F;p&gt;
&lt;p&gt;On the &lt;strong&gt;FizzBuzz Pro&lt;&#x2F;strong&gt; end, I, at least, want to finish the &lt;strong&gt;IDM&lt;&#x2F;strong&gt; µService
endpoints (&lt;em&gt;which is almost done&lt;&#x2F;em&gt;), but we’ll see how it goes.
I’ll let you know next week.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;random-thought-of-the-week&quot;&gt;Random Thought of the Week&lt;&#x2F;h2&gt;
&lt;p&gt;Don’t take the phrase “&lt;em&gt;you must have a mentor&lt;&#x2F;em&gt;” too literally. The reality is
&lt;strong&gt;you need more than a single mentor&lt;&#x2F;strong&gt;; you need your &lt;strong&gt;personal board of
advisors&lt;&#x2F;strong&gt; if you will. But how do you find all these people? Let’s see.&lt;&#x2F;p&gt;
&lt;p&gt;I don’t want to sound cheesy, but the first step is to
&lt;a href=&quot;https:&#x2F;&#x2F;zerotohero.dev&#x2F;highlights&#x2F;issue-0003&#x2F;&quot;&gt;&lt;strong&gt;know yourself&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt;. Finding what you
want requires knowing what you want. Then, reflect deeply and write down a *
&lt;em&gt;personal vision statement&lt;&#x2F;em&gt;*. Make sure that your &lt;em&gt;personal vision statement&lt;&#x2F;em&gt;
resonates with what &lt;strong&gt;you&lt;&#x2F;strong&gt; want to aspire to be. &lt;strong&gt;Not&lt;&#x2F;strong&gt; what society, your
teammates, your managers, or your family expects from you.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Think about how your career &lt;strong&gt;aligns&lt;&#x2F;strong&gt; with your personal vision down the
road. How does your ideal life look like fifteen years ahead?&lt;br &#x2F;&gt;
How will it be different from your present-day?&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Then create a list of different kinds of support that you will need to
&lt;strong&gt;actualize&lt;&#x2F;strong&gt; that aspiration. For example, what types of support do you need to
take yourself from where you are to where you want to be?&lt;&#x2F;p&gt;
&lt;p&gt;Then consider which areas are already fulfilled by mentors and helpers and which
aren’t.&lt;&#x2F;p&gt;
&lt;p&gt;Do you want a few examples?&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Who do you go when you need to discuss some tactical advice to navigate
company internals?&lt;&#x2F;li&gt;
&lt;li&gt;Where do you go for emotional support?&lt;&#x2F;li&gt;
&lt;li&gt;Whom do you rely on to enhance your technical understanding?&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Enhance the list as much as you can.&lt;&#x2F;p&gt;
&lt;p&gt;Then for any role that is “&lt;em&gt;missing&lt;&#x2F;em&gt;” a mentor, think about who could fill that
need. Does that person exist in your network, do they exist in your
second-degree network; or do you need to look even further?&lt;&#x2F;p&gt;
&lt;p&gt;Based on that assessment, you can develop new relationships or strengthen the
existing ones.&lt;&#x2F;p&gt;
&lt;p&gt;You’ll also find that a prospective mentor or a coach will be &lt;strong&gt;much&lt;&#x2F;strong&gt; inclined
to help you on a particular topic rather than the generic “&lt;em&gt;would you be my
mentor?&lt;&#x2F;em&gt;” questions.&lt;&#x2F;p&gt;
&lt;p&gt;In short, as I’ve been telling you a million times: &lt;strong&gt;do your homework&lt;&#x2F;strong&gt; before
reaching out for help.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;look-what-i-ve-found&quot;&gt;Look What I’ve Found&lt;&#x2F;h2&gt;
&lt;p&gt;Here are the things that grabbed my attention this week.&lt;&#x2F;p&gt;
&lt;p&gt;I typically don’t share these anywhere else.&lt;&#x2F;p&gt;
&lt;p&gt;Exclusively hand-picked for you 👌. Enjoy.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;middyjs&#x2F;middy&quot;&gt;&lt;strong&gt;Middy&lt;&#x2F;strong&gt; is the stylish Node.js middleware engine for AWS Lambda&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.blog&#x2F;2021-03-18-how-we-found-and-fixed-a-rare-race-condition-in-our-session-handling&#x2F;&quot;&gt;Here’s how &lt;strong&gt;GitHub&lt;&#x2F;strong&gt; found and fixed a rare race condition in their
session handling&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;nesslabs.com&#x2F;power-of-simplicity-complexity-bias&quot;&gt;&lt;strong&gt;Flash News&lt;&#x2F;strong&gt;: You can manage your complexity bias by… keeping things
simple, who knew&lt;&#x2F;a&gt;!&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;thanks-a-lot-heart&quot;&gt;Thanks a Lot ❤️&lt;&#x2F;h2&gt;
&lt;p&gt;That’s all for this week. Next week, I’ll gather more unique content and resources.&lt;&#x2F;p&gt;
&lt;p&gt;So, until next time… May the source be with you 🦄.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;issues&quot;&gt;Issues&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;zerotohero.dev&#x2F;highlights&#x2F;issue-0001&#x2F;&quot;&gt;Issue 1: Hello World, Hello Stars, Hello Universe&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;zerotohero.dev&#x2F;highlights&#x2F;issue-0002&#x2F;&quot;&gt;Issue 2: The Only Thing That doesn’t Change is Change Itself&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;zerotohero.dev&#x2F;highlights&#x2F;issue-0003&#x2F;&quot;&gt;Issue 3: Know Thyself&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;zerotohero.dev&#x2F;highlights&#x2F;issue-0004&#x2F;&quot;&gt;Issue 4: Have You Fizzed that Buzz?&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;zerotohero.dev&#x2F;highlights&#x2F;issue-0005&#x2F;&quot;&gt;Issue 5: Be Kind&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;zerotohero.dev&#x2F;highlights&#x2F;issue-0006&#x2F;&quot;&gt;Issue 6: Earn the Promotion You Deserve&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;zerotohero.dev&#x2F;highlights&#x2F;issue-0007&#x2F;&quot;&gt;Issue 7: Who Else Journals Daily?&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;zerotohero.dev&#x2F;highlights&#x2F;issue-0008&#x2F;&quot;&gt;Issue 8: Who Are You?&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;zerotohero.dev&#x2F;highlights&#x2F;issue-0009&#x2F;&quot;&gt;Issue 9: How to Make Yourself Heard&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;zerotohero.dev&#x2F;highlights&#x2F;issue-0010&#x2F;&quot;&gt;Issue 10: Tough Conversations&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;▶ Issue 11: Assemble Your Personal Board of Advisor&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;zerotohero.dev&#x2F;highlights&#x2F;issue-0012&#x2F;&quot;&gt;Issue 12: What’s Your Plan&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;zerotohero.dev&#x2F;highlights&#x2F;issue-0013&#x2F;&quot;&gt;Issue 13: Nine-to-Five? I Don’t Think So&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;zerotohero.dev&#x2F;highlights&#x2F;issue-0014&#x2F;&quot;&gt;Issue 14: Respect and Understanding&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;zerotohero.dev&#x2F;highlights&#x2F;issue-0015&#x2F;&quot;&gt;Issue 15: Pivoting Your Career?&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;zerotohero.dev&#x2F;highlights&#x2F;issue-0016&#x2F;&quot;&gt;Issue 16: Ghosted?&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;zerotohero.dev&#x2F;highlights&#x2F;issue-0017&#x2F;&quot;&gt;Issue 17: ‘Following Your Passion’ Is Hardly Enough&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;zerotohero.dev&#x2F;highlights&#x2F;issue-0018&#x2F;&quot;&gt;Issue 18: Keep Cam and Carry On&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;zerotohero.dev&#x2F;highlights&#x2F;issue-0019&#x2F;&quot;&gt;Issue 19: Attention, Intention, Compassion&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;zerotohero.dev&#x2F;highlights&#x2F;issue-0020&#x2F;&quot;&gt;Issue 20: Words Matter&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;zerotohero.dev&#x2F;highlights&#x2F;issue-0021&#x2F;&quot;&gt;Issue 21: Change Is the Only Constant&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;zerotohero.dev&#x2F;highlights&#x2F;issue-0022&#x2F;&quot;&gt;Issue 22: Overcome the Awkward Feeling of Networking&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;zerotohero.dev&#x2F;highlights&#x2F;issue-0023&#x2F;&quot;&gt;Issue 23: Unleash Your Curiosity: Unlock Your Potential as a Leader&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;zerotohero.dev&#x2F;highlights&#x2F;issue-0024&#x2F;&quot;&gt;Issue 24: Interview Done. Radio Silence 🎃 What Now?&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;zerotohero.dev&#x2F;highlights&#x2F;issue-0025&#x2F;&quot;&gt;Issue 25: Unlock Your True Potential: Make Your Hard Work Visible&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;zerotohero.dev&#x2F;highlights&#x2F;issue-0026&#x2F;&quot;&gt;Issue 26: Winning at Work: Thriving With Difficult Colleagues&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;zerotohero.dev&#x2F;highlights&#x2F;issue-0027&#x2F;&quot;&gt;Issue 27: Promotions Don’t Happen Overnight&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
</feed>
