Posts tagged: bash

All posts with the tag "bash"

31 posts latest post 2025-11-26
Publishing rhythm
Nov 2025 | 1 posts

Vaulted Secrets Without Git Churn

Ansible Vault keeps secrets out of sight, but the ciphertext changes on every encrypt. That turns Git [1] diffs into noise and makes it hard to tell if anything actually changed. Decrypting, editing, and re-encrypting often leaves uncertainty about whether any plaintext changed. This is amplified when secret repos are tightly coupled to dependent repositories. A typical cycle includes decrypting, adding a key, updating a value, applying changes, and returning later with little clarity about what changed while secrets were in plaintext. Today a new workflow was created with @gpt-5.2-codex to keep diffs clean and avoid re-encrypting when the plaintext is identical. Chat-reply This repo has ansible vaulted secrets and an encrypt/decrypt process, but no way to compare. Please research compare options. The goal is to avoid changing files on encrypt/decrypt when plaintext is unchanged, ideally by comparing decrypted content and reusing the remote encrypted file. @gpt-5.2-codex The re...
setting COLUMNS env var to a number greater than 0 will make the terminal resize to that number of columns. COLUMNS=80 uvx --from rich-cli rich myscript.py Note Not all programs respct the COLUMNS env var, but rich does, and a lot of stuff I’m building uses rich. I discovered this when I was trying to make a low effort readme generated from the code, but did not depend on the size of terminal it was ran on. # justfile readme: echo "# Workspaces" > README.md echo "" >> README.md echo '``` bash' >> README.md COLUMNS=80 ./workspaces.py --help >> README.md echo '```' >> README.md
Today I learned how to use tar over ssh to save hours in file transfers. I keep all of my projects in ~/git [1] (very creative I know, I’ve done it for years and haven’t changed). I just swapped out my main desktop from bazzite to hyprland, and wanted to get all of my projects back. Before killing my bazzite install I moved everything over (16GB of many small files), it took over 14 hours, maybe longer. I had started in the morning and just let it churn. This was not going to happen for re-seeding all of my projects on my new system, I knew there had to be a better way, I looked at rsync, but for seeding I ran into this tar over ssh technique and it only took me 6m51s to pull all of my projects off of my remote server. ssh [email protected] 'tar -C /tank/git -cpf - .' \ | tar -C "$HOME/git" -xpf - References: [1]: /glossary/git/
[1]2025-07-09 Notes [1] from yesterday I have temporal stuff kind of going with postiz in a windsurf session working on [[thoughts-to-nostr]] Been cleaning up my z" loading="lazy"> 2025-07-10 Notes | Nic Payne 2025-07-09 Notes [2] from yesterday I have temporal stuff kind of going with postiz in a windsurf session working on [[thoughts-to-nostr]] Been cleaning up my z pype.dev big fan of eza and dust, I like these aliases to have some common commands at my fingertips. I often use the tree command and yes it sometimes goes too deep to actually be useful. alias lt='eza -T --level=2' # Tree view, 2 levels deep alias ltt='eza -T --level=3' # Tree view, 3 levels deep alias du1='dust -d 1' # Show only 1 level deep alias du2='dust -d 2' # Show 2 levels deep Note This post is a thought [3]. It’s a short note that I make about someone else’s content online #thoughts References: [1]: https://pype.dev/2025-07-10-notes/ [2]: /2025-07-09-notes/ [3]: /thoughts/
I am a linux user through and through. Desktop, server, vms, containers, everything except my phone is linux. With this I spend a lot of time in the terminal, and have been a long time user of !! to rerun the last command, but with the ability to tack something on at the beginning or end. TIL about fc, which opens the last command in your shell history in your $EDITOR or pass in your editor -e nvim. man fc [1] Rcap of how !! works # [2] !! pronounces bang bang and will run the last command in your history. ls -l !! | wc -l # ls -l | wc -l sudo !! # sudo ls -l | wc -l !!:s/-l/-l \/tmp # sudo ls -l /tmp | wc -l fc enters the chat # [3] Now making complex edits in your shell can be a bit of a chore, so fc moves this work to your $EDITOR. fc This pops open your $EDITOR with the last command in your history. sudo ls -l | wc -l [4] Shell History # [5] fc shows up in shell history, but !! does not, !! gets replaced by the command that it becomes. Up Arrow # [6] yaya yaya, I know you can also up-arrow c-e, but what fun is that, it’s barely a flex. fc just looks big brained and like you really know what you are doing. References: [1]: https://manned.org/fc [2]: #rcap-of...
You can unset multiple environment variables at once. I did not know this was a thing, its something that ended up happening organically on a call and asking someone to run unset. They had never done it before and did not know how it works, but did exactly as I said instead of what I meant. I like this handy shortcut doing it in one line rather than each one individually, I will be using this in the future. You might need this for something like running aws cli commands with localstack [1]. unset AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_DEFAULT_REGION References: [1]: /running-aws-cli-commands-with-localstack/
bic Static blog generator, in bash bic · bic.sh [1] Intereresting someone built a blog generator in bash. it comes with normal markdown to html [2], static content, robots.txt, sitemap, rss, and tags. It uses pandoc to take markdown to html and mustache for page templates. Note This post is a thought [3]. It’s a short note that I make about someone else’s content online #thoughts References: [1]: https://bic.sh/ [2]: /html/ [3]: /thoughts/
GitHub - casey/just: 🤖 Just a command runner 🤖 Just a command runner. Contribute to casey/just development by creating an account on GitHub. GitHub · github.com [1] new versions of just now come with color variables already set. [group('manage')] version: #!/usr/bin/env bash version=$(cat version) echo current version {{BOLD}}{{GREEN}}$version{{NORMAL}} Note This post is a thought [2]. It’s a short note that I make about someone else’s content online #thoughts References: [1]: https://github.com/casey/just?tab=readme-ov-file#constants [2]: /thoughts/
pipely/justfile at main · thechangelog/pipely I like the idea of having like this 20-line Varnish config that we deploy around the world, and it’s like: Look at our CDN! - thechangelog/pipely GitHub · github.com [1] I found this nugget in thechangelogs justfile, it lets you add color to your justfile with variables quite easily. # https://linux.101hacks.com/ps1-examples/prompt-color-using-tput/ _BOLD := "$(tput bold)" _RESET := "$(tput sgr0)" _BLACK := "$(tput bold)$(tput setaf 0)" _RED := "$(tput bold)$(tput setaf 1)" _GREEN := "$(tput bold)$(tput setaf 2)" _YELLOW := "$(tput bold)$(tput setaf 3)" _BLUE := "$(tput bold)$(tput setaf 4)" _MAGENTA := "$(tput bold)$(tput setaf 5)" _CYAN := "$(tput bold)$(tput setaf 6)" _WHITE := "$(tput bold)$(tput setaf 7)" _BLACKB := "$(tput bold)$(tput setab 0)" _REDB := "$(tput setab 1)$(tput setaf 0)" _GREENB := "$(tput setab 2)$(tput setaf 0)" _YELLOWB := "$(tput setab 3)$(tput setaf 0)" _BLUEB := "$(tput setab 4)$(tput setaf 0)" _MAGENTAB := "$(tput setab 5)$(tput setaf 0)" _CYANB := "$(tput setab 6)$(tput setaf 0)" _WHITEB := "$(tput setab 7)$(tput setaf 0)" Usage echo: echo {{_BOLD}}{{_GREEN}}hello there{{_RESET}} Note This post i...
Today I discovered the Urllink function in bash from the ujust tool from ublue.it [1]. Seems like a cool trick, but might not work everywhere. ######## ### Special text formating ######## ## Function to generate a clickable link, you can call this using # url=$(Urllink "https://ublue.it" "Visit the ublue website") # echo "${url}" function Urllink (){ URL=$1 TEXT=$2 # Generate a clickable hyperlink printf "\e]8;;%s\e\\%s\e]8;;\e\\" "$URL" "$TEXT${n}" } ```j References: [1]: https://ublue.it
hostnamectl to easily change hostname | Nic Payne hostnamectl is apparently a linux utility for easily changing your hostname in a variety of ways I learned there's transient and static hostnames, so that& pype.dev [1] For some reason the ublue ecosystem does not prompt you to set your hostname on install and you get a hostname like bazzite showing up. Looks like this is the fix. hostnamectl –static hostname babyblue-aurora Note This post is a thought [2]. It’s a short note that I make about someone else’s content online #thoughts References: [1]: https://pype.dev/hostnamectl-to-easily-change-hostname [2]: /thoughts/
I’ve had a couple of uploads to twitter fail recently and has been a pain. I tried some online converters for convenience, but none of them worked. I reached out to chatgpt and found succeess with this ffmpeg command. ffmpeg -i input.mp4 \ -vf "scale=trunc(oh*a/2)*2:min(720\,trunc(ih*a/2)*2)" \ -c:v libx264 -profile:v high -level:v 4.1 \ -b:v 3500k -maxrate 3500k -bufsize 7000k \ -pix_fmt yuv420p \ -c:a aac -b:a 128k -ar 44100 \ -movflags +faststart \ output.mp4
Authentication from cli tools can be a bit of a bear, and I have to look it up every time. This is my reference guide for future me to remember how to easily do it. I set up a fastapi [1] server running on port 8000, it uses a basic auth with waylonwalker as the username and asdf as the password. The server follows along with what comes out of the docs. I have it setup to take basic auth, form username and password, or a bearer token for authentication. curl # [2] The og [3] of command line url tools. # basic auth curl -u 'waylonwalker:asdf' -X POST localhost:8000/token # basic auth with password prompt curl -u 'waylonwalker' -X POST localhost:8000/token # token curl -H 'Authorization: bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ3YXlsb253YWxrZXIiLCJleHAiOjE3MDI5NTI2MDJ9.GeYNt7DNal6LTiPoavJnqypaMt4vYeriXdq5lqu1ILg' -X POST localhost:8000/token wget # [4] My go to if I want the result to go into a file. # basic auth wget -q -O - --auth-no-challenge --http-user=waylonwalker --http-password=asdf --post-data '' localhost:8000/token # token wget -q -O - --header="Authorization: bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ3YXlsb253YWxrZXIiLCJleHAiOjE3MDI5NT...
jpillora/installer is the install script generator I have been looking for. It downloads binaries for your machine from GitHub releases and unzips them for you. It grabs the latest release, so you can easily update them. I have tried scripting these installs in the past and struggled to consistently get the latest version for every package and unpack it correctly. Also these pre-compiled binaries install rediculously fast compared to building them from source. Check out some example links. opening in a browser will show metadata https://i.jpillora.com/serve If you pass in script=true it will instead return the install script as it would by default through curl. https://i.jpillora.com/serve?script=true Use it to install neovim # [1] All you need to do to generate an install script is to pass in the GitHub repo slug with the org. curl https://i.jpillora.com/neovim/neovim | bash The shell script that it generates for neovim looks like this. #!/bin/bash if [ "$DEBUG" == "1" ]; then set -x fi TMP_DIR=$(mktemp -d -t jpillora-installer-XXXXXXXXXX) function cleanup { rm -rf $TMP_DIR > /dev/null } function fail { cleanup msg=$1 echo "============" echo "Error: $msg" 1>&2 ...
Deleting Specific Lines in a File with sed or yq — Nick Janetakis We Nick Janetakis · nickjanetakis.com [1] sed can be a tricky beast, I often stumble when trying to pipe into it. Next time I need to use sed, I should reference this article by Nick Janetakis. He makes it looks much easier than my experience has been, and it appears to behave like a vim :%s/ substitution does, or a g/ g command. Note This post is a thought [2]. It’s a short note that I make about someone else’s content online #thoughts References: [1]: https://nickjanetakis.com/blog/deleting-specific-lines-in-a-file-with-sed-or-yq [2]: /thoughts/
Give github actions the -e flag in the shebang #! so they fail on any one command failure. Otherwise each line will set the exit status, but only the last one will be passed to ci. #!/bin/bash -e What is -e # [1] The -e flag to the bash command allows your script to exit immediately if any command within the script returns a non-zero exit status. This can be useful for ensuring that your script exits with an error if any of the commands it runs fail, which can help you identify and debug issues in your script. For example, if you have a script that runs several commands and one of those commands fails, the script will continue running without the -e flag, but will exit immediately if the -e flag is present. This can make it easier to troubleshoot your script and ensure that it runs correctly. Solution for Windows # [2] In windows the solution is not quite as simple. You can define a function in a Windows batch script that wraps an if statement to check the exit status of a command and handle any errors that may have occurred. Here is an example of how you might define a function called “check_error” that does this: :check_error if errorlevel 1 ( echo An error occurred! ex...
I am often editing my own scripts as I develop them. I want to make a better workflow for working with scripts like this. Currently # [1] Currently I am combining nvim with a which subshell to etit these files like this. for now lets use my todo command as an example nvim `which todo` First pass # [2] On first pass I made a bash function to do exactly what I have been doing. ewhich () {$EDITOR `which "$1"`} The $1 will pass the first input to the which subshell. Now we can edit our todo script like this. ewich todo Note, I use bash functions instead of aliases for things that require input. Final State # [3] This works fine for commands that are files, but not aliases or shell functions. Next I jumped to looking at the output of command -V $1. - if the command is not found, search for a file - if its a builtin, exit - if its an alias, open my ~/.alias file to that line - if its a function, open my ~/.alias file to that line ewhich () { case `command -V $1` in "$1 not found") FILE=`fzf --prompt "$1 not found searching ..." --query $1` [ -z "$FILE" ] && echo "closing" || $EDITOR $FILE;; *"is a shell builtin"*) echo "$1 is a builtin";; *"is an alias"*) $EDITOR...
This morning I was trying to install a modpack on my minecraft server after getting a zip file, and its quite painful when I unzip everything in the current directory rather than the directory it belongs in. I had the files on a Windows Machine # [1] So I’ve been struggling to get mods installed on linux lately and the easiest way to download the entire pack rather than each mod one by one seems to be to use the overwolf application on windows. Once I have the modpack I can start myself a small mod-server by zipping it, putting it in a mod-server directory and running a python http.server python -m http.server Downoading on the server # [2] Then I go back to my server and download the modpack with wget. wget 10.0.0.171:8000/One%2BBlock%2BServer%2BPack-1.4.zip Unzip to the minecraft-data directory # [3] Now I can unzip my mods into the minecraft-data directory. unzip One+Block+Server+Pack-1.4.zip -d minecraft-data Running the server with docker # [4] I run the minecraft server with docker, which is setup to mount the minecraft-data directory. Running a Minecraft Server in Docker [5] A bit more on that in the other post, but when I download the whole modpack like this I ...
There is GNU coreutils command called mktemp that is super handy in shell scripts to make temporary landing spots for files so that they never clash with another instance, and will automatically get cleaned up when you restart, or whenever /tmp gets wiped. I’m not sure when that is, but I don’t expect it to be long. Making temp directories # [1] Here are some examples of making temp directories in different places, my favorite is mktemp -dt mytemp-XXXXXX. # makes a temporary directory in /tmp/ with the defaul template tmp.XXXXXXXXXX mktemp # makes a temporary directory in your current directory mktemp --directory mytemp-XXXXXX # shorter version mktemp -d mytemp-XXXXXX # same thing, but makes a file mktemp mytemp-XXXXXX # makes a temporary directory in your /tmp/ directory (or what ever you have configured as your TMPDIR) mktemp --directory --tmpdir mytemp-XXXXXX # shorter version mktemp -dt mytemp-XXXXXX # same thing, but makes a file mktemp --tmpdir mytemp-XXXXXX # shorter version mktemp -t mytemp-XXXXXX Use Case # [2] Here is a sample script that shows how to capture the tempdir as a variable and reuse it. Here is an example of curling my bootstrap file into a temp dir...
Reading eventbridge rules from the command line can be a total drag, pipe it into visidata to make it a breeze. I just love when I start thinking through how to parse a bunch of json at the command line, maybe building out my own custom cli, then the solution is as simple as piping it into visidata. Which is a fantastic tui application that had a ton of vim-like keybindings and data features. alias awsevents = aws events list-rules | visidata -f json