touring the scripts in my dotfiles

coding 2428 words

hey friends! this is late, but seeing as this is my first post of the year, happy 2026!

i love to write random shell scripts, either because they automate something i do all the time, or simply because i'm bored. a lot of my recent scripts have been lifted/inspired by the ones found in Evan Hahn's dotfiles, which he wrote about in the post Scripts I wrote that I use all the time. as this post has greatly inspired my own dotfiles and how i automate my personal tasks, i decided i'd just straight up rip off that post and do a similar one for my own scripts! sorry Mr. Hahn— i hope this is okay!

i'll preface this with a few things: first off, my scripts are messy. i'm still somewhat a beginner to scripting, and i'm very much not a programmer; if the script works even a little bit, it goes in my dotfiles repo and i only touch it if there's something wrong. second, i rely on lots of external dependencies often; these are to automate personal tasks, most of which involve making it easier to use an existing tool, like imagemagick, ffmpeg, yt-dlp, and more.

one of these dependencies is gum by Charm CLI, which, in their words, allows you to make "glamorous shell scripts," AKA, make your shell scripts interactive. though i realize i can replace lots of this interactivity with tools that have been around longer, such as read for text input, i just prefer the way gum does it! it's not only very cute, but more importantly, it is intuitive and easy to get started with. ease of use matters a lot to me! i recommend you give gum a shot, it really makes shell scripting fun. (obligatory in this day and age: i am in no way sponsored to say all of that, i'm just some guy who really likes what Charm does.)

some scripts have a "tools" suffix; this means that they collect various code snippets with a common theme, and presents them in a menu that you can choose from. each option usually runs as a bash loop, as they are intended to run in a directory applying to all the files contained.

lastly, i won't be covering all of my scripts because some of them suck ass. also i'm linking to the tangled mirror of my dotfiles, in case my personal forge ever goes down

okay, onto the scripts!

general file management

copy will, well, copy anything it's told to. i use it most often with a pipe; for example, i'll do echo "thing to be copied" | copy, and then if i check my clipboard or paste it, it'll result in that copied string.

paste is basically the inverse of the above; it just pastes stuff! i can use it similarly to copy, like if i want to put the clipboard contents in a file: paste > my_epic_file.txt.

extlan is short for extract language; this means that it'll extract ZIP archives with certain language encodings, specifically CJK, without resulting in mangled mojibake files. it prompts for the type of encoding (at the moment i've only needed this for japanese & korean encodings), and when one is chosen, it prompts for the name of the file to be extracted.

md2html is a mess but it's my mess okay. i love it. this script will convert markdown to HTML, using a variety of cluttered, probably sometimes useless dependencies. it has two options: paste in your markdown, or pull it from a file. i use the paste option the most, but both use very similar code. most of the heavy-lifting (such as accepting text input, or fuzzy-searching through a file list) is done by love of my life gum, but the text conversion itself is handled by pandoc, and the resulting HTML entities of characters like double quotes and ampersands are handled by a perl one-liner. i use this script all the fucking time, mainly to process my fanfiction as i prepare it to be posted, copying from the obsidian editor right into the script. i love it so much.

txttools gathers several text processing functions into one script: unwraptxt will accept pasted-in wrapped text and unwrap it using a perl one-liner; wraptxt does the same but for wrapping text by a certain amount of characters; and lastly, wdcount will tell you the word count of pasted-in text. i recognize that a lot of these things can be done with simple tools like awk, wc, and others, but i am a lazy fuck and love to paste in text with gum write.

mksh allows me to quickly make scripts and either place them in my $PATH (specifically ~/.local/bin with the rest of my scripts), or in the current working directory. it adds a shebang and makes the script executable before i open it.

stripexif uses exiftool to strip the EXIF data (minus orientation/rotation) of any image supplied to it. good for privacy nerd stuff.

life utilities

mini_timer is well, a mini timer! it's "mini" because it only works in minutes. it uses timer by caarlos0 to do the heavy lifting. when the timer is done, it will send a system notification, as well as playing a little chime sound, and even a text-to-speech line informing me that it's done, in case i miss the notification (and i also almost always have my headphones on).

mvpn is a wrapper around my VPN (mullvad) CLI, and allows me to quickly launch any application in my $PATH outside of my VPN's connection (split-tunneled).

mvpnall (also linked to splitvpn) is a semi-complex script that achieves a simple goal: split-tunneling a bunch of my commonly used applications away from my VPN. sometimes i'll have my VPN on for some background tasks, and then having it on will affect my usual daily applications like my browser, IRC client, discord, and more. running this once will auto-magically split-tunnel all of those applications out from the VPN, and if the VPN isn't currently connected, it will do that as well.

pick uses xcolor to let me color pick anything on screen. it then copies the hex code to my clipboard, and sends a notification upon completion. i have this tied to a hotkey for ease of use!

pomodoro is basically a souped-up version of bashbunni's .zshrc pomodoro timers; in other words, it's over-engineered for something i barely use lol. the various options are for different lengths of time: a quick run, which is 15 minutes, a break which lasts for 20 minutes, a work run that goes for 45 minutes, and lastly, a custom option that allows me to enter any duration i want.

screenshot & screenshotpick have completely replaced my distro's built-in GUI screenshot utilities. basically, on both my PC and laptop each, i have one big screenshot folder, and in my PC's case, i've been maintaining it since 2020. each file is numbered sequentially. before these scripts, i used to take the screenshot with a hotkey, which would launch the GUI; then i'd have to manually save the file, after my massive folder of screenshots has loaded, which can take a few seconds, so i could see what the last number was. this was miserable!!! i also hated the GUI's click-and-drag function for screenshots. so after taking inspiration from a github script, i ended up with these two, which are both bound to two different hotkeys. they're efficient as hell and perfect for my highly opinionated approach to screenshot taking and saving!

share quickly beams any file to a file server of mine that holds a bunch of randomly dumped files that i need a link to. it uses rsync to send the files over, and then outputs a fancy link (in rainbow text using lolcat!!!!)

today is pretty much just a turbo lazy wrapper around date, because i can never remember the flags for that, nor can i be bothered to learn. without any arguments, today will output the current date in ISO format (for example: 2026-03-05). if you supply the time argument, it includes the current hour & minute in 12 hour time, with an underscore between it and the date. i use this most often in scripting (as you'll see in the next script).

updiscord is so incredibly lazy and useful at the same time. since discord distributes .deb files through their web server instead of using a package manager like normal people (to be fair the APT repositories take forever to update, but still! this is a pain!!!!), i automated the download and installation process for getting the new file and installing it with dpkg.

multimedia (videos, images, audio, etc.)

audiotools collects several options for audio processing: flac2mp3, which will convert all FLAC files to the highest quality MP3s possible, and wav2mp3, which does the same but for WAV files.

switchbluez lets me switch between bluetooth audio profiles for my headset. the LXQt GUI for this is really annoying and often requires a few disconnect-and-reconnects of the headset for the right profile to show, so i finally made a script for it after getting really annoyed with the GUI.

cbtools is for managing comic books: cbr2cbz will unzip CBR files into folders, and dir2cbz will zip those resulting folders into CBZ files.

snsclip allows for me to spread the good word of dambara ruru as fast as possible, by quickly ripping videos from youtube and other platforms, and keeping the resolution under 1080p for a smaller file size.

vidtools collects tools related to video processing: avi2mkv, which converts all AVI files to MKV; any2hevc, which converts all MKV files in the current working directory to HEVC encoding; vid2frames, which splits any video in the current working directory into every single frame it consists of (i use this for making GIFs, if the use case is unclear); and vidsubs, which leverages mkvmerge to remux MKV files with subtitles of identical file names in the same directory, setting the default subtitle language to English.

webcamimg is exclusively for my laptop. it allows me to take two photos with my webcam on demand. it first turns on my webcam for a few seconds, because if it doesn't, the webcam will immediately turn on when taking the photo, and as it turns on it adjusts to the lighting of the room, which results in extremely dark, barely visible photos. turning it on beforehand momentarily seems to fix that. the photos are taken with ffmpeg.

ytbest will download a video from youtube (or any other video platform supported by yt-dlp) in the best audio & video formats possible, while excluding AI upscales (see this post by alexwlchan for info on how to do that).

ytmp3 is a lazy way for me to get my idol performance MP3s :P in other words, it will extract audio from a video in the best quality possible, outputting it with the video title and an MP3 file extension.


Comment Form is loading comments...

webmentions