{
  "version": "https://jsonfeed.org/version/1.1",
  "title": "My thoughts on the pang-wang Archive",
  "home_page_url": "https://pype.dev/linux/",
  "feed_url": "https://pype.dev/linux/archive/feed.json",
  "description": "My thoughts and streams of consciousness organized into barely coherent posts about things",
  "authors": [
    {
      "name": "Nic Payne"
    }
  ],
  "items": [
    {
      "id": "https://pype.dev/thoughts-745/",
      "url": "https://pype.dev/thoughts-745/",
      "title": "💭 Tyblog | systemd has been a complete, utter, unmitigated success",
      "content_html": "\u003ca href=\"https://blog.tjll.net/the-systemd-revolution-has-been-a-success/\"\u003e\n    \u003cimg\n        src=\"https://shots.wayl.one/shot/?url=https://blog.tjll.net/the-systemd-revolution-has-been-a-success/\u0026height=450\u0026width=800\u0026scaled_width=800\u0026scaled_height=450\u0026selectors=\"\n        alt=\"shot of post - Tyblog | systemd has been a complete, utter, unmitigated success\"\n        height=450\n        width=800\n    \u003e\n\u003c/a\u003e\n\u003cp\u003eHere\u0026rsquo;s my thought on \u003ca href=\"https://blog.tjll.net/the-systemd-revolution-has-been-a-success/\"\u003eTyblog | systemd has been a complete, utter, unmitigated success\u003c/a\u003e\u003c/p\u003e\n\u003chr\u003e\n\u003cp\u003eI found this post on systemd this morning, and although I\u0026rsquo;ve been a Linux user for around 6 years now, there\u0026rsquo;s some levels of it that are pretty foreign to me. One of the things I never got was the drama around systemd - but that\u0026rsquo;s because I wasn\u0026rsquo;t around in the beforefore times, I don\u0026rsquo;t use cron THAT MUCH, and I\u0026rsquo;ve only had to setup a few systemd unit files - not enough to generate a real opinion on it.\nBut lately I\u0026rsquo;m looking into more automation at home - and some stuff is fun to put into an overkill of a platform for a homelab, like temporal, but some stuff should probably be run in more hardened ways (backups for example) - so getting a little download this morning on systemd from a clearly seasoned Linux user is a nice addition to my hot cup of coffee.\u003c/p\u003e\n\u003chr\u003e\n\u003cdiv class=\"admonition note\"\u003e\n\u003cp class=\"admonition-title\"\u003eNote\u003c/p\u003e\n\u003cp\u003eThis is one of [[ my-thoughts ]]. I picked this up from \u003ca href=\"https://waylonwalker.com\"\u003eWaylon Walker\u003c/a\u003e(\u003ca href=\"https://thoughts.waylonwalker.com\"\u003ehttps://thoughts.waylonwalker.com\u003c/a\u003e). It\u0026rsquo;s a short note that I make about someone else\u0026rsquo;s content online.  Learn more about the process \u003ca href=\"/thoughts/\" class=\"wikilink\" data-title=\"Thoughts\" data-description=\"My thoughts are found at my thoughts feed\" data-date=\"2025-06-09\" data-preview=\"My thoughts are found at my thoughts feed\"\u003eThoughts\u003c/a\u003e\u003c/p\u003e\n\u003c/div\u003e\n",
      "content_text": "\n\u003ca href=\"https://blog.tjll.net/the-systemd-revolution-has-been-a-success/\"\u003e\n    \u003cimg\n        src=\"https://shots.wayl.one/shot/?url=https://blog.tjll.net/the-systemd-revolution-has-been-a-success/\u0026height=450\u0026width=800\u0026scaled_width=800\u0026scaled_height=450\u0026selectors=\"\n        alt=\"shot of post - Tyblog | systemd has been a complete, utter, unmitigated success\"\n        height=450\n        width=800\n    \u003e\n\u003c/a\u003e\n\nHere's my thought on \u003ca href=\"https://blog.tjll.net/the-systemd-revolution-has-been-a-success/\"\u003eTyblog | systemd has been a complete, utter, unmitigated success\u003c/a\u003e\n\n---\n\nI found this post on systemd this morning, and although I've been a Linux user for around 6 years now, there's some levels of it that are pretty foreign to me. One of the things I never got was the drama around systemd - but that's because I wasn't around in the beforefore times, I don't use cron THAT MUCH, and I've only had to setup a few systemd unit files - not enough to generate a real opinion on it.\nBut lately I'm looking into more automation at home - and some stuff is fun to put into an overkill of a platform for a homelab, like temporal, but some stuff should probably be run in more hardened ways (backups for example) - so getting a little download this morning on systemd from a clearly seasoned Linux user is a nice addition to my hot cup of coffee.\n\n---\n\n!!! note\n    This is one of [[ my-thoughts ]]. I picked this up from [Waylon Walker](https://waylonwalker.com)(https://thoughts.waylonwalker.com). It's a short note that I make about someone else's content online.  Learn more about the process \u003ca href=\"/thoughts/\" class=\"wikilink\" data-title=\"Thoughts\" data-description=\"My thoughts are found at my thoughts feed\" data-date=\"2025-06-09\"\u003eThoughts\u003c/a\u003e\n",
      "summary": "I found this post on systemd this morning, and although I've been a Linux user for around 6 years now, there's some leve",
      "date_published": "2025-07-11T11:00:54Z",
      "date_modified": "2025-07-11T11:00:54Z",
      "authors": [
        {
          "name": "Nic Payne",
          "url": "https://pype.dev"
        }
      ],
      "tags": [
        "systemd",
        "linux",
        "blog",
        "thoughts"
      ]
    },
    {
      "id": "https://pype.dev/thoughts-735/",
      "url": "https://pype.dev/thoughts-735/",
      "title": "💭 Self-Hosting A Cluster On Old Phones | Hackaday",
      "content_html": "\u003ca href=\"https://hackaday.com/2025/04/09/self-hosting-a-cluster-on-old-phones/?ref=dailydev\"\u003e\n    \u003cimg\n        src=\"https://shots.wayl.one/shot/?url=https://hackaday.com/2025/04/09/self-hosting-a-cluster-on-old-phones/?ref=dailydev\u0026height=450\u0026width=800\u0026scaled_width=800\u0026scaled_height=450\u0026selectors=\"\n        alt=\"shot of post - Self-Hosting A Cluster On Old Phones | Hackaday\"\n        height=450\n        width=800\n    \u003e\n\u003c/a\u003e\n\u003cp\u003eHere\u0026rsquo;s my thought on \u003ca href=\"https://hackaday.com/2025/04/09/self-hosting-a-cluster-on-old-phones/?ref=dailydev\"\u003eSelf-Hosting A Cluster On Old Phones | Hackaday\u003c/a\u003e\u003c/p\u003e\n\u003chr\u003e\n\u003cp\u003eCame across a blog and article on using a mobile OS to self-host a cluster on old phones\u0026hellip; I happen to keep several old android phones lying around and although I\u0026rsquo;m not presently super interested in figuring out an android/arm based homelab, I am excited for the next coming years when I\u0026rsquo;m sure it\u0026rsquo;ll only get easier, phones will only be more powerful, and perhaps we\u0026rsquo;ll be running full blown CV pipeline in k8s clusters running on Pixel devices!\u003c/p\u003e\n\u003chr\u003e\n\u003cdiv class=\"admonition note\"\u003e\n\u003cp class=\"admonition-title\"\u003eNote\u003c/p\u003e\n\u003cp\u003eThis is one of [[ my-thoughts ]]. I picked this up from \u003ca href=\"https://waylonwalker.com\"\u003eWaylon Walker\u003c/a\u003e(\u003ca href=\"https://thoughts.waylonwalker.com\"\u003ehttps://thoughts.waylonwalker.com\u003c/a\u003e). It\u0026rsquo;s a short note that I make about someone else\u0026rsquo;s content online.  Learn more about the process \u003ca href=\"/thoughts/\" class=\"wikilink\" data-title=\"Thoughts\" data-description=\"My thoughts are found at my thoughts feed\" data-date=\"2025-06-09\" data-preview=\"My thoughts are found at my thoughts feed\"\u003eThoughts\u003c/a\u003e\u003c/p\u003e\n\u003c/div\u003e\n",
      "content_text": "\n\u003ca href=\"https://hackaday.com/2025/04/09/self-hosting-a-cluster-on-old-phones/?ref=dailydev\"\u003e\n    \u003cimg\n        src=\"https://shots.wayl.one/shot/?url=https://hackaday.com/2025/04/09/self-hosting-a-cluster-on-old-phones/?ref=dailydev\u0026height=450\u0026width=800\u0026scaled_width=800\u0026scaled_height=450\u0026selectors=\"\n        alt=\"shot of post - Self-Hosting A Cluster On Old Phones | Hackaday\"\n        height=450\n        width=800\n    \u003e\n\u003c/a\u003e\n\nHere's my thought on \u003ca href=\"https://hackaday.com/2025/04/09/self-hosting-a-cluster-on-old-phones/?ref=dailydev\"\u003eSelf-Hosting A Cluster On Old Phones | Hackaday\u003c/a\u003e\n\n---\n\nCame across a blog and article on using a mobile OS to self-host a cluster on old phones... I happen to keep several old android phones lying around and although I'm not presently super interested in figuring out an android/arm based homelab, I am excited for the next coming years when I'm sure it'll only get easier, phones will only be more powerful, and perhaps we'll be running full blown CV pipeline in k8s clusters running on Pixel devices!\n\n---\n\n!!! note\n    This is one of [[ my-thoughts ]]. I picked this up from [Waylon Walker](https://waylonwalker.com)(https://thoughts.waylonwalker.com). It's a short note that I make about someone else's content online.  Learn more about the process \u003ca href=\"/thoughts/\" class=\"wikilink\" data-title=\"Thoughts\" data-description=\"My thoughts are found at my thoughts feed\" data-date=\"2025-06-09\"\u003eThoughts\u003c/a\u003e\n",
      "summary": "Came across a blog and article on using a mobile OS to self-host a cluster on old phones... I happen to keep several old",
      "date_published": "2025-07-06T11:30:17Z",
      "date_modified": "2025-07-06T11:30:17Z",
      "authors": [
        {
          "name": "Nic Payne",
          "url": "https://pype.dev"
        }
      ],
      "tags": [
        "k8s",
        "linux",
        "android",
        "homelab",
        "thoughts"
      ]
    },
    {
      "id": "https://pype.dev/thoughts-670/",
      "url": "https://pype.dev/thoughts-670/",
      "title": "💭 Linux Explained: What is The Linux Kernel? - YouTube",
      "content_html": "\u003ca href=\"https://www.youtube.com/watch?si=CFRBAdjtI0x7Pmj7\u0026v=pJ607nDnyE0\u0026feature=youtu.be\"\u003e\n    \u003cimg\n        src=\"https://shots.wayl.one/shot/?url=https://www.youtube.com/watch?si=CFRBAdjtI0x7Pmj7\u0026v=pJ607nDnyE0\u0026feature=youtu.be\u0026height=450\u0026width=800\u0026scaled_width=800\u0026scaled_height=450\u0026selectors=\"\n        alt=\"shot of post - Linux Explained: What is The Linux Kernel? - YouTube\"\n        height=450\n        width=800\n    \u003e\n\u003c/a\u003e\n\u003cp\u003eHere\u0026rsquo;s my thought on \u003ca href=\"https://www.youtube.com/watch?si=CFRBAdjtI0x7Pmj7\u0026v=pJ607nDnyE0\u0026feature=youtu.be\"\u003eLinux Explained: What is The Linux Kernel? - YouTube\u003c/a\u003e\u003c/p\u003e\n\u003chr\u003e\n\u003cp\u003eI\u0026rsquo;m getting sucked into the Linux is a kernel not an operating system crowd because tonight I realized I couldn\u0026rsquo;t describe what a kernel is so I YouTubeda few things and before you know it you joined a decades old war before finishing loading the dishwasher\u003c/p\u003e\n\u003chr\u003e\n\u003cdiv class=\"admonition note\"\u003e\n\u003cp class=\"admonition-title\"\u003eNote\u003c/p\u003e\n\u003cp\u003eThis is one of [[ my-thoughts ]]. I picked this up from \u003ca href=\"https://waylonwalker.com\"\u003eWaylon Walker\u003c/a\u003e(\u003ca href=\"https://thoughts.waylonwalker.com\"\u003ehttps://thoughts.waylonwalker.com\u003c/a\u003e). It\u0026rsquo;s a short note that I make about someone else\u0026rsquo;s content online.  Learn more about the process \u003ca href=\"/thoughts/\" class=\"wikilink\" data-title=\"Thoughts\" data-description=\"My thoughts are found at my thoughts feed\" data-date=\"2025-06-09\" data-preview=\"My thoughts are found at my thoughts feed\"\u003eThoughts\u003c/a\u003e\u003c/p\u003e\n\u003c/div\u003e\n",
      "content_text": "\n\u003ca href=\"https://www.youtube.com/watch?si=CFRBAdjtI0x7Pmj7\u0026v=pJ607nDnyE0\u0026feature=youtu.be\"\u003e\n    \u003cimg\n        src=\"https://shots.wayl.one/shot/?url=https://www.youtube.com/watch?si=CFRBAdjtI0x7Pmj7\u0026v=pJ607nDnyE0\u0026feature=youtu.be\u0026height=450\u0026width=800\u0026scaled_width=800\u0026scaled_height=450\u0026selectors=\"\n        alt=\"shot of post - Linux Explained: What is The Linux Kernel? - YouTube\"\n        height=450\n        width=800\n    \u003e\n\u003c/a\u003e\n\nHere's my thought on \u003ca href=\"https://www.youtube.com/watch?si=CFRBAdjtI0x7Pmj7\u0026v=pJ607nDnyE0\u0026feature=youtu.be\"\u003eLinux Explained: What is The Linux Kernel? - YouTube\u003c/a\u003e\n\n---\n\nI'm getting sucked into the Linux is a kernel not an operating system crowd because tonight I realized I couldn't describe what a kernel is so I YouTubeda few things and before you know it you joined a decades old war before finishing loading the dishwasher\n\n---\n\n!!! note\n    This is one of [[ my-thoughts ]]. I picked this up from [Waylon Walker](https://waylonwalker.com)(https://thoughts.waylonwalker.com). It's a short note that I make about someone else's content online.  Learn more about the process \u003ca href=\"/thoughts/\" class=\"wikilink\" data-title=\"Thoughts\" data-description=\"My thoughts are found at my thoughts feed\" data-date=\"2025-06-09\"\u003eThoughts\u003c/a\u003e\n",
      "summary": "I'm getting sucked into the Linux is a kernel not an operating system crowd because tonight I realized I couldn't descri",
      "date_published": "2025-06-07T11:28:18Z",
      "date_modified": "2025-06-07T11:28:18Z",
      "authors": [
        {
          "name": "Nic Payne",
          "url": "https://pype.dev"
        }
      ],
      "tags": [
        "linux",
        "youtube",
        "kernel",
        "thoughts"
      ]
    },
    {
      "id": "https://pype.dev/i-was-wrecked-by-a-weird-combo-of-and-e/",
      "url": "https://pype.dev/i-was-wrecked-by-a-weird-combo-of-and-e/",
      "title": "I was wrecked by a weird combo of » and -e",
      "content_html": "\u003ch2 id=\"tl-dr\"\u003e\u003cspan class=\"heading-wear-glyph\"\u003eTL;DR\u003c/span\u003e \u003ca href=\"#tl-dr\" class=\"heading-anchor\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eIf state matters then check it in the beginning or handle it on a failure\u0026hellip; Let me explain\u003c/p\u003e\n\u003cp\u003eI ran into some trouble recently \u003cem\u003ealmost\u003c/em\u003e losing some encrypted data\u0026hellip; Now\nthis would be the second time I\u0026rsquo;ve had that happen, so I\u0026rsquo;m going to write a\nlittle bit about it now that I figured it out\u003c/p\u003e\n\u003ch2 id=\"the-stage\"\u003e\u003cspan class=\"heading-wear-glyph\"\u003eThe Stage\u003c/span\u003e \u003ca href=\"#the-stage\" class=\"heading-anchor\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eHere\u0026rsquo;s the scenario - I use \u003ccode\u003eansible-vault\u003c/code\u003e to keep some sensitive data in a\nfew public repos, and I keep the keys I use in Bitwarden Secrets Manager.\u003c/p\u003e\n\u003cp\u003eI use \u003ccode\u003ejust\u003c/code\u003e as a command runner and have common \u003ccode\u003ejust encrypt\u003c/code\u003e and \u003ccode\u003ejust decrypt\u003c/code\u003e recipes throughout many justfiles. It might look something like this\u003c/p\u003e\n\u003cpre class=\"chroma\"\u003e\u003ccode\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eget-vault-key:\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    bws secret get \u003cspan class=\"nv\"\u003e$HOMELAB_BOT_VAULT_KEY_ID\u003c/span\u003e  \u003cspan class=\"p\"\u003e|\u003c/span\u003e jq -r \u003cspan class=\"s1\"\u003e\u0026#39;.value\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eencrypt:\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"c1\"\u003e#!/bin/bash\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nb\"\u003eset\u003c/span\u003e +e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    just get-vault-key \u0026gt; key\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    ansible-vault encrypt ./secret-file --vault-password-file key\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    ansible-vault encrypt ./secret-file2 --vault-password-file key\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    rm key\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003edecrypt:\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"c1\"\u003e#!/bin/bash\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nb\"\u003eset\u003c/span\u003e +e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    just get-vault-key \u0026gt; key\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    ansible-vault decrypt ./secret-file --vault-password-file key\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    ansible-vault decrypt ./secret-file2 --vault-password-file key\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    rm key\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003ch2 id=\"spoiler\"\u003e\u003cspan class=\"heading-wear-glyph\"\u003eSpoiler\u003c/span\u003e \u003ca href=\"#spoiler\" class=\"heading-anchor\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eAbove is a good example of the 2 recipes, but prior to this morning they looked like this\u003c/p\u003e\n\u003cpre class=\"chroma\"\u003e\u003ccode\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eget-vault-key:\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    bws secret get \u003cspan class=\"nv\"\u003e$HOMELAB_BOT_VAULT_KEY_ID\u003c/span\u003e  \u003cspan class=\"p\"\u003e|\u003c/span\u003e jq -r \u003cspan class=\"s1\"\u003e\u0026#39;.value\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# BAD EXAMPLES! DO NOT DO THIS\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eencrypt:\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nb\"\u003eset\u003c/span\u003e -e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    just get-vault-key \u0026gt;\u0026gt; key\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    ansible-vault encrypt ./secret-file --vault-password-file key\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    ansible-vault encrypt ./secret-file2 --vault-password-file key\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    rm key\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003edecrypt:\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nb\"\u003eset\u003c/span\u003e -e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    just get-vault-key \u0026gt;\u0026gt; key\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    ansible-vault decrypt ./secret-file --vault-password-file key\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    ansible-vault decrypt ./secret-file2 --vault-password-file key\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    rm key\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003ch2 id=\"problem\"\u003e\u003cspan class=\"heading-wear-glyph\"\u003eProblem\u003c/span\u003e \u003ca href=\"#problem\" class=\"heading-anchor\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eSo here\u0026rsquo;s the story - in real life I started using distrobox when I ran into\nthis and I thought it was an issue with different versions of ansible installed\nin distrobox and on my desktop. After a few more odd deployment workflows I\nthink I\u0026rsquo;ve determined that the real problem is that \u003ccode\u003e\u0026gt;\u0026gt;\u003c/code\u003e appends to a file (see\nthe issue yet?), but if my recipes fail (say I try to encrypt an already\nencrypted file) then the command exits but what\u0026rsquo;s left on my disk? \u003ccode\u003ekey\u003c/code\u003e is\nstill there\u0026hellip; and the next time I go to run a command I\u0026rsquo;ll echo the real key\nto the \u003ccode\u003ekey\u003c/code\u003e file again and if I called \u003ccode\u003eencrypt\u003c/code\u003e when the first or more files\nin the list were \u003ccode\u003edecrypted\u003c/code\u003e then they\u0026rsquo;ll be encrypted not with my key, but\nwith my key repeated as many times as I ran a command with \u003ccode\u003ejust get-vault-key \u0026gt;\u0026gt; key\u003c/code\u003e\nbefore ever removing the key file!\u003c/p\u003e\n\u003cpre class=\"chroma\"\u003e\u003ccode\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003enic in pype.dev   main   ×2  ×3  ×7 via   v3.11.10\u003cspan class=\"o\"\u003e(\u003c/span\u003epype-dev\u003cspan class=\"o\"\u003e)\u003c/span\u003e   \u003cspan class=\"o\"\u003e(\u003c/span\u003edev\u003cspan class=\"o\"\u003e)\u003c/span\u003e 󰒄 \n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e❯ cat secret-file\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eDanger, Will Robinson\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003enic in pype.dev   main   ×2  ×3  ×7 via   v3.11.10\u003cspan class=\"o\"\u003e(\u003c/span\u003epype-dev\u003cspan class=\"o\"\u003e)\u003c/span\u003e   \u003cspan class=\"o\"\u003e(\u003c/span\u003edev\u003cspan class=\"o\"\u003e)\u003c/span\u003e 󰒄 \n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e❯ just encrypt\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ebws secret get \u003cspan class=\"nv\"\u003e$HOMELAB_BOT_VAULT_KEY_ID\u003c/span\u003e  \u003cspan class=\"p\"\u003e|\u003c/span\u003e jq -r \u003cspan class=\"s1\"\u003e\u0026#39;.value\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eEncryption successful\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003enic in pype.dev   main   ×2  ×3  ×7 via   v3.11.10\u003cspan class=\"o\"\u003e(\u003c/span\u003epype-dev\u003cspan class=\"o\"\u003e)\u003c/span\u003e   \u003cspan class=\"o\"\u003e(\u003c/span\u003edev\u003cspan class=\"o\"\u003e)\u003c/span\u003e 󰒄 \n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e❯ cat secret-file\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nv\"\u003e$ANSIBLE_VAULT\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e1.1\u003cspan class=\"p\"\u003e;\u003c/span\u003eAES256\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"m\"\u003e39616332393662346639633030633766666336323939346138633238626239363733316431333737\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e6463663763366434376437303335643431663431326135300a636261663636336139323033316232\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"m\"\u003e37666439383131393631333332353731633661396431633834326432363936613331623135666565\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e6364363039663933620a326563323931643632323031396664646363613636613562366166386439\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"m\"\u003e63653661653037393538356461323239396630643338393231306163343964623866\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003enic in pype.dev   main   ×2  ×3  ×7 via   v3.11.10\u003cspan class=\"o\"\u003e(\u003c/span\u003epype-dev\u003cspan class=\"o\"\u003e)\u003c/span\u003e   \u003cspan class=\"o\"\u003e(\u003c/span\u003edev\u003cspan class=\"o\"\u003e)\u003c/span\u003e 󰒄 \n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e❯ just decrypt\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ebws secret get \u003cspan class=\"nv\"\u003e$HOMELAB_BOT_VAULT_KEY_ID\u003c/span\u003e  \u003cspan class=\"p\"\u003e|\u003c/span\u003e jq -r \u003cspan class=\"s1\"\u003e\u0026#39;.value\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eDecryption successful\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003enic in pype.dev   main   ×2  ×3  ×7 via   v3.11.10\u003cspan class=\"o\"\u003e(\u003c/span\u003epype-dev\u003cspan class=\"o\"\u003e)\u003c/span\u003e   \u003cspan class=\"o\"\u003e(\u003c/span\u003edev\u003cspan class=\"o\"\u003e)\u003c/span\u003e 󰒄 \n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e❯ cat secret-file\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eDanger, Will Robinson\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003cp\u003eSo as you can see, I have \u003ccode\u003esecret-file\u003c/code\u003e here, and I can encrypt and decrypt\njust fine. But if I have that \u003ccode\u003e\u0026gt;\u0026gt;\u003c/code\u003e in the recipe, add a second file, and a\nfailure in a command - well then I\u0026rsquo;ll start getting confused\u0026hellip;\u003c/p\u003e\n\u003cp\u003eFollow along with the workflow of adding a file that I\u0026rsquo;ll need encrypted\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003eOnly secret-file is in the just recipe here - I add secret-file2 after\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cpre class=\"chroma\"\u003e\u003ccode\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003enic in pype.dev   main   ×2  ×3  ×7 via   v3.11.10\u003cspan class=\"o\"\u003e(\u003c/span\u003epype-dev\u003cspan class=\"o\"\u003e)\u003c/span\u003e   \u003cspan class=\"o\"\u003e(\u003c/span\u003edev\u003cspan class=\"o\"\u003e)\u003c/span\u003e 󰒄 \n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e❯ just decrypt\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ebws secret get \u003cspan class=\"nv\"\u003e$HOMELAB_BOT_VAULT_KEY_ID\u003c/span\u003e  \u003cspan class=\"p\"\u003e|\u003c/span\u003e jq -r \u003cspan class=\"s1\"\u003e\u0026#39;.value\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eERROR! input is not vault encrypted data. /var/home/nic/projects/personal/pype.dev/secret-file is not a vault encrypted file \u003cspan class=\"k\"\u003efor\u003c/span\u003e /var/home/nic/projects/personal/pype.dev/secret-file\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eerror: Recipe \u003cspan class=\"sb\"\u003e`\u003c/span\u003edecrypt\u003cspan class=\"sb\"\u003e`\u003c/span\u003e failed with \u003cspan class=\"nb\"\u003eexit\u003c/span\u003e code \u003cspan class=\"m\"\u003e1\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003enic in pype.dev   main   ×2  ×3  ×8 via   v3.11.10\u003cspan class=\"o\"\u003e(\u003c/span\u003epype-dev\u003cspan class=\"o\"\u003e)\u003c/span\u003e   \u003cspan class=\"o\"\u003e(\u003c/span\u003edev\u003cspan class=\"o\"\u003e)\u003c/span\u003e 󰒄 \n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e✗ \u003cspan class=\"nb\"\u003eecho\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;Good - secret-file is already decrypted! So lets add another file\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eGood - secret-file is already decrypted! So lets add another file\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003enic in pype.dev   main   ×2  ×3  ×7 via   v3.11.10\u003cspan class=\"o\"\u003e(\u003c/span\u003epype-dev\u003cspan class=\"o\"\u003e)\u003c/span\u003e   \u003cspan class=\"o\"\u003e(\u003c/span\u003edev\u003cspan class=\"o\"\u003e)\u003c/span\u003e 󰒄 \n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e❯ \u003cspan class=\"nb\"\u003eecho\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;Foo Bar Bam Baz\u0026#34;\u003c/span\u003e \u0026gt; secret-file2                                    \n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003enic in pype.dev   main   ×2  ×3  ×8 via   v3.11.10\u003cspan class=\"o\"\u003e(\u003c/span\u003epype-dev\u003cspan class=\"o\"\u003e)\u003c/span\u003e   \u003cspan class=\"o\"\u003e(\u003c/span\u003edev\u003cspan class=\"o\"\u003e)\u003c/span\u003e 󰒄 \n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e❯ \u003cspan class=\"nb\"\u003eecho\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;Added secret-file2 to my Just recipes\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eAdded secret-file2 to my Just recipes\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003enic in pype.dev   main   ×2  ×3  ×8 via   v3.11.10\u003cspan class=\"o\"\u003e(\u003c/span\u003epype-dev\u003cspan class=\"o\"\u003e)\u003c/span\u003e   \u003cspan class=\"o\"\u003e(\u003c/span\u003edev\u003cspan class=\"o\"\u003e)\u003c/span\u003e 󰒄 \n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e❯ just encrypt\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ebws secret get \u003cspan class=\"nv\"\u003e$HOMELAB_BOT_VAULT_KEY_ID\u003c/span\u003e  \u003cspan class=\"p\"\u003e|\u003c/span\u003e jq -r \u003cspan class=\"s1\"\u003e\u0026#39;.value\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eEncryption successful\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eEncryption successful\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003enic in pype.dev   main   ×2  ×3  ×7 via   v3.11.10\u003cspan class=\"o\"\u003e(\u003c/span\u003epype-dev\u003cspan class=\"o\"\u003e)\u003c/span\u003e   \u003cspan class=\"o\"\u003e(\u003c/span\u003edev\u003cspan class=\"o\"\u003e)\u003c/span\u003e 󰒄 \n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e❯ just decrypt\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ebws secret get \u003cspan class=\"nv\"\u003e$HOMELAB_BOT_VAULT_KEY_ID\u003c/span\u003e  \u003cspan class=\"p\"\u003e|\u003c/span\u003e jq -r \u003cspan class=\"s1\"\u003e\u0026#39;.value\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eERROR! Decryption failed \u003cspan class=\"o\"\u003e(\u003c/span\u003eno vault secrets were found that could decrypt\u003cspan class=\"o\"\u003e)\u003c/span\u003e on /var/home/nic/projects/personal/pype.dev/secret-file \u003cspan class=\"k\"\u003efor\u003c/span\u003e /var/home/nic/projects/personal/pype.dev/secret-file\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eerror: Recipe \u003cspan class=\"sb\"\u003e`\u003c/span\u003edecrypt\u003cspan class=\"sb\"\u003e`\u003c/span\u003e failed with \u003cspan class=\"nb\"\u003eexit\u003c/span\u003e code \u003cspan class=\"m\"\u003e1\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003enic in pype.dev   main   ×2  ×3  ×8 via   v3.11.10\u003cspan class=\"o\"\u003e(\u003c/span\u003epype-dev\u003cspan class=\"o\"\u003e)\u003c/span\u003e   \u003cspan class=\"o\"\u003e(\u003c/span\u003edev\u003cspan class=\"o\"\u003e)\u003c/span\u003e 󰒄 \n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e✗ \u003cspan class=\"nb\"\u003eecho\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;Oh no!\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003cp\u003eSo what happened?\u003c/p\u003e\n\u003cp\u003eRecall that my recipes originally had \u003ccode\u003eset -e\u003c/code\u003e at the top and used \u003ccode\u003e\u0026gt;\u0026gt;\u003c/code\u003e to cat\nmy secret to a file \u003ccode\u003ekey\u003c/code\u003e. Well, when the fir| decryption recipe failed the\n\u003ccode\u003ekey\u003c/code\u003e file was left behind. Then when I went to encrypt both of my files the\nrecipe got the key again and made a keyfile like this:\u003c/p\u003e\n\u003cpre class=\"chroma\"\u003e\u003ccode\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003esecretKey\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003esecretKey\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003cp\u003eThe encryption recipe encrypted the files with this key, removed the key file,\nand then the next decryption recipe failed because when it got the key and made\nthe file it looked like\u003c/p\u003e\n\u003cpre\u003e\u003ccode\u003esecretKey\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eSo the solution in the end is to remake the \u003ccode\u003ekey\u003c/code\u003e file every time (\u003ccode\u003e\u0026gt;\u003c/code\u003e instead\nof \u003ccode\u003e\u0026gt;\u0026gt;\u003c/code\u003e), or check if it exists, or handle the error when the recipe fails, or\njust keep going (\u003ccode\u003eset +e\u003c/code\u003e)\u003c/p\u003e\n\u003ch2 id=\"fin\"\u003e\u003cspan class=\"heading-wear-glyph\"\u003eFin\u003c/span\u003e \u003ca href=\"#fin\" class=\"heading-anchor\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eAnd that\u0026rsquo;s how I lost some secrets in my homelab once, and how I almost lost a\nsecond time if I hadn\u0026rsquo;t noticed the \u003ccode\u003ekey\u003c/code\u003e file in my file tree\u003c/p\u003e\n",
      "content_text": "\n## TL;DR\n\nIf state matters then check it in the beginning or handle it on a failure... Let me explain\n\nI ran into some trouble recently _almost_ losing some encrypted data... Now\nthis would be the second time I've had that happen, so I'm going to write a\nlittle bit about it now that I figured it out\n\n## The Stage\n\nHere's the scenario - I use `ansible-vault` to keep some sensitive data in a\nfew public repos, and I keep the keys I use in Bitwarden Secrets Manager.\n\nI use `just` as a command runner and have common `just encrypt` and `just\ndecrypt` recipes throughout many justfiles. It might look something like this\n\n```bash\n\nget-vault-key:\n    bws secret get $HOMELAB_BOT_VAULT_KEY_ID  | jq -r '.value'\n\nencrypt:\n    #!/bin/bash\n    set +e\n    just get-vault-key \u003e key\n    ansible-vault encrypt ./secret-file --vault-password-file key\n    ansible-vault encrypt ./secret-file2 --vault-password-file key\n    rm key\n\ndecrypt:\n    #!/bin/bash\n    set +e\n    just get-vault-key \u003e key\n    ansible-vault decrypt ./secret-file --vault-password-file key\n    ansible-vault decrypt ./secret-file2 --vault-password-file key\n    rm key\n```\n\n## Spoiler\n\nAbove is a good example of the 2 recipes, but prior to this morning they looked like this\n\n```bash\n\nget-vault-key:\n    bws secret get $HOMELAB_BOT_VAULT_KEY_ID  | jq -r '.value'\n\n# BAD EXAMPLES! DO NOT DO THIS\n\nencrypt:\n    set -e\n    just get-vault-key \u003e\u003e key\n    ansible-vault encrypt ./secret-file --vault-password-file key\n    ansible-vault encrypt ./secret-file2 --vault-password-file key\n    rm key\n\ndecrypt:\n    set -e\n    just get-vault-key \u003e\u003e key\n    ansible-vault decrypt ./secret-file --vault-password-file key\n    ansible-vault decrypt ./secret-file2 --vault-password-file key\n    rm key\n```\n\n## Problem\n\nSo here's the story - in real life I started using distrobox when I ran into\nthis and I thought it was an issue with different versions of ansible installed\nin distrobox and on my desktop. After a few more odd deployment workflows I\nthink I've determined that the real problem is that `\u003e\u003e` appends to a file (see\nthe issue yet?), but if my recipes fail (say I try to encrypt an already\nencrypted file) then the command exits but what's left on my disk? `key` is\nstill there... and the next time I go to run a command I'll echo the real key\nto the `key` file again and if I called `encrypt` when the first or more files\nin the list were `decrypted` then they'll be encrypted not with my key, but\nwith my key repeated as many times as I ran a command with `just get-vault-key \u003e\u003e key`\nbefore ever removing the key file!\n\n```bash\n\nnic in pype.dev   main   ×2  ×3  ×7 via   v3.11.10(pype-dev)   (dev) 󰒄 \n❯ cat secret-file\nDanger, Will Robinson\n\nnic in pype.dev   main   ×2  ×3  ×7 via   v3.11.10(pype-dev)   (dev) 󰒄 \n❯ just encrypt\nbws secret get $HOMELAB_BOT_VAULT_KEY_ID  | jq -r '.value'\nEncryption successful\n\nnic in pype.dev   main   ×2  ×3  ×7 via   v3.11.10(pype-dev)   (dev) 󰒄 \n❯ cat secret-file\n$ANSIBLE_VAULT;1.1;AES256\n39616332393662346639633030633766666336323939346138633238626239363733316431333737\n6463663763366434376437303335643431663431326135300a636261663636336139323033316232\n37666439383131393631333332353731633661396431633834326432363936613331623135666565\n6364363039663933620a326563323931643632323031396664646363613636613562366166386439\n63653661653037393538356461323239396630643338393231306163343964623866\n\nnic in pype.dev   main   ×2  ×3  ×7 via   v3.11.10(pype-dev)   (dev) 󰒄 \n❯ just decrypt\nbws secret get $HOMELAB_BOT_VAULT_KEY_ID  | jq -r '.value'\nDecryption successful\n\nnic in pype.dev   main   ×2  ×3  ×7 via   v3.11.10(pype-dev)   (dev) 󰒄 \n❯ cat secret-file\nDanger, Will Robinson\n```\n\nSo as you can see, I have `secret-file` here, and I can encrypt and decrypt\njust fine. But if I have that `\u003e\u003e` in the recipe, add a second file, and a\nfailure in a command - well then I'll start getting confused...\n\nFollow along with the workflow of adding a file that I'll need encrypted\n\n\u003e Only secret-file is in the just recipe here - I add secret-file2 after\n\n```bash\nnic in pype.dev   main   ×2  ×3  ×7 via   v3.11.10(pype-dev)   (dev) 󰒄 \n❯ just decrypt\nbws secret get $HOMELAB_BOT_VAULT_KEY_ID  | jq -r '.value'\nERROR! input is not vault encrypted data. /var/home/nic/projects/personal/pype.dev/secret-file is not a vault encrypted file for /var/home/nic/projects/personal/pype.dev/secret-file\nerror: Recipe `decrypt` failed with exit code 1\n\nnic in pype.dev   main   ×2  ×3  ×8 via   v3.11.10(pype-dev)   (dev) 󰒄 \n✗ echo \"Good - secret-file is already decrypted! So lets add another file\"\nGood - secret-file is already decrypted! So lets add another file\n\nnic in pype.dev   main   ×2  ×3  ×7 via   v3.11.10(pype-dev)   (dev) 󰒄 \n❯ echo \"Foo Bar Bam Baz\" \u003e secret-file2                                    \n\nnic in pype.dev   main   ×2  ×3  ×8 via   v3.11.10(pype-dev)   (dev) 󰒄 \n❯ echo \"Added secret-file2 to my Just recipes\"\nAdded secret-file2 to my Just recipes\n\nnic in pype.dev   main   ×2  ×3  ×8 via   v3.11.10(pype-dev)   (dev) 󰒄 \n❯ just encrypt\nbws secret get $HOMELAB_BOT_VAULT_KEY_ID  | jq -r '.value'\nEncryption successful\nEncryption successful\n\nnic in pype.dev   main   ×2  ×3  ×7 via   v3.11.10(pype-dev)   (dev) 󰒄 \n❯ just decrypt\nbws secret get $HOMELAB_BOT_VAULT_KEY_ID  | jq -r '.value'\nERROR! Decryption failed (no vault secrets were found that could decrypt) on /var/home/nic/projects/personal/pype.dev/secret-file for /var/home/nic/projects/personal/pype.dev/secret-file\nerror: Recipe `decrypt` failed with exit code 1\n\nnic in pype.dev   main   ×2  ×3  ×8 via   v3.11.10(pype-dev)   (dev) 󰒄 \n✗ echo \"Oh no!\"\n```\n\nSo what happened?\n\nRecall that my recipes originally had `set -e` at the top and used `\u003e\u003e` to cat\nmy secret to a file `key`. Well, when the fir| decryption recipe failed the\n`key` file was left behind. Then when I went to encrypt both of my files the\nrecipe got the key again and made a keyfile like this:\n\n```bash\nsecretKey\nsecretKey\n```\n\nThe encryption recipe encrypted the files with this key, removed the key file,\nand then the next decryption recipe failed because when it got the key and made\nthe file it looked like\n\n```\nsecretKey\n```\n\nSo the solution in the end is to remake the `key` file every time (`\u003e` instead\nof `\u003e\u003e`), or check if it exists, or handle the error when the recipe fails, or\njust keep going (`set +e`)\n\n## Fin\n\nAnd that's how I lost some secrets in my homelab once, and how I almost lost a\nsecond time if I hadn't noticed the `key` file in my file tree\n",
      "summary": "If state matters then check it in the beginning or handle it on a failure... Let me explain",
      "date_published": "2025-04-23T08:44:59Z",
      "date_modified": "2025-04-23T08:44:59Z",
      "authors": [
        {
          "name": "Nic Payne",
          "url": "https://pype.dev"
        }
      ],
      "tags": [
        "linux",
        "cli",
        "tech"
      ]
    },
    {
      "id": "https://pype.dev/smb-with-zfs-on-ubuntu/",
      "url": "https://pype.dev/smb-with-zfs-on-ubuntu/",
      "title": "SMB with ZFS on Ubuntu",
      "content_html": "\u003cp\u003esudo apt-get install -y samba \\ then set sharesmb=on \\ chown the user \\ smbpasswd \u003cuser\u003e -a \\ then mount with user/password from other machine\u003c/p\u003e\n",
      "content_text": "\nsudo apt-get install -y samba \\\\ then set sharesmb=on \\\\ chown the user \\\\ smbpasswd \u003cuser\u003e -a \\\\ then mount with user/password from other machine\n",
      "summary": "sudo apt-get install -y samba \\\\ then set sharesmb=on \\\\ chown the user \\\\ smbpasswd -a \\\\ then mount with user/password from other machine",
      "date_published": "2025-02-20T09:18:35Z",
      "date_modified": "2025-02-20T09:18:35Z",
      "authors": [
        {
          "name": "Nic Payne",
          "url": "https://pype.dev"
        }
      ],
      "tags": [
        "zfs",
        "linux",
        "tech",
        "til"
      ]
    },
    {
      "id": "https://pype.dev/jellyfin-container-updates-for-hwe-amd/",
      "url": "https://pype.dev/jellyfin-container-updates-for-hwe-amd/",
      "title": "Jellyfin container updates for HWE + AMD",
      "content_html": "\u003cp\u003eI use LSIO Jelyfin container for the easy addon they provide for AMD GPUs but I couldn\u0026rsquo;t get trickplay to work with HWE\u0026hellip;\u003c/p\u003e\n\u003cp\u003eThere was almost NOTHING on the internet about the error, and all the threads were about BSD systems\u0026hellip;\u003c/p\u003e\n\u003cp\u003eThankfully someone posted \u003ca href=\"https://forum.jellyfin.org/t-jellyfin-amd-docker\"\u003eon the formum here\u003c/a\u003e but the only answer was to literally upgrade stuff in the container\u0026hellip;\u003c/p\u003e\n\u003cp\u003eSomeday maybe I\u0026rsquo;ll build off of LSIO to add this, but until then I shell\u0026rsquo;d in and homelab\u0026rsquo;d the hell out of it\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003eTHIS IS INSIDE THE CONTAINER - I use Portianer to make it easy\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cpre\u003e\u003ccode\u003e\napt update \u0026amp;\u0026amp; apt install -y curl gpg\n\nmkdir -p /etc/apt/keyrings\n\ncurl -fsSL https://repo.radeon.com/rocm/rocm.gpg.key | gpg --dearmor -o /etc/apt/keyrings/rocm.gpg\n\ncat \u0026lt;\u0026lt;EOF | tee /etc/apt/sources.list.d/rocm.sources\n\nTypes: deb\n\nURIs: https://repo.radeon.com/rocm/apt/latest\n\nSuites: ubuntu\n\nComponents: main\n\nArchitectures: amd64\n\nSigned-By: /etc/apt/keyrings/rocm.gpg\n\nEOF\n\napt update \u0026amp;\u0026amp; apt install -y rocm-opencl-runtime\n\u003c/code\u003e\u003c/pre\u003e\n",
      "content_text": "\nI use LSIO Jelyfin container for the easy addon they provide for AMD GPUs but I couldn't get trickplay to work with HWE... \n\nThere was almost NOTHING on the internet about the error, and all the threads were about BSD systems...\n\nThankfully someone posted [on the formum here](https://forum.jellyfin.org/t-jellyfin-amd-docker) but the only answer was to literally upgrade stuff in the container...\n\nSomeday maybe I'll build off of LSIO to add this, but until then I shell'd in and homelab'd the hell out of it\n\n\u003e THIS IS INSIDE THE CONTAINER - I use Portianer to make it easy\n\n```\n\napt update \u0026\u0026 apt install -y curl gpg\n\nmkdir -p /etc/apt/keyrings\n\ncurl -fsSL https://repo.radeon.com/rocm/rocm.gpg.key | gpg --dearmor -o /etc/apt/keyrings/rocm.gpg\n\ncat \u003c\u003cEOF | tee /etc/apt/sources.list.d/rocm.sources\n\nTypes: deb\n\nURIs: https://repo.radeon.com/rocm/apt/latest\n\nSuites: ubuntu\n\nComponents: main\n\nArchitectures: amd64\n\nSigned-By: /etc/apt/keyrings/rocm.gpg\n\nEOF\n\napt update \u0026\u0026 apt install -y rocm-opencl-runtime\n```\n",
      "summary": "I use LSIO Jelyfin container for the easy addon they provide for AMD GPUs but I couldn't get trickplay to work with HWE...",
      "date_published": "2024-12-14T11:27:15Z",
      "date_modified": "2024-12-14T11:27:15Z",
      "authors": [
        {
          "name": "Nic Payne",
          "url": "https://pype.dev"
        }
      ],
      "tags": [
        "docker",
        "linux",
        "homelab",
        "til"
      ]
    },
    {
      "id": "https://pype.dev/rsync-like-a-pro/",
      "url": "https://pype.dev/rsync-like-a-pro/",
      "title": "rsync like a pro",
      "content_html": "\u003cp\u003eI am moving a hefty amount of data to a new ZFS pool due to some corruption and I want to avoid using \u003ccode\u003ezfs send/recv\u003c/code\u003e for this just to make sure I don\u0026rsquo;t propagate any corrupted data to my new pool.\u003c/p\u003e\n\u003cp\u003eI\u0026rsquo;ve used \u003ccode\u003ersync\u003c/code\u003e for simple things before but I needed this to be a little smarter and I wanted to see simple progress without flooding my terminal with a billion filenames.\u003c/p\u003e\n\u003ch2 id=\"tldr\"\u003e\u003cspan class=\"heading-wear-glyph\"\u003eTLDR\u003c/span\u003e \u003ca href=\"#tldr\" class=\"heading-anchor\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eTLDR:\n\u003ccode\u003ersync -aHAX --chmod=Da+s --info=progress2 --inplace --exclude='encrypted/docker/frigate-media' /tank/ /harbor/\u003c/code\u003e\u003c/p\u003e\n\u003ch2 id=\"explanation\"\u003e\u003cspan class=\"heading-wear-glyph\"\u003eExplanation\u003c/span\u003e \u003ca href=\"#explanation\" class=\"heading-anchor\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003e-aHAX: Preserves attributes (archive mode, hard links, ACLs, extended attributes).\n\u0026ndash;chmod=Da+s: Ensures the setgid bit is applied to directories.\n\u0026ndash;info=progress2: Provides detailed progress information, including overall data transfer stats.\n\u0026ndash;inplace: Writes directly to the destination file, avoiding temporary files (useful for large files).\n\u0026ndash;exclude=\u0026lsquo;encrypted/\u003ca href=\"/docker/\" class=\"glossary-term\" title=\"docker - container runtime\" data-hover-title=\"docker\"\u003edocker\u003c/a\u003e/frigate-media\u0026rsquo;: Excludes the specified path (relative to the /tank root).\n/tank/ /harbor/: Ensures the contents of /tank are copied directly into /harbor.\u003c/p\u003e\n",
      "content_text": "\n\nI am moving a hefty amount of data to a new ZFS pool due to some corruption and I want to avoid using `zfs send/recv` for this just to make sure I don't propagate any corrupted data to my new pool.\n\nI've used `rsync` for simple things before but I needed this to be a little smarter and I wanted to see simple progress without flooding my terminal with a billion filenames.\n\n## TLDR\nTLDR: \n`rsync -aHAX --chmod=Da+s --info=progress2 --inplace --exclude='encrypted/docker/frigate-media' /tank/ /harbor/`\n\n## Explanation\n\n-aHAX: Preserves attributes (archive mode, hard links, ACLs, extended attributes).\n--chmod=Da+s: Ensures the setgid bit is applied to directories.\n--info=progress2: Provides detailed progress information, including overall data transfer stats.\n--inplace: Writes directly to the destination file, avoiding temporary files (useful for large files).\n--exclude='encrypted/docker/frigate-media': Excludes the specified path (relative to the /tank root).\n/tank/ /harbor/: Ensures the contents of /tank are copied directly into /harbor.\n\n\n",
      "summary": "I am moving a hefty amount of data to a new ZFS pool due to some corruption and I want to avoid using for this just to make sure I don't propagate any...",
      "date_published": "2024-12-11T10:52:23Z",
      "date_modified": "2024-12-11T10:52:23Z",
      "authors": [
        {
          "name": "Nic Payne",
          "url": "https://pype.dev"
        }
      ],
      "tags": [
        "linux",
        "terminal",
        "cli",
        "til"
      ]
    },
    {
      "id": "https://pype.dev/d-and-uninterruptable-sleep/",
      "url": "https://pype.dev/d-and-uninterruptable-sleep/",
      "title": "D and uninterruptable sleep",
      "content_html": "\u003ch2 id=\"htop\"\u003e\u003cspan class=\"heading-wear-glyph\"\u003eHtop\u003c/span\u003e \u003ca href=\"#htop\" class=\"heading-anchor\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eI recently have been having significant home server issues, and that\u0026rsquo;s not the point of this - today I learned what \u003ccode\u003eD\u003c/code\u003e state is when looking at htop.\u003c/p\u003e\n\u003cimg src=\"https://cdn.statically.io/gh/pypeaday/images.pype.dev/main/blog-media/d-htop.png\" alt=\"htop-d\" title=\"htop with D state\" /\u003e\n\u003cp\u003eApparently this means \u0026ldquo;uninterruptable sleep\u0026rdquo; and it\u0026rsquo;s a dev\u0026rsquo;s nightmare\u0026hellip;\u003c/p\u003e\n\u003ch3 id=\"context\"\u003e\u003cspan class=\"heading-wear-glyph\"\u003eContext\u003c/span\u003e \u003ca href=\"#context\" class=\"heading-anchor\"\u003e#\u003c/a\u003e\u003c/h3\u003e\n\u003cp\u003eThe issue I was having was that some \u003ccode\u003ezfs rollback\u003c/code\u003e commands were hung - for hours\u0026hellip; I wasn\u0026rsquo;t sure what was going on, rollbacks should be instant but I figured it was just an artifact of these issues.\u003c/p\u003e\n\u003cp\u003eTurns out I still don\u0026rsquo;t know what locked the disks up but I learned why \u003ccode\u003e\u0026lt;C\u0026gt;-c\u003c/code\u003e did \u003cstrong\u003enothing\u003c/strong\u003e\u0026hellip;\nthe more you know\u003c/p\u003e\n",
      "content_text": "\n## Htop\n\nI recently have been having significant home server issues, and that's not the point of this - today I learned what `D` state is when looking at htop.\n\n\n\u003cimg src=\"https://cdn.statically.io/gh/pypeaday/images.pype.dev/main/blog-media/d-htop.png\" alt=\"htop-d\" title=\"htop with D state\" /\u003e\n\nApparently this means \"uninterruptable sleep\" and it's a dev's nightmare... \n\n### Context\n\nThe issue I was having was that some `zfs rollback` commands were hung - for hours... I wasn't sure what was going on, rollbacks should be instant but I figured it was just an artifact of these issues.\n\nTurns out I still don't know what locked the disks up but I learned why `\u003cC\u003e-c` did __nothing__...\nthe more you know\n",
      "summary": "I recently have been having significant home server issues, and that's not the point of this - today I learned what state is when looking at htop.",
      "date_published": "2024-12-11T10:48:10Z",
      "date_modified": "2024-12-11T10:48:10Z",
      "authors": [
        {
          "name": "Nic Payne",
          "url": "https://pype.dev"
        }
      ],
      "tags": [
        "linux",
        "zfs",
        "tech",
        "til"
      ]
    },
    {
      "id": "https://pype.dev/hostnamectl-to-easily-change-hostname/",
      "url": "https://pype.dev/hostnamectl-to-easily-change-hostname/",
      "title": "hostnamectl to easily change hostname",
      "content_html": "\u003cp\u003ehostnamectl is apparently a linux utility for easily changing your hostname in a variety of ways\u003c/p\u003e\n\u003cpre class=\"chroma\"\u003e\u003ccode\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e❯ hostnamectl --help\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ehostnamectl \u003cspan class=\"o\"\u003e[\u003c/span\u003eOPTIONS...\u003cspan class=\"o\"\u003e]\u003c/span\u003e COMMAND ...\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eQuery or change system hostname.\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eCommands:\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  status                 Show current hostname settings\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  hostname \u003cspan class=\"o\"\u003e[\u003c/span\u003eNAME\u003cspan class=\"o\"\u003e]\u003c/span\u003e        Get/set system hostname\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  icon-name \u003cspan class=\"o\"\u003e[\u003c/span\u003eNAME\u003cspan class=\"o\"\u003e]\u003c/span\u003e       Get/set icon name \u003cspan class=\"k\"\u003efor\u003c/span\u003e host\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  chassis \u003cspan class=\"o\"\u003e[\u003c/span\u003eNAME\u003cspan class=\"o\"\u003e]\u003c/span\u003e         Get/set chassis \u003cspan class=\"nb\"\u003etype\u003c/span\u003e \u003cspan class=\"k\"\u003efor\u003c/span\u003e host\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  deployment \u003cspan class=\"o\"\u003e[\u003c/span\u003eNAME\u003cspan class=\"o\"\u003e]\u003c/span\u003e      Get/set deployment environment \u003cspan class=\"k\"\u003efor\u003c/span\u003e host\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  location \u003cspan class=\"o\"\u003e[\u003c/span\u003eNAME\u003cspan class=\"o\"\u003e]\u003c/span\u003e        Get/set location \u003cspan class=\"k\"\u003efor\u003c/span\u003e host\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eOptions:\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  -h --help              Show this \u003cspan class=\"nb\"\u003ehelp\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e     --version           Show package version\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e     --no-ask-password   Do not prompt \u003cspan class=\"k\"\u003efor\u003c/span\u003e password\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  -H --host\u003cspan class=\"o\"\u003e=[\u003c/span\u003eUSER@\u003cspan class=\"o\"\u003e]\u003c/span\u003eHOST  Operate on remote host\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  -M --machine\u003cspan class=\"o\"\u003e=\u003c/span\u003eCONTAINER Operate on \u003cspan class=\"nb\"\u003elocal\u003c/span\u003e container\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e     --transient         Only \u003cspan class=\"nb\"\u003eset\u003c/span\u003e transient hostname\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e     --static            Only \u003cspan class=\"nb\"\u003eset\u003c/span\u003e static hostname\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e     --pretty            Only \u003cspan class=\"nb\"\u003eset\u003c/span\u003e pretty hostname\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e     --json\u003cspan class=\"o\"\u003e=\u003c/span\u003epretty\u003cspan class=\"p\"\u003e|\u003c/span\u003eshort\u003cspan class=\"p\"\u003e|\u003c/span\u003eoff\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                         Generate JSON output\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eSee the hostnamectl\u003cspan class=\"o\"\u003e(\u003c/span\u003e1\u003cspan class=\"o\"\u003e)\u003c/span\u003e man page \u003cspan class=\"k\"\u003efor\u003c/span\u003e details.\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003cp\u003eI learned there\u0026rsquo;s transient and static hostnames, so that\u0026rsquo;s cool\u0026hellip;\u003c/p\u003e\n\u003cp\u003eThe thing I needed was \u003ccode\u003ehostnamectl --static hostname babyblue-aurora\u003c/code\u003e\u003c/p\u003e\n\u003cp\u003epretty sweet tool\u003c/p\u003e\n",
      "content_text": "\nhostnamectl is apparently a linux utility for easily changing your hostname in a variety of ways\n\n```bash\n\n❯ hostnamectl --help\nhostnamectl [OPTIONS...] COMMAND ...\n\nQuery or change system hostname.\n\nCommands:\n  status                 Show current hostname settings\n  hostname [NAME]        Get/set system hostname\n  icon-name [NAME]       Get/set icon name for host\n  chassis [NAME]         Get/set chassis type for host\n  deployment [NAME]      Get/set deployment environment for host\n  location [NAME]        Get/set location for host\n\nOptions:\n  -h --help              Show this help\n     --version           Show package version\n     --no-ask-password   Do not prompt for password\n  -H --host=[USER@]HOST  Operate on remote host\n  -M --machine=CONTAINER Operate on local container\n     --transient         Only set transient hostname\n     --static            Only set static hostname\n     --pretty            Only set pretty hostname\n     --json=pretty|short|off\n                         Generate JSON output\n\nSee the hostnamectl(1) man page for details.\n```\n\nI learned there's transient and static hostnames, so that's cool...\n\nThe thing I needed was `hostnamectl --static hostname babyblue-aurora`\n\npretty sweet tool\n",
      "summary": "hostnamectl is apparently a linux utility for easily changing your hostname in a variety of ways",
      "date_published": "2024-12-06T07:25:59Z",
      "date_modified": "2024-12-06T07:25:59Z",
      "authors": [
        {
          "name": "Nic Payne",
          "url": "https://pype.dev"
        }
      ],
      "tags": [
        "linux",
        "terminal",
        "homelab",
        "cli",
        "til"
      ]
    },
    {
      "id": "https://pype.dev/dns-broke-after-reboot-ubuntu-22-04/",
      "url": "https://pype.dev/dns-broke-after-reboot-ubuntu-22-04/",
      "title": "DNS Broke After Reboot - Ubuntu 22.04",
      "content_html": "\u003cp\u003eI rebooted by server and DNS broke randomly. I have no idea if it was from a kernel update or what but that\u0026rsquo;s the issue with Ubuntu I guess\u0026hellip;\u003c/p\u003e\n\u003cp\u003eAfter much toil and none of the other options working for me (sorry to not have those documented here) this is what got me the vic from this \u003ca href=\"https://askubuntu.com/questions/1406827/how-to-set-dns-on-ubuntu-22-04-when-you-have-no-netplan-config\"\u003eSO Post\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003esudo mkdir /etc/systemd/resolved.conf.d/\nsudo $EDITOR /etc/systemd/resolved.conf.d/dns_servers.conf\u003c/p\u003e\n\u003cp\u003eMost folks probably are good with google (8.8.8.8) and cloudflare (1.1.1.1)\u003c/p\u003e\n\u003cpre\u003e\u003ccode\u003e[Resolve]\nDNS=8.8.8.8 1.1.1.1\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eBut I decided to use tailscale\u003c/p\u003e\n\u003cpre\u003e\u003ccode\u003e[Resolve]\nDNS=100.100.100.100\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eThen restart systemd-resolved\u003c/p\u003e\n\u003cp\u003esudo systemctl restart systemd-resolved\u003c/p\u003e\n",
      "content_text": "\nI rebooted by server and DNS broke randomly. I have no idea if it was from a kernel update or what but that's the issue with Ubuntu I guess...\n\nAfter much toil and none of the other options working for me (sorry to not have those documented here) this is what got me the vic from this [SO Post](https://askubuntu.com/questions/1406827/how-to-set-dns-on-ubuntu-22-04-when-you-have-no-netplan-config)\n\nsudo mkdir /etc/systemd/resolved.conf.d/\nsudo $EDITOR /etc/systemd/resolved.conf.d/dns_servers.conf\n\nMost folks probably are good with google (8.8.8.8) and cloudflare (1.1.1.1)\n\n```\n[Resolve]\nDNS=8.8.8.8 1.1.1.1\n```\n\nBut I decided to use tailscale\n\n```\n[Resolve]\nDNS=100.100.100.100\n```\n\nThen restart systemd-resolved\n\nsudo systemctl restart systemd-resolved\n",
      "summary": "I rebooted by server and DNS broke randomly. I have no idea if it was from a kernel update or what but that's the issue with Ubuntu I guess...",
      "date_published": "2024-11-22T08:08:40Z",
      "date_modified": "2024-11-22T08:08:40Z",
      "authors": [
        {
          "name": "Nic Payne",
          "url": "https://pype.dev"
        }
      ],
      "tags": [
        "homelab",
        "linux",
        "tech",
        "til"
      ]
    },
    {
      "id": "https://pype.dev/restart-kde-plasma/",
      "url": "https://pype.dev/restart-kde-plasma/",
      "title": "Restart KDE Plasma",
      "content_html": "\u003cp\u003ePlasma shits the bed a little too often on Fedora for me right now but I finally have a quick fix\u0026hellip;\u003c/p\u003e\n\u003cpre\u003e\u003ccode\u003e\nsudo killall plasmashell\n\nkstart plasmashell\n\n\u003c/code\u003e\u003c/pre\u003e\n",
      "content_text": "\nPlasma shits the bed a little too often on Fedora for me right now but I finally have a quick fix...\n\n```\n\nsudo killall plasmashell\n\nkstart plasmashell\n\n```\n",
      "summary": "Plasma shits the bed a little too often on Fedora for me right now but I finally have a quick fix...",
      "date_published": "2024-11-08T15:53:52Z",
      "date_modified": "2024-11-08T15:53:52Z",
      "authors": [
        {
          "name": "Nic Payne",
          "url": "https://pype.dev"
        }
      ],
      "tags": [
        "linux",
        "terminal",
        "cli",
        "til"
      ]
    },
    {
      "id": "https://pype.dev/docker-remote-add/",
      "url": "https://pype.dev/docker-remote-add/",
      "title": "docker-remote-add",
      "content_html": "\u003cp\u003eAdd from url??\u003c/p\u003e\n\u003cp\u003eADD \u003ca href=\"http://example.com/cars.csv\"\u003ehttp://example.com/cars.csv\u003c/a\u003e /tmp/cars.csv\u003c/p\u003e\n\u003cp\u003eUnpack automatically!? (.tar, .tar.gz, .tgz, .bz2, .tbz2, .txz, .zip)\u003c/p\u003e\n\u003cp\u003eADD myapp.tar.gz /opt/myapp/\u003c/p\u003e\n",
      "content_text": "\nAdd from url??\n\nADD http://example.com/cars.csv /tmp/cars.csv\n\nUnpack automatically!? (.tar, .tar.gz, .tgz, .bz2, .tbz2, .txz, .zip)\n\nADD myapp.tar.gz /opt/myapp/\n",
      "summary": "Add from url??",
      "date_published": "2024-09-17T06:19:00Z",
      "date_modified": "2024-09-17T06:19:00Z",
      "authors": [
        {
          "name": "Nic Payne",
          "url": "https://pype.dev"
        }
      ],
      "tags": [
        "homelab",
        "linux",
        "tech",
        "til"
      ]
    },
    {
      "id": "https://pype.dev/docker-copy-and-chown/",
      "url": "https://pype.dev/docker-copy-and-chown/",
      "title": "Docker copy and chown",
      "content_html": "\u003cp\u003eCOPY \u0026ndash;chown=myuser:mygroup source-file target-file\u003c/p\u003e\n",
      "content_text": "\nCOPY --chown=myuser:mygroup source-file target-file\n",
      "summary": "COPY --chown=myuser:mygroup source-file target-file",
      "date_published": "2024-09-17T06:18:09Z",
      "date_modified": "2024-09-17T06:18:09Z",
      "authors": [
        {
          "name": "Nic Payne",
          "url": "https://pype.dev"
        }
      ],
      "tags": [
        "linux",
        "homelab",
        "tech",
        "til"
      ]
    },
    {
      "id": "https://pype.dev/interesting-ips-between-jellyfin-clients-and-server-depending-on-tailscale-and-server-address/",
      "url": "https://pype.dev/interesting-ips-between-jellyfin-clients-and-server-depending-on-tailscale-and-server-address/",
      "title": "Interesting IPs between Jellyfin clients and server depending on tailscale and server address",
      "content_html": "\u003cp\u003eWhen connecting from my phone to jellyfin I\u0026rsquo;m seeing some interesting patterns.\u003c/p\u003e\n\u003ch2 id=\"scenarios\"\u003e\u003cspan class=\"heading-wear-glyph\"\u003eScenarios\u003c/span\u003e \u003ca href=\"#scenarios\" class=\"heading-anchor\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003ch3 id=\"tailscale-ip-of-phone-is-listed-as-local-network-to-jellyfin\"\u003e\u003cspan class=\"heading-wear-glyph\"\u003eTailscale IP of phone is listed as local network to jellyfin\u003c/span\u003e \u003ca href=\"#tailscale-ip-of-phone-is-listed-as-local-network-to-jellyfin\" class=\"heading-anchor\"\u003e#\u003c/a\u003e\u003c/h3\u003e\n\u003cp\u003eWifi: off\nTailscale: on\nUse exit node: on\nLAN access: on\nJellyfin: LAN IP\u003c/p\u003e\n\u003cp\u003eJellyfin sees 192.168.1.1, my router address\u003c/p\u003e\n\u003chr\u003e\n\u003cp\u003eWifi: off\ntailscale: on\nUse exit node: on\nLAN access: on\nJellyfin: Tailscale magic DNS\u003c/p\u003e\n\u003cp\u003eJellyfin sees the \u003ca href=\"/docker/\" class=\"glossary-term\" title=\"docker - container runtime\" data-hover-title=\"docker\"\u003edocker\u003c/a\u003e bridge network\u003c/p\u003e\n\u003cp\u003eQ: This might be because of traefik somehow\u003c/p\u003e\n\u003chr\u003e\n\u003cp\u003eWifi: off\ntailsacale: on\nUse exit node: on\nLAN access: off\nJellyfin: LAN IP\u003c/p\u003e\n\u003cp\u003eJellyfin sees the 192.168.1.1\u003c/p\u003e\n\u003cp\u003eQ: Why did this work even work?\u003c/p\u003e\n\u003chr\u003e\n\u003cp\u003eWifi: off\ntailsacale: on\nUse exit node: on\nLAN access: off\nJellyfin: Tailscale magic DNS\u003c/p\u003e\n\u003cp\u003eJellyfin sees the docker bridge network\u003c/p\u003e\n\u003chr\u003e\n\u003cp\u003eWifi: off\ntailsacale: on\nUse exit node: off\nLAN access: off\nJellyfin: LAN IP\u003c/p\u003e\n\u003cp\u003eJellyfin sees the 192.168.1.1\u003c/p\u003e\n\u003cp\u003eQ: Why did this work?\u003c/p\u003e\n\u003chr\u003e\n\u003cp\u003eWifi: off\ntailsacale: on\nUse exit node: off\nLAN access: off\nJellyfin: Tailscale magic DNS\u003c/p\u003e\n\u003cp\u003eJellyfin sees the docker bridge network\u003c/p\u003e\n\u003chr\u003e\n\u003cp\u003eWifi: on\ntailsacale: of\nUse exit node: off\nLAN access: off\nJellyfin: LAN IP (via pihole DNS)\u003c/p\u003e\n\u003cp\u003eJellyfin sees the IP of my phone\u003c/p\u003e\n\u003chr\u003e\n",
      "content_text": "\nWhen connecting from my phone to jellyfin I'm seeing some interesting patterns.\n\n## Scenarios\n\n### Tailscale IP of phone is listed as local network to jellyfin\n\nWifi: off\nTailscale: on\nUse exit node: on\nLAN access: on\nJellyfin: LAN IP\n\nJellyfin sees 192.168.1.1, my router address\n\n***\n\nWifi: off\ntailscale: on\nUse exit node: on \nLAN access: on\nJellyfin: Tailscale magic DNS\n\nJellyfin sees the docker bridge network\n\nQ: This might be because of traefik somehow\n\n***\n\nWifi: off\ntailsacale: on\nUse exit node: on\nLAN access: off\nJellyfin: LAN IP\n\nJellyfin sees the 192.168.1.1\n\nQ: Why did this work even work?\n\n***\n\nWifi: off\ntailsacale: on\nUse exit node: on\nLAN access: off\nJellyfin: Tailscale magic DNS\n\nJellyfin sees the docker bridge network\n\n***\n\nWifi: off\ntailsacale: on\nUse exit node: off\nLAN access: off\nJellyfin: LAN IP\n\nJellyfin sees the 192.168.1.1\n\nQ: Why did this work?\n\n***\n\nWifi: off\ntailsacale: on\nUse exit node: off\nLAN access: off\nJellyfin: Tailscale magic DNS\n\nJellyfin sees the docker bridge network\n\n***\n\nWifi: on\ntailsacale: of\nUse exit node: off\nLAN access: off\nJellyfin: LAN IP (via pihole DNS)\n\nJellyfin sees the IP of my phone\n\n***\n",
      "summary": "When connecting from my phone to jellyfin I'm seeing some interesting patterns.",
      "date_published": "2024-07-12T06:24:57Z",
      "date_modified": "2024-07-12T06:24:57Z",
      "authors": [
        {
          "name": "Nic Payne",
          "url": "https://pype.dev"
        }
      ],
      "tags": [
        "homelab",
        "linux",
        "tech"
      ]
    },
    {
      "id": "https://pype.dev/upgrading-your-kernel-can-f-you-up-whoops/",
      "url": "https://pype.dev/upgrading-your-kernel-can-f-you-up-whoops/",
      "title": "Upgrading your kernel can F you up… whoops",
      "content_html": "\u003cp\u003e\u003ca href=\"https://forum.proxmox.com/threads/update-error-with-coral-tpu-drivers.136888/#post-608975\"\u003ehttps://forum.proxmox.com/threads/update-error-with-coral-tpu-drivers.136888/#post-608975\u003c/a\u003e I lost TPU for frigate, this saved me ass\u003c/p\u003e\n",
      "content_text": "\nhttps://forum.proxmox.com/threads/update-error-with-coral-tpu-drivers.136888/#post-608975 I lost TPU for frigate, this saved me ass\n",
      "summary": "https://forum.proxmox.com/threads/update-error-with-coral-tpu-drivers.136888/#post-608975 I lost TPU for frigate, this saved me ass",
      "date_published": "2024-06-26T10:21:59Z",
      "date_modified": "2024-06-26T10:21:59Z",
      "authors": [
        {
          "name": "Nic Payne",
          "url": "https://pype.dev"
        }
      ],
      "tags": [
        "homelab",
        "linux",
        "tech",
        "til"
      ]
    },
    {
      "id": "https://pype.dev/dhcp-restart-to-save-ubuntu-22-04-server-networking/",
      "url": "https://pype.dev/dhcp-restart-to-save-ubuntu-22-04-server-networking/",
      "title": "DHCP Restart to Save Ubuntu 22.04 Server Networking",
      "content_html": "\u003cp\u003eI moved a computer to a remote location for an off-site backup but when it was powered on it wouldn\u0026rsquo;t show up on any networks. A solution that got me back in was a friend restarting the dhcp client for me:\u003c/p\u003e\n\u003cpre class=\"chroma\"\u003e\u003ccode\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003esudo dhclient -r -v \u0026lt;interface\u0026gt; \u003cspan class=\"o\"\u003e\u0026amp;\u0026amp;\u003c/span\u003e sudo dhclient -v \u0026lt;interface\u0026gt;\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e",
      "content_text": "\nI moved a computer to a remote location for an off-site backup but when it was powered on it wouldn't show up on any networks. A solution that got me back in was a friend restarting the dhcp client for me:\n\n```bash\nsudo dhclient -r -v \u003cinterface\u003e \u0026\u0026 sudo dhclient -v \u003cinterface\u003e\n```\n",
      "summary": "I moved a computer to a remote location for an off-site backup but when it was powered on it wouldn't show up on any networks. A solution that got me back in...",
      "date_published": "2023-12-31T20:26:50Z",
      "date_modified": "2023-12-31T20:26:50Z",
      "authors": [
        {
          "name": "Nic Payne",
          "url": "https://pype.dev"
        }
      ],
      "tags": [
        "homelab",
        "linux",
        "tech",
        "til"
      ]
    },
    {
      "id": "https://pype.dev/refresh-nextcloud-groupfolders-after-messing-around-on-the-filesystem/",
      "url": "https://pype.dev/refresh-nextcloud-groupfolders-after-messing-around-on-the-filesystem/",
      "title": "Refresh Nextcloud Groupfolders after messing around on the filesystem",
      "content_html": "\u003cp\u003eExec in as www-data and run ./occ groupfolders:scan folder_id -v (the -v to see what it\u0026rsquo;s doing)\u003c/p\u003e\n",
      "content_text": "\nExec in as www-data and run ./occ groupfolders:scan folder_id -v (the -v to see what it's doing)\n",
      "summary": "Exec in as www-data and run ./occ groupfolders:scan folder_id -v (the -v to see what it's doing)",
      "date_published": "2023-09-23T12:45:06Z",
      "date_modified": "2023-09-23T12:45:06Z",
      "authors": [
        {
          "name": "Nic Payne",
          "url": "https://pype.dev"
        }
      ],
      "tags": [
        "homelab",
        "linux",
        "tech",
        "til"
      ]
    },
    {
      "id": "https://pype.dev/convert-word-doc-to-pdf-with-headless-libreoffice/",
      "url": "https://pype.dev/convert-word-doc-to-pdf-with-headless-libreoffice/",
      "title": "Convert Word Doc to PDF with Headless Libreoffice",
      "content_html": "\u003cp\u003eI\u0026rsquo;ve been using paperless-ngx to manage all my documents, but every once in a while I\u0026rsquo;ll get a \u003ccode\u003e.docx\u003c/code\u003e file to deal with\u0026hellip;\u003c/p\u003e\n\u003cp\u003eTurns out Libreoffice has a headless mode a \u003ccode\u003epdf\u003c/code\u003e converter built-in!\u003c/p\u003e\n\u003cpre class=\"chroma\"\u003e\u003ccode\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003elibreoffice --headless --convert-to pdf /path/to/file.docx --outdir /path/to/output/directory\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003cblockquote\u003e\n\u003cp\u003eNote that \u003ccode\u003e--outdir\u003c/code\u003e is in fact a directory, not the path to a file\u003c/p\u003e\n\u003c/blockquote\u003e\n",
      "content_text": "\nI've been using paperless-ngx to manage all my documents, but every once in a while I'll get a `.docx` file to deal with...\n\nTurns out Libreoffice has a headless mode a `pdf` converter built-in!\n\n```Bash\nlibreoffice --headless --convert-to pdf /path/to/file.docx --outdir /path/to/output/directory\n```\n\n\u003e Note that `--outdir` is in fact a directory, not the path to a file\n",
      "summary": "I've been using paperless-ngx to manage all my documents, but every once in a while I'll get a file to deal with...",
      "date_published": "2023-03-09T06:48:38Z",
      "date_modified": "2023-03-09T06:48:38Z",
      "authors": [
        {
          "name": "Nic Payne",
          "url": "https://pype.dev"
        }
      ],
      "tags": [
        "linux",
        "cli",
        "tech",
        "til"
      ]
    },
    {
      "id": "https://pype.dev/i3-like-keyboard-mapping-in-pop-os/",
      "url": "https://pype.dev/i3-like-keyboard-mapping-in-pop-os/",
      "title": "i3-Like keyboard mapping in Pop_OS",
      "content_html": "\u003cp\u003eI was introduced to tiling window managers through i3, which I use heavily on\none of my machines. I have switched to Pop_OS! at home though, which has a\ntiling window mode but the keybindings are not what I\u0026rsquo;m used to for i3. I\nwanted to at least navigate workspaces how I\u0026rsquo;m used to doing (cause I set\nworkspace 3 for communication apps, 1 for my terminal, etc\u0026hellip;)\u003c/p\u003e\n\u003cp\u003eHere\u0026rsquo;s how I set keybindings for:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ccode\u003e\u0026lt;Super\u0026gt; + \u0026lt;number\u0026gt;\u003c/code\u003e sends me to that numbered workspace\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003e\u0026lt;Shift\u0026gt; + \u0026lt;Super\u0026gt; + \u0026lt;number\u0026gt;\u003c/code\u003e moves the window I\u0026rsquo;m focused on to workspace \u003ccode\u003enumber\u003c/code\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003cpre class=\"chroma\"\u003e\u003ccode\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#!/bin/bash\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egsettings \u003cspan class=\"nb\"\u003eset\u003c/span\u003e org.gnome.mutter dynamic-workspaces \u003cspan class=\"nb\"\u003efalse\u003c/span\u003e \n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egsettings \u003cspan class=\"nb\"\u003eset\u003c/span\u003e org.gnome.desktop.wm.preferences num-workspaces \u003cspan class=\"m\"\u003e8\u003c/span\u003e \n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egsettings \u003cspan class=\"nb\"\u003eset\u003c/span\u003e org.gnome.shell.keybindings switch-to-application-1 \u003cspan class=\"o\"\u003e[]\u003c/span\u003e \n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egsettings \u003cspan class=\"nb\"\u003eset\u003c/span\u003e org.gnome.shell.keybindings switch-to-application-2 \u003cspan class=\"o\"\u003e[]\u003c/span\u003e \n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egsettings \u003cspan class=\"nb\"\u003eset\u003c/span\u003e org.gnome.shell.keybindings switch-to-application-3 \u003cspan class=\"o\"\u003e[]\u003c/span\u003e \n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egsettings \u003cspan class=\"nb\"\u003eset\u003c/span\u003e org.gnome.shell.keybindings switch-to-application-4 \u003cspan class=\"o\"\u003e[]\u003c/span\u003e \n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egsettings \u003cspan class=\"nb\"\u003eset\u003c/span\u003e org.gnome.shell.keybindings switch-to-application-5 \u003cspan class=\"o\"\u003e[]\u003c/span\u003e \n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egsettings \u003cspan class=\"nb\"\u003eset\u003c/span\u003e org.gnome.shell.keybindings switch-to-application-6 \u003cspan class=\"o\"\u003e[]\u003c/span\u003e \n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egsettings \u003cspan class=\"nb\"\u003eset\u003c/span\u003e org.gnome.shell.keybindings switch-to-application-7 \u003cspan class=\"o\"\u003e[]\u003c/span\u003e \n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egsettings \u003cspan class=\"nb\"\u003eset\u003c/span\u003e org.gnome.shell.keybindings switch-to-application-8 \u003cspan class=\"o\"\u003e[]\u003c/span\u003e \n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egsettings \u003cspan class=\"nb\"\u003eset\u003c/span\u003e org.gnome.shell.keybindings switch-to-application-9 \u003cspan class=\"o\"\u003e[]\u003c/span\u003e \n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egsettings \u003cspan class=\"nb\"\u003eset\u003c/span\u003e org.gnome.desktop.wm.keybindings switch-to-workspace-1 \u003cspan class=\"s2\"\u003e\u0026#34;[\u0026#39;\u0026lt;Super\u0026gt;1\u0026#39;]\u0026#34;\u003c/span\u003e \n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egsettings \u003cspan class=\"nb\"\u003eset\u003c/span\u003e org.gnome.desktop.wm.keybindings switch-to-workspace-2 \u003cspan class=\"s2\"\u003e\u0026#34;[\u0026#39;\u0026lt;Super\u0026gt;2\u0026#39;]\u0026#34;\u003c/span\u003e \n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egsettings \u003cspan class=\"nb\"\u003eset\u003c/span\u003e org.gnome.desktop.wm.keybindings switch-to-workspace-3 \u003cspan class=\"s2\"\u003e\u0026#34;[\u0026#39;\u0026lt;Super\u0026gt;3\u0026#39;]\u0026#34;\u003c/span\u003e \n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egsettings \u003cspan class=\"nb\"\u003eset\u003c/span\u003e org.gnome.desktop.wm.keybindings switch-to-workspace-4 \u003cspan class=\"s2\"\u003e\u0026#34;[\u0026#39;\u0026lt;Super\u0026gt;4\u0026#39;]\u0026#34;\u003c/span\u003e \n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egsettings \u003cspan class=\"nb\"\u003eset\u003c/span\u003e org.gnome.desktop.wm.keybindings switch-to-workspace-5 \u003cspan class=\"s2\"\u003e\u0026#34;[\u0026#39;\u0026lt;Super\u0026gt;5\u0026#39;]\u0026#34;\u003c/span\u003e \n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egsettings \u003cspan class=\"nb\"\u003eset\u003c/span\u003e org.gnome.desktop.wm.keybindings switch-to-workspace-6 \u003cspan class=\"s2\"\u003e\u0026#34;[\u0026#39;\u0026lt;Super\u0026gt;6\u0026#39;]\u0026#34;\u003c/span\u003e \n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egsettings \u003cspan class=\"nb\"\u003eset\u003c/span\u003e org.gnome.desktop.wm.keybindings switch-to-workspace-7 \u003cspan class=\"s2\"\u003e\u0026#34;[\u0026#39;\u0026lt;Super\u0026gt;7\u0026#39;]\u0026#34;\u003c/span\u003e \n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egsettings \u003cspan class=\"nb\"\u003eset\u003c/span\u003e org.gnome.desktop.wm.keybindings switch-to-workspace-8 \u003cspan class=\"s2\"\u003e\u0026#34;[\u0026#39;\u0026lt;Super\u0026gt;8\u0026#39;]\u0026#34;\u003c/span\u003e \n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egsettings \u003cspan class=\"nb\"\u003eset\u003c/span\u003e org.gnome.desktop.wm.keybindings switch-to-workspace-9 \u003cspan class=\"s2\"\u003e\u0026#34;[\u0026#39;\u0026lt;Super\u0026gt;9\u0026#39;]\u0026#34;\u003c/span\u003e \n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egsettings \u003cspan class=\"nb\"\u003eset\u003c/span\u003e org.gnome.desktop.wm.keybindings switch-to-workspace-10 \u003cspan class=\"s2\"\u003e\u0026#34;[\u0026#39;\u0026lt;Super\u0026gt;0\u0026#39;]\u0026#34;\u003c/span\u003e \n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egsettings \u003cspan class=\"nb\"\u003eset\u003c/span\u003e org.gnome.desktop.wm.keybindings move-to-workspace-1 \u003cspan class=\"s2\"\u003e\u0026#34;[\u0026#39;\u0026lt;Super\u0026gt;\u0026lt;Shift\u0026gt;1\u0026#39;]\u0026#34;\u003c/span\u003e \n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egsettings \u003cspan class=\"nb\"\u003eset\u003c/span\u003e org.gnome.desktop.wm.keybindings move-to-workspace-2 \u003cspan class=\"s2\"\u003e\u0026#34;[\u0026#39;\u0026lt;Super\u0026gt;\u0026lt;Shift\u0026gt;2\u0026#39;]\u0026#34;\u003c/span\u003e \n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egsettings \u003cspan class=\"nb\"\u003eset\u003c/span\u003e org.gnome.desktop.wm.keybindings move-to-workspace-3 \u003cspan class=\"s2\"\u003e\u0026#34;[\u0026#39;\u0026lt;Super\u0026gt;\u0026lt;Shift\u0026gt;3\u0026#39;]\u0026#34;\u003c/span\u003e \n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egsettings \u003cspan class=\"nb\"\u003eset\u003c/span\u003e org.gnome.desktop.wm.keybindings move-to-workspace-4 \u003cspan class=\"s2\"\u003e\u0026#34;[\u0026#39;\u0026lt;Super\u0026gt;\u0026lt;Shift\u0026gt;4\u0026#39;]\u0026#34;\u003c/span\u003e \n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egsettings \u003cspan class=\"nb\"\u003eset\u003c/span\u003e org.gnome.desktop.wm.keybindings move-to-workspace-5 \u003cspan class=\"s2\"\u003e\u0026#34;[\u0026#39;\u0026lt;Super\u0026gt;\u0026lt;Shift\u0026gt;5\u0026#39;]\u0026#34;\u003c/span\u003e \n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egsettings \u003cspan class=\"nb\"\u003eset\u003c/span\u003e org.gnome.desktop.wm.keybindings move-to-workspace-6 \u003cspan class=\"s2\"\u003e\u0026#34;[\u0026#39;\u0026lt;Super\u0026gt;\u0026lt;Shift\u0026gt;6\u0026#39;]\u0026#34;\u003c/span\u003e \n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egsettings \u003cspan class=\"nb\"\u003eset\u003c/span\u003e org.gnome.desktop.wm.keybindings move-to-workspace-7 \u003cspan class=\"s2\"\u003e\u0026#34;[\u0026#39;\u0026lt;Super\u0026gt;\u0026lt;Shift\u0026gt;7\u0026#39;]\u0026#34;\u003c/span\u003e \n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egsettings \u003cspan class=\"nb\"\u003eset\u003c/span\u003e org.gnome.desktop.wm.keybindings move-to-workspace-8 \u003cspan class=\"s2\"\u003e\u0026#34;[\u0026#39;\u0026lt;Super\u0026gt;\u0026lt;Shift\u0026gt;8\u0026#39;]\u0026#34;\u003c/span\u003e \n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egsettings \u003cspan class=\"nb\"\u003eset\u003c/span\u003e org.gnome.desktop.wm.keybindings move-to-workspace-9 \u003cspan class=\"s2\"\u003e\u0026#34;[\u0026#39;\u0026lt;Super\u0026gt;\u0026lt;Shift\u0026gt;9\u0026#39;]\u0026#34;\u003c/span\u003e \n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egsettings \u003cspan class=\"nb\"\u003eset\u003c/span\u003e org.gnome.desktop.wm.keybindings move-to-workspace-10 \u003cspan class=\"s2\"\u003e\u0026#34;[\u0026#39;\u0026lt;Super\u0026gt;\u0026lt;Shift\u0026gt;0\u0026#39;]\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e",
      "content_text": "\nI was introduced to tiling window managers through i3, which I use heavily on\none of my machines. I have switched to Pop_OS! at home though, which has a\ntiling window mode but the keybindings are not what I'm used to for i3. I\nwanted to at least navigate workspaces how I'm used to doing (cause I set\nworkspace 3 for communication apps, 1 for my terminal, etc...)\n\nHere's how I set keybindings for:\n\n* `\u003cSuper\u003e + \u003cnumber\u003e` sends me to that numbered workspace\n* `\u003cShift\u003e + \u003cSuper\u003e + \u003cnumber\u003e` moves the window I'm focused on to workspace `number`\n\n```bash\n#!/bin/bash\ngsettings set org.gnome.mutter dynamic-workspaces false \ngsettings set org.gnome.desktop.wm.preferences num-workspaces 8 \ngsettings set org.gnome.shell.keybindings switch-to-application-1 [] \ngsettings set org.gnome.shell.keybindings switch-to-application-2 [] \ngsettings set org.gnome.shell.keybindings switch-to-application-3 [] \ngsettings set org.gnome.shell.keybindings switch-to-application-4 [] \ngsettings set org.gnome.shell.keybindings switch-to-application-5 [] \ngsettings set org.gnome.shell.keybindings switch-to-application-6 [] \ngsettings set org.gnome.shell.keybindings switch-to-application-7 [] \ngsettings set org.gnome.shell.keybindings switch-to-application-8 [] \ngsettings set org.gnome.shell.keybindings switch-to-application-9 [] \ngsettings set org.gnome.desktop.wm.keybindings switch-to-workspace-1 \"['\u003cSuper\u003e1']\" \ngsettings set org.gnome.desktop.wm.keybindings switch-to-workspace-2 \"['\u003cSuper\u003e2']\" \ngsettings set org.gnome.desktop.wm.keybindings switch-to-workspace-3 \"['\u003cSuper\u003e3']\" \ngsettings set org.gnome.desktop.wm.keybindings switch-to-workspace-4 \"['\u003cSuper\u003e4']\" \ngsettings set org.gnome.desktop.wm.keybindings switch-to-workspace-5 \"['\u003cSuper\u003e5']\" \ngsettings set org.gnome.desktop.wm.keybindings switch-to-workspace-6 \"['\u003cSuper\u003e6']\" \ngsettings set org.gnome.desktop.wm.keybindings switch-to-workspace-7 \"['\u003cSuper\u003e7']\" \ngsettings set org.gnome.desktop.wm.keybindings switch-to-workspace-8 \"['\u003cSuper\u003e8']\" \ngsettings set org.gnome.desktop.wm.keybindings switch-to-workspace-9 \"['\u003cSuper\u003e9']\" \ngsettings set org.gnome.desktop.wm.keybindings switch-to-workspace-10 \"['\u003cSuper\u003e0']\" \ngsettings set org.gnome.desktop.wm.keybindings move-to-workspace-1 \"['\u003cSuper\u003e\u003cShift\u003e1']\" \ngsettings set org.gnome.desktop.wm.keybindings move-to-workspace-2 \"['\u003cSuper\u003e\u003cShift\u003e2']\" \ngsettings set org.gnome.desktop.wm.keybindings move-to-workspace-3 \"['\u003cSuper\u003e\u003cShift\u003e3']\" \ngsettings set org.gnome.desktop.wm.keybindings move-to-workspace-4 \"['\u003cSuper\u003e\u003cShift\u003e4']\" \ngsettings set org.gnome.desktop.wm.keybindings move-to-workspace-5 \"['\u003cSuper\u003e\u003cShift\u003e5']\" \ngsettings set org.gnome.desktop.wm.keybindings move-to-workspace-6 \"['\u003cSuper\u003e\u003cShift\u003e6']\" \ngsettings set org.gnome.desktop.wm.keybindings move-to-workspace-7 \"['\u003cSuper\u003e\u003cShift\u003e7']\" \ngsettings set org.gnome.desktop.wm.keybindings move-to-workspace-8 \"['\u003cSuper\u003e\u003cShift\u003e8']\" \ngsettings set org.gnome.desktop.wm.keybindings move-to-workspace-9 \"['\u003cSuper\u003e\u003cShift\u003e9']\" \ngsettings set org.gnome.desktop.wm.keybindings move-to-workspace-10 \"['\u003cSuper\u003e\u003cShift\u003e0']\"\n```\n",
      "summary": "I was introduced to tiling window managers through i3, which I use heavily on one of my machines. I have switched to Pop_OS! at home though, which has a...",
      "date_published": "2023-01-12T05:51:25Z",
      "date_modified": "2023-01-12T05:51:25Z",
      "authors": [
        {
          "name": "Nic Payne",
          "url": "https://pype.dev"
        }
      ],
      "tags": [
        "linux",
        "tech",
        "til"
      ]
    },
    {
      "id": "https://pype.dev/use-non-standard-named-ssh-keys-with-github/",
      "url": "https://pype.dev/use-non-standard-named-ssh-keys-with-github/",
      "title": "Use non-standard named ssh keys with github",
      "content_html": "\u003cp\u003eI was getting \u003ccode\u003e(publickey denied)\u003c/code\u003e when trying to push to GH using ssh. When I\ntested the connection I saw that a bunch of keys in ``~/.ssh/ were being\nattempted\u003c/p\u003e\n\u003cpre class=\"chroma\"\u003e\u003ccode\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"go\"\u003e✗ ssh git@github.com -vv\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"err\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"go\"\u003e...\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"err\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"go\"\u003edebug1: Will attempt key: /home/nic/.ssh/id_rsa \n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"go\"\u003edebug1: Will attempt key: /home/nic/.ssh/id_ecdsa \n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"go\"\u003edebug1: Will attempt key: /home/nic/.ssh/id_ecdsa_sk \n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"go\"\u003edebug1: Will attempt key: /home/nic/.ssh/id_ed25519 \n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"go\"\u003edebug1: Will attempt key: /home/nic/.ssh/id_ed25519_sk \n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"go\"\u003edebug1: Will attempt key: /home/nic/.ssh/id_xmss \n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"go\"\u003edebug1: Will attempt key: /home/nic/.ssh/id_dsa \n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"err\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"go\"\u003e...\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"err\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"go\"\u003edebug1: No more authentication methods to try.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"go\"\u003egit@github.com: Permission denied (publickey).\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"err\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003cp\u003eNone of those were the key I setup with GH. So I added an entry\ninto \u003ccode\u003e~/.ssh/config\u003c/code\u003e:\u003c/p\u003e\n\u003cpre class=\"chroma\"\u003e\u003ccode\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eHost\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egithub.com\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eUser git\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ePort 22\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eHostname github.com\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eIdentityFile ~/.ssh/my_custom_github_key\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eTCPKeepAlive yes\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eIdentitiesOnly yes \n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e",
      "content_text": "\nI was getting `(publickey denied)` when trying to push to GH using ssh. When I\ntested the connection I saw that a bunch of keys in ``~/.ssh/ were being\nattempted\n\n```console\n✗ ssh git@github.com -vv\n\n...\n\ndebug1: Will attempt key: /home/nic/.ssh/id_rsa \ndebug1: Will attempt key: /home/nic/.ssh/id_ecdsa \ndebug1: Will attempt key: /home/nic/.ssh/id_ecdsa_sk \ndebug1: Will attempt key: /home/nic/.ssh/id_ed25519 \ndebug1: Will attempt key: /home/nic/.ssh/id_ed25519_sk \ndebug1: Will attempt key: /home/nic/.ssh/id_xmss \ndebug1: Will attempt key: /home/nic/.ssh/id_dsa \n\n...\n\ndebug1: No more authentication methods to try.\ngit@github.com: Permission denied (publickey).\n\n```\n\nNone of those were the key I setup with GH. So I added an entry\ninto `~/.ssh/config`:\n\n```text\nHost\ngithub.com\nUser git\nPort 22\nHostname github.com\nIdentityFile ~/.ssh/my_custom_github_key\nTCPKeepAlive yes\nIdentitiesOnly yes \n\n```\n\n",
      "summary": "I was getting when trying to push to GH using ssh. When I tested the connection I saw that a bunch of keys in ``~/.ssh/ were being attempted",
      "date_published": "2023-01-03T08:34:50Z",
      "date_modified": "2023-01-03T08:34:50Z",
      "authors": [
        {
          "name": "Nic Payne",
          "url": "https://pype.dev"
        }
      ],
      "tags": [
        "linux",
        "cli",
        "tech",
        "til"
      ]
    },
    {
      "id": "https://pype.dev/reminder-about-ssh-copy-id-for-ssh-and-ansible/",
      "url": "https://pype.dev/reminder-about-ssh-copy-id-for-ssh-and-ansible/",
      "title": "Reminder about ssh-copy-id for SSH and Ansible",
      "content_html": "\u003cp\u003e\u003ccode\u003essh-copy-id -i my.key.pub \u0026lt;hostname probably from tailscale\u0026gt;\u003c/code\u003e\nthis makes sure I can run ansible from my desktop against VMs on my server\neasily if they have tailscale for the hostname - otherwise use the IP\u003c/p\u003e\n",
      "content_text": "\n`ssh-copy-id -i my.key.pub \u003chostname probably from tailscale\u003e` \nthis makes sure I can run ansible from my desktop against VMs on my server\neasily if they have tailscale for the hostname - otherwise use the IP\n",
      "summary": "this makes sure I can run ansible from my desktop against VMs on my server easily if they have tailscale for the hostname - otherwise use the IP",
      "date_published": "2022-12-28T13:33:07Z",
      "date_modified": "2022-12-28T13:33:07Z",
      "authors": [
        {
          "name": "Nic Payne",
          "url": "https://pype.dev"
        }
      ],
      "tags": [
        "homelab",
        "linux",
        "tech",
        "til"
      ]
    },
    {
      "id": "https://pype.dev/nextcloud-docker-upgrade-error/",
      "url": "https://pype.dev/nextcloud-docker-upgrade-error/",
      "title": "Nextcloud Docker Upgrade Error",
      "content_html": "\u003cp\u003e\u003ca href=\"https://nicolasbouliane.com/blog/nextcloud-docker-upgrade-error\"\u003ehttps://nicolasbouliane.com/blog/nextcloud-docker-upgrade-error\u003c/a\u003e\u003c/p\u003e\n",
      "content_text": "\n\n\nhttps://nicolasbouliane.com/blog/nextcloud-docker-upgrade-error\n",
      "summary": "https://nicolasbouliane.com/blog/nextcloud-docker-upgrade-error",
      "date_published": "2022-12-28T09:39:27Z",
      "date_modified": "2022-12-28T09:39:27Z",
      "authors": [
        {
          "name": "Nic Payne",
          "url": "https://pype.dev"
        }
      ],
      "tags": [
        "homelab",
        "linux",
        "tech"
      ]
    },
    {
      "id": "https://pype.dev/adding-docker-daemon-json-broke-docker/",
      "url": "https://pype.dev/adding-docker-daemon-json-broke-docker/",
      "title": "Adding docker daemon.json broke docker",
      "content_html": "\u003cp\u003ein /lib/systemd/system/\u003ca href=\"/docker/\" class=\"glossary-term\" title=\"docker - container runtime\" data-hover-title=\"docker\"\u003edocker\u003c/a\u003e.service there is an ExecStart command that got placed there when I setup Docker with Ansible - it threw the -H flag which told the daemon what hosts to setup. But I added the \u0026ldquo;hosts\u0026rdquo; key in my daemon.json and it broke - so removing the -H flag from the systemd unit fixed it\u003c/p\u003e\n",
      "content_text": "\nin /lib/systemd/system/docker.service there is an ExecStart command that got placed there when I setup Docker with Ansible - it threw the -H flag which told the daemon what hosts to setup. But I added the \"hosts\" key in my daemon.json and it broke - so removing the -H flag from the systemd unit fixed it\n",
      "summary": "in /lib/systemd/system/docker.service there is an ExecStart command that got placed there when I setup Docker with Ansible - it threw the -H flag which told...",
      "date_published": "2022-12-21T10:02:25Z",
      "date_modified": "2022-12-21T10:02:25Z",
      "authors": [
        {
          "name": "Nic Payne",
          "url": "https://pype.dev"
        }
      ],
      "tags": [
        "linux",
        "tech",
        "docker",
        "til"
      ]
    },
    {
      "id": "https://pype.dev/suda-vim-for-sudo-access-to-files/",
      "url": "https://pype.dev/suda-vim-for-sudo-access-to-files/",
      "title": "suda.vim for sudo access to files",
      "content_html": "\u003cp\u003eI regularly need to edit system config files - take /etc/sanoid/sanoid.conf as\nan example\u0026hellip; I\u0026rsquo;ll want to play with something but if I don\u0026rsquo;t start Neovim as\nroot then I get in trouble making edits I can\u0026rsquo;t save! So\n\u003ca href=\"https://github.com/lambdalisue/suda.vim\"\u003esuda.vim\u003c/a\u003e gives me\n\u003ccode\u003e:SudaWrite\u003c/code\u003e which let\u0026rsquo;s me write that buffer with sudo privileges even though\nI\u0026rsquo;m Neovim is running with my login user!\u003c/p\u003e\n",
      "content_text": "\nI regularly need to edit system config files - take /etc/sanoid/sanoid.conf as\nan example... I'll want to play with something but if I don't start Neovim as\nroot then I get in trouble making edits I can't save! So\n[suda.vim](https://github.com/lambdalisue/suda.vim) gives me\n`:SudaWrite` which let's me write that buffer with sudo privileges even though\nI'm Neovim is running with my login user!\n",
      "summary": "I regularly need to edit system config files - take /etc/sanoid/sanoid.conf as an example... I'll want to play with something but if I don't start Neovim as...",
      "date_published": "2022-12-21T09:45:34Z",
      "date_modified": "2022-12-21T09:45:34Z",
      "authors": [
        {
          "name": "Nic Payne",
          "url": "https://pype.dev"
        }
      ],
      "tags": [
        "vim",
        "linux",
        "tech",
        "til"
      ]
    },
    {
      "id": "https://pype.dev/pipe-to-a-pager-to-preserve-console-output-in-ssh-session/",
      "url": "https://pype.dev/pipe-to-a-pager-to-preserve-console-output-in-ssh-session/",
      "title": "Pipe to a pager to preserve console output in SSH session",
      "content_html": "\u003cp\u003eI\u0026rsquo;m playing with my ansible playbook in a remote tmux session, and I\u0026rsquo;m no wiz\nso I don\u0026rsquo;t know the ins and outs, but I can\u0026rsquo;t scroll up to get any console log\noutput that\u0026rsquo;s not already visible on my screen. So I\u0026rsquo;m starting to end my\ncommands with \u003ccode\u003e | less\u003c/code\u003e so I can page through the console output!\u003c/p\u003e\n\u003cp\u003e\u003ccode\u003eansible-playbook plays.yml -v --tags mytag | less\u003c/code\u003e\u003c/p\u003e\n",
      "content_text": "\nI'm playing with my ansible playbook in a remote tmux session, and I'm no wiz\nso I don't know the ins and outs, but I can't scroll up to get any console log\noutput that's not already visible on my screen. So I'm starting to end my\ncommands with ` | less` so I can page through the console output!\n\n`ansible-playbook plays.yml -v --tags mytag | less`\n",
      "summary": "I'm playing with my ansible playbook in a remote tmux session, and I'm no wiz so I don't know the ins and outs, but I can't scroll up to get any console log...",
      "date_published": "2022-12-18T15:04:02Z",
      "date_modified": "2022-12-18T15:04:02Z",
      "authors": [
        {
          "name": "Nic Payne",
          "url": "https://pype.dev"
        }
      ],
      "tags": [
        "linux",
        "cli",
        "til"
      ]
    },
    {
      "id": "https://pype.dev/description-of-my-proposed-vimconf-2022-talk/",
      "url": "https://pype.dev/description-of-my-proposed-vimconf-2022-talk/",
      "title": "Description of my proposed vimconf 2022 talk",
      "content_html": "\u003cp\u003eSwitching to Vim opened a whole new world to me for interacting with a computer\nand for getting things done. Before I adopted Vim I used GUIs for everything\nbecause I thought that\u0026rsquo;s how it had to be done\u0026hellip; Notes in OneNote, code using\na GUI editor, different notes in TiddlyWiki, slides for work in PowerPoint,\nslides for church using Logos, etc\u0026hellip; Adopting Vim allowed me to disconnect a\nspecific tool from the problem that tool is solving - because usually I just\nneed to write text (notes, code, slides, etc.). Now, very nearly everything I\ndo is from a text-based and git-based workflow\u0026hellip; I put all my notes on\nbasically anything just in my blog, which is all markdown and deployed to GH\nwith Markata on every push (living dangerously pushing to main) - and that\u0026rsquo;s\nall done easily from Vim with nice syntax highlighting, fast response,\nintegrated git-plugins, etc.. I keep project-specific task lists just in\nmarkdown files and I have Vim/tmux shortcuts to quickly add todos for any\nproject (todo list is done with markata todoui) and I can get there fast\nbecause my Vim workflow dovetails with Tmux nicely. Also I can pull that list\nup right from the terminal, which I\u0026rsquo;m already in because Vim\u0026hellip;. Vim also\npushed me into the cli more - because Vim is so easily extended with cli tools\nand I\u0026rsquo;m already in the terminal\u0026hellip; The builtin functionality also made things\nmake more sense - no more right-click, find \u0026ldquo;refactor all\u0026rdquo; or \u0026ldquo;rename symbol\u0026rdquo;\n(for some stupid reason)\u0026hellip; Vim find-replace is so intuitive and if I need it\nextended then I learned what sed was because of Vim. Moving quickly in Vim also\nenables me to do my job incredibly fast because I hop into several projects a\nday in a coaching role - if I was bound by GUIs I\u0026rsquo;d be waiting forever for\nstartup, would lose which GUI instance was which project, etc\u0026hellip; Being in the\nterminal also made Tmux a trivial choice - now I have 90 tmux sessions, all\nnamed appropriately, ready for me to jump back to and all while keeping the\nmajority of RAM still free for Chrome. Vim as my IDE also forced me to learn\nway more about Python (I\u0026rsquo;m a python developer primarily), how LSP works, how to\nconfigure a development environment, etc\u0026hellip; things I took for granted in my GUI\nworkflows, or never knew, or worse - thought I knew but deeply misunderstood.\nNow that I understand them better, I can coach my peers more effectively even\nif they are still in a GUI-based ecosystem.\u003c/p\u003e\n\u003cp\u003eBasically, (Neo)Vim actually did change my life and I\u0026rsquo;m really thankful for it\n(maybe that should be the title?)\u003c/p\u003e\n",
      "content_text": "\nSwitching to Vim opened a whole new world to me for interacting with a computer\nand for getting things done. Before I adopted Vim I used GUIs for everything\nbecause I thought that's how it had to be done... Notes in OneNote, code using\na GUI editor, different notes in TiddlyWiki, slides for work in PowerPoint,\nslides for church using Logos, etc... Adopting Vim allowed me to disconnect a\nspecific tool from the problem that tool is solving - because usually I just\nneed to write text (notes, code, slides, etc.). Now, very nearly everything I\ndo is from a text-based and git-based workflow... I put all my notes on\nbasically anything just in my blog, which is all markdown and deployed to GH\nwith Markata on every push (living dangerously pushing to main) - and that's\nall done easily from Vim with nice syntax highlighting, fast response,\nintegrated git-plugins, etc.. I keep project-specific task lists just in\nmarkdown files and I have Vim/tmux shortcuts to quickly add todos for any\nproject (todo list is done with markata todoui) and I can get there fast\nbecause my Vim workflow dovetails with Tmux nicely. Also I can pull that list\nup right from the terminal, which I'm already in because Vim.... Vim also\npushed me into the cli more - because Vim is so easily extended with cli tools\nand I'm already in the terminal... The builtin functionality also made things\nmake more sense - no more right-click, find \"refactor all\" or \"rename symbol\"\n(for some stupid reason)... Vim find-replace is so intuitive and if I need it\nextended then I learned what sed was because of Vim. Moving quickly in Vim also\nenables me to do my job incredibly fast because I hop into several projects a\nday in a coaching role - if I was bound by GUIs I'd be waiting forever for\nstartup, would lose which GUI instance was which project, etc... Being in the\nterminal also made Tmux a trivial choice - now I have 90 tmux sessions, all\nnamed appropriately, ready for me to jump back to and all while keeping the\nmajority of RAM still free for Chrome. Vim as my IDE also forced me to learn\nway more about Python (I'm a python developer primarily), how LSP works, how to\nconfigure a development environment, etc... things I took for granted in my GUI\nworkflows, or never knew, or worse - thought I knew but deeply misunderstood.\nNow that I understand them better, I can coach my peers more effectively even\nif they are still in a GUI-based ecosystem.\n\nBasically, (Neo)Vim actually did change my life and I'm really thankful for it\n(maybe that should be the title?)\n",
      "summary": "Switching to Vim opened a whole new world to me for interacting with a computer and for getting things done. Before I adopted Vim I used GUIs for everything...",
      "date_published": "2022-11-12T19:39:19Z",
      "date_modified": "2022-11-12T19:39:19Z",
      "authors": [
        {
          "name": "Nic Payne",
          "url": "https://pype.dev"
        }
      ],
      "tags": [
        "linux",
        "vim",
        "tech"
      ]
    },
    {
      "id": "https://pype.dev/make-a-series-of-directories-fast/",
      "url": "https://pype.dev/make-a-series-of-directories-fast/",
      "title": "Make a series of directories fast!",
      "content_html": "\u003cp\u003emkdir s{1..10} will make directories s1, s2, \u0026hellip; s10 in one command!\u003c/p\u003e\n",
      "content_text": "\nmkdir s{1..10} will make directories s1, s2, ... s10 in one command!\n",
      "summary": "mkdir s{1..10} will make directories s1, s2, ... s10 in one command!",
      "date_published": "2022-11-10T15:27:50Z",
      "date_modified": "2022-11-10T15:27:50Z",
      "authors": [
        {
          "name": "Nic Payne",
          "url": "https://pype.dev"
        }
      ],
      "tags": [
        "linux",
        "cli",
        "tech",
        "til"
      ]
    },
    {
      "id": "https://pype.dev/dont-forget-to-load-xmp/",
      "url": "https://pype.dev/dont-forget-to-load-xmp/",
      "title": "Don’t forget to load XMP!",
      "content_html": "\u003cp\u003eBought some DDR4-3600 speed RAM but only seeing 2666? Load up the BIOS, find DRAM config or something similar, and make sure to load the XMP profile to get that advertised RAM speed!\u003c/p\u003e\n",
      "content_text": "\nBought some DDR4-3600 speed RAM but only seeing 2666? Load up the BIOS, find DRAM config or something similar, and make sure to load the XMP profile to get that advertised RAM speed!\n",
      "summary": "Bought some DDR4-3600 speed RAM but only seeing 2666? Load up the BIOS, find DRAM config or something similar, and make sure to load the XMP profile to get...",
      "date_published": "2022-10-09T07:17:43Z",
      "date_modified": "2022-10-09T07:17:43Z",
      "authors": [
        {
          "name": "Nic Payne",
          "url": "https://pype.dev"
        }
      ],
      "tags": [
        "homelab",
        "linux",
        "tech",
        "til"
      ]
    },
    {
      "id": "https://pype.dev/my-passmark-scores/",
      "url": "https://pype.dev/my-passmark-scores/",
      "title": "My PassMark Scores",
      "content_html": "\u003cdiv class=\"admonition note\"\u003e\n\u003cp class=\"admonition-title\"\u003eBabyblue v2\u003c/p\u003e\n\u003cp\u003eRyzen 5700x + 32 GB 3200 CL16 RAM\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"https://www.passmark.com/baselines/V10/display.php?id=503041456656\"\u003e\u003cimg src=\"https://www.passmark.com/baselines/V10/media/503041456656.png\" alt=\"PassMark Rating\" border=\"0\" /\u003e\u003c/a\u003e\u003c/p\u003e\n\u003c/div\u003e\n\u003cdiv class=\"admonition note\"\u003e\n\u003cp class=\"admonition-title\"\u003eVenus \u003c/p\u003e\n\u003cp\u003eRyzen 3200G + 16GB 3600 CL16 RAM\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"https://www.passmark.com/baselines/V10/display.php?id=502360857958\"\u003e\u003cimg src=\"https://www.passmark.com/baselines/V10/media/502360857958.png\" height=120px alt=\"PassMark Rating\" border=\"0\" /\u003e\u003c/a\u003e\u003c/p\u003e\n\u003c/div\u003e\n\u003cdiv class=\"admonition note\"\u003e\n\u003cp class=\"admonition-title\"\u003eHogwarts\u003c/p\u003e\n\u003cp\u003eDual Xeon X5650 @2.67GHz | 90 GB 1883 DDR3 ECC RAM\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"https://www.passmark.com/baselines/V10/display.php?id=502361259420\"\u003e\u003cimg src=\"https://www.passmark.com/baselines/V10/media/502361259420.png\" height=120px alt=\"PassMark Rating\" border=\"0\" /\u003e\u003c/a\u003e\u003c/p\u003e\n\u003c/div\u003e\n\u003cdiv class=\"admonition note\"\u003e\n\u003cp class=\"admonition-title\"\u003eServer 2 ... Change the name\u003c/p\u003e\n\u003cp\u003eRyzen 5700G + 128GB 3200 CL18 RAM\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"https://www.passmark.com/baselines/V10/display.php?id=502361424410\"\u003e\u003cimg src=\"https://www.passmark.com/baselines/V10/media/502361424410.png\" height=120px alt=\"PassMark Rating\" border=\"0\" /\u003e\u003c/a\u003e\u003c/p\u003e\n\u003c/div\u003e\n\u003cdiv class=\"admonition note\"\u003e\n\u003cp class=\"admonition-title\"\u003eServer 2 with XMP enabled and undervolted from 1.35 to 1.2\u003c/p\u003e\n\u003cp\u003eRyzen 5700G + 128GB 3200 CL18 RAM\u003c/p\u003e\n\u003cp\u003eUndervolted to 1.2V (from 1.35)\nXMP enabled\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"https://www.passmark.com/baselines/V10/display.php?id=502363064921\"\u003e\u003cimg src=\"https://www.passmark.com/baselines/V10/media/502363064921.png\" height=120px alt=\"PassMark Rating\" border=\"0\" /\u003e\u003c/a\u003e\u003c/p\u003e\n\u003c/div\u003e\n",
      "content_text": "\n!!! note \"Babyblue v2\"\n\n    Ryzen 5700x + 32 GB 3200 CL16 RAM\n\n    \u003ca href=\"https://www.passmark.com/baselines/V10/display.php?id=503041456656\"\u003e\u003cimg src=\"https://www.passmark.com/baselines/V10/media/503041456656.png\" alt=\"PassMark Rating\" border=\"0\" /\u003e\u003c/a\u003e\n\n!!! note \"Venus \"\n\n    Ryzen 3200G + 16GB 3600 CL16 RAM\n\n    \u003ca href=\"https://www.passmark.com/baselines/V10/display.php?id=502360857958\"\u003e\u003cimg src=\"https://www.passmark.com/baselines/V10/media/502360857958.png\" height=120px alt=\"PassMark Rating\" border=\"0\" /\u003e\u003c/a\u003e\n\n!!! note \"Hogwarts\"\n\n    Dual Xeon X5650 @2.67GHz | 90 GB 1883 DDR3 ECC RAM\n\n    \u003ca href=\"https://www.passmark.com/baselines/V10/display.php?id=502361259420\"\u003e\u003cimg src=\"https://www.passmark.com/baselines/V10/media/502361259420.png\" height=120px alt=\"PassMark Rating\" border=\"0\" /\u003e\u003c/a\u003e\n\n\n!!! note \"Server 2 ... Change the name\"\n\n    Ryzen 5700G + 128GB 3200 CL18 RAM\n\n    \u003ca href=\"https://www.passmark.com/baselines/V10/display.php?id=502361424410\"\u003e\u003cimg src=\"https://www.passmark.com/baselines/V10/media/502361424410.png\" height=120px alt=\"PassMark Rating\" border=\"0\" /\u003e\u003c/a\u003e\n\n!!! note \"Server 2 with XMP enabled and undervolted from 1.35 to 1.2\"\n\n    Ryzen 5700G + 128GB 3200 CL18 RAM\n\n    Undervolted to 1.2V (from 1.35)\n    XMP enabled\n\n    \u003ca href=\"https://www.passmark.com/baselines/V10/display.php?id=502363064921\"\u003e\u003cimg src=\"https://www.passmark.com/baselines/V10/media/502363064921.png\" height=120px alt=\"PassMark Rating\" border=\"0\" /\u003e\u003c/a\u003e\n",
      "summary": "!!! note \"Babyblue v2\"",
      "date_published": "2022-10-08T18:43:29Z",
      "date_modified": "2022-10-08T18:43:29Z",
      "authors": [
        {
          "name": "Nic Payne",
          "url": "https://pype.dev"
        }
      ],
      "tags": [
        "homelab",
        "linux",
        "tech",
        "til"
      ]
    },
    {
      "id": "https://pype.dev/suddenly-ssh-requires-a-password/",
      "url": "https://pype.dev/suddenly-ssh-requires-a-password/",
      "title": "Suddenly SSH requires a password",
      "content_html": "\u003cp\u003essh -v -i ~/.ssh/id_rsa nic@hogwarts\u003c/p\u003e\n\u003cp\u003eTHen we can look at print outs\u003c/p\u003e\n\u003cp\u003ecat /var/log/auth.log  also showed me that I had too wide permissions on files in ~/.ssh -\u0026gt; probably changed from an rsync job\u003c/p\u003e\n",
      "content_text": "\n\nssh -v -i ~/.ssh/id_rsa nic@hogwarts\n\nTHen we can look at print outs\n\ncat /var/log/auth.log  also showed me that I had too wide permissions on files in ~/.ssh -\u003e probably changed from an rsync job\n",
      "summary": "ssh -v -i ~/.ssh/id_rsa nic@hogwarts",
      "date_published": "2022-10-07T11:14:37Z",
      "date_modified": "2022-10-07T11:14:37Z",
      "authors": [
        {
          "name": "Nic Payne",
          "url": "https://pype.dev"
        }
      ],
      "tags": [
        "linux",
        "cli",
        "tech",
        "til"
      ]
    },
    {
      "id": "https://pype.dev/check-your-bios-version-on-ubuntu/",
      "url": "https://pype.dev/check-your-bios-version-on-ubuntu/",
      "title": "Check Your BIOS Version On Ubuntu",
      "content_html": "\u003cp\u003esudo dmidecode -s bios-version\u003c/p\u003e\n",
      "content_text": "\nsudo dmidecode -s bios-version\n",
      "summary": "sudo dmidecode -s bios-version",
      "date_published": "2022-10-02T18:21:58Z",
      "date_modified": "2022-10-02T18:21:58Z",
      "authors": [
        {
          "name": "Nic Payne",
          "url": "https://pype.dev"
        }
      ],
      "tags": [
        "linux",
        "cli",
        "tech",
        "til"
      ]
    },
    {
      "id": "https://pype.dev/append-string-to-list-of-files-with-xarg/",
      "url": "https://pype.dev/append-string-to-list-of-files-with-xarg/",
      "title": "Append string to list of files with xarg",
      "content_html": "\u003cp\u003e❯ find . -name \u0026ldquo;requirements.in\u0026rdquo; -print0 | xargs -0 sh -c \u0026lsquo;for arg in \u0026ldquo;$@\u0026rdquo;; do echo \u0026ldquo;awscli\u0026rdquo; \u0026raquo;\u0026quot;$arg\u0026quot;; done\u0026rsquo;\u003c/p\u003e\n",
      "content_text": "\n❯ find . -name \"requirements.in\" -print0 | xargs -0 sh -c 'for arg in \"$@\"; do echo \"awscli\" \u003e\u003e\"$arg\"; done'\n\n",
      "summary": "❯ find . -name \"requirements.in\" -print0 | xargs -0 sh -c 'for arg in \"$@\"; do echo \"awscli\" \u003e\u003e\"$arg\"; done'",
      "date_published": "2022-09-21T11:26:02Z",
      "date_modified": "2022-09-21T11:26:02Z",
      "authors": [
        {
          "name": "Nic Payne",
          "url": "https://pype.dev"
        }
      ],
      "tags": [
        "linux",
        "bash",
        "til"
      ]
    },
    {
      "id": "https://pype.dev/check-your-smart-status-with-smartctl/",
      "url": "https://pype.dev/check-your-smart-status-with-smartctl/",
      "title": "Check your SMART status with smartctl",
      "content_html": "\u003cp\u003e\u003ca href=\"https://www.simplified.guide/linux/disk-health-check\"\u003ehttps://www.simplified.guide/linux/disk-health-check\u003c/a\u003e\u003c/p\u003e\n\u003ch1 id=\"install\"\u003e\u003cspan class=\"heading-wear-glyph\"\u003eInstall\u003c/span\u003e\u003c/h1\u003e\n\u003cp\u003eFor ubuntu/debian based distros (which is what I primarly use presently)\u003c/p\u003e\n\u003cp\u003e\u003ccode\u003esudo apt update -y \u0026amp;\u0026amp; sudo apt install smartmontools -y\u003c/code\u003e\u003c/p\u003e\n\u003ch1 id=\"list-hard-drives\"\u003e\u003cspan class=\"heading-wear-glyph\"\u003eList hard drives\u003c/span\u003e\u003c/h1\u003e\n\u003cp\u003e\u003ccode\u003elsblk | grep disk\u003c/code\u003e is one way or \u003ccode\u003esudo lshw -c disk\u003c/code\u003e is another\u003c/p\u003e\n\u003ch1 id=\"smartctl\"\u003e\u003cspan class=\"heading-wear-glyph\"\u003esmartctl\u003c/span\u003e\u003c/h1\u003e\n\u003cp\u003eUse a device\u0026rsquo;s logical name such as \u003ccode\u003edev/sda\u003c/code\u003e, not a partition of the disk\u003c/p\u003e\n\u003cp\u003e\u003ccode\u003esudo smartctl -t short /dev/sda\u003c/code\u003e\u003c/p\u003e\n\u003cpre class=\"chroma\"\u003e\u003ccode\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"go\"\u003edotfiles   home   ×3  ×2  ×2 via   v3.10.6(dotfiles)  took 11s\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"go\"\u003e❯ sudo smartctl -t short /dev/sda\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"go\"\u003esmartctl 7.1 2019-12-30 r5022 [x86_64-linux-5.15.0-48-generic] (local build)\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"go\"\u003eCopyright (C) 2002-19, Bruce Allen, Christian Franke, www.smartmontools.org\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"err\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"go\"\u003e=== START OF OFFLINE IMMEDIATE AND SELF-TEST SECTION ===\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"go\"\u003eSending command: \u0026#34;Execute SMART Short self-test routine immediately in off-line mode\u0026#34;.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"go\"\u003eDrive command \u0026#34;Execute SMART Short self-test routine immediately in off-line mode\u0026#34; successful.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"go\"\u003eTesting has begun.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"go\"\u003ePlease wait 2 minutes for test to complete.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"go\"\u003eTest will complete after Fri Sep 23 05:59:39 2022 CDT\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"go\"\u003eUse smartctl -X to abort test.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003ch1 id=\"check-status\"\u003e\u003cspan class=\"heading-wear-glyph\"\u003echeck status\u003c/span\u003e\u003c/h1\u003e\n\u003cp\u003e\u003ccode\u003esudo smartctl -H /dev/sda\u003c/code\u003e\u003c/p\u003e\n\u003cpre class=\"chroma\"\u003e\u003ccode\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"err\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"go\"\u003edotfiles   home   ×3  ×2  ×2 via   v3.10.6(dotfiles)\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"go\"\u003e❯ sudo smartctl -H /dev/sda\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"go\"\u003esmartctl 7.1 2019-12-30 r5022 [x86_64-linux-5.15.0-48-generic] (local build)\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"go\"\u003eCopyright (C) 2002-19, Bruce Allen, Christian Franke, www.smartmontools.org\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"err\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"go\"\u003e=== START OF READ SMART DATA SECTION ===\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"go\"\u003eSMART overall-health self-assessment test result: PASSED\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"err\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"err\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e",
      "content_text": "\nhttps://www.simplified.guide/linux/disk-health-check\n\n# Install\nFor ubuntu/debian based distros (which is what I primarly use presently)\n\n`sudo apt update -y \u0026\u0026 sudo apt install smartmontools -y`\n\n# List hard drives\n\n`lsblk | grep disk` is one way or `sudo lshw -c disk` is another\n\n# smartctl \n\nUse a device's logical name such as `dev/sda`, not a partition of the disk\n\n`sudo smartctl -t short /dev/sda`\n\n```console\ndotfiles   home   ×3  ×2  ×2 via   v3.10.6(dotfiles)  took 11s\n❯ sudo smartctl -t short /dev/sda\nsmartctl 7.1 2019-12-30 r5022 [x86_64-linux-5.15.0-48-generic] (local build)\nCopyright (C) 2002-19, Bruce Allen, Christian Franke, www.smartmontools.org\n\n=== START OF OFFLINE IMMEDIATE AND SELF-TEST SECTION ===\nSending command: \"Execute SMART Short self-test routine immediately in off-line mode\".\nDrive command \"Execute SMART Short self-test routine immediately in off-line mode\" successful.\nTesting has begun.\nPlease wait 2 minutes for test to complete.\nTest will complete after Fri Sep 23 05:59:39 2022 CDT\nUse smartctl -X to abort test.\n```\n\n# check status\n\n`sudo smartctl -H /dev/sda`\n\n```console\n\ndotfiles   home   ×3  ×2  ×2 via   v3.10.6(dotfiles)\n❯ sudo smartctl -H /dev/sda\nsmartctl 7.1 2019-12-30 r5022 [x86_64-linux-5.15.0-48-generic] (local build)\nCopyright (C) 2002-19, Bruce Allen, Christian Franke, www.smartmontools.org\n\n=== START OF READ SMART DATA SECTION ===\nSMART overall-health self-assessment test result: PASSED\n\n\n```\n",
      "summary": "https://www.simplified.guide/linux/disk-health-check",
      "date_published": "2022-08-29T06:30:27Z",
      "date_modified": "2022-08-29T06:30:27Z",
      "authors": [
        {
          "name": "Nic Payne",
          "url": "https://pype.dev"
        }
      ],
      "tags": [
        "cli",
        "linux",
        "tech",
        "til"
      ]
    },
    {
      "id": "https://pype.dev/mounting-exfat-usb-in-linux/",
      "url": "https://pype.dev/mounting-exfat-usb-in-linux/",
      "title": "Mounting exFAT USB in Linux",
      "content_html": "\u003ch1 id=\"steps\"\u003e\u003cspan class=\"heading-wear-glyph\"\u003eSteps\u003c/span\u003e\u003c/h1\u003e\n\u003cp\u003e\u003ccode\u003esudo fdisk -l\u003c/code\u003e\u003c/p\u003e\n\u003cp\u003ethen look for the device and partition\u003c/p\u003e\n\u003cp\u003eget the Type column\u003c/p\u003e\n\u003cp\u003emount\u003c/p\u003e\n\u003ch2 id=\"example\"\u003e\u003cspan class=\"heading-wear-glyph\"\u003eExample\u003c/span\u003e \u003ca href=\"#example\" class=\"heading-anchor\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cpre\u003e\u003ccode\u003e\ndumbledore in /media  NO PYTHON VENV SET \n❯ sudo fdisk -l\n\n...\n\nDevice     Boot    Start      End  Sectors  Size Id Type\n/dev/sdk1  *        2048 60371951 60369904 28.8G  7 HPFS/NTFS/exFAT\n/dev/sdk2       60371952 60437487    65536   32M ef EFI (FAT-12/16/32)\n\n\ndumbledore in /media  NO PYTHON VENV SET \n❯ sudo mount -t ntfs /dev/sdk1 /media/ventoy-usb -o uid=1000                       \nNTFS signature is missing.\nFailed to mount '/dev/sdk1': Invalid argument\nThe device '/dev/sdk1' doesn't seem to have a valid NTFS.\nMaybe the wrong device is used? Or the whole disk instead of a\npartition (e.g. /dev/sda, not /dev/sda1)? Or the other way around?\n\ndumbledore in /media  NO PYTHON VENV SET \n✗ sudo mount -t exfat /dev/sdk1 /media/ventoy-usb -o uid=1000\n\n\u003c/code\u003e\u003c/pre\u003e\n",
      "content_text": "\n# Steps\n\n`sudo fdisk -l`\n\nthen look for the device and partition\n\nget the Type column\n\nmount\n\n## Example\n\n```\n\ndumbledore in /media  NO PYTHON VENV SET \n❯ sudo fdisk -l\n\n...\n\nDevice     Boot    Start      End  Sectors  Size Id Type\n/dev/sdk1  *        2048 60371951 60369904 28.8G  7 HPFS/NTFS/exFAT\n/dev/sdk2       60371952 60437487    65536   32M ef EFI (FAT-12/16/32)\n\n\ndumbledore in /media  NO PYTHON VENV SET \n❯ sudo mount -t ntfs /dev/sdk1 /media/ventoy-usb -o uid=1000                       \nNTFS signature is missing.\nFailed to mount '/dev/sdk1': Invalid argument\nThe device '/dev/sdk1' doesn't seem to have a valid NTFS.\nMaybe the wrong device is used? Or the whole disk instead of a\npartition (e.g. /dev/sda, not /dev/sda1)? Or the other way around?\n\ndumbledore in /media  NO PYTHON VENV SET \n✗ sudo mount -t exfat /dev/sdk1 /media/ventoy-usb -o uid=1000\n\n```\n",
      "date_published": "2022-07-31T07:38:43Z",
      "date_modified": "2022-07-31T07:38:43Z",
      "authors": [
        {
          "name": "Nic Payne",
          "url": "https://pype.dev"
        }
      ],
      "tags": [
        "linux",
        "homelab",
        "tech",
        "til"
      ]
    },
    {
      "id": "https://pype.dev/setup-kvm-to-boot-from-local-pxe-server/",
      "url": "https://pype.dev/setup-kvm-to-boot-from-local-pxe-server/",
      "title": "Setup KVM to boot from local PXE server",
      "content_html": "\u003cp\u003eAssuming you have a PXE server running you only need small edits to the virt-manager config\u003c/p\u003e\n",
      "content_text": "\nAssuming you have a PXE server running you only need small edits to the virt-manager config\n",
      "summary": "Assuming you have a PXE server running you only need small edits to the virt-manager config",
      "date_published": "2022-07-06T12:30:50Z",
      "date_modified": "2022-07-06T12:30:50Z",
      "authors": [
        {
          "name": "Nic Payne",
          "url": "https://pype.dev"
        }
      ],
      "tags": [
        "homelab",
        "linux",
        "tech",
        "til"
      ]
    },
    {
      "id": "https://pype.dev/kvm-network-interface-via-nat-ubuntu-20/",
      "url": "https://pype.dev/kvm-network-interface-via-nat-ubuntu-20/",
      "title": "kvm-network-interface-via-nat-ubuntu-20",
      "content_html": "\u003cp\u003eI have started using VMs more and more in my development workflow and it\u0026rsquo;s\nimpossible to work in a VM without an internet connection for me most of the\ntime. Setting up the KVM networking is \u003ca href=\"/kind/\" class=\"glossary-term\" title=\"kind - kubernetes in docker\" data-hover-title=\"kind\"\u003ekind\u003c/a\u003e of confusing to me and I\u0026rsquo;ve done it\ntwo different ways. Here is how I set it up on my home desktop using NAT.\u003c/p\u003e\n\u003ch1 id=\"credit\"\u003e\u003cspan class=\"heading-wear-glyph\"\u003eCredit\u003c/span\u003e\u003c/h1\u003e\n\u003cp\u003eFirst thing\u0026rsquo;s first: \u003ca href=\"https://computingforgeeks.com/managing-kvm-network-interfaces-in-linux/\"\u003ecredit to this post\u003c/a\u003e\u003c/p\u003e\n\u003ch1 id=\"commands\"\u003e\u003cspan class=\"heading-wear-glyph\"\u003eCommands\u003c/span\u003e\u003c/h1\u003e\n\u003cp\u003eThere was a \u003ccode\u003edefault\u003c/code\u003e network already made by virt-manager but my VM couldn\u0026rsquo;t connect over it at all\u0026hellip;\u003c/p\u003e\n\u003cp\u003eThese commands got me up and running without even turning the VM off\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003eI went full on \u003ccode\u003esudo -i\u003c/code\u003e for this just to make it easier - be careful\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003ch2 id=\"dump-an-existint-network-config\"\u003e\u003cspan class=\"heading-wear-glyph\"\u003eDump an existint network config\u003c/span\u003e \u003ca href=\"#dump-an-existint-network-config\" class=\"heading-anchor\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cpre class=\"chroma\"\u003e\u003ccode\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# as root\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evirsh net-dumpxml default \u0026gt; br1.xml\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evim br1.xml\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003ch2 id=\"edit-it\"\u003e\u003cspan class=\"heading-wear-glyph\"\u003eEdit it\u003c/span\u003e \u003ca href=\"#edit-it\" class=\"heading-anchor\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eI was unsure what the ip range should be so I just stuck with the original blog.\nThe \u003ccode\u003edefault\u003c/code\u003e network had the CIDR block defined as \u003ccode\u003e192.168.122.0/24\u003c/code\u003e which is different from my home network so I guess it\u0026rsquo;s fine?\u003c/p\u003e\n\u003cpre class=\"chroma\"\u003e\u003ccode\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nt\"\u003e\u0026lt;network\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"nt\"\u003e\u0026lt;name\u0026gt;\u003c/span\u003ebr1\u003cspan class=\"nt\"\u003e\u0026lt;/name\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"nt\"\u003e\u0026lt;forward\u003c/span\u003e \u003cspan class=\"na\"\u003emode=\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#39;nat\u0026#39;\u003c/span\u003e\u003cspan class=\"nt\"\u003e\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nt\"\u003e\u0026lt;nat\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e      \u003cspan class=\"nt\"\u003e\u0026lt;port\u003c/span\u003e \u003cspan class=\"na\"\u003estart=\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#39;1024\u0026#39;\u003c/span\u003e \u003cspan class=\"na\"\u003eend=\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#39;65535\u0026#39;\u003c/span\u003e\u003cspan class=\"nt\"\u003e/\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nt\"\u003e\u0026lt;/nat\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"nt\"\u003e\u0026lt;/forward\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"nt\"\u003e\u0026lt;bridge\u003c/span\u003e \u003cspan class=\"na\"\u003ename=\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#39;br1\u0026#39;\u003c/span\u003e \u003cspan class=\"na\"\u003estp=\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#39;on\u0026#39;\u003c/span\u003e \u003cspan class=\"na\"\u003edelay=\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#39;0\u0026#39;\u003c/span\u003e\u003cspan class=\"nt\"\u003e/\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"nt\"\u003e\u0026lt;ip\u003c/span\u003e \u003cspan class=\"na\"\u003eaddress=\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#39;192.168.10.1\u0026#39;\u003c/span\u003e \u003cspan class=\"na\"\u003enetmask=\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#39;255.255.255.0\u0026#39;\u003c/span\u003e\u003cspan class=\"nt\"\u003e\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nt\"\u003e\u0026lt;dhcp\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e      \u003cspan class=\"nt\"\u003e\u0026lt;range\u003c/span\u003e \u003cspan class=\"na\"\u003estart=\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#39;192.168.10.10\u0026#39;\u003c/span\u003e \u003cspan class=\"na\"\u003eend=\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#39;192.168.10.100\u0026#39;\u003c/span\u003e\u003cspan class=\"nt\"\u003e/\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nt\"\u003e\u0026lt;/dhcp\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"nt\"\u003e\u0026lt;/ip\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nt\"\u003e\u0026lt;/network\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003ch2 id=\"define-a-network\"\u003e\u003cspan class=\"heading-wear-glyph\"\u003eDefine a network\u003c/span\u003e \u003ca href=\"#define-a-network\" class=\"heading-anchor\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cpre class=\"chroma\"\u003e\u003ccode\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evirsh net-define br1.xml\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evirsh net-autostart br1\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003cp\u003eThen to check\u0026hellip;\u003c/p\u003e\n\u003cpre class=\"chroma\"\u003e\u003ccode\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evirsh net-list --all\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e Name      State    Autostart   Persistent\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e--------------------------------------------\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e br1       active   yes         yes\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e default   active   yes         yes\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003ch2 id=\"uuid\"\u003e\u003cspan class=\"heading-wear-glyph\"\u003eUUID\u003c/span\u003e \u003ca href=\"#uuid\" class=\"heading-anchor\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003e\u003ccode\u003evirsh net-uuid br1\u003c/code\u003e\u003c/p\u003e\n\u003ch2 id=\"magic\"\u003e\u003cspan class=\"heading-wear-glyph\"\u003eMagic\u003c/span\u003e \u003ca href=\"#magic\" class=\"heading-anchor\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003e\u003ccode\u003evirsh attach-interface --domain \u0026lt;NAME OF VM\u0026gt; --type bridge --source br1 --model virtio --config --live\u003c/code\u003e\u003c/p\u003e\n\u003cp\u003eMy VM, \u003ccode\u003eubuntu20.04\u003c/code\u003e was running and immediately connected to the newly attached device!\u003c/p\u003e\n\u003ch1 id=\"credit-again\"\u003e\u003cspan class=\"heading-wear-glyph\"\u003eCredit again\u003c/span\u003e\u003c/h1\u003e\n\u003cp\u003eVisit the original post for more details - this serves more as as a quicker set of notes for future me\u003c/p\u003e\n",
      "content_text": "\nI have started using VMs more and more in my development workflow and it's\nimpossible to work in a VM without an internet connection for me most of the\ntime. Setting up the KVM networking is kind of confusing to me and I've done it\ntwo different ways. Here is how I set it up on my home desktop using NAT.\n\n# Credit\n\nFirst thing's first: [credit to this post](https://computingforgeeks.com/managing-kvm-network-interfaces-in-linux/)\n\n# Commands\n\nThere was a `default` network already made by virt-manager but my VM couldn't connect over it at all...\n\nThese commands got me up and running without even turning the VM off\n\n\u003e I went full on `sudo -i` for this just to make it easier - be careful\n\n## Dump an existint network config\n\n```bash\n# as root\n\nvirsh net-dumpxml default \u003e br1.xml\n\nvim br1.xml\n\n```\n\n## Edit it\n\nI was unsure what the ip range should be so I just stuck with the original blog. \nThe `default` network had the CIDR block defined as `192.168.122.0/24` which is different from my home network so I guess it's fine?\n\n```xml\n\u003cnetwork\u003e\n  \u003cname\u003ebr1\u003c/name\u003e\n  \u003cforward mode='nat'\u003e\n    \u003cnat\u003e\n      \u003cport start='1024' end='65535'/\u003e\n    \u003c/nat\u003e\n  \u003c/forward\u003e\n  \u003cbridge name='br1' stp='on' delay='0'/\u003e\n  \u003cip address='192.168.10.1' netmask='255.255.255.0'\u003e\n    \u003cdhcp\u003e\n      \u003crange start='192.168.10.10' end='192.168.10.100'/\u003e\n    \u003c/dhcp\u003e\n  \u003c/ip\u003e\n\u003c/network\u003e\n```\n\n## Define a network\n\n```bash\nvirsh net-define br1.xml\nvirsh net-autostart br1\n```\n\nThen to check...\n\n```bash\nvirsh net-list --all\n\n Name      State    Autostart   Persistent\n--------------------------------------------\n br1       active   yes         yes\n default   active   yes         yes\n```\n\n## UUID\n\n`virsh net-uuid br1`\n\n\n## Magic\n\n`virsh attach-interface --domain \u003cNAME OF VM\u003e --type bridge --source br1 --model virtio --config --live`\n\nMy VM, `ubuntu20.04` was running and immediately connected to the newly attached device!\n\n\n# Credit again\n\nVisit the original post for more details - this serves more as as a quicker set of notes for future me\n\n",
      "summary": "I have started using VMs more and more in my development workflow and it's impossible to work in a VM without an internet connection for me most of the time....",
      "date_published": "2022-06-25T07:20:41Z",
      "date_modified": "2022-06-25T07:20:41Z",
      "authors": [
        {
          "name": "Nic Payne",
          "url": "https://pype.dev"
        }
      ],
      "tags": [
        "homelab",
        "linux",
        "tech"
      ]
    },
    {
      "id": "https://pype.dev/cheat-on-your-man/",
      "url": "https://pype.dev/cheat-on-your-man/",
      "title": "cheat on your man",
      "content_html": "\u003cp\u003e\u003ccode\u003eman\u003c/code\u003e can be a pain to read\u0026hellip; and there\u0026rsquo;s lots of alternatives out there and one I\u0026rsquo;ve just started playing with is \u003ca href=\"https://github.com/cheat/cheat\"\u003echeat\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003e\u003ccode\u003eman man\u003c/code\u003e will give you this plus a billion more lines of docs, which is useful when you need it\u0026hellip;\u003c/p\u003e\n\u003cpre class=\"chroma\"\u003e\u003ccode\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eMAN\u003cspan class=\"o\"\u003e(\u003c/span\u003e1\u003cspan class=\"o\"\u003e)\u003c/span\u003e                                                                                                                       Manual pager utils                                                                                                                      MAN\u003cspan class=\"o\"\u003e(\u003c/span\u003e1\u003cspan class=\"o\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eNAME\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e       man - an interface to the on-line reference manuals\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eSYNOPSIS\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e       man  \u003cspan class=\"o\"\u003e[\u003c/span\u003e-C  file\u003cspan class=\"o\"\u003e]\u003c/span\u003e  \u003cspan class=\"o\"\u003e[\u003c/span\u003e-d\u003cspan class=\"o\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e[\u003c/span\u003e-D\u003cspan class=\"o\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e[\u003c/span\u003e--warnings\u003cspan class=\"o\"\u003e[=\u003c/span\u003ewarnings\u003cspan class=\"o\"\u003e]]\u003c/span\u003e \u003cspan class=\"o\"\u003e[\u003c/span\u003e-R encoding\u003cspan class=\"o\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e[\u003c/span\u003e-L locale\u003cspan class=\"o\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e[\u003c/span\u003e-m system\u003cspan class=\"o\"\u003e[\u003c/span\u003e,...\u003cspan class=\"o\"\u003e]]\u003c/span\u003e \u003cspan class=\"o\"\u003e[\u003c/span\u003e-M path\u003cspan class=\"o\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e[\u003c/span\u003e-S list\u003cspan class=\"o\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e[\u003c/span\u003e-e extension\u003cspan class=\"o\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e[\u003c/span\u003e-i\u003cspan class=\"p\"\u003e|\u003c/span\u003e-I\u003cspan class=\"o\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e[\u003c/span\u003e--regex\u003cspan class=\"p\"\u003e|\u003c/span\u003e--wildcard\u003cspan class=\"o\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e[\u003c/span\u003e--names-only\u003cspan class=\"o\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e[\u003c/span\u003e-a\u003cspan class=\"o\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e[\u003c/span\u003e-u\u003cspan class=\"o\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e[\u003c/span\u003e--no-subpages\u003cspan class=\"o\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e[\u003c/span\u003e-P pager\u003cspan class=\"o\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e[\u003c/span\u003e-r prompt\u003cspan class=\"o\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e[\u003c/span\u003e-7\u003cspan class=\"o\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e[\u003c/span\u003e-E encoding\u003cspan class=\"o\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e[\u003c/span\u003e--no-hyphenation\u003cspan class=\"o\"\u003e]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e       \u003cspan class=\"o\"\u003e[\u003c/span\u003e--no-justification\u003cspan class=\"o\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e[\u003c/span\u003e-p string\u003cspan class=\"o\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e[\u003c/span\u003e-t\u003cspan class=\"o\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e[\u003c/span\u003e-T\u003cspan class=\"o\"\u003e[\u003c/span\u003edevice\u003cspan class=\"o\"\u003e]]\u003c/span\u003e \u003cspan class=\"o\"\u003e[\u003c/span\u003e-H\u003cspan class=\"o\"\u003e[\u003c/span\u003ebrowser\u003cspan class=\"o\"\u003e]]\u003c/span\u003e \u003cspan class=\"o\"\u003e[\u003c/span\u003e-X\u003cspan class=\"o\"\u003e[\u003c/span\u003edpi\u003cspan class=\"o\"\u003e]]\u003c/span\u003e \u003cspan class=\"o\"\u003e[\u003c/span\u003e-Z\u003cspan class=\"o\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e[[\u003c/span\u003esection\u003cspan class=\"o\"\u003e]\u003c/span\u003e page\u003cspan class=\"o\"\u003e[\u003c/span\u003e.section\u003cspan class=\"o\"\u003e]\u003c/span\u003e ...\u003cspan class=\"o\"\u003e]\u003c/span\u003e ...\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e       man -k \u003cspan class=\"o\"\u003e[\u003c/span\u003eapropos options\u003cspan class=\"o\"\u003e]\u003c/span\u003e regexp ...\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e       man -K \u003cspan class=\"o\"\u003e[\u003c/span\u003e-w\u003cspan class=\"p\"\u003e|\u003c/span\u003e-W\u003cspan class=\"o\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e[\u003c/span\u003e-S list\u003cspan class=\"o\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e[\u003c/span\u003e-i\u003cspan class=\"p\"\u003e|\u003c/span\u003e-I\u003cspan class=\"o\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e[\u003c/span\u003e--regex\u003cspan class=\"o\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e[\u003c/span\u003esection\u003cspan class=\"o\"\u003e]\u003c/span\u003e term ...\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e       man -f \u003cspan class=\"o\"\u003e[\u003c/span\u003ewhatis options\u003cspan class=\"o\"\u003e]\u003c/span\u003e page ...\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e       man -l \u003cspan class=\"o\"\u003e[\u003c/span\u003e-C file\u003cspan class=\"o\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e[\u003c/span\u003e-d\u003cspan class=\"o\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e[\u003c/span\u003e-D\u003cspan class=\"o\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e[\u003c/span\u003e--warnings\u003cspan class=\"o\"\u003e[=\u003c/span\u003ewarnings\u003cspan class=\"o\"\u003e]]\u003c/span\u003e \u003cspan class=\"o\"\u003e[\u003c/span\u003e-R encoding\u003cspan class=\"o\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e[\u003c/span\u003e-L locale\u003cspan class=\"o\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e[\u003c/span\u003e-P pager\u003cspan class=\"o\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e[\u003c/span\u003e-r prompt\u003cspan class=\"o\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e[\u003c/span\u003e-7\u003cspan class=\"o\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e[\u003c/span\u003e-E encoding\u003cspan class=\"o\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e[\u003c/span\u003e-p string\u003cspan class=\"o\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e[\u003c/span\u003e-t\u003cspan class=\"o\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e[\u003c/span\u003e-T\u003cspan class=\"o\"\u003e[\u003c/span\u003edevice\u003cspan class=\"o\"\u003e]]\u003c/span\u003e \u003cspan class=\"o\"\u003e[\u003c/span\u003e-H\u003cspan class=\"o\"\u003e[\u003c/span\u003ebrowser\u003cspan class=\"o\"\u003e]]\u003c/span\u003e \u003cspan class=\"o\"\u003e[\u003c/span\u003e-X\u003cspan class=\"o\"\u003e[\u003c/span\u003edpi\u003cspan class=\"o\"\u003e]]\u003c/span\u003e \u003cspan class=\"o\"\u003e[\u003c/span\u003e-Z\u003cspan class=\"o\"\u003e]\u003c/span\u003e file ...\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e       man -w\u003cspan class=\"p\"\u003e|\u003c/span\u003e-W \u003cspan class=\"o\"\u003e[\u003c/span\u003e-C file\u003cspan class=\"o\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e[\u003c/span\u003e-d\u003cspan class=\"o\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e[\u003c/span\u003e-D\u003cspan class=\"o\"\u003e]\u003c/span\u003e page ...\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e       man -c \u003cspan class=\"o\"\u003e[\u003c/span\u003e-C file\u003cspan class=\"o\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e[\u003c/span\u003e-d\u003cspan class=\"o\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e[\u003c/span\u003e-D\u003cspan class=\"o\"\u003e]\u003c/span\u003e page ...\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e       man \u003cspan class=\"o\"\u003e[\u003c/span\u003e-?V\u003cspan class=\"o\"\u003e]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eDESCRIPTION\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e       man is the system\u003cspan class=\"err\"\u003e\u0026#39;\u003c/span\u003es manual pager.  Each page argument given to man is normally the name of a program, utility or \u003cspan class=\"k\"\u003efunction\u003c/span\u003e.  The manual page associated with each of these arguments is \u003cspan class=\"k\"\u003ethen\u003c/span\u003e found and displayed.  A section, \u003cspan class=\"k\"\u003eif\u003c/span\u003e provided, will direct  man  to  look\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e       only  in  that  section of the manual.  The default action is to search in all of the available sections following a pre-defined order \u003cspan class=\"o\"\u003e(\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;1 n l 8 3 2 3posix 3pm 3perl 3am 5 4 9 6 7\u0026#34;\u003c/span\u003e by default, unless overridden by the SECTION directive in /etc/manpath.config\u003cspan class=\"o\"\u003e)\u003c/span\u003e,\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e       and to show only the first page found, even \u003cspan class=\"k\"\u003eif\u003c/span\u003e page exists in several sections.\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e       The table below shows the section numbers of the manual followed by the types of pages they contain.\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e       \u003cspan class=\"m\"\u003e1\u003c/span\u003e   Executable programs or shell commands\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e       \u003cspan class=\"m\"\u003e2\u003c/span\u003e   System calls \u003cspan class=\"o\"\u003e(\u003c/span\u003efunctions provided by the kernel\u003cspan class=\"o\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e       \u003cspan class=\"m\"\u003e3\u003c/span\u003e   Library calls \u003cspan class=\"o\"\u003e(\u003c/span\u003efunctions within program libraries\u003cspan class=\"o\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e       \u003cspan class=\"m\"\u003e4\u003c/span\u003e   Special files \u003cspan class=\"o\"\u003e(\u003c/span\u003eusually found in /dev\u003cspan class=\"o\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e       \u003cspan class=\"m\"\u003e5\u003c/span\u003e   File formats and conventions eg /etc/passwd\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e       \u003cspan class=\"m\"\u003e6\u003c/span\u003e   Games\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e       \u003cspan class=\"m\"\u003e7\u003c/span\u003e   Miscellaneous \u003cspan class=\"o\"\u003e(\u003c/span\u003eincluding macro packages and conventions\u003cspan class=\"o\"\u003e)\u003c/span\u003e, e.g. man\u003cspan class=\"o\"\u003e(\u003c/span\u003e7\u003cspan class=\"o\"\u003e)\u003c/span\u003e, groff\u003cspan class=\"o\"\u003e(\u003c/span\u003e7\u003cspan class=\"o\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e       \u003cspan class=\"m\"\u003e8\u003c/span\u003e   System administration commands \u003cspan class=\"o\"\u003e(\u003c/span\u003eusually only \u003cspan class=\"k\"\u003efor\u003c/span\u003e root\u003cspan class=\"o\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e       \u003cspan class=\"m\"\u003e9\u003c/span\u003e   Kernel routines \u003cspan class=\"o\"\u003e[\u003c/span\u003eNon standard\u003cspan class=\"o\"\u003e]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e       A manual page consists of several sections.\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e       Conventional section names include NAME, SYNOPSIS, CONFIGURATION, DESCRIPTION, OPTIONS, EXIT STATUS, RETURN VALUE, ERRORS, ENVIRONMENT, FILES, VERSIONS, CONFORMING TO, NOTES, BUGS, EXAMPLE, AUTHORS, and SEE ALSO.\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e       The following conventions apply to the SYNOPSIS section and can be used as a guide in other sections.\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e       bold text          \u003cspan class=\"nb\"\u003etype\u003c/span\u003e exactly as shown.\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e       italic text        replace with appropriate argument.\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e       \u003cspan class=\"o\"\u003e[\u003c/span\u003e-abc\u003cspan class=\"o\"\u003e]\u003c/span\u003e             any or all arguments within \u003cspan class=\"o\"\u003e[\u003c/span\u003e \u003cspan class=\"o\"\u003e]\u003c/span\u003e are optional.\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e       -a\u003cspan class=\"p\"\u003e|\u003c/span\u003e-b              options delimited by \u003cspan class=\"p\"\u003e|\u003c/span\u003e cannot be used together.\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e       argument ...       argument is repeatable.\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e       \u003cspan class=\"o\"\u003e[\u003c/span\u003eexpression\u003cspan class=\"o\"\u003e]\u003c/span\u003e ...   entire expression within \u003cspan class=\"o\"\u003e[\u003c/span\u003e \u003cspan class=\"o\"\u003e]\u003c/span\u003e is repeatable.\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e       Exact rendering may vary depending on the output device.  For instance, man will usually not be able to render italics when running in a terminal, and will typically use underlined or coloured text instead.\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e       The \u003cspan class=\"nb\"\u003ecommand\u003c/span\u003e or \u003cspan class=\"k\"\u003efunction\u003c/span\u003e illustration is a pattern that should match all possible invocations.  In some cases it is advisable to illustrate several exclusive invocations as is shown in the SYNOPSIS section of this manual page.\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eEXAMPLES\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e       man ls\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e           Display the manual page \u003cspan class=\"k\"\u003efor\u003c/span\u003e the item \u003cspan class=\"o\"\u003e(\u003c/span\u003eprogram\u003cspan class=\"o\"\u003e)\u003c/span\u003e ls.\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e       man man.7\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e           Display the manual page \u003cspan class=\"k\"\u003efor\u003c/span\u003e macro package man from section 7.\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003ch2 id=\"but-what-if-you-don-t\"\u003e\u003cspan class=\"heading-wear-glyph\"\u003eBut what if you don’t?\u003c/span\u003e \u003ca href=\"#but-what-if-you-don-t\" class=\"heading-anchor\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003e\u003ccode\u003echeat man\u003c/code\u003e\u003c/p\u003e\n\u003cpre class=\"chroma\"\u003e\u003ccode\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# To convert a man page to pdf:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eman -t bash \u003cspan class=\"p\"\u003e|\u003c/span\u003e ps2pdf - bash.pdf\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# To view the ascii chart:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eman \u003cspan class=\"m\"\u003e7\u003c/span\u003e ascii\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003cp\u003eYou get tiny examples to remind you of what you \u003cstrong\u003eprobably\u003c/strong\u003e are trying to do!\u003c/p\u003e\n",
      "content_text": "\n\n`man` can be a pain to read... and there's lots of alternatives out there and one I've just started playing with is [cheat](https://github.com/cheat/cheat)\n\n\n`man man` will give you this plus a billion more lines of docs, which is useful when you need it...\n\n```bash\nMAN(1)                                                                                                                       Manual pager utils                                                                                                                      MAN(1)\n\nNAME\n       man - an interface to the on-line reference manuals\n\nSYNOPSIS\n       man  [-C  file]  [-d] [-D] [--warnings[=warnings]] [-R encoding] [-L locale] [-m system[,...]] [-M path] [-S list] [-e extension] [-i|-I] [--regex|--wildcard] [--names-only] [-a] [-u] [--no-subpages] [-P pager] [-r prompt] [-7] [-E encoding] [--no-hyphenation]\n       [--no-justification] [-p string] [-t] [-T[device]] [-H[browser]] [-X[dpi]] [-Z] [[section] page[.section] ...] ...\n       man -k [apropos options] regexp ...\n       man -K [-w|-W] [-S list] [-i|-I] [--regex] [section] term ...\n       man -f [whatis options] page ...\n       man -l [-C file] [-d] [-D] [--warnings[=warnings]] [-R encoding] [-L locale] [-P pager] [-r prompt] [-7] [-E encoding] [-p string] [-t] [-T[device]] [-H[browser]] [-X[dpi]] [-Z] file ...\n       man -w|-W [-C file] [-d] [-D] page ...\n       man -c [-C file] [-d] [-D] page ...\n       man [-?V]\n\nDESCRIPTION\n       man is the system's manual pager.  Each page argument given to man is normally the name of a program, utility or function.  The manual page associated with each of these arguments is then found and displayed.  A section, if provided, will direct  man  to  look\n       only  in  that  section of the manual.  The default action is to search in all of the available sections following a pre-defined order (\"1 n l 8 3 2 3posix 3pm 3perl 3am 5 4 9 6 7\" by default, unless overridden by the SECTION directive in /etc/manpath.config),\n       and to show only the first page found, even if page exists in several sections.\n\n       The table below shows the section numbers of the manual followed by the types of pages they contain.\n\n       1   Executable programs or shell commands\n       2   System calls (functions provided by the kernel)\n       3   Library calls (functions within program libraries)\n       4   Special files (usually found in /dev)\n       5   File formats and conventions eg /etc/passwd\n       6   Games\n       7   Miscellaneous (including macro packages and conventions), e.g. man(7), groff(7)\n       8   System administration commands (usually only for root)\n       9   Kernel routines [Non standard]\n\n       A manual page consists of several sections.\n\n       Conventional section names include NAME, SYNOPSIS, CONFIGURATION, DESCRIPTION, OPTIONS, EXIT STATUS, RETURN VALUE, ERRORS, ENVIRONMENT, FILES, VERSIONS, CONFORMING TO, NOTES, BUGS, EXAMPLE, AUTHORS, and SEE ALSO.\n\n       The following conventions apply to the SYNOPSIS section and can be used as a guide in other sections.\n\n       bold text          type exactly as shown.\n       italic text        replace with appropriate argument.\n       [-abc]             any or all arguments within [ ] are optional.\n       -a|-b              options delimited by | cannot be used together.\n       argument ...       argument is repeatable.\n       [expression] ...   entire expression within [ ] is repeatable.\n\n       Exact rendering may vary depending on the output device.  For instance, man will usually not be able to render italics when running in a terminal, and will typically use underlined or coloured text instead.\n\n       The command or function illustration is a pattern that should match all possible invocations.  In some cases it is advisable to illustrate several exclusive invocations as is shown in the SYNOPSIS section of this manual page.\n\nEXAMPLES\n       man ls\n           Display the manual page for the item (program) ls.\n\n       man man.7\n           Display the manual page for macro package man from section 7.\n```\n\n\n## But what if you don't?\n\n`cheat man`\n\n```bash\n# To convert a man page to pdf:\nman -t bash | ps2pdf - bash.pdf\n\n# To view the ascii chart:\nman 7 ascii\n```\n\nYou get tiny examples to remind you of what you **probably** are trying to do!\n",
      "summary": "can be a pain to read... and there's lots of alternatives out there and one I've just started playing with is cheat",
      "date_published": "2022-06-23T09:35:31Z",
      "date_modified": "2022-06-23T09:35:31Z",
      "authors": [
        {
          "name": "Nic Payne",
          "url": "https://pype.dev"
        }
      ],
      "tags": [
        "linux",
        "cli",
        "tech",
        "til"
      ]
    },
    {
      "id": "https://pype.dev/reset-ssh-key-passphrase/",
      "url": "https://pype.dev/reset-ssh-key-passphrase/",
      "title": "Reset SSH key passphrase",
      "content_html": "\u003cp\u003eI got into a pickle where I encrypted the ssh keys I use for my SSH connections on LAN, but then I couldn\u0026rsquo;t run my ansible playbook on my server! ssh-keygen -p and leave the new passphrase blank saved my day (although password protected key files are safer!)\u003c/p\u003e\n\u003ch1 id=\"tl-dr-just-reset-it-to-nothing\"\u003e\u003cspan class=\"heading-wear-glyph\"\u003eTL;DR - just reset it to nothing\u003c/span\u003e\u003c/h1\u003e\n\u003cp\u003e\u003ccode\u003essh-keygen -p\u003c/code\u003e will let you reset the passphrase on your ssh keys (good for you! yay security!)\u003c/p\u003e\n\u003cp\u003eBut I needed to remove the passphrase to quickly deploy an ansible playbook 🤓\u003c/p\u003e\n",
      "content_text": "\nI got into a pickle where I encrypted the ssh keys I use for my SSH connections on LAN, but then I couldn't run my ansible playbook on my server! ssh-keygen -p and leave the new passphrase blank saved my day (although password protected key files are safer!)\n\n# TL;DR - just reset it to nothing\n\n`ssh-keygen -p` will let you reset the passphrase on your ssh keys (good for you! yay security!)\n\nBut I needed to remove the passphrase to quickly deploy an ansible playbook 🤓\n",
      "summary": "I got into a pickle where I encrypted the ssh keys I use for my SSH connections on LAN, but then I couldn't run my ansible playbook on my server! ssh-keygen...",
      "date_published": "2022-06-13T06:55:32Z",
      "date_modified": "2022-06-13T06:55:32Z",
      "authors": [
        {
          "name": "Nic Payne",
          "url": "https://pype.dev"
        }
      ],
      "tags": [
        "homelab",
        "cli",
        "linux",
        "til"
      ]
    },
    {
      "id": "https://pype.dev/samba-on-ubuntu-22-needs-inherit-permissions-set/",
      "url": "https://pype.dev/samba-on-ubuntu-22-needs-inherit-permissions-set/",
      "title": "Samba on Ubuntu 22 needs “inherit permissions” set",
      "content_html": "\u003cp\u003esee samba config on hogwarts\u003c/p\u003e\n",
      "content_text": "\nsee samba config on hogwarts\n",
      "summary": "see samba config on hogwarts",
      "date_published": "2022-05-31T06:30:42Z",
      "date_modified": "2022-05-31T06:30:42Z",
      "authors": [
        {
          "name": "Nic Payne",
          "url": "https://pype.dev"
        }
      ],
      "tags": [
        "homelab",
        "linux",
        "tech",
        "til"
      ]
    },
    {
      "id": "https://pype.dev/filtering-emails-with-core-utils/",
      "url": "https://pype.dev/filtering-emails-with-core-utils/",
      "title": "Filtering emails with core utils",
      "content_html": "\u003cpre class=\"chroma\"\u003e\u003ccode\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eemail1@me.com\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003esomebody_else@gmail.com\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003cpre class=\"chroma\"\u003e\u003ccode\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#! /bin/bash\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# pick multiple emails from list and combine into comma seperated array\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nv\"\u003eemails\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"sb\"\u003e`\u003c/span\u003ecat .../emails \u003cspan class=\"p\"\u003e|\u003c/span\u003e fzf -m \u003cspan class=\"p\"\u003e|\u003c/span\u003e sed \u003cspan class=\"s1\"\u003e\u0026#39;s/^\\|$/\u0026#34;/g\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e|\u003c/span\u003epaste -sd,\u003cspan class=\"sb\"\u003e`\u003c/span\u003e \n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eecho\u003c/span\u003e \u003cspan class=\"nv\"\u003e$emails\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e",
      "content_text": "\n```text\nemail1@me.com\nsomebody_else@gmail.com\n\n```\n\n```bash\n#! /bin/bash\n# pick multiple emails from list and combine into comma seperated array\nemails=`cat .../emails | fzf -m | sed 's/^\\|$/\"/g'|paste -sd,` \n\necho $emails\n\n```\n",
      "date_published": "2022-05-30T06:09:27Z",
      "date_modified": "2022-05-30T06:09:27Z",
      "authors": [
        {
          "name": "Nic Payne",
          "url": "https://pype.dev"
        }
      ],
      "tags": [
        "linux",
        "cli",
        "tech",
        "til"
      ]
    },
    {
      "id": "https://pype.dev/reindex-nextcloud-after-adding-data-via-cli/",
      "url": "https://pype.dev/reindex-nextcloud-after-adding-data-via-cli/",
      "title": "Reindex Nextcloud After Adding Data via CLI",
      "content_html": "\u003ch1 id=\"my-nextcloud-woes\"\u003e\u003cspan class=\"heading-wear-glyph\"\u003eMy Nextcloud woes\u003c/span\u003e\u003c/h1\u003e\n\u003cp\u003eI wrote \u003ca href=\"%22nextcloud-permissions-with-zfs-and-ansible-nas%22\"\u003ehere\u003c/a\u003e about setting\nup \u003ccode\u003ewww-data\u003c/code\u003e as the owner of any directories you want nextcloud to manage.\nHowever, I regularly struggle wtih permissions issues on my NAS because of the\nexternal storage app anyways so I\u0026rsquo;ve decided to just put our photos in the spot\nNextcloud would otherwise put them, and use this as healthy pressure on our\nfamily to organize our photos and put the ones we care about with the rest of\nour family media.\u003c/p\u003e\n\u003ch1 id=\"migration\"\u003e\u003cspan class=\"heading-wear-glyph\"\u003eMigration\u003c/span\u003e\u003c/h1\u003e\n\u003cp\u003eBecause I had a ton of photos on the NAS anyways that I wanted moved over to\nNextcloud I just rsync\u0026rsquo;d the photos directory on my NAS to the user\u0026rsquo;s photos\ndirectory in nextcloud but they weren\u0026rsquo;t showing up in the web UI!\u003c/p\u003e\n\u003ch1 id=\"the-fix\"\u003e\u003cspan class=\"heading-wear-glyph\"\u003eThe Fix?\u003c/span\u003e\u003c/h1\u003e\n\u003cp\u003eAs www-data I needed to \u003ccode\u003ephp /var/www/nextcloud/occ files:scan --all\u003c/code\u003e inside my\nnextcloud \u003ca href=\"/docker/\" class=\"glossary-term\" title=\"docker - container runtime\" data-hover-title=\"docker\"\u003edocker\u003c/a\u003e container AFTER moving a bunch of photos off my \u0026ldquo;NAS\u0026rdquo; into the\nfolder mounted to the nextcloud container as its data folder! Before I did this\nthey weren\u0026rsquo;t showing up in the web UI/\u003c/p\u003e\n",
      "content_text": "\n# My Nextcloud woes\n\nI wrote [here](\"nextcloud-permissions-with-zfs-and-ansible-nas\") about setting\nup `www-data` as the owner of any directories you want nextcloud to manage.\nHowever, I regularly struggle wtih permissions issues on my NAS because of the\nexternal storage app anyways so I've decided to just put our photos in the spot\nNextcloud would otherwise put them, and use this as healthy pressure on our\nfamily to organize our photos and put the ones we care about with the rest of\nour family media.\n\n# Migration\n\nBecause I had a ton of photos on the NAS anyways that I wanted moved over to\nNextcloud I just rsync'd the photos directory on my NAS to the user's photos\ndirectory in nextcloud but they weren't showing up in the web UI!\n\n# The Fix?\n\nAs www-data I needed to `php /var/www/nextcloud/occ files:scan --all` inside my\nnextcloud docker container AFTER moving a bunch of photos off my \"NAS\" into the\nfolder mounted to the nextcloud container as its data folder! Before I did this\nthey weren't showing up in the web UI/\n",
      "summary": "I wrote here about setting up as the owner of any directories you want nextcloud to manage. However, I regularly struggle wtih permissions issues on my NAS...",
      "date_published": "2022-05-29T15:34:33Z",
      "date_modified": "2022-05-29T15:34:33Z",
      "authors": [
        {
          "name": "Nic Payne",
          "url": "https://pype.dev"
        }
      ],
      "tags": [
        "homelab",
        "linux",
        "tech",
        "til"
      ]
    },
    {
      "id": "https://pype.dev/add-space-to-your-lvm-on-ubuntu/",
      "url": "https://pype.dev/add-space-to-your-lvm-on-ubuntu/",
      "title": "Add space to your LVM on Ubuntu",
      "content_html": "\u003cp\u003eI ran out of space on the SSD in my server when doing some file transfers but only 100GB was used of a 256 GB SSD?\u003c/p\u003e\n\u003ch1 id=\"lvm\"\u003e\u003cspan class=\"heading-wear-glyph\"\u003eLVM\u003c/span\u003e\u003c/h1\u003e\n\u003cp\u003eWhen installing Ubuntu live server the default option for how to partition the\ndisk (in my experience) has been to setup an LVM group that defaults to less\nthan the available space. Most recently I put Ubuntu server on a 256 GB SSD but\nthe main partition was formatted as an LVM group with 100GB of storage\u0026hellip; I\ndidn\u0026rsquo;t think anything of this even though I\u0026rsquo;m mostly used to EXT4.\u003c/p\u003e\n\u003cp\u003eI think the reason for LVMs is performance, but in hindsight, I don\u0026rsquo;t really\ncare much about the performance differences, I really just want all my storage\nthat\u0026rsquo;s fast enough\u003c/p\u003e\n\u003ch1 id=\"extending-the-lvm\"\u003e\u003cspan class=\"heading-wear-glyph\"\u003eExtending the LVM\u003c/span\u003e\u003c/h1\u003e\n\u003cp\u003eA moment of googling brought me to Ubuntu\u0026rsquo;s wiki and I\nlearned that I can expand my LVM to the space I need\u0026hellip;\u003c/p\u003e\n\u003cp\u003e\u003ccode\u003esudo lvdisplay\u003c/code\u003e and \u003ccode\u003esudo pvdisplay\u003c/code\u003e show detailed views of the logical volumes and physical volumes respectively.\u003c/p\u003e\n\u003cp\u003eTake a look at those and find the volume you need to extend. For me I found this:\u003c/p\u003e\n\u003cpre class=\"chroma\"\u003e\u003ccode\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  --- Logical volume ---\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  LV Path                /dev/ubuntu-vg/ubuntu-lv\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  LV Name                ubuntu-lv\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  VG Name                ubuntu-vg\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  LV Write Access        read/write\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  LV Status              available\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  ...\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003cp\u003eThere\u0026rsquo;s more that you\u0026rsquo;ll see but this is what\u0026rsquo;s relevant - I need to extend the\n\u003ccode\u003eubuntu-lv\u003c/code\u003e logical volume in the \u003ccode\u003eubuntu-vg\u003c/code\u003e volume group.\u003c/p\u003e\n\u003cp\u003e\u003ccode\u003esudo lvextend -L +50g ubuntu-vg/ubuntu-lv\u003c/code\u003e gives me 50 more GB of storage which should be enough for at least tonight 🤓\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"https://wiki.ubuntu.com/Lvm\"\u003eRTFM\u003c/a\u003e\u003c/p\u003e\n",
      "content_text": "\nI ran out of space on the SSD in my server when doing some file transfers but only 100GB was used of a 256 GB SSD?\n\n# LVM\n\nWhen installing Ubuntu live server the default option for how to partition the\ndisk (in my experience) has been to setup an LVM group that defaults to less\nthan the available space. Most recently I put Ubuntu server on a 256 GB SSD but\nthe main partition was formatted as an LVM group with 100GB of storage... I\ndidn't think anything of this even though I'm mostly used to EXT4.\n\nI think the reason for LVMs is performance, but in hindsight, I don't really\ncare much about the performance differences, I really just want all my storage\nthat's fast enough\n\n# Extending the LVM\n\nA moment of googling brought me to Ubuntu's wiki and I\nlearned that I can expand my LVM to the space I need...\n\n`sudo lvdisplay` and `sudo pvdisplay` show detailed views of the logical volumes and physical volumes respectively.\n\nTake a look at those and find the volume you need to extend. For me I found this:\n\n```bash\n  --- Logical volume ---\n  LV Path                /dev/ubuntu-vg/ubuntu-lv\n  LV Name                ubuntu-lv\n  VG Name                ubuntu-vg\n  LV Write Access        read/write\n  LV Status              available\n  ...\n```\n\nThere's more that you'll see but this is what's relevant - I need to extend the\n`ubuntu-lv` logical volume in the `ubuntu-vg` volume group.\n\n`sudo lvextend -L +50g ubuntu-vg/ubuntu-lv` gives me 50 more GB of storage which should be enough for at least tonight 🤓\n\n[RTFM](https://wiki.ubuntu.com/Lvm)\n",
      "summary": "I ran out of space on the SSD in my server when doing some file transfers but only 100GB was used of a 256 GB SSD?",
      "date_published": "2022-05-26T21:33:55Z",
      "date_modified": "2022-05-26T21:33:55Z",
      "authors": [
        {
          "name": "Nic Payne",
          "url": "https://pype.dev"
        }
      ],
      "tags": [
        "homelab",
        "linux",
        "tech",
        "til"
      ]
    },
    {
      "id": "https://pype.dev/configure-bridge-network-on-ubuntu-22-04-with-netplan/",
      "url": "https://pype.dev/configure-bridge-network-on-ubuntu-22-04-with-netplan/",
      "title": "Configure bridge network on Ubuntu 22.04 with Netplan",
      "content_html": "\u003cp\u003eSee 02-\u0026hellip;.yaml in ansible-nas\u003c/p\u003e\n",
      "content_text": "\nSee 02-....yaml in ansible-nas\n",
      "summary": "See 02-....yaml in ansible-nas",
      "date_published": "2022-05-22T14:55:28Z",
      "date_modified": "2022-05-22T14:55:28Z",
      "authors": [
        {
          "name": "Nic Payne",
          "url": "https://pype.dev"
        }
      ],
      "tags": [
        "homelab",
        "linux",
        "tech",
        "til"
      ]
    },
    {
      "id": "https://pype.dev/netplan-change-from-focal-to-jammy/",
      "url": "https://pype.dev/netplan-change-from-focal-to-jammy/",
      "title": "Netplan change from Focal to Jammy",
      "content_html": "\u003cp\u003eI am revamping my home server and bumped myself early up to Jammy Jellyfish\u0026hellip;\nhowever to my peril I reused my netplan config and after hitting my server with\nthe \u0026lsquo;ol \u003ccode\u003enetplan apply\u003c/code\u003e I lost connection\u0026hellip;\nDNS still seemed to kinda work externally, but internally nothing was up\u0026hellip;\u003c/p\u003e\n\u003cp\u003eTurns out Netplan got a little change in how to express the \u003ccode\u003egateway\u003c/code\u003e key in the netplan config!\u003c/p\u003e\n\u003cp\u003eOld Ubuntu 20.04 way\u003c/p\u003e\n\u003cpre class=\"chroma\"\u003e\u003ccode\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nt\"\u003enetwork\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e  \u003c/span\u003e\u003cspan class=\"nt\"\u003eversion\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"m\"\u003e2\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e  \u003c/span\u003e\u003cspan class=\"nt\"\u003eethernets\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"nt\"\u003eenp0s4\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e      \u003c/span\u003e\u003cspan class=\"nt\"\u003eaddresses\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"m\"\u003e192.168.1\u003c/span\u003e\u003cspan class=\"l\"\u003e.{Static IP}/24]\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e      \u003c/span\u003e\u003cspan class=\"nt\"\u003egateway4\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"m\"\u003e192.168.1.1\u003c/span\u003e\u003cspan class=\"w\"\u003e  \u003c/span\u003e\u003cspan class=\"c\"\u003e# \u0026lt;-- This changes!\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e      \u003c/span\u003e\u003cspan class=\"nt\"\u003enameservers\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e        \u003c/span\u003e\u003cspan class=\"nt\"\u003eaddresses\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"m\"\u003e192.168.1.1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"m\"\u003e1.1.1.1\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003cp\u003eNew jammin way for Jammy Jellyfish (\u003cstrong\u003eat least that worked for me\u003c/strong\u003e)\u003c/p\u003e\n\u003cpre class=\"chroma\"\u003e\u003ccode\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nt\"\u003enetwork\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e  \u003c/span\u003e\u003cspan class=\"nt\"\u003eversion\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"m\"\u003e2\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e  \u003c/span\u003e\u003cspan class=\"nt\"\u003eethernets\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"nt\"\u003eenp0s4\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e      \u003c/span\u003e\u003cspan class=\"nt\"\u003eaddresses\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"m\"\u003e192.168.1\u003c/span\u003e\u003cspan class=\"l\"\u003e.{Static IP}/24]\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e      \u003c/span\u003e\u003cspan class=\"nt\"\u003eroutes\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e        \u003c/span\u003e- \u003cspan class=\"nt\"\u003eto\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"l\"\u003edefault\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e          \u003c/span\u003e\u003cspan class=\"nt\"\u003evia\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"m\"\u003e192.168.1.1\u003c/span\u003e\u003cspan class=\"w\"\u003e \n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e      \u003c/span\u003e\u003cspan class=\"nt\"\u003enameservers\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e        \u003c/span\u003e\u003cspan class=\"nt\"\u003eaddresses\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"m\"\u003e192.168.1.1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"m\"\u003e1.1.1.1\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e",
      "content_text": "\nI am revamping my home server and bumped myself early up to Jammy Jellyfish...\nhowever to my peril I reused my netplan config and after hitting my server with\nthe 'ol `netplan apply` I lost connection...\nDNS still seemed to kinda work externally, but internally nothing was up... \n\nTurns out Netplan got a little change in how to express the `gateway` key in the netplan config!\n\nOld Ubuntu 20.04 way\n\n```yaml\nnetwork:\n  version: 2\n  ethernets:\n    enp0s4:\n      addresses: [192.168.1.{Static IP}/24]\n      gateway4: 192.168.1.1  # \u003c-- This changes!\n      nameservers:\n        addresses: [192.168.1.1, 1.1.1.1]\n```\n\nNew jammin way for Jammy Jellyfish (__at least that worked for me__)\n```yaml\nnetwork:\n  version: 2\n  ethernets:\n    enp0s4:\n      addresses: [192.168.1.{Static IP}/24]\n      routes:\n        - to: default\n          via: 192.168.1.1 \n      nameservers:\n        addresses: [192.168.1.1, 1.1.1.1]\n```\n",
      "summary": "I am revamping my home server and bumped myself early up to Jammy Jellyfish... however to my peril I reused my netplan config and after hitting my server...",
      "date_published": "2022-05-22T13:23:17Z",
      "date_modified": "2022-05-22T13:23:17Z",
      "authors": [
        {
          "name": "Nic Payne",
          "url": "https://pype.dev"
        }
      ],
      "tags": [
        "homelab",
        "linux",
        "tech",
        "til"
      ]
    },
    {
      "id": "https://pype.dev/deleting-files-on-remote-storage-from-ubuntu-might-not-do-what-you-think/",
      "url": "https://pype.dev/deleting-files-on-remote-storage-from-ubuntu-might-not-do-what-you-think/",
      "title": "Deleting files on remote storage from Ubuntu might not do what you think",
      "content_html": "\u003cp\u003eFrom my daily driver Ubuntu machine I often open nautilus, dolphin, etc. and delete a file here or there on my NAS\u0026hellip; turns out Ubuntu sends thse file to \u003ccode\u003e.Trash-100\u003c/code\u003e ON THE NAS so I\u0026rsquo;m effectively just moving that file and not freeing up any space\u0026hellip;\u003c/p\u003e\n",
      "content_text": "\nFrom my daily driver Ubuntu machine I often open nautilus, dolphin, etc. and delete a file here or there on my NAS... turns out Ubuntu sends thse file to `.Trash-100` ON THE NAS so I'm effectively just moving that file and not freeing up any space...\n",
      "summary": "From my daily driver Ubuntu machine I often open nautilus, dolphin, etc. and delete a file here or there on my NAS... turns out Ubuntu sends thse file to ON...",
      "date_published": "2022-05-19T05:51:50Z",
      "date_modified": "2022-05-19T05:51:50Z",
      "authors": [
        {
          "name": "Nic Payne",
          "url": "https://pype.dev"
        }
      ],
      "tags": [
        "linux",
        "cli",
        "tech",
        "til"
      ]
    },
    {
      "id": "https://pype.dev/remove-zfs-dataset-specific-snapshots/",
      "url": "https://pype.dev/remove-zfs-dataset-specific-snapshots/",
      "title": "Remove ZFS Dataset Specific Snapshots",
      "content_html": "\u003cp\u003eI started my homelab journey being super naive about ZFS and how to manage the\nfilesystem\u0026hellip; that bit me in the butt when transfering a ton of files out of\nfolders and into datasets because ZFS is copy on write so I was essentially\nduplicating my storage until I got a hair smarter about removing files after\nthey\u0026rsquo;re moved (rsync \u0026ndash;remove-source-file ftw). But I had a ton of snapshots of\nchild datasets with a ton of data that I just never will need, so I learned\n\u003ccode\u003ezfs list -H -o name -t snapshot tank/dataset1/dataset2\u003c/code\u003e will list just the\nsnapshots for dataset2 and if you pipe that into \u003ccode\u003exargs -n1 zfs destroy\u003c/code\u003e then\nyou have a way to clear out some snapshots you don\u0026rsquo;t need!\u003c/p\u003e\n",
      "content_text": "\nI started my homelab journey being super naive about ZFS and how to manage the\nfilesystem... that bit me in the butt when transfering a ton of files out of\nfolders and into datasets because ZFS is copy on write so I was essentially\nduplicating my storage until I got a hair smarter about removing files after\nthey're moved (rsync --remove-source-file ftw). But I had a ton of snapshots of\nchild datasets with a ton of data that I just never will need, so I learned\n`zfs list -H -o name -t snapshot tank/dataset1/dataset2` will list just the\nsnapshots for dataset2 and if you pipe that into `xargs -n1 zfs destroy` then\nyou have a way to clear out some snapshots you don't need!\n",
      "summary": "I started my homelab journey being super naive about ZFS and how to manage the filesystem... that bit me in the butt when transfering a ton of files out of...",
      "date_published": "2022-05-19T05:49:16Z",
      "date_modified": "2022-05-19T05:49:16Z",
      "authors": [
        {
          "name": "Nic Payne",
          "url": "https://pype.dev"
        }
      ],
      "tags": [
        "linux",
        "zfs",
        "cli",
        "bash",
        "homelab",
        "til"
      ]
    },
    {
      "id": "https://pype.dev/file-length/",
      "url": "https://pype.dev/file-length/",
      "title": "File-Length",
      "content_html": "\u003cp\u003eI have a specific need for counting the number of lines in a file quickly.\nAt work we use S3 for data storage during our Kedro pipeline development, and in the development process we may end up orphaning several datasets.\nIn order to keep our workspace clean I have a short utility that compares the datasets in a Kedro DataCatalog with the files in the relevant S3 location.\u003c/p\u003e\n\u003cp\u003eTo get that list I run an internal tool like this:\u003c/p\u003e\n\u003cpre class=\"chroma\"\u003e\u003ccode\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ekedro our-liter \u003cspan class=\"p\"\u003e|\u003c/span\u003e grep s3 \u0026gt;\u0026gt; orphaned_datasets.txt\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003cp\u003eThis simply parses our internal linter for the lines releated to my s3 linter utility and pipes those lines to a file.\u003c/p\u003e\n\u003cp\u003eTo get a quick idea of how out of wack a pipeline is I could open the text file in vim, git it with the \u003ccode\u003eG\u003c/code\u003e and see what line number I\u0026rsquo;m on but I\u0026rsquo;m way too lazy for that\u0026hellip;\u003c/p\u003e\n\u003ch2 id=\"awk\"\u003e\u003cspan class=\"heading-wear-glyph\"\u003eAWK\u003c/span\u003e \u003ca href=\"#awk\" class=\"heading-anchor\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003e\u003ccode\u003eawk 'END {print NR}' orphaned_datasets.txt\u003c/code\u003e gives me the number of lines and I can alias this to whatever feels appropriate in my \u003ccode\u003ezshrc\u003c/code\u003e!\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003ebuilt-ins for the win!\u003c/strong\u003e\u003c/p\u003e\n",
      "content_text": "\nI have a specific need for counting the number of lines in a file quickly.\nAt work we use S3 for data storage during our Kedro pipeline development, and in the development process we may end up orphaning several datasets.\nIn order to keep our workspace clean I have a short utility that compares the datasets in a Kedro DataCatalog with the files in the relevant S3 location.\n\nTo get that list I run an internal tool like this:\n\n```bash\nkedro our-liter | grep s3 \u003e\u003e orphaned_datasets.txt\n```\n\nThis simply parses our internal linter for the lines releated to my s3 linter utility and pipes those lines to a file.\n\nTo get a quick idea of how out of wack a pipeline is I could open the text file in vim, git it with the `G` and see what line number I'm on but I'm way too lazy for that...\n\n## AWK\n\n`awk 'END {print NR}' orphaned_datasets.txt` gives me the number of lines and I can alias this to whatever feels appropriate in my `zshrc`!\n\n__built-ins for the win!__\n",
      "summary": "I have a specific need for counting the number of lines in a file quickly. At work we use S3 for data storage during our Kedro pipeline development, and in...",
      "date_published": "2022-04-04T00:00:00Z",
      "date_modified": "2022-04-04T00:00:00Z",
      "authors": [
        {
          "name": "Nic Payne",
          "url": "https://pype.dev"
        }
      ],
      "tags": [
        "linux",
        "tech",
        "til"
      ]
    },
    {
      "id": "https://pype.dev/polybar-01/",
      "url": "https://pype.dev/polybar-01/",
      "title": "Polybar-01",
      "content_html": "\u003cp\u003e\u003ca href=\"https://github.com/polybar/polybar\"\u003epolybar\u003c/a\u003e is an awesome and super customizable status bar for your desktop environment.\u003c/p\u003e\n\u003cp\u003eI use it with i3-gaps on Ubuntu for work and it makes my day just that much better to have a clean and elegant bar with the things in it that I care about.\u003c/p\u003e\n\u003cp\u003eThe GitHub has all the instructions you\u0026rsquo;d need to install and get started with an example.\u003c/p\u003e\n\u003cp\u003eI want to make some notes about how I use polybar and customize it.\u003c/p\u003e\n\u003ch2 id=\"organization\"\u003e\u003cspan class=\"heading-wear-glyph\"\u003eOrganization\u003c/span\u003e \u003ca href=\"#organization\" class=\"heading-anchor\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eFirst of all, I recently moved my polybar config out of one config file into a modular structure that keeps my config files small and easiser to edit.\u003c/p\u003e\n\u003cp\u003eYou can find my config \u003ca href=\"https://github.com/nicpayne713/dotfiles/tree/main/polybar\"\u003ehere\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003eThe apps or services you put into polybar are called \u003ccode\u003emodules\u003c/code\u003e.\nI have moved all of my modules into their own config files and I source them with one centralized \u003ccode\u003einclude-modules.ini\u003c/code\u003e config.\u003c/p\u003e\n\u003cp\u003eThis separation also makes it easier for me to keep my home and work polybars as in sync as possible without duplicating a ton of config!\u003c/p\u003e\n\u003cpre class=\"chroma\"\u003e\u003ccode\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e./polybar\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e├── colors.ini\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e├── config.ini\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e├── fonts.ini\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e├── home-modules.ini\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e├── include-modules.ini\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e├── launch.sh\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e├── modules\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e│   ├── aws.ini\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e│   ├── battery.ini\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e│   ├── bluetooth.ini\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e│   ├── cisco.ini\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e│   ├── cpu.ini\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e│   ├── date.ini\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e│   ├── eth.ini\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e│   ├── eth_work.ini\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e│   ├── i3.ini\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e│   ├── memory.ini\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e│   ├── nm-editor.ini\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e│   ├── powermenu.ini\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e│   ├── pulseaudio-control.ini\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e│   ├── pulseaudio.ini\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e│   ├── rofi.ini\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e│   ├── vpn.ini\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e│   └── wlan.ini\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e└── work-modules.ini\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"m\"\u003e1\u003c/span\u003e directory, \u003cspan class=\"m\"\u003e24\u003c/span\u003e files\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003cp\u003eTo break this down there are several configs to see:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\u003ccode\u003ecolors.ini\u003c/code\u003e is what you\u0026rsquo;d expect - a set of defined colors like \u003ccode\u003eforeground\u003c/code\u003e, \u003ccode\u003eunderline\u003c/code\u003e, etc.\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003econfig.ini\u003c/code\u003e is the general polybar config file where bars are defined. Currently in mine there is a \u003ccode\u003ework\u003c/code\u003e and \u003ccode\u003ehome\u003c/code\u003e bar defined with the modules sourced in from the explicit config files.\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003efonts.ini \u003c/code\u003e is like \u003ccode\u003ecolors.ini\u003c/code\u003e -\u0026gt; you put fonts here. I recommend using a font patched with NerdFont so you get fancy icons! (I use JetBrains Mono)\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003einclude-modules.ini\u003c/code\u003e is where I list out all the config files in \u003ccode\u003emodules/\u003c/code\u003e so I can basically source just the \u003ccode\u003einclude-modules.ini\u003c/code\u003e without explicitly sourcing every module\u0026rsquo;s config in every polybar defintion.\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003elaunch.sh\u003c/code\u003e is a simple shell script to launch the polybar! You\u0026rsquo;ll see mine takes multiple monitors into consideration which I manage via environment variables setup in my \u003ccode\u003e.zshenv\u003c/code\u003e file that is different for my work and home setups.\u003c/li\u003e\n\u003cli\u003eFinally there are \u003ccode\u003ehome-modules.ini\u003c/code\u003e and \u003ccode\u003ework-modules.ini\u003c/code\u003e which is where, for each of my bars, I define which modules I want!\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch2 id=\"config\"\u003e\u003cspan class=\"heading-wear-glyph\"\u003eConfig\u003c/span\u003e \u003ca href=\"#config\" class=\"heading-anchor\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eMy \u003ccode\u003econfig.ini\u003c/code\u003e file has 2 bar definitions in it - here\u0026rsquo;s my home one:\u003c/p\u003e\n\u003cpre class=\"chroma\"\u003e\u003ccode\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"na\"\u003einclude-file\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s\"\u003e$DOTFILES/polybar/include-modules.ini\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003e[bar/home]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"na\"\u003emonitor\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s\"\u003e${env:MONITOR:}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"na\"\u003ewidth\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s\"\u003e100%\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"na\"\u003eheight\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s\"\u003e25\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"na\"\u003eradius\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s\"\u003e8.0\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"na\"\u003efixed-center\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s\"\u003etrue\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"na\"\u003ebottom\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s\"\u003efalse\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"na\"\u003ebackground\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s\"\u003e${colors.background}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"na\"\u003eforeground\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s\"\u003e${colors.foreground}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"na\"\u003einclude-file\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s\"\u003e$DOTFILES/polybar/fonts.ini\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"na\"\u003einclude-file\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s\"\u003e$DOTFILES/polybar/home-modules.ini\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003cp\u003eIt should be easy to follow - I bring in the \u003ccode\u003einclude-modules\u003c/code\u003e, set a few colors for the bar like \u003ccode\u003ebackground\u003c/code\u003e and \u003ccode\u003eforeground\u003c/code\u003e which are sourced by the \u003ccode\u003ecolors.ini\u003c/code\u003e, and finally bring in my fonts and home modules via their config files!\u003c/p\u003e\n\u003cp\u003eIt\u0026rsquo;s super easy to then change one or two things in the appropriate places rather than combing through one massive config. This also makes it easy for me to seperate my work and home setups.\u003c/p\u003e\n\u003ch2 id=\"modules\"\u003e\u003cspan class=\"heading-wear-glyph\"\u003eModules\u003c/span\u003e \u003ca href=\"#modules\" class=\"heading-anchor\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eThere are several builtin modules, like \u003ccode\u003ewlan\u003c/code\u003e which gives your wifi status right there in polybar.\u003c/p\u003e\n\u003cp\u003eYou can also make custom ones.\nA big-time custom one for me is an indicator of whether or not I have an active AWS token for working with the \u003ccode\u003eaws\u003c/code\u003e cli.\u003c/p\u003e\n\u003cp\u003eThis is defined in\u003ccode\u003e modules/aws.ini\u003c/code\u003e and it looks like this:\u003c/p\u003e\n\u003cpre class=\"chroma\"\u003e\u003ccode\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003e[module/aws]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"na\"\u003einterval\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s\"\u003e5.0\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"na\"\u003etype\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s\"\u003ecustom/script\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"na\"\u003eexec\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s\"\u003ehas_aws_token\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"na\"\u003eclick-left\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s\"\u003e$HOME/.local/bin/auto_get_aws_token\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"na\"\u003eclick-right\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s\"\u003erm -rf ~/.aws/credentials\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003cp\u003eEvery \u003ccode\u003e5\u003c/code\u003e seconds my \u003ccode\u003ehas_aws_token\u003c/code\u003e script is ran.\nThat script looks like this:\u003c/p\u003e\n\u003cpre class=\"chroma\"\u003e\u003ccode\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#!/bin/bash\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003esource\u003c/span\u003e auto_proxy\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eaws sts get-caller-identity \u003cspan class=\"p\"\u003e\u0026amp;\u003c/span\u003e\u0026gt; /dev/null \u003cspan class=\"o\"\u003e\u0026amp;\u0026amp;\u003c/span\u003e \u003cspan class=\"nb\"\u003eecho\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;%{T5}%{F#00ff00}  %{F-}%{T-}\u0026#34;\u003c/span\u003e  \u003cspan class=\"o\"\u003e||(\u003c/span\u003e \u003cspan class=\"nb\"\u003eecho\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;%{T5}%{F#ff0000} %{F-}%{T-}\u0026#34;\u003c/span\u003e \u003cspan class=\"o\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003cp\u003eSee how the script echos out a colored icon to indicate the status of my token -\u0026gt; that icon is displayed in the polybar so I have real-time (5 second latency) status of whether or not I can do things in my AWS environment.\u003c/p\u003e\n\u003cp\u003eIn the module I also configured actions for \u003ccode\u003eclick-left\u003c/code\u003e and \u003ccode\u003eclick-right\u003c/code\u003e which are as straight forward as could be.\u003c/p\u003e\n\u003ch2 id=\"my-issues-with-i3\"\u003e\u003cspan class=\"heading-wear-glyph\"\u003eMy issues with i3\u003c/span\u003e \u003ca href=\"#my-issues-with-i3\" class=\"heading-anchor\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eThere\u0026rsquo;s a few things to be considerate of if you use \u003ccode\u003ei3\u003c/code\u003e such as needing a workaround for a centered bar that \u003cstrong\u003eis not\u003c/strong\u003e the full width of the monitor.\nPolybar can look really nice by not taking up the full width of the bar which you can configure in \u003ccode\u003econfig.ini\u003c/code\u003e with these options:\u003c/p\u003e\n\u003cpre class=\"chroma\"\u003e\u003ccode\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"na\"\u003ewidth\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s\"\u003e90%\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"na\"\u003eoffset-x\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s\"\u003e5%  # set to (100 - width) / 2\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003cp\u003eHowever due to an issue with polybar and i3 you need to also set \u003ccode\u003eoverride-redirect = true\u003c/code\u003e.\nBUT then you\u0026rsquo;ll notice that the bar overlaps your i3 windows\u0026hellip; ARGH! what do we do?\u003c/p\u003e\n\u003cp\u003eQuick work around is to set \u003ccode\u003egaps top\u003c/code\u003e in your i3 config if you use i3-gaps\u0026hellip; if not? well, idk\u0026hellip; use gaps\u0026hellip; lol\u003c/p\u003e\n\u003cp\u003eHowever this introduces another issue - which is then full screen windows will  have polybar sitting on top of them\u0026hellip;\u003c/p\u003e\n\u003cp\u003eThis isn\u0026rsquo;t necessarily a deal breaker, but for me it\u0026rsquo;s worth it to just have the bar go 100% width.\u003c/p\u003e\n\u003ch2 id=\"fin\"\u003e\u003cspan class=\"heading-wear-glyph\"\u003eFIN\u003c/span\u003e \u003ca href=\"#fin\" class=\"heading-anchor\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eThere\u0026rsquo;s a tiny intro to polybar and how I organize my config files so things are easy to edit and manage!\nFeel free to grab mine and try it out!\u003c/p\u003e\n",
      "content_text": "\n[polybar](https://github.com/polybar/polybar) is an awesome and super customizable status bar for your desktop environment.\n\nI use it with i3-gaps on Ubuntu for work and it makes my day just that much better to have a clean and elegant bar with the things in it that I care about.\n\nThe GitHub has all the instructions you'd need to install and get started with an example.\n\nI want to make some notes about how I use polybar and customize it.\n\n## Organization\n\nFirst of all, I recently moved my polybar config out of one config file into a modular structure that keeps my config files small and easiser to edit.\n\nYou can find my config [here](https://github.com/nicpayne713/dotfiles/tree/main/polybar)\n\nThe apps or services you put into polybar are called `modules`.\nI have moved all of my modules into their own config files and I source them with one centralized `include-modules.ini` config.\n\nThis separation also makes it easier for me to keep my home and work polybars as in sync as possible without duplicating a ton of config!\n\n```bash\n./polybar\n├── colors.ini\n├── config.ini\n├── fonts.ini\n├── home-modules.ini\n├── include-modules.ini\n├── launch.sh\n├── modules\n│   ├── aws.ini\n│   ├── battery.ini\n│   ├── bluetooth.ini\n│   ├── cisco.ini\n│   ├── cpu.ini\n│   ├── date.ini\n│   ├── eth.ini\n│   ├── eth_work.ini\n│   ├── i3.ini\n│   ├── memory.ini\n│   ├── nm-editor.ini\n│   ├── powermenu.ini\n│   ├── pulseaudio-control.ini\n│   ├── pulseaudio.ini\n│   ├── rofi.ini\n│   ├── vpn.ini\n│   └── wlan.ini\n└── work-modules.ini\n\n1 directory, 24 files\n```\n\nTo break this down there are several configs to see:\n\n1. `colors.ini` is what you'd expect - a set of defined colors like `foreground`, `underline`, etc.\n2. `config.ini` is the general polybar config file where bars are defined. Currently in mine there is a `work` and `home` bar defined with the modules sourced in from the explicit config files.\n3. `fonts.ini ` is like `colors.ini` -\u003e you put fonts here. I recommend using a font patched with NerdFont so you get fancy icons! (I use JetBrains Mono)\n4. `include-modules.ini` is where I list out all the config files in `modules/` so I can basically source just the `include-modules.ini` without explicitly sourcing every module's config in every polybar defintion.\n5. `launch.sh` is a simple shell script to launch the polybar! You'll see mine takes multiple monitors into consideration which I manage via environment variables setup in my `.zshenv` file that is different for my work and home setups.\n6. Finally there are `home-modules.ini` and `work-modules.ini` which is where, for each of my bars, I define which modules I want!\n\n## Config\n\nMy `config.ini` file has 2 bar definitions in it - here's my home one:\n\n```ini\ninclude-file = $DOTFILES/polybar/include-modules.ini\n\n[bar/home]\nmonitor = ${env:MONITOR:}\nwidth = 100%\nheight = 25\nradius = 8.0\nfixed-center = true\nbottom = false\n\nbackground = ${colors.background}\nforeground = ${colors.foreground}\n\ninclude-file = $DOTFILES/polybar/fonts.ini\ninclude-file = $DOTFILES/polybar/home-modules.ini\n```\n\nIt should be easy to follow - I bring in the `include-modules`, set a few colors for the bar like `background` and `foreground` which are sourced by the `colors.ini`, and finally bring in my fonts and home modules via their config files!\n\nIt's super easy to then change one or two things in the appropriate places rather than combing through one massive config. This also makes it easy for me to seperate my work and home setups.\n\n\n## Modules\n\nThere are several builtin modules, like `wlan` which gives your wifi status right there in polybar.\n\nYou can also make custom ones. \nA big-time custom one for me is an indicator of whether or not I have an active AWS token for working with the `aws` cli.\n\nThis is defined in` modules/aws.ini` and it looks like this:\n\n```ini\n[module/aws]\ninterval = 5.0\ntype = custom/script\nexec = has_aws_token\nclick-left = $HOME/.local/bin/auto_get_aws_token\nclick-right = rm -rf ~/.aws/credentials\n```\n\nEvery `5` seconds my `has_aws_token` script is ran.\nThat script looks like this:\n\n```bash\n#!/bin/bash\nsource auto_proxy\naws sts get-caller-identity \u0026\u003e /dev/null \u0026\u0026 echo \"%{T5}%{F#00ff00}  %{F-}%{T-}\"  ||( echo \"%{T5}%{F#ff0000} %{F-}%{T-}\" )\n```\n\nSee how the script echos out a colored icon to indicate the status of my token -\u003e that icon is displayed in the polybar so I have real-time (5 second latency) status of whether or not I can do things in my AWS environment.\n\nIn the module I also configured actions for `click-left` and `click-right` which are as straight forward as could be.\n\n## My issues with i3\n\n\nThere's a few things to be considerate of if you use `i3` such as needing a workaround for a centered bar that __is not__ the full width of the monitor.\nPolybar can look really nice by not taking up the full width of the bar which you can configure in `config.ini` with these options:\n\n```ini\nwidth = 90%\noffset-x = 5%  # set to (100 - width) / 2\n```\n\nHowever due to an issue with polybar and i3 you need to also set `override-redirect = true`. \nBUT then you'll notice that the bar overlaps your i3 windows... ARGH! what do we do?\n\nQuick work around is to set `gaps top` in your i3 config if you use i3-gaps... if not? well, idk... use gaps... lol\n\nHowever this introduces another issue - which is then full screen windows will  have polybar sitting on top of them...\n\nThis isn't necessarily a deal breaker, but for me it's worth it to just have the bar go 100% width.\n\n\n## FIN\n\nThere's a tiny intro to polybar and how I organize my config files so things are easy to edit and manage!\nFeel free to grab mine and try it out!\n",
      "summary": "polybar is an awesome and super customizable status bar for your desktop environment.",
      "date_published": "2022-04-01T00:00:00Z",
      "date_modified": "2022-04-01T00:00:00Z",
      "authors": [
        {
          "name": "Nic Payne",
          "url": "https://pype.dev"
        }
      ],
      "tags": [
        "linux",
        "tech"
      ]
    },
    {
      "id": "https://pype.dev/starship/",
      "url": "https://pype.dev/starship/",
      "title": "Starship",
      "content_html": "\u003cp\u003eIf you spend time in the terminal then you\u0026rsquo;ll want it to look somewhat pleasing to the eye.\nI used to ssh into servers with no customization, use \u003ccode\u003evi\u003c/code\u003e  to edit a file or two, then get back to my regularly scheduled programming in VS C**e\u0026hellip;\u003c/p\u003e\n\u003cp\u003eOne of the first steps for me loving my terminal was a beautiful prompt\u0026hellip;\u003c/p\u003e\n\u003ch2 id=\"prompt\"\u003e\u003cspan class=\"heading-wear-glyph\"\u003ePrompt\u003c/span\u003e \u003ca href=\"#prompt\" class=\"heading-anchor\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eThe default sh/bash/zsh prompts are\u0026hellip; to put it lightly\u0026hellip; garbage\u0026hellip; I can\u0026rsquo;t speak for other shells like fish simply because I do not use them but let me justify my trash talk.\u003c/p\u003e\n\u003cp\u003eHere\u0026rsquo;s the default \u003ccode\u003esh\u003c/code\u003e prompt\u0026hellip;\u003c/p\u003e\n\u003cimg src=\"https://cdn.statically.io/gh/pypeaday/images.pype.dev/main/blog-media/sh-prompt.png\" alt=\"sh\" title=\"A default sh prompt\" /\u003e\n\u003cp\u003eThen switching to \u003ccode\u003ezsh\u003c/code\u003e you get something marginally better (plus tab completion!)\u003c/p\u003e\n\u003cimg src=\"https://cdn.statically.io/gh/pypeaday/images.pype.dev/main/blog-media/zsh-prompt.png\" alt=\"zsh\" title=\"A default zsh prompt\" /\u003e\n\u003cp\u003eBut this still is super gross\u0026hellip; there\u0026rsquo;s nothing to indicate file types and no status information readily available (ie. \u003ccode\u003egit status\u003c/code\u003e etc.)\u003c/p\u003e\n\u003ch2 id=\"oh-my-zsh\"\u003e\u003cspan class=\"heading-wear-glyph\"\u003eOh-My-Zsh!\u003c/span\u003e \u003ca href=\"#oh-my-zsh\" class=\"heading-anchor\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003eNow there are several ways to make your prmompt nicer depending on your shell (terminal emulator plays a role too).\nNow I use \u003ccode\u003ezsh\u003c/code\u003e and there\u0026rsquo;s a great tool out there \u003ca href=\"https://ohmyz.sh/\"\u003eoh-my-zsh\u003c/a\u003e that brings a crazy amount of customization to the terminal experience.\u003c/p\u003e\n\u003cp\u003eI do not use \u003ccode\u003eoh-my-zsh\u003c/code\u003e for theming though and that\u0026rsquo;s simply because of my other choices - I use \u003ccode\u003ekitty\u003c/code\u003e themes since I understood the implementation better.\nKitty themes though - do not give me a nice prompt.\u003c/p\u003e\n\u003cp\u003eThe default prompt you get with \u003ccode\u003eoh-my-zsh\u003c/code\u003e themes isn\u0026rsquo;t bad though (and you can pick from several default themes)\u0026hellip;\u003c/p\u003e\n\u003cimg src=\"https://cdn.statically.io/gh/pypeaday/images.pype.dev/main/blog-media/zsh-oh-my-zsh-prompt.png\" alt=\"omz\" title=\"A default oh-my-zsh prompt\" /\u003e\n\u003cp\u003eNotice that you get some nice coloring and some default \u003ccode\u003egit\u003c/code\u003e status stuff, mainly the branch you are on.\nThere\u0026rsquo;s plugins to show you more and that\u0026rsquo;s all well and good, but again it\u0026rsquo;s not my choice\u0026hellip;\u003c/p\u003e\n\u003cp\u003eIf I don\u0026rsquo;t use this then what\u0026rsquo;s my goto?\u003c/p\u003e\n\u003ch2 id=\"starship\"\u003e\u003cspan class=\"heading-wear-glyph\"\u003eStarship\u003c/span\u003e \u003ca href=\"#starship\" class=\"heading-anchor\"\u003e#\u003c/a\u003e\u003c/h2\u003e\n\u003cp\u003e\u003ca href=\"https://starship.rs/\"\u003estarship\u003c/a\u003e is a cross-shell prompt with nice default and super easy customizaton!\u003c/p\u003e\n\u003cp\u003eTo get started click that link and follow the \u0026ldquo;Getting Started\u0026rdquo; button - it\u0026rsquo;s incredibly fast to get up and running with sane defaults.\u003c/p\u003e\n\u003cp\u003eThe default starship config is plenty nice but I got a little tired of emojis in my prompt and wanted to switch to icons instead\u0026hellip;\u003c/p\u003e\n\u003cp\u003eTo get started with your own customizaton you add a \u003ccode\u003estarship.toml\u003c/code\u003e file to \u003ccode\u003e~/.config\u003c/code\u003e\nMy starship config is found \u003ca href=\"https://github.com/nicpayne713/dotfiles/blob/main/starship/.config/starship.toml\"\u003ehere\u003c/a\u003e.\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003eNote you need a font installed patched with nerdfonts - I use JetBrains Mono\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003eNow I have a beautiful prompt with relevant information that\u0026rsquo;s a dream to look at!\u003c/p\u003e\n\u003cimg src=\"https://cdn.statically.io/gh/pypeaday/images.pype.dev/main/blog-media/zsh-starship-prompt.png\" alt=\"starship\" title=\"A starship prompt\" /\u003e\n\u003cp\u003eI have configured my starship to show me relevant \u003ccode\u003egit status\u003c/code\u003e options (stashes, untracked files, etc etc.)\nI also have starship show me if I\u0026rsquo;m in a git repo, what branch I\u0026rsquo;m on, if I\u0026rsquo;m in a python project and if so what virtual environment is active.\nI do some work in AWS at work and so I have starship show me if my \u003ccode\u003eaws cli\u003c/code\u003e is configured to the right region for whichever project I\u0026rsquo;m in!\u003c/p\u003e\n\u003cp\u003eThere\u0026rsquo;s a billion more options and after a few minutes of play it becomes really easy and intuitive to customize colors, icons, etc.\u003c/p\u003e\n",
      "content_text": "\nIf you spend time in the terminal then you'll want it to look somewhat pleasing to the eye.\nI used to ssh into servers with no customization, use `vi`  to edit a file or two, then get back to my regularly scheduled programming in VS C**e...\n\nOne of the first steps for me loving my terminal was a beautiful prompt... \n\n## Prompt\n\nThe default sh/bash/zsh prompts are... to put it lightly... garbage... I can't speak for other shells like fish simply because I do not use them but let me justify my trash talk.\n\nHere's the default `sh` prompt...\n\n\n\u003cimg src=\"https://cdn.statically.io/gh/pypeaday/images.pype.dev/main/blog-media/sh-prompt.png\" alt=\"sh\" title=\"A default sh prompt\" /\u003e\n\n\nThen switching to `zsh` you get something marginally better (plus tab completion!)\n\n\u003cimg src=\"https://cdn.statically.io/gh/pypeaday/images.pype.dev/main/blog-media/zsh-prompt.png\" alt=\"zsh\" title=\"A default zsh prompt\" /\u003e\n\nBut this still is super gross... there's nothing to indicate file types and no status information readily available (ie. `git status` etc.)\n\n## Oh-My-Zsh!\n\nNow there are several ways to make your prmompt nicer depending on your shell (terminal emulator plays a role too).\nNow I use `zsh` and there's a great tool out there [oh-my-zsh](https://ohmyz.sh/) that brings a crazy amount of customization to the terminal experience.\n\nI do not use `oh-my-zsh` for theming though and that's simply because of my other choices - I use `kitty` themes since I understood the implementation better.\nKitty themes though - do not give me a nice prompt.\n\nThe default prompt you get with `oh-my-zsh` themes isn't bad though (and you can pick from several default themes)...\n\n\u003cimg src=\"https://cdn.statically.io/gh/pypeaday/images.pype.dev/main/blog-media/zsh-oh-my-zsh-prompt.png\" alt=\"omz\" title=\"A default oh-my-zsh prompt\" /\u003e\n\nNotice that you get some nice coloring and some default `git` status stuff, mainly the branch you are on.\nThere's plugins to show you more and that's all well and good, but again it's not my choice...\n\nIf I don't use this then what's my goto?\n\n## Starship\n\n[starship](https://starship.rs/) is a cross-shell prompt with nice default and super easy customizaton!\n\nTo get started click that link and follow the \"Getting Started\" button - it's incredibly fast to get up and running with sane defaults.\n\nThe default starship config is plenty nice but I got a little tired of emojis in my prompt and wanted to switch to icons instead...\n\nTo get started with your own customizaton you add a `starship.toml` file to `~/.config` \nMy starship config is found [here](https://github.com/nicpayne713/dotfiles/blob/main/starship/.config/starship.toml).\n\n\u003eNote you need a font installed patched with nerdfonts - I use JetBrains Mono\n\nNow I have a beautiful prompt with relevant information that's a dream to look at!\n\n\u003cimg src=\"https://cdn.statically.io/gh/pypeaday/images.pype.dev/main/blog-media/zsh-starship-prompt.png\" alt=\"starship\" title=\"A starship prompt\" /\u003e\n\nI have configured my starship to show me relevant `git status` options (stashes, untracked files, etc etc.)\nI also have starship show me if I'm in a git repo, what branch I'm on, if I'm in a python project and if so what virtual environment is active.\nI do some work in AWS at work and so I have starship show me if my `aws cli` is configured to the right region for whichever project I'm in!\n\nThere's a billion more options and after a few minutes of play it becomes really easy and intuitive to customize colors, icons, etc.\n",
      "summary": "If you spend time in the terminal then you'll want it to look somewhat pleasing to the eye. I used to ssh into servers with no customization, use to edit a...",
      "date_published": "2022-03-25T00:00:00Z",
      "date_modified": "2022-03-25T00:00:00Z",
      "authors": [
        {
          "name": "Nic Payne",
          "url": "https://pype.dev"
        }
      ],
      "tags": [
        "linux",
        "tech"
      ]
    },
    {
      "id": "https://pype.dev/tree/",
      "url": "https://pype.dev/tree/",
      "title": "Tree",
      "content_html": "\u003cp\u003eI wanted a quick way to generate an \u003ccode\u003eindex.html\u003c/code\u003e for a directory of html files that grows by 1 or 2 files a week.\nI don\u0026rsquo;t know any html (the files are exports from my \u003ca href=\"/tiddly-wiki\"\u003etiddlywiki\u003c/a\u003e)\u0026hellip;\u003c/p\u003e\n\u003cp\u003e\u003ccode\u003etree\u003c/code\u003e is just the answer.\u003c/p\u003e\n\u003cp\u003eSay I have a file structure like this:\u003c/p\u003e\n\u003cpre\u003e\u003ccode\u003e./html-files\n├── file1.html\n└── file2.html\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eTo generate a barebones simple \u003ccode\u003eindex.html\u003c/code\u003e we can use tree as follows:\u003c/p\u003e\n\u003cp\u003e\u003ccode\u003etree ./html-files -H \u0026quot;.\u0026quot; -L 1 -P \u0026quot;*.html\u0026quot;\u003c/code\u003e\u003c/p\u003e\n\u003cp\u003eand get the following:\u003c/p\u003e\n\u003cpre class=\"chroma\"\u003e\u003ccode\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e\u0026lt;!DOCTYPE html\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"nt\"\u003ehtml\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"nt\"\u003ehead\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"nt\"\u003emeta\u003c/span\u003e \u003cspan class=\"na\"\u003ehttp-equiv\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;Content-Type\u0026#34;\u003c/span\u003e \u003cspan class=\"na\"\u003econtent\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;text/html; charset=UTF-8\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"nt\"\u003emeta\u003c/span\u003e \u003cspan class=\"na\"\u003ename\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;Author\u0026#34;\u003c/span\u003e \u003cspan class=\"na\"\u003econtent\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;Made by \u0026#39;tree\u0026#39;\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"nt\"\u003emeta\u003c/span\u003e \u003cspan class=\"na\"\u003ename\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;GENERATOR\u0026#34;\u003c/span\u003e \u003cspan class=\"na\"\u003econtent\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;$Version: $ tree v1.8.0 (c) 1996 - 2018 by Steve Baker, Thomas Moore, Francesc Rocher, Florian Sesser, Kyosuke Tokoro $\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"nt\"\u003etitle\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026gt;\u003c/span\u003eDirectory Tree\u003cspan class=\"p\"\u003e\u0026lt;/\u003c/span\u003e\u003cspan class=\"nt\"\u003etitle\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"nt\"\u003estyle\u003c/span\u003e \u003cspan class=\"na\"\u003etype\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;text/css\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"o\"\u003e\u0026lt;!\u003c/span\u003e\u003cspan class=\"nt\"\u003e--\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"nt\"\u003eBODY\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e \u003cspan class=\"k\"\u003efont-family\u003c/span\u003e \u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"n\"\u003eariel\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kc\"\u003emonospace\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kc\"\u003esans-serif\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"nt\"\u003eP\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e \u003cspan class=\"k\"\u003efont-weight\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"kc\"\u003enormal\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"k\"\u003efont-family\u003c/span\u003e \u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"n\"\u003eariel\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kc\"\u003emonospace\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kc\"\u003esans-serif\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"k\"\u003ecolor\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"kc\"\u003eblack\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"k\"\u003ebackground-color\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"kc\"\u003etransparent\u003c/span\u003e\u003cspan class=\"p\"\u003e;}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"nt\"\u003eB\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e \u003cspan class=\"k\"\u003efont-weight\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"kc\"\u003enormal\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"k\"\u003ecolor\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"kc\"\u003eblack\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"k\"\u003ebackground-color\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"kc\"\u003etransparent\u003c/span\u003e\u003cspan class=\"p\"\u003e;}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"nt\"\u003eA\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"nd\"\u003evisited\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e \u003cspan class=\"k\"\u003efont-weight\u003c/span\u003e \u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"kc\"\u003enormal\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"k\"\u003etext-decoration\u003c/span\u003e \u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"kc\"\u003enone\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"k\"\u003ebackground-color\u003c/span\u003e \u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"kc\"\u003etransparent\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"k\"\u003emargin\u003c/span\u003e \u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"kt\"\u003epx\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"kt\"\u003epx\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"kt\"\u003epx\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"kt\"\u003epx\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"k\"\u003epadding\u003c/span\u003e \u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"kt\"\u003epx\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"kt\"\u003epx\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"kt\"\u003epx\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"kt\"\u003epx\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"k\"\u003edisplay\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"kc\"\u003einline\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"nt\"\u003eA\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"nd\"\u003elink\u003c/span\u003e    \u003cspan class=\"p\"\u003e{\u003c/span\u003e \u003cspan class=\"k\"\u003efont-weight\u003c/span\u003e \u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"kc\"\u003enormal\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"k\"\u003etext-decoration\u003c/span\u003e \u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"kc\"\u003enone\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"k\"\u003emargin\u003c/span\u003e \u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"kt\"\u003epx\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"kt\"\u003epx\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"kt\"\u003epx\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"kt\"\u003epx\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"k\"\u003epadding\u003c/span\u003e \u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"kt\"\u003epx\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"kt\"\u003epx\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"kt\"\u003epx\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"kt\"\u003epx\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"k\"\u003edisplay\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"kc\"\u003einline\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"nt\"\u003eA\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"nd\"\u003ehover\u003c/span\u003e   \u003cspan class=\"p\"\u003e{\u003c/span\u003e \u003cspan class=\"k\"\u003ecolor\u003c/span\u003e \u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"mh\"\u003e#000000\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"k\"\u003efont-weight\u003c/span\u003e \u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"kc\"\u003enormal\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"k\"\u003etext-decoration\u003c/span\u003e \u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"kc\"\u003eunderline\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"k\"\u003ebackground-color\u003c/span\u003e \u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"kc\"\u003eyellow\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"k\"\u003emargin\u003c/span\u003e \u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"kt\"\u003epx\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"kt\"\u003epx\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"kt\"\u003epx\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"kt\"\u003epx\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"k\"\u003epadding\u003c/span\u003e \u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"kt\"\u003epx\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"kt\"\u003epx\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"kt\"\u003epx\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"kt\"\u003epx\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"k\"\u003edisplay\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"kc\"\u003einline\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"nt\"\u003eA\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"nd\"\u003eactive\u003c/span\u003e  \u003cspan class=\"p\"\u003e{\u003c/span\u003e \u003cspan class=\"k\"\u003ecolor\u003c/span\u003e \u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"mh\"\u003e#000000\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"k\"\u003efont-weight\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"kc\"\u003enormal\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"k\"\u003ebackground-color\u003c/span\u003e \u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"kc\"\u003etransparent\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"k\"\u003emargin\u003c/span\u003e \u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"kt\"\u003epx\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"kt\"\u003epx\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"kt\"\u003epx\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"kt\"\u003epx\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"k\"\u003epadding\u003c/span\u003e \u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"kt\"\u003epx\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"kt\"\u003epx\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"kt\"\u003epx\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"kt\"\u003epx\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"k\"\u003edisplay\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"kc\"\u003einline\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nc\"\u003eVERSION\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e \u003cspan class=\"k\"\u003efont-size\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"kc\"\u003esmall\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"k\"\u003efont-family\u003c/span\u003e \u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"n\"\u003earial\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kc\"\u003esans-serif\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nc\"\u003eNORM\u003c/span\u003e  \u003cspan class=\"p\"\u003e{\u003c/span\u003e \u003cspan class=\"k\"\u003ecolor\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"kc\"\u003eblack\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e  \u003cspan class=\"k\"\u003ebackground-color\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"kc\"\u003etransparent\u003c/span\u003e\u003cspan class=\"p\"\u003e;}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nc\"\u003eFIFO\u003c/span\u003e  \u003cspan class=\"p\"\u003e{\u003c/span\u003e \u003cspan class=\"k\"\u003ecolor\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"kc\"\u003epurple\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"k\"\u003ebackground-color\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"kc\"\u003etransparent\u003c/span\u003e\u003cspan class=\"p\"\u003e;}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nc\"\u003eCHAR\u003c/span\u003e  \u003cspan class=\"p\"\u003e{\u003c/span\u003e \u003cspan class=\"k\"\u003ecolor\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"kc\"\u003eyellow\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"k\"\u003ebackground-color\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"kc\"\u003etransparent\u003c/span\u003e\u003cspan class=\"p\"\u003e;}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nc\"\u003eDIR\u003c/span\u003e   \u003cspan class=\"p\"\u003e{\u003c/span\u003e \u003cspan class=\"k\"\u003ecolor\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"kc\"\u003eblue\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e   \u003cspan class=\"k\"\u003ebackground-color\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"kc\"\u003etransparent\u003c/span\u003e\u003cspan class=\"p\"\u003e;}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nc\"\u003eBLOCK\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e \u003cspan class=\"k\"\u003ecolor\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"kc\"\u003eyellow\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"k\"\u003ebackground-color\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"kc\"\u003etransparent\u003c/span\u003e\u003cspan class=\"p\"\u003e;}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nc\"\u003eLINK\u003c/span\u003e  \u003cspan class=\"p\"\u003e{\u003c/span\u003e \u003cspan class=\"k\"\u003ecolor\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"kc\"\u003eaqua\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e   \u003cspan class=\"k\"\u003ebackground-color\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"kc\"\u003etransparent\u003c/span\u003e\u003cspan class=\"p\"\u003e;}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nc\"\u003eSOCK\u003c/span\u003e  \u003cspan class=\"p\"\u003e{\u003c/span\u003e \u003cspan class=\"k\"\u003ecolor\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"kc\"\u003efuchsia\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"k\"\u003ebackground-color\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"kc\"\u003etransparent\u003c/span\u003e\u003cspan class=\"p\"\u003e;}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nc\"\u003eEXEC\u003c/span\u003e  \u003cspan class=\"p\"\u003e{\u003c/span\u003e \u003cspan class=\"k\"\u003ecolor\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"kc\"\u003egreen\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e  \u003cspan class=\"k\"\u003ebackground-color\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"kc\"\u003etransparent\u003c/span\u003e\u003cspan class=\"p\"\u003e;}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"nt\"\u003e--\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e\u0026lt;/\u003c/span\u003e\u003cspan class=\"nt\"\u003estyle\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e\u0026lt;/\u003c/span\u003e\u003cspan class=\"nt\"\u003ehead\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"nt\"\u003ebody\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"p\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"nt\"\u003eh1\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026gt;\u003c/span\u003eDirectory Tree\u003cspan class=\"p\"\u003e\u0026lt;/\u003c/span\u003e\u003cspan class=\"nt\"\u003eh1\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026gt;\u0026lt;\u003c/span\u003e\u003cspan class=\"nt\"\u003ep\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"p\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"nt\"\u003ea\u003c/span\u003e \u003cspan class=\"na\"\u003ehref\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;.\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026gt;\u003c/span\u003e.\u003cspan class=\"p\"\u003e\u0026lt;/\u003c/span\u003e\u003cspan class=\"nt\"\u003ea\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026gt;\u0026lt;\u003c/span\u003e\u003cspan class=\"nt\"\u003ebr\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        ├── \u003cspan class=\"p\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"nt\"\u003ea\u003c/span\u003e \u003cspan class=\"na\"\u003ehref\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;./file1.html\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026gt;\u003c/span\u003efile1.html\u003cspan class=\"p\"\u003e\u0026lt;/\u003c/span\u003e\u003cspan class=\"nt\"\u003ea\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026gt;\u0026lt;\u003c/span\u003e\u003cspan class=\"nt\"\u003ebr\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        └── \u003cspan class=\"p\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"nt\"\u003ea\u003c/span\u003e \u003cspan class=\"na\"\u003ehref\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;./file2.html\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026gt;\u003c/span\u003efile2.html\u003cspan class=\"p\"\u003e\u0026lt;/\u003c/span\u003e\u003cspan class=\"nt\"\u003ea\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026gt;\u0026lt;\u003c/span\u003e\u003cspan class=\"nt\"\u003ebr\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"p\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"nt\"\u003ebr\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026gt;\u0026lt;\u003c/span\u003e\u003cspan class=\"nt\"\u003ebr\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"p\"\u003e\u0026lt;/\u003c/span\u003e\u003cspan class=\"nt\"\u003ep\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"p\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"nt\"\u003ep\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e0 directories, 2 files\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"p\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"nt\"\u003ebr\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026gt;\u0026lt;\u003c/span\u003e\u003cspan class=\"nt\"\u003ebr\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"p\"\u003e\u0026lt;/\u003c/span\u003e\u003cspan class=\"nt\"\u003ep\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"p\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"nt\"\u003ehr\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"p\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"nt\"\u003ep\u003c/span\u003e \u003cspan class=\"na\"\u003eclass\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;VERSION\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                 tree v1.8.0 © 1996 - 2018 by Steve Baker and Thomas Moore \u003cspan class=\"p\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"nt\"\u003ebr\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                 HTML output hacked and copyleft © 1998 by Francesc Rocher \u003cspan class=\"p\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"nt\"\u003ebr\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                 JSON output hacked and copyleft © 2014 by Florian Sesser \u003cspan class=\"p\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"nt\"\u003ebr\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                 Charsets / OS/2 support © 2001 by Kyosuke Tokoro\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"p\"\u003e\u0026lt;/\u003c/span\u003e\u003cspan class=\"nt\"\u003ep\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e\u0026lt;/\u003c/span\u003e\u003cspan class=\"nt\"\u003ebody\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e\u0026lt;/\u003c/span\u003e\u003cspan class=\"nt\"\u003ehtml\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003cp\u003ewhich \u003ca href=\"/tree-index-example.html\"\u003elooks like this\u003c/a\u003e when you serve it up with \u003ccode\u003epython -m http.server\u003c/code\u003e\u003c/p\u003e\n",
      "content_text": "\nI wanted a quick way to generate an `index.html` for a directory of html files that grows by 1 or 2 files a week.\nI don't know any html (the files are exports from my [tiddlywiki](/tiddly-wiki))...\n\n`tree` is just the answer.\n\nSay I have a file structure like this:\n\n```\n./html-files\n├── file1.html\n└── file2.html\n```\n\nTo generate a barebones simple `index.html` we can use tree as follows:\n\n`tree ./html-files -H \".\" -L 1 -P \"*.html\"`\n\nand get the following:\n\n```html\n\n\u003c!DOCTYPE html\u003e\n\u003chtml\u003e\n\u003chead\u003e\n \u003cmeta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\"\u003e\n \u003cmeta name=\"Author\" content=\"Made by 'tree'\"\u003e\n \u003cmeta name=\"GENERATOR\" content=\"$Version: $ tree v1.8.0 (c) 1996 - 2018 by Steve Baker, Thomas Moore, Francesc Rocher, Florian Sesser, Kyosuke Tokoro $\"\u003e\n \u003ctitle\u003eDirectory Tree\u003c/title\u003e\n \u003cstyle type=\"text/css\"\u003e\n  \u003c!--\n  BODY { font-family : ariel, monospace, sans-serif; }\n  P { font-weight: normal; font-family : ariel, monospace, sans-serif; color: black; background-color: transparent;}\n  B { font-weight: normal; color: black; background-color: transparent;}\n  A:visited { font-weight : normal; text-decoration : none; background-color : transparent; margin : 0px 0px 0px 0px; padding : 0px 0px 0px 0px; display: inline; }\n  A:link    { font-weight : normal; text-decoration : none; margin : 0px 0px 0px 0px; padding : 0px 0px 0px 0px; display: inline; }\n  A:hover   { color : #000000; font-weight : normal; text-decoration : underline; background-color : yellow; margin : 0px 0px 0px 0px; padding : 0px 0px 0px 0px; display: inline; }\n  A:active  { color : #000000; font-weight: normal; background-color : transparent; margin : 0px 0px 0px 0px; padding : 0px 0px 0px 0px; display: inline; }\n  .VERSION { font-size: small; font-family : arial, sans-serif; }\n  .NORM  { color: black;  background-color: transparent;}\n  .FIFO  { color: purple; background-color: transparent;}\n  .CHAR  { color: yellow; background-color: transparent;}\n  .DIR   { color: blue;   background-color: transparent;}\n  .BLOCK { color: yellow; background-color: transparent;}\n  .LINK  { color: aqua;   background-color: transparent;}\n  .SOCK  { color: fuchsia;background-color: transparent;}\n  .EXEC  { color: green;  background-color: transparent;}\n  --\u003e\n \u003c/style\u003e\n\u003c/head\u003e\n\u003cbody\u003e\n        \u003ch1\u003eDirectory Tree\u003c/h1\u003e\u003cp\u003e\n        \u003ca href=\".\"\u003e.\u003c/a\u003e\u003cbr\u003e\n        ├── \u003ca href=\"./file1.html\"\u003efile1.html\u003c/a\u003e\u003cbr\u003e\n        └── \u003ca href=\"./file2.html\"\u003efile2.html\u003c/a\u003e\u003cbr\u003e\n        \u003cbr\u003e\u003cbr\u003e\n        \u003c/p\u003e\n        \u003cp\u003e\n\n0 directories, 2 files\n        \u003cbr\u003e\u003cbr\u003e\n        \u003c/p\u003e\n        \u003chr\u003e\n        \u003cp class=\"VERSION\"\u003e\n                 tree v1.8.0 © 1996 - 2018 by Steve Baker and Thomas Moore \u003cbr\u003e\n                 HTML output hacked and copyleft © 1998 by Francesc Rocher \u003cbr\u003e\n                 JSON output hacked and copyleft © 2014 by Florian Sesser \u003cbr\u003e\n                 Charsets / OS/2 support © 2001 by Kyosuke Tokoro\n        \u003c/p\u003e\n\u003c/body\u003e\n\u003c/html\u003e\n\n```\n\n\nwhich [looks like this](/tree-index-example.html) when you serve it up with `python -m http.server`\n",
      "summary": "I wanted a quick way to generate an for a directory of html files that grows by 1 or 2 files a week. I don't know any html (the files are exports from my...",
      "date_published": "2022-03-06T00:00:00Z",
      "date_modified": "2022-03-06T00:00:00Z",
      "authors": [
        {
          "name": "Nic Payne",
          "url": "https://pype.dev"
        }
      ],
      "tags": [
        "linux",
        "tech",
        "til"
      ]
    },
    {
      "id": "https://pype.dev/stow/",
      "url": "https://pype.dev/stow/",
      "title": "Stow",
      "content_html": "\u003cp\u003eStow is a great tool for managing dotfiles. My usage looks like cloning my dotfiles to my home directory, setting some environment variables via a script, then stowing relevant packages and boom my config is good to go\u0026hellip;\u003c/p\u003e\n\u003cpre class=\"chroma\"\u003e\u003ccode\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003ecd\u003c/span\u003e ~\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egit clone \u0026lt;my dotfiles repo\u0026gt;\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003ecd\u003c/span\u003e dotfiles\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# env variable stuff ignored here\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003estow zsh  \u003cspan class=\"c1\"\u003e# This will symlink my .zshrc file which is in ~/dotfiles/zsh to ~/.zshrc\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003cp\u003eBy default stow will stow packages up one directory from the root directory.\nIn this example the root directory is \u003ccode\u003e~/dotfiles\u003c/code\u003e and the package is \u003ccode\u003ezsh\u003c/code\u003e.\nSo the files in the \u003ccode\u003ezsh\u003c/code\u003e package will symlinked into \u003ccode\u003e~/\u003c/code\u003e.\u003c/p\u003e\n\u003cp\u003e\u003ccode\u003estow\u003c/code\u003e makes it easy to share dotfiles across machines, or safely experiment with config changes while always being protected by \u003ccode\u003egit\u003c/code\u003e since your dotfiles are in a git repo!\n\u0026hellip;They are in a git repo\u0026hellip; right?\u003c/p\u003e\n",
      "content_text": "\nStow is a great tool for managing dotfiles. My usage looks like cloning my dotfiles to my home directory, setting some environment variables via a script, then stowing relevant packages and boom my config is good to go...\n\n```bash\ncd ~\ngit clone \u003cmy dotfiles repo\u003e\ncd dotfiles\n# env variable stuff ignored here\nstow zsh  # This will symlink my .zshrc file which is in ~/dotfiles/zsh to ~/.zshrc\n```\nBy default stow will stow packages up one directory from the root directory. \nIn this example the root directory is `~/dotfiles` and the package is `zsh`.\nSo the files in the `zsh` package will symlinked into `~/`.\n\n`stow` makes it easy to share dotfiles across machines, or safely experiment with config changes while always being protected by `git` since your dotfiles are in a git repo!\n...They are in a git repo... right?\n",
      "summary": "Stow is a great tool for managing dotfiles. My usage looks like cloning my dotfiles to my home directory, setting some environment variables via a script,...",
      "date_published": "2022-03-04T00:00:00Z",
      "date_modified": "2022-03-04T00:00:00Z",
      "authors": [
        {
          "name": "Nic Payne",
          "url": "https://pype.dev"
        }
      ],
      "tags": [
        "bash",
        "linux",
        "tech",
        "til"
      ]
    },
    {
      "id": "https://pype.dev/stow-target/",
      "url": "https://pype.dev/stow-target/",
      "title": "Stow-Target",
      "content_html": "\u003cp\u003eCheck out \u003ca href=\"/stow\"\u003estow\u003c/a\u003e for a brief introduction to \u003ccode\u003estow\u003c/code\u003e\u003c/p\u003e\n\u003cp\u003eWhat if I want to stow a package somewhere else?\nBoom, that\u0026rsquo;s where \u003ccode\u003e-t\u003c/code\u003e comes in\u0026hellip;\u003c/p\u003e\n\u003cp\u003eMaybe I don\u0026rsquo;t like having my \u003ccode\u003edotfiles\u003c/code\u003e repo at \u003ccode\u003e$HOME\u003c/code\u003e and instead I want it in \u003ccode\u003e~/git\u003c/code\u003e or \u003ccode\u003e~/personal\u003c/code\u003e just to stay organized\u0026hellip;\nWell then I could have the same workflow except the \u003ccode\u003estow\u003c/code\u003e command looks like this:\u003c/p\u003e\n\u003cpre class=\"chroma\"\u003e\u003ccode\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003estow zsh -t ~/\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e#or\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003estow zsh -t \u003cspan class=\"nv\"\u003e$HOME\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e",
      "content_text": "\nCheck out [stow](/stow) for a brief introduction to `stow`\n\nWhat if I want to stow a package somewhere else?\nBoom, that's where `-t` comes in...\n\nMaybe I don't like having my `dotfiles` repo at `$HOME` and instead I want it in `~/git` or `~/personal` just to stay organized...\nWell then I could have the same workflow except the `stow` command looks like this:\n\n```bash\nstow zsh -t ~/\n#or\nstow zsh -t $HOME\n```\n",
      "summary": "Check out stow for a brief introduction to",
      "date_published": "2022-03-04T00:00:00Z",
      "date_modified": "2022-03-04T00:00:00Z",
      "authors": [
        {
          "name": "Nic Payne",
          "url": "https://pype.dev"
        }
      ],
      "tags": [
        "bash",
        "linux",
        "tech",
        "til"
      ]
    },
    {
      "id": "https://pype.dev/ubuntu-static-ip/",
      "url": "https://pype.dev/ubuntu-static-ip/",
      "title": "Ubuntu-Static-Ip",
      "content_html": "\u003cp\u003eSometimes I need to manually set a static IP of a Linux machine. I generally run the latest version of Ubuntu server in my VMs at home.\u003c/p\u003e\n\u003cp\u003eIn Ubuntu 20 I\u0026rsquo;m able to change up \u003ccode\u003e/etc/netplan/\u0026lt;something\u0026gt;.yml\u003c/code\u003e\u003c/p\u003e\n\u003cpre class=\"chroma\"\u003e\u003ccode\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nt\"\u003enetwork\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e  \u003c/span\u003e\u003cspan class=\"nt\"\u003eversion\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"m\"\u003e2\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e  \u003c/span\u003e\u003cspan class=\"nt\"\u003eethernets\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"nt\"\u003eenp0s4\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e      \u003c/span\u003e\u003cspan class=\"nt\"\u003eaddresses\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"m\"\u003e192.168.1\u003c/span\u003e\u003cspan class=\"l\"\u003e.{Static IP}/24]\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e      \u003c/span\u003e\u003cspan class=\"nt\"\u003egateway4\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"m\"\u003e192.168.1.1\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e      \u003c/span\u003e\u003cspan class=\"nt\"\u003enameservers\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e        \u003c/span\u003e\u003cspan class=\"nt\"\u003eaddresses\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"m\"\u003e192.168.1.1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"m\"\u003e1.1.1.1\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003cp\u003e\u003ccode\u003egateway4\u003c/code\u003e is your router address\n\u003ccode\u003enameservers\u003c/code\u003e is a list of desired DNS servers for that machine to use. I  usually use my router which is configured to use my pi-hole as my primary DNS, then set  \u003ccode\u003e1.1.1.1\u003c/code\u003e (CloudFlare) as a backup\u003c/p\u003e\n\u003cp\u003eHit it with the \u003ccode\u003esudo netplan apply\u003c/code\u003e and you should be good to go!\u003c/p\u003e\n",
      "content_text": "\nSometimes I need to manually set a static IP of a Linux machine. I generally run the latest version of Ubuntu server in my VMs at home.\n\nIn Ubuntu 20 I'm able to change up `/etc/netplan/\u003csomething\u003e.yml`\n\n```yaml\nnetwork:\n  version: 2\n  ethernets:\n    enp0s4:\n      addresses: [192.168.1.{Static IP}/24]\n      gateway4: 192.168.1.1\n      nameservers:\n        addresses: [192.168.1.1, 1.1.1.1]\n```\n\n`gateway4` is your router address\n`nameservers` is a list of desired DNS servers for that machine to use. I  usually use my router which is configured to use my pi-hole as my primary DNS, then set  `1.1.1.1` (CloudFlare) as a backup\n\nHit it with the `sudo netplan apply` and you should be good to go!\n",
      "summary": "Sometimes I need to manually set a static IP of a Linux machine. I generally run the latest version of Ubuntu server in my VMs at home.",
      "date_published": "2022-03-03T00:00:00Z",
      "date_modified": "2022-03-03T00:00:00Z",
      "authors": [
        {
          "name": "Nic Payne",
          "url": "https://pype.dev"
        }
      ],
      "tags": [
        "linux",
        "til"
      ]
    }
  ]
}