toolbelt
Small Bash commands for the Linux jobs you do every week and never remember the flags for.
New here? Getting started walks through install, the health check and the shell settings.
Install
One line. It installs into ~/.local and needs no sudo.
curl -fsSL https://raw.githubusercontent.com/khadirullah/toolbelt/main/install.sh | bash
To read the code before it runs, clone the repo and run the installer from the clone.
git clone https://github.com/khadirullah/toolbelt.git
cd toolbelt
./install.sh
Commands
Each name opens its full manual page. The same text is in man and --help.
No command matches. Try a shorter word.
Archives
- unpackUnpack any archive, from a file or a URL.
- squashPack files and folders into any free format.
- archdiffList what changed between two archives.
- archmountOpen an archive as a folder without unpacking.
- autounpackUnpack archives as they land in ~/Downloads.
Files
- bakCopy a file aside before you edit it.
- checksumHash a file, or check it against a hash or SUMS file.
- bulkrenameRename many files with a pattern or in your editor.
- fixpermsSet folders to 755 and files to 644, with a preview.
- dupesFind duplicate files by content.
- bigfilesList the biggest files or folders under a path.
- recentList the files changed lately, newest first.
- mirrorMake a folder match another, showing the changes first.
- lockEncrypt a file or folder with age, or gpg.
- unlockDecrypt a file made by lock, age or gpg.
- shrinkMake an image, video or PDF fit a size.
- togifTurn a video clip into a small GIF.
System
- pkgOne package command on every distro.
- memWho uses the memory, and who goes first when it runs out.
- cleanupSee what fills the disk, then clean it safely.
- sysinfoThe whole machine on one screen.
- procEverything about one process.
- svcSystemd services in one place.
- logsErrors and warnings from the journal, grouped by unit.
- disksDrives, partitions, space and health together.
- boottimeWhere the boot time went.
- tempsCPU, drive and board temperatures, and fan speed.
- seccheckA quick security check of this machine, with fixes.
- schedulesCron jobs and systemd timers in one table.
Network
- portShow who is listening on a port.
- myipLocal and public IP addresses, gateway and DNS.
- netcheckFind where the network breaks, step by step.
- waitforWait for a port, a URL or a file.
- shareSend text, a link, Wi-Fi or a folder to your phone.
- lanEvery device on the local network.
- httptimeWhere the time goes in one HTTP request.
- sshfwdSSH tunnels without remembering -L, -R and -D.
- speedDownload and upload speed test.
Everyday
- againRun a command again until it works.
- notify-doneTell you when a long command finishes.
- cheatsShort examples for a command, cached offline.
- clipCopy and paste from the terminal.
- genpassRandom passwords and passphrases.
- timerCountdown or stopwatch in the terminal.
- noteJot a line into today's notes file.
- epochConvert Unix timestamps and dates both ways.
Kubernetes
- kwhyShow why pods are not Ready, on one screen.
- ksecretShow a Secret decoded, one key or all.
- kyamlPrint clean YAML of a live object, ready to reuse.
- kcleanDelete evicted, completed and crashing pods.
- kfwdPort-forward a service to a spare local port.
- kresCompare node requests with real usage.
- knodesShow node health and pressure at a glance.
- keventsShow recent events in time order, newest last.
DevOps
- ctxWhere your commands will land, on one screen.
- certcheckDays until a TLS certificate expires.
- dnscheckThe DNS records email depends on.
- tfcheckEvery Terraform check in one pass.
- yamlcheckLint YAML and check Kubernetes manifests.
- imgpeekLook inside a container image.
- jwtpeekDecode a JWT and show when it expires.
- git-undoTake back the last commit and keep its changes.
- git-prune-mergedDelete local branches already merged into main.
- git-recentList local branches by their last commit, newest first.
- git-wipSave every change as a commit named wip.
- git-syncFetch and rebase the current branch onto its upstream.
- git-whoamiShow the name, email and signing key git will use here.
What it looks like
Real runs, copied from the manual pages, next to what you would type without toolbelt.
Unpack a split backup into another folder
Without toolbelt
mkdir -p ~/restore
cat backup.tar.gz.a* | tar -xzf - -C ~/restore
With unpack
unpack -o ~/restore backup.tar.gz.aa
backup.tar.gz (4 parts) -> ~/restore/backup/ (31MB, 201 files, 3.4s)
Who holds a port
Without toolbelt
ss -tlnp 'sport = :8000'
ps -o user=,args= -p 4121
With port
port 8000
8000/tcp 0.0.0.0 pid 4121 me python3 -m http.server 8000
What is wrong in this namespace
Without toolbelt
kubectl get pods
kubectl describe pod NAME
kubectl get events --sort-by=.lastTimestamp
With kwhy
kwhy
context kind-kind, namespace shop, 3 of 4 pods not Ready
cart-7d9f8c6b54-q2lzx ImagePullBackOff restarts 0
image registry.example.com/cart:1.4.3
event Failed to pull image "registry.example.com/cart:1.4.3": rpc error: code = NotFound desc = failed to pull and unpack image "registry.example.com/cart:1.4.3": manifest unknown
hint the tag does not exist, or the pull secret is wrong
api-5b8c9d7f6-mk4tn CrashLoopBackOff restarts 9
event Back-off restarting failed container api
exit 1, 5h ago, last 20 lines of the crashed container
2026/09/29 10:31:58 loading config from /etc/api/config.yaml
2026/09/29 10:31:58 connecting to postgres at db:5432
panic: dial tcp 10.96.12.4:5432: connect: connection refused
hint the app stops on start, read the log lines above
worker-6c7b9f5d8-8vhwp Pending restarts 0
event 0/1 nodes are available: 1 Insufficient cpu.
asks cpu 2, memory 1Gi
hint no node has cpu 2, memory 1Gi free, see kres
echo $?
1
A passphrase
Without toolbelt
shuf -n 5 /usr/share/dict/words | paste -sd-
With genpass
genpass -v -w 5
blot-geriatric-robin-germinate-undated
genpass: 5 words from 7776, about 64 bits
How every command works
Learn this once and it holds for every command.
Three layers of options
- Common options.
-h,-q,-vand-ymean the same in every command.squash -l 9is the smallest level for gzip and for zstd alike, mapped onto each tool's own scale. - Pass-through. Anything after
--goes to the tool underneath, so its own options stay yours, as insquash photos/ -- --long=27orunpack photos.7z -- -mmt=4. -vshows the real command. It prints every step, and each real command as a line starting with+. Copy that line and change any flag you like.
squash -v -l 9 -o v.tar.zst site/
squash: site/: 3 files, 60KB
squash: format: tar.zst, from the name v.tar.zst
squash: level: -l 9 is zstd -19
squash: threads: 4, zstd -T4
+ tar -cf - site | zstd -c -q --size-hint=61465 -19 -T4 > v.tar.zst
site/ -> v.tar.zst (60KB to 25KB, 3 files, 0.0s)
Common options
| Option | What it does |
|---|---|
-h, --help | Show the help and exit 0. |
-q, --quiet | Show only the result line and errors. |
-v, --verbose | Show every step, and each real command before it runs. |
-y, --yes | Go ahead without asking. With no terminal, a command that would ask refuses unless -y is given. |
--version | Show the command name and the toolbelt version. |
-- | Pass the rest to the tool underneath. |
Exit codes
| Code | Meaning |
|---|---|
| 0 | It worked. |
| 1 | It failed. The message says why. |
| 2 | Bad usage, such as an unknown option. |
| 3 | A tool is missing. The message has the install line. |
| 4 | A safety check refused. |
| 5 | You answered no, so nothing changed. |
A command may give a code a meaning of its own, such as certcheck exiting 1 when a certificate expires soon. Its
page says so under Exit status.
Six rules
- It points you to good tools it does not replace.
toolbelt doctorrecommends btop, ncdu, fzf, tldr and dive when they are missing. -hand--helpalways mean help. Every help page has the same layout. Usage, one line on what the command does, options, pass-through, examples, then what it needs and its exit codes.toolbelt help unpackprints the same page asunpack --help, andman unpackhas the full manual.- A missing tool comes with the install line for your distro. It knows apt, dnf, yum, pacman, zypper and apk,
and one table in
lib/pkgmapholds the package name for each. 7-Zip is7zipon Debian 13, Fedora and Arch, andp7zip-fullon older Ubuntu releases. - Nothing destructive happens without asking. Deletes go to the trash in
~/.local/share/Trash, so you can restore them. Afterunpackorsquashchecks its result, it asks whether to delete the archive or the source.--rmdeletes without asking and-kkeeps without asking. In a script there is nobody to ask, so the file stays unless you pass--rm. No command writes over a file of yours. It picks a free name such asbackup-1. - Scripts stay clean. Results go to stdout and everything meant for a person goes to stderr. Colour and
progress bars appear only in a terminal, and
NO_COLORturns colour off. The exit codes are the same in every command. - It is small on memory. Commands stream data through pipes instead of reading whole files, and check free memory and disk space before heavy work.
Rule 3 in practice:
unpack logs.tar.zst
unpack: needs zstd. Install it with: sudo apt install zstd
Where it runs
On every push to main and every pull request, CI runs the whole test suite on GitHub Actions in a container of each of these images.
| Image | Package manager |
|---|---|
debian:13 | apt |
ubuntu:24.04 | apt |
ubuntu:22.04 | apt |
fedora:44 | dnf |
rockylinux:9 | dnf |
archlinux:latest | pacman |
opensuse/leap:15 | zypper |
alpine:3 | apk |
- toolbelt needs Bash 4.4 or newer, and the installer stops on an older one. Alpine does not ship bash, so the
installer asks you to run
apk add bashfirst. - The shared library has fallbacks for BusyBox, such as whole seconds where
date +%Nis missing. - CI checks every package name in
lib/pkgmapagainst the real repos of each image, except Rocky 9 and Ubuntu 22.04.