My first week on Void Linux was humbling
I moved from a standard Ubuntu setup to Void Linux running DWM, and the first thing I noticed was how much I suddenly needed the terminal for everything. No GUI package manager, no file manager open by default — just a clean tiling window manager and a terminal emulator staring back at me. It was uncomfortable at first, then extremely freeing. The thing is, you don't need to memorize hundreds of commands. I've been doing this for a while now and I still lean on the same 20 or so for most of my day. These are the ones that actually stuck.
1. pwd — where am I right now?
Sounds almost too basic to mention, but on a fresh Void install with DWM, I lost track of my location in the filesystem constantly during the first week. pwd (print working directory) is the fastest way to reorient yourself. I still run it more than I'd admit.
pwd2. ls — what's in here?
The bare ls works, but I always use it with flags. -l gives a proper list with permissions and sizes, -a reveals dotfiles (your .bashrc, .config folder, all the hidden stuff). On Void, most of what you care about configuring lives in dotfiles, so -a becomes muscle memory pretty fast.
ls
ls -l
ls -la3. cd — navigate the filesystem
You'll type this more than any other command. Two shortcuts that save time every day: cd .. moves up one level, cd ~ drops you home from anywhere. When you're three directories deep in a project and need to get back fast, these matter.
cd projects
cd ..
cd ~
cd /etc4. mkdir — create folders instantly
The -p flag is the one that actually matters. It creates the full nested path in a single command without complaining that intermediate directories don't exist yet. I use this constantly when scaffolding new Next.js projects from the terminal.
mkdir projects
mkdir -p app/src/components5. touch — create files without opening anything
touch creates empty files instantly. Technically it also updates timestamps on existing files, but in practice I use it purely for scaffolding — getting a project structure laid out before I start writing a single line of code.
touch notes.txt
touch index.js style.css6. cp — copy files and directories
Simple enough, but don't forget -r when copying a whole directory. I skipped it once, got an error, and spent five minutes confused. The r stands for recursive — it copies everything inside the folder too.
cp file.txt backup.txt
cp -r folder backup-folder7. mv — move or rename anything
mv does two jobs: it moves files to a new location, and it renames them by 'moving' to a new name in the same place. Renaming a misnamed file mid-project without leaving the terminal is genuinely satisfying.
mv old.txt new.txt
mv screenshot.png ~/Pictures8. rm — delete permanently (no undo)
This one is serious. There's no Recycle Bin in the terminal. Once it's gone, it's gone. Use -r for directories. The -f flag forces deletion without confirmation — powerful but dangerous. I once ran rm -rf with a slightly wrong path and deleted an entire project folder. Always double-check what you're about to delete, especially with wildcards or -f.
rm notes.txt
rm -r old-folder
rm -rf cache-folder9. cat — peek at a file without opening an editor
I use cat constantly to check config files, read .env examples, or quickly verify that a script looks right. It just dumps the file contents to the terminal. No frills. On Void Linux where I'm editing configuration files often, this saves a lot of editor round-trips.
cat .env.example
cat /etc/hosts10. nano — friendly terminal editor for quick edits
I use Vim for real development (more on that in another post), but for quick config edits — changing a systemd unit file, tweaking a cron job — nano is just faster to think in. Ctrl+O to save, Ctrl+X to exit. No mode confusion.
nano /etc/hosts11. grep — search inside files like a surgeon
This one sneaks up on you. At first it seems fiddly. Then one day you use grep -r to hunt a hardcoded API URL across an entire codebase and find it in two seconds, and something clicks. The -i flag makes it case-insensitive when you're not sure about casing.
grep "error" server.log
grep -r "API_KEY" .
grep -ri "todo" src/12. find — locate files by name or pattern
When grep searches inside files, find searches for the files themselves. The syntax is a bit verbose but it's worth learning. I use it most to find all JavaScript files in a project or track down a config file I know exists but can't remember where.
find . -name "*.js"
find /home -name "config*"
find . -name "*.env" -type f13. which — debug PATH issues instantly
Installed Node.js but npm still throws 'command not found'? which tells you exactly where a command lives on your system — or shows nothing if it can't find it, which tells you it's a PATH problem. Saved me hours of confusion on Void where you sometimes install things outside the default PATH.
which node
which npm
which xbps-install14. history — find that command you ran three days ago
Your shell keeps a log of every command you've run. Piping history through grep to find that long docker run command from last week is something I do at least twice a week. You can also hit Ctrl+R to do a live reverse search through history.
history
history | grep docker
history | grep git15. ps — see what's actually running
ps aux dumps all running processes. On its own it's a lot of output, but combined with grep it becomes precise. When I'm building an ESP32 dashboard and something is holding onto a port, ps aux | grep node finds it immediately.
ps aux
ps aux | grep node
ps aux | grep mosquitto16. top — live system monitor
Task Manager for the terminal. Real-time CPU and memory, updated live. Press q to quit. I check it when my system feels sluggish or I want to see which process is eating resources. htop is a friendlier alternative if you install it — colored output, scrollable process list.
top17. kill — shut down a stuck process
Get the process ID from ps or top, then kill it. The -9 flag (SIGKILL) is a hard stop — no cleanup, immediate termination. I reach for it when a Node.js server refuses to exit gracefully and is still holding the port I need.
kill 3421
kill -9 342118. df — check remaining disk space
The -h flag gives you human-readable output in GB and MB instead of raw block counts. I check this before recording video tutorials or doing large npm installs on my machine. Running out of disk space mid-operation causes cryptic errors that are annoying to diagnose.
df -h19. du — figure out what's eating your disk
du -sh * is one I run regularly. It shows the size of everything in the current directory sorted by nothing, which is why I often add a pipe to sort. Perfect for finding that node_modules folder you forgot was sitting in your home directory at 800MB.
du -sh *
du -sh node_modules
du -sh * | sort -h20. man — the answer is always in here
Every command ships with a manual page. When you don't know what a flag does, man is faster than a Google search and works offline. I use it most with commands I know well but whose edge cases I've forgotten. Press q to exit, / to search inside the man page.
man ls
man grep
man findThe part that actually makes all of this powerful: pipes
Once you start chaining commands with | you stop running individual commands and start building workflows. The output of one command becomes the input of the next. This is where the terminal starts feeling like it was designed for you specifically — because you can compose exactly what you need from small, focused tools.
ps aux | grep mosquitto
history | grep "npm run"
ls -la | grep ".env"
du -sh * | sort -h | tail -5Closing thoughts
I'm not going to tell you to memorize this list all at once — that's not how it works anyway. Pick three commands you don't know yet, force yourself to use them this week, and let the rest follow naturally. The terminal only feels foreign until it doesn't. After a month on Void Linux with nothing but DWM and a terminal, I genuinely can't imagine going back to clicking through GUIs for things I can do in two keystrokes.
