No. 0531 min read
undo for the shell, because rm has never once asked me if I was sure
A shell that can undo the last thing you did.
No. 0543 min read
A timestamp, a cron line, an exit code, an invisible Unicode character. huh ranks the plausible readings and prints the Unix one-liner that proves each one.
I keep a browser tab open to decode some string. An epoch timestamp, a JWT, a cron line, a color hex, an exit code. Open a converter site, paste, squint at ads, close the tab, forget what the site assumed. Then do it again tomorrow for the same kind of string.
So I wrote huh[1]Ref. 1huh github.com. Paste a string in, get the plausible readings ranked, each one carrying the conversions you actually came for and the plain Unix one-liner — the receipt — that would have told you the same thing. The point is not to depend on it. The point is to stop needing it.
$ huh 1696500000
epoch seconds Thu 2023-10-05 06:00:00 EDT, 3 years ago
ISO 2023-10-05T10:00:00Z
$ date -u -d @1696500000
One file, standard library only, Python 3.10+. Offline. Nothing leaves the machine, nothing is written, and it never runs the receipts — it only prints them.
Here is the thing that made me build it instead of just using a converter. A number like 137 is not one thing. It is an exit code, and a port, and a chmod mode, and probably two more readings I hid behind --all. A converter picks one and pretends it was sure. huh shows you all of them and tags how confident it is: kind means likely, kind? maybe, kind?? a long shot it shows because nothing better matched.
$ huh 137
exit code exit code 137: killed with SIGKILL (128 + 9)
often the OOM killer or a memory limit
port? port 137: NetBIOS name service
chmod? chmod 137 = ---x-wxrwx
It is a decoder ring, not an oracle. When it is wrong, the receipt shows you exactly what it assumed, so you can see the seam.
My favorite reading is the invisible one. You paste café and it looks fine, and the build fails anyway, and you spend an hour on it. Somewhere in there is a ZERO WIDTH SPACE[2]Ref. 2Zero-width space en.wikipedia.org, and huh finds it, tells you the offset, the codepoint, the UTF-8 bytes, and shows you the string with the ghost stripped out.
$ huh 'café'
unicode 1 hidden character (ZERO WIDTH SPACE)
offset 3: U+200B <- invisible
without the invisible characters: café
It catches bidi overrides, Cyrillic and Greek lookalike letters in hostnames, and mojibake[3]Ref. 3Mojibake en.wikipedia.org — the café that means somebody decoded UTF-8 as Latin-1 somewhere upstream.
Base64 that holds JSON that holds a timestamp: huh follows it down, three levels deep, and dates the timestamp at the bottom. But a JWT[4]Ref. 4JSON Web Token en.wikipedia.org gets decoded and never trusted — the claims are whatever the issuer, or an attacker, put there, and it says so right in the output. A PEM private key gets a warning. An API token gets read but gets no receipt at all, because the whole point is that some strings you decode in your head and never paste into a website.
Every reading ends with a $ line: the command that produces the same answer with tools that already exist on your box — date, base64, xxd, numfmt, stat, kill -l, ssh-keygen. They are printed, never run. When the input has invisible characters, the receipt spells them as octal escapes, the one form every POSIX printf understands, so it stays copy-pasteable in bash, zsh and dash.
The receipts are the actual product. huh is the training wheels. Learn the one-liner, delete the training wheels. That is the whole design.
It is on GitHub[5]Ref. 5huh on GitHub github.com, installable as whatsthis on PyPI (the name huh was taken), or just grab the one file — it has no dependencies.
No. 0531 min read
A shell that can undo the last thing you did.
No. 0441 min read
Corkscrew fits in 291 lines, folks.
No. 0431 min read
Corkscrew reported success without establishing a tunnel.
No. 0371 min read
Unix rename can publish a finished file or claim a queue item.