Useful Linux commands I actually use (and why)

Linux is one of those things that feels "basic"... until you're on call, production is on fire, and you need one command to confirm a hypothesis right now.

This post is not a random cheatsheet. It's a small list of commands I keep coming back to when I'm debugging systems, migrations, data pipelines, and "why is this service slow?" situations.

Rule of thumb: start with observation, not with changing stuff. These commands help you observe fast.


watch — when you need a live view (without writing code)

Sometimes there's no async way to get state (no events, no UI, no metrics you trust yet) and you end up polling: progress endpoints, counters, queue sizes, replication lag, etc.

watch runs a command every n seconds and refreshes the output.

watch -n 1 'curl -s localhost:27182/api/v1/progress -X GET | jq .'

Why it's useful

  • quick "poor man's dashboard"
  • great for long-running operations (migrations, backfills, rebalances)

Pro tips

  • Add -d to highlight diffs between refreshes:
    watch -n 1 -d 'curl -s localhost:27182/api/v1/progress | jq .'
    
  • If the output is JSON, pipe through jq and keep the filter simple (start with .).
    (If you forget the filter, jq won't behave how you expect.)

scp — quick file copy over SSH (when you can't be bothered with S3)

Copy a file from a remote VM to your laptop:

scp -i "david-sanchez-key.pem"   ec2-user@ec2-1-10-15-121.eu-west-1.compute.amazonaws.com:/home/ec2-user/logs.log   /Users/user/Downloads/

Copy a file from your laptop to the VM:

scp -i "david-sanchez-key.pem"   /Users/folder1/logs.log   ec2-user@ec2-1-10-15-121.eu-west-1.compute.amazonaws.com:/home/ec2-user/

Replace:

  • path to the key
  • VM username
  • VM hostname
  • remote path
  • local destination path

Pro tips

  • Copy a whole folder (recursive): -r
  • If SSH is on a non-standard port: -P 2222
  • If you're copying big files regularly, use rsync (below). scp is fine for "get me that log now".

rsyncscp, but grown up (fast + resumable)

rsync is my default when:

  • files are large
  • connections are flaky
  • I want progress + resume
  • I'm syncing directories
rsync -avP -e "ssh -i david-sanchez-key.pem"   ec2-user@ec2-1-10-15-121.eu-west-1.compute.amazonaws.com:/home/ec2-user/exports/   ./exports/

Flags I use:

  • -a archive mode (preserves permissions/timestamps)
  • -v verbose
  • -P progress + partial (resume-friendly)

tail + grep — the "I need the signal, not the noise" combo

Follow logs live:

tail -f /var/log/syslog

Follow logs and filter:

tail -f /var/log/syslog | grep -i error

Pro tip: show context lines around matches:

grep -i -n -C 2 "timeout" /var/log/syslog
  • -n line numbers
  • -C 2 two lines of context above and below

journalctl — systemd logs without guessing where the file is

On many modern Linux distros, services log to systemd.

journalctl -u myservice -f

Useful variations:

journalctl -u myservice --since "1 hour ago"
journalctl -u myservice -n 200

ss — what's listening on this box? (and who owns it)

When someone says "the port is open" and you don't trust them:

ss -lntp
  • -l listening
  • -n numeric (no DNS)
  • -t TCP
  • -p process info

If you want to focus on a port:

ss -lntp | grep ":27017"

lsof — "who is using this file/port?"

Classic "why can't I delete this file?" or "who has this port?"

lsof -i :27017
lsof /path/to/file

curl — when you need to test a service like a machine would

Two patterns I use constantly:

1) show timing breakdown

curl -s -o /dev/null -w "dns:%{time_namelookup} connect:%{time_connect} ttfb:%{time_starttransfer} total:%{time_total}\n" https://example.com

2) fail fast (so scripts don't pretend everything is OK)

curl -fsS https://example.com/health
  • -f fail on HTTP errors
  • -sS silent, but still show errors

jq — JSON sanity without opening a browser

Pretty print:

curl -s https://api.example.com/status | jq .

Extract only what you care about:

curl -s https://api.example.com/status | jq -r '.progress.percentage'

find — locate files fast (and safely)

Find big log files:

find /var/log -type f -size +100M -print

Find and delete (careful):

find /tmp -type f -name "*.tmp" -mtime +7 -print
# if it looks correct, then:
# find /tmp -type f -name "*.tmp" -mtime +7 -delete

I always run the -print version first. Always.


Tiny checklist: what I run first in a "something is slow" incident

  1. Is the service even up?
curl -fsS http://localhost:8080/health
  1. Are we CPU/mem bound?
top
  1. Are we network/ports bound?
ss -lntp
  1. Do logs show errors/timeouts?
journalctl -u myservice --since "30 min ago"

That sequence alone finds a surprising amount of issues.