Ask HN: Can I see your scripts?
A few weeks ago, I asked if I could see your cheatsheets (https://news.ycombinator.com/item?id=31928736) and I was really impressed by all the high quality responses!
Today I'm asking about your scripts.
Almost every engineer I know has a collection of scripts/utilities for automating ${something}. I'm willing to bet that HN users have some of the most interesting scripts on the internet.
So that said, could I please see your scripts?
I'll go first: https://github.com/fastily/autobots
306 comments
[ 5.4 ms ] story [ 268 ms ] threadOne I was particularly proud of/disgusted by was one that allowed me to jump around a network with a single command despite access being gated by regional jumphosts..
You are warned: https://git.drk.sc/-/snippets/107
Another script I wrote for our devs to get access to MySQL in production on GCP; the intent was for the script to be executable only by root and allow sudo access to only this script: that means also ''chmod ugo-rwx gcloud'' too though: https://git.drk.sc/-/snippets/98
I have another script to generate screenshots from grafana dashboards since that functionality was removed from grafana itself (https://github.com/grafana/grafana/issues/18914): https://git.drk.sc/-/snippets/66
Another time I got annoyed that Wayland/Sway would relabel my screens on successive disconnect/reconnects (IE my right screen could be DP-1 or DP-7 or anything in between randomly); so I wrote a docking script which moves the screens to the right place based on serial number: https://git.drk.sc/-/snippets/74
I can relate! I think it just reflects the nature of the problem space. The script is gnarly because the thing one is trying to do is gnarly. Utility is the driving force, as far as I'm concerned.
The following aren't as gnarly as yours, but served their purpose nicely in that little project's context. I like to put/accumulate project-related automations in a `./bin` in my projects.
https://gitlab.com/nilenso/cats/-/tree/master/bin
My "Bash Toolkit": https://github.com/adityaathalye/bash-toolkit
My (yak-shaving-in-progress :) "little hot-reloadin' static shite generator from shell": https://github.com/adityaathalye/shite
A subtle-ish aspect is, I like to write Functional Programming style Bash. I've been blogging about it here: https://www.evalapply.org/tags/bash/
Also a bookmarklet that you use to turn any page dark with a click:
From here: https://github.com/x08d/222- have something mildly repetitive to do, notice how to do parts of it with keyboard only.
- right click AutoHotkey icon in taskbar, edit (opens Notepad).
- change some of these automations, alt+1, alt+2, alt+3, ...
- press ctrl+s to save and reload.
- switch back to the program and use the hotkey immediately to begin helping.
- repeat switching to AutoHotkey and the program, tweaking and adding more.
It's amenable to the kind of occasional task which has no easy proper automation, or is a one-off and isn't worth more time to do it through proper interfaces. Things like a vendor support telling you to "go through every affected record and toggle X field off and on again".
search_notes() { input=$(rg -v '(\-\-)|(^\s*$)' --line-number /home/user/some-dir | fzf --ansi --delimiter : --preview 'batcat --color=always {1} --highlight-line {2}' --preview-window 'up,60%,border-bottom,+{2}+3/3,~3' | choose -f : 0) if [[$input = ""]]; then else less $input fi }
It uses various linux utilities including fzf and batcat(https://github.com/sharkdp/bat) to open a terminal with all the places where my query comes up (supporting fuzzy search). Since the workhorses are fzf and ripgrep its is quite fast even for very large directories.
So i will do `search_notes postgres authentication`. I can select a line and it will open the file in less. Works like a charm!
For example, I have one script that uses rumps to show how many outdated homebrew packages I have (and also as a convenient shortcut to update those packages in the dropdown menu). I also have a second script that uses it to show a counter for open pull requests that I need to review (with links to individual PRs in the dropdown menu). It's great!
Result looks like this: https://imgur.com/yy6GlYk.jpg
My examples: https://imgur.com/a/SrjG1xe
I basically do all my local management from there, no need to run scripts manually, no need to click around in Finder manually, I even added a command to quickly copy my email, simply because it is so low friction to do it.
Hands down the best tool I've ever used
[1] https://github.com/benwinding/dotfiles
[2] https://zachholman.com/2010/08/dotfiles-are-meant-to-be-fork...
So I use this script to give me a nice work environment, based on each day.
Every time you open bash, it'll drop you into today's directory. (~/work/year/month/day/)
When I think about stuff it's like.. oh yeah I worked on that last week, last year, etc - the folder structure makes this a lot easier, and you can just write 'notes' or 'meeting-with-joe' and you know the ref date.
For your bashrc:
Now every day you'll know what you worked on yesterday! additionally you'll get a shortcut, you can type 't' as a bash fn, or go to ~/t/ which is symlinked and updated everytime you run today (which is everytime you open bash or hit 't'. this is useful if you want to have Firefox/Slack/whatever always save something in your 'today' folder.https://git.ceux.org/today.git/
Do you mean Nepomuk, that thing from KDE, which dead like 10+ years ago?
> Every time you open bash, it'll drop you into today's directory. (~/work/year/month/day/)
Ok, that's an interesting Idea, but isn't this more akin to Gnome Zeitgeist? When aimed Nepopmuk at journaling?
> https://git.ceux.org/today.git/
But where is the script? I only see the readme, no code for creating the folder.
Yeah. I mean I think the pitch when KDE4 launched was like... let's rethink how we deal with our files as less discrete paths and more like easily findable stuff.
> But where is the script? I only see the readme, no code for creating the folder.
whoops, I added it!
I eventually got tired of writing that manually, so I wrote a small
that works just like 'git commit', except it adds another line to the commit message template.Placing it in e.g. ~/bin/git-co-commit and having ~/bin in your $PATH will enable it as a git sub-command.
I've never had a use for this before, and I don't think I'll need it much beyond this team, but this was my first git sub-command that wasn't trivially solvable by existing command parameters (that I know of).
https://gist.github.com/sshine/d5a2986a6fc377b440bc8aa096037...
https://blog.sebastian-daschner.com/entries/custom-git-subco...
Many "built-in" Git commands are themselves separate executables. My Linux machine has them in `/usr/lib/git-core/`, and my macOS machine has them in `/Applications/Xcode.app/Contents/Developer/usr/libexec/git-core/`.
Many Linux tools do this. Rust's cargo is another.
In fact, `man` itself can take multiple positional arguments and will concatenate them with a hyphen to perform the lookup.
To the OP: You might be able to simplify the script by using `git commit --trailer …`. Or maybe you tried that and it didn't display the message in the editor window satisfactorily?
For some reason `--trailer` is not available on my system, so I'd need to upgrade git, it seems.
You configure a ~/.git-authors file with people with whom you regularly pair, and use `git duet [author-1] [author-2]` to set primary and secondary commit authors. Env variables set whether you want `Signed-off-by` or `Co-authored-by` trailers.
There seems to be at least these three advantages over my approach:
I might consider switching for the next small project. :-)My .gitconfig has:
Now `git co-authored-by Tom` generates a Co-authored-by: trailer for the last person named Tom who committed to the repo. Typically I'd just do `:r !git co-authored-by Name` in vim (mapped to \gc to save typing).Command help, inspired by http://explainshell.com/ to extract help text from builtin commands and man pages. Here's an example:
---https://github.com/learnbyexample/regexp-cut/blob/main/rcut is another - uses awk to provide cut like syntax for field extraction. After writing this, I found commands like `hck`, `tuc` written in Rust that solves most of the things I wanted.
Charging: 32.15W
Discharging: -5.15W
I have in my shell history which I occasionally use:
(With ^[ being actual escape, entered via Ctrl-V Escape, because I find writing the escape codes literally easier and more consistent than using echo -e or whatever else.)It’ll show lines like this every minute (with nice colouring):
My PinePhone has an axp20x-battery with current_now and voltage_now, like your various laptops except that while discharging it gets a negative current_now, which makes perfect sense to me but which doesn’t seem to match your laptops (since you add the negative sign manually in your script) or my laptop’s power_now (which is likewise still positive while discharging).function go() {
}setTimeout(go, 100);
There are several different plaintext accounting tools, but they all support automation like this. I personally use Beancount because I work best in Python.
The other huge advantage is that the "state" of your finances isn't opaque like in Xero. If you realize you've been categorizing certain transactions incorrectly in Xero, it's a hassle to navigate Xero's interface to correct everything, whereas in plaintext accounting it's usually a 2-second find/replace.
The downside is that there's a steep learning curve and the documentation is kind of overwhelming, but once you learn it, it's extremely valuable.
[0] https://plaintextaccounting.org/
Here are some selected scripts folks might find interesting.
Here's my backup script that I use to encrypt my data at rest before shipping it off to s3. Runs every night and is idempotent. I use s3 lifecycle rules to keep data around for 6 months after it's deleted. That way, if my script goofs, I can recover: https://github.com/BurntSushi/dotfiles/blob/2f58eedf3b7f7dae...
I have so many machines running Archlinux that I wrote my own little helper for installing Arch that configures the machine in the way I expect: https://github.com/BurntSushi/dotfiles/blob/2f58eedf3b7f7dae...
A tiny little script to recover the git commit message you spent 10 minutes writing, but "lost" because something caused the actual commit to fail (like a gpg error): https://github.com/BurntSushi/dotfiles/blob/2f58eedf3b7f7dae...
A script that produces a GitHub permalink from just a file path and some optional file numbers. Pass --clip to put it on your clipboard: https://github.com/BurntSushi/dotfiles/blob/2f58eedf3b7f7dae... --- I use it with this vimscript function to quickly generate permalinks from my editor: https://github.com/BurntSushi/dotfiles/blob/2f58eedf3b7f7dae...
A wrapper around 'gh' (previously: 'hub') that lets you run 'hub-rollup pr-number' and it will automatically rebase that PR into your current branch. This is useful for creating one big "rollup" branch of a bunch of PRs. It is idempotent. https://github.com/BurntSushi/dotfiles/blob/2f58eedf3b7f7dae...
Scale a video without having to memorize ffmpeg's crazy CLI syntax: https://github.com/BurntSushi/dotfiles/blob/2f58eedf3b7f7dae...
Under X11, copy something to your clipboard using the best tool available: https://github.com/BurntSushi/dotfiles/blob/2f58eedf3b7f7dae...
https://www.masteringemacs.org/article/fuzzy-finding-emacs-i...
https://gist.github.com/stuporglue/83714cdfa0e4b4401cb6
It's one of my favorites because it's pretty simple, and I wrote it when a lot of things were finally coming together for me (including GIS concepts, plpgsql programming, and a project I was working on at the time).
This is code which takes either two foci points and a distance, or two foci, a distance and the number of pointers per quadrant and generates a polygon representing an ellipse. Nothing fancy, but it made me happy when I finally got it working.
The use case was to calculate a naive estimate of how far someone could have ridden on a bike share bike. I had the locations they checked out the bike, and where they returned it, and the time they were gone. By assuming some average speed, I could make an ellipse where everywhere within the ellipse could have been reached during the bike rental.
As a workaround, I wrote a small wrapper script that would enable multi-threading for SimpleHTTPServer.
~/bin/http-cwd , Python 2 version (original):
Python 3 version (necessary for platforms that have dropped Python 2, such as macOS):It fixes an issue in the Python built-in HTTP server that causes it to hang under concurrent connections.
First, run the built-in Python web server:
Then connect to it with a client that doesn't immediately send a request, such as `netcat`. This simulates the behavior of modern browsers, which seem to set up a pool of pre-established connections. Now try to get a page from the server via Curl (or wget, etc). It will hang after sending the request, because the server's single thread is trying to serve the idle connection. In real life, the behavior I saw was that I'd try to connect to the server with Chrome and it would hang after the pages had partially loaded.This issue appears to have been fixed: https://github.com/python/cpython/issues/75820
---------
#!/bin/sh
echo "Store and retrieve session token AWS STS \n\n"
# Get source profile read -p "Source Profile [<profile_name>]: " source_profile source_profile=${source_profile:-'<profile_name>'} echo $source_profile
# Get destination profile read -p "Destination Profile [<profile_name>-mfa]: " destination_profile destination_profile=${destination_profile:-'<profile_name>-mfa'} echo $destination_profile
mfa_serial_number='arn:aws:iam::<id>:mfa/<name>'
echo "\nOTP: " read -p "One Time Password (OTP): " otp
echo "\nOTP:" $otp echo "\n"
output=$(aws sts get-session-token --profile <profile_name> --serial-number $mfa_serial_number --output json --token-code $otp)
echo $output
access_key_id=$(echo $output | jq .Credentials.AccessKeyId | tr -d '"') secret_access_key=$(echo $output | jq .Credentials.SecretAccessKey | tr -d '"') session_token=$(echo $output | jq .Credentials.SessionToken | tr -d '"')
aws configure set aws_access_key_id $access_key_id --profile=$destination_profile aws configure set aws_secret_access_key $secret_access_key --profile=$destination_profile aws configure set aws_session_token $session_token --profile=$destination_profile
echo "Configured AWS for profile" $destination_profile
It also uses my https://github.com/pcho/dotfiles, https://github.com/pcho/vimfiles and https://github.com/pcho/zshfiles