Skip to main content

Command Palette

Search for a command to run...

Linux from my Eyes

Lets understand Linux what I understand

Published
6 min read
Linux from my Eyes
S

Frontend Developer 💻 | Fueled by curiosity and Tea ☕ | Always learning and exploring new technologies.

The Filesystem That Doesn't Exist

Every Linux user knows /proc. But almost nobody knows what it actually is. It's not a filesystem. There are no files on any disk. Everything inside it is generated on the fly by the kernel the moment you read it. It's theater a stage where the kernel performs its internal state for you, formatted as files.

This matters because it means reading /proc/meminfo is not like reading a log file. It is the act of asking the kernel a live question. The answer is constructed at the exact moment your cat command touches the file descriptor.

Imagine you walk into a library. You see thousands of books on the shelves. Normally, you’d pick one up, and the words inside would be printed in ink, unchanging since the day the book was made. That is a Standard Filesystem (like your hard drive).

But Linux has a ghost library called /proc. When you open a book in /proc, the pages are blank until your eyes touch the paper. The moment you look, a librarian (the Kernel) sprints behind the page and scribbles down exactly what is happening in the building at that microsecond. When you close the book, the ink vanishes.

Notice the sizes: every file is 0 bytes. That's the tell. Real files have sizes. These are kernel function pointers dressed as files. /proc/self is particularly mind-bending it's a symlink that points to the PID of whoever reads it. Every process that reads /proc/self sees itself. It's a mirror.

Your Process Is a Directory

Every running process gets its own directory in /proc/[PID]/. Inside that directory is a complete portrait of the process its open files, its memory map, its environment variables, its current working directory, what executable it is. This is not metadata. This is the process, seen from the outside.

What we found in PID 1

PID 1 is the init process the ancestor of all other processes. In a traditional Linux system, this is systemd or init. Here, it revealed something different:

Command

  • /proc/1/: This is the directory for the Init process, the mother of all processes. It is the first thing the kernel starts after booting.

  • cmdline: This "file" contains the exact command used to start that process.

  • tr '\0' ' ': Kernel files in /proc often use "null bytes" (\0) to separate arguments. This part of your command simply replaces those invisible separators with spaces so you can read them.

The output /usr/lib/systemd/systemd tells us that our system is managed by systemd.

In the illusion of the filesystem, this file exists to tell you exactly how the system was brought to life. The --deserialize=79 flag is a piece of internal state a memory systemd kept of its previous self if it was re-executed without a full reboot.

Network Knobs Hidden in /proc/sys/net

Sysadmins tune Linux networking by writing numbers to files. Security hardening, performance tuning, DDoS mitigation all of it lives in /proc/sys/net/ipv4/ and friends. Most documentation tells you what to set. Almost none explains what you can read to understand the system's current posture.

Everything is a File in Linux

You're running a Node.js or Python server and under load it crashes with EMFILE: too many open files. This is one of the most common errors developers hit and one of the least understood. Here's the full picture.

Every open file, socket, pipe, or database connection consumes a file descriptor (FD). Linux enforces limits on how many a process can hold at once. There are two limits stacked on top of each other:

Limit Where it lives Default Scope
Soft limit ulimit -n 1,024 Per process — the active ceiling. Can be raised to hard limit by user.
Hard limit ulimit -Hn 4,096 Per process — the ceiling on the soft limit. Only root can raise.
System limit /proc/sys/fs/file-max ~400,000 Entire OS — total FDs across all processes combined.

The default soft limit of 1,024. A modern web server handling 500 concurrent connections is already using half its budget just for sockets, before counting open config files, logs, and library handles.

Address Already in Use

You start your dev server and get EADDRINUSE: address already in use :::3000. Something is already listening on that port. Here's how to find and handle it.

Sometimes there's no process on the port but you still can't bind. This happens because the port is in TIME_WAIT state the kernel is holding it for 60 seconds after a recent connection closed, to ensure stale packets don't confuse a new connection.

Zombie Processes

A zombie process is not a running process. It's a dead process whose exit code hasn't been collected yet. The kernel keeps a tiny tombstone entry in the process table until the parent calls wait() to read the exit status. Until then: zombie.

Scenario Why zombies appear Fix
Python subprocess You call Popen() but never call .wait() or .communicate() Always call proc.wait() or use subprocess.run()
Node.js child_process Spawned process exits but 'exit' event never handled Listen to the 'exit' or 'close' event
Docker containers Your app is PID 1 and spawns children without a proper init Use --init flag or tini as PID 1
Shell scripts Background jobs & whose parent script exits without wait Call wait at end of script or use wait $! per job

/etc/hosts

/etc/hosts is checked before DNS. This is defined in /etc/nsswitch.conf as hosts: files dns "files" (hosts) first, "dns" second. This makes /etc/hosts an instant, zero-latency DNS override with no servers involved.

Entry to add What it does for you
127.0.0.1 myapp.local Access your local dev server at http://myapp.local:3000 in any browser — useful when cookies or CORS require a real-looking hostname.
127.0.0.1 api.myapp.local Fake a subdomain for your local API. No DNS server. No Nginx. Just edit hosts and curl works immediately.
0.0.0.0 ads.tracker.com Block a domain entirely by routing it to 0.0.0.0 (not routable, fails fast). More effective than 127.0.0.1 because 127.0.0.1 might have something listening.
192.168.1.50 staging Give your staging server a short name. Now you can ssh staging, curl staging:8080, etc.
127.0.0.1 prod-db.company.com Intercept production DNS for testing. Point the production hostname to localhost temporarily. Useful for testing without modifying app configs.

Quick Reference Cheatsheet

H

This makes me wanna work on linux, soon will hop on.