Mastering Linux Commands: A Practical Guide for Developers and AI Engineers
Quick summary: Eight reads before you restart a slow API: load, memory, disk, inodes, listeners, DNS, one request, and the log tail.
Key Takeaways
- Eight reads before you restart a slow API: load, memory, disk, inodes, listeners, DNS, one request, and the log tail
- On 11 October 2026 the lab script on this Mac printed , , , , and
- showed the root volume at 11% capacity with 105Gi available
- Eight reads come before you restart a slow API: load, memory, disk, inodes, listeners, DNS, one request, and the log tail
- Published copy: /examples/architecture-blog-2026/mastering-developer-tools/mastering-linux-commands/check-host

Table of Contents
On 11 October 2026 the lab script on this Mac printed uname=Darwin 27.0.0 arm64, bash=GNU bash, version 5.3.20(1)-release, ls_family=not_gnu, systemd=absent, and rg=present. df -h / showed the root volume at 11% capacity with 105Gi available. That number describes one workstation, not a production server.
Eight reads come before you restart a slow API: load, memory, disk, inodes, listeners, DNS, one request, and the log tail. Restarting first throws away the evidence.
What broke —
ls --versionon this Darwin host exited withunrecognized optionand printed BSDlsusage. A command an agent copied from a GNU coreutils page failed immediately. The fix is to read the locallshelp or install GNU coreutils asgls, not to assume the flag exists.
Reproduce this — Run
bash examples/architecture-blog-2026/mastering-developer-tools/mastering-linux-commands/check-host.sh. Expected lines:ls_family=,systemd=, andlab=ok. On macOS,not_gnuandabsentare normal. Published copy: /examples/architecture-blog-2026/mastering-developer-tools/mastering-linux-commands/check-host.sh.
We recommend set -euo pipefail in scripts you keep, and an interactive shell without set -e. The trade-off: -e stops a script at the first failure, which is what you want in automation, and it surprises you in an interactive session when a test command is meant to fail.
Why shell skill still matters
An agent can propose rm -rf node_modules or kill -9 the API pid. You need to see the expanded path, the real pid, and whether the disk is full before you agree. The shell is also how you read logs on a host that has no agent installed.
Shell mechanics that change what a command does
Bash built-ins (cd, export, exit, jobs) run inside the shell. External programs (/bin/ls, rg) are separate processes. type cd and type ls show which is which.
Quoting:
'single quotes'pass the text literally."double quotes"allow$variablesand command substitution.- Unquoted
*expands to file names. An empty match can become a literal*or, withnullglob, an empty argument. Echo the command before you run it when the path includes a glob.
Exit status is $? immediately after the command. 0 means success. A pipeline’s status is the last command unless set -o pipefail is on. With pipefail, any failed stage fails the pipeline. Chain with && when the second command should run only after success, and || for a fallback. ; runs the next command either way.
Redirects: > truncates a file. >> appends. 2> is stderr. > on an existing file replaces it. Potentially destructive. noclobber (set -o noclobber) makes > fail if the file exists. There is no trash folder.
man bash is the manual for the shell on this machine. GNU Bash is documented at gnu.org/software/bash/manual.
Installation and what is already there
You do not install ls. You install missing tools, and you check the family first.
Context: the lab script above. Read-only.
uname -srm
bash --version
type ls
command -v systemctl || echo "systemd tools absent"
command -v rg || echo "ripgrep absent"- Linux: coreutils, findutils, and grep come from the distro.
apt,dnf, andapkare not interchangeable. Read that distro’s docs before a system upgrade. - macOS: BSD userland plus a Bash you may have installed separately. This host’s
/bin/bashmay be older than the Bash 5.3.20 reported bybash --versionifbashonPATHis Homebrew.type -a bashshows every copy. - Windows: use WSL for these commands. PowerShell aliases (
lsasGet-ChildItem) are a different language. Run the lab inside the Linux environment you mean to operate.
man ls or ls --help (GNU) documents flags. BSD ls has no --help in the GNU sense. The lab’s ls_family line is the check.
Files and inspection
| Task | Command | Risk |
|---|---|---|
| Where you are | pwd -P | Read-only |
| List | ls -la | Read-only |
| Change directory | cd | Shell state only |
| Make a directory | mkdir -p dir/sub | Local change |
| Copy | cp -a SRC DEST | Local change. Overwrites DEST. |
| Move | mv SRC DEST | Local change. Overwrites DEST. |
| Delete a file | rm FILE | Potentially destructive |
| Recursive delete | rm -r DIR | Potentially destructive |
| Disk type of a path | df -h PATH | Read-only |
| File type | file PATH | Read-only |
| Metadata | stat PATH | Read-only. Flags differ on BSD vs GNU. |
| Pager | less PATH | Read-only |
| Head and tail | head, tail -n 50 | Read-only |
| Follow a log | tail -f FILE | Read-only |
| Counts | wc -l FILE | Read-only |
pwd -P resolves symlinks. pwd alone may show the logical path.
rm -r does not prompt unless you pass -i or the shell aliases rm to rm -i. Check type rm. Alias or not, echo the path first:
echo /path/you/mean
ls -ld /path/you/meanIf the variable is empty, rm -r "$dir" can target the current directory or fail. With set -u, an unset variable aborts the script. Prefer that.
Archives: tar -tzf file.tar.gz lists a tarball and extracts nothing. tar -xzf extracts. Local change. List first.
Links: ln -s TARGET LINK creates a symlink. ls -l shows the target. A relative symlink breaks when the link is moved.
Search
| Task | Tool | Notes |
|---|---|---|
| Find files | find DIR -name '*.log' | POSIX. -delete is destructive. |
| Search content | grep -R -n PATTERN DIR | GNU and BSD differ on -P. |
| Faster search | rg PATTERN DIR | Optional. Present on the lab host. |
| Sort and unique | sort FILE, uniq -c | uniq expects sorted input. |
| Columns | cut -d, -f1 | Text only. |
| Translate | tr '[:upper:]' '[:lower:]' | Bytes, not a parser. |
| Streams | xargs | Splits on spaces unless -0. |
| Line edits | sed, awk | GNU and BSD sed -i differ. |
find DIR -type f -name '*.log' -print is read-only. find ... -exec rm {} \; deletes. Potentially destructive. Use -print and read the list before -exec or -delete.
xargs runs a command on arguments from stdin. xargs rm is how a bad search becomes a delete. Prefer xargs -r on GNU (do not run if stdin is empty) and null-delimited pairs: find ... -print0 | xargs -0.
rg is not part of POSIX. If command -v rg fails, use grep.
Permissions
ls -l shows mode, owner, group, size. id shows your uid, gid, and groups. chmod and chown change metadata. Local change, and on a shared host they change who can read data.
chmod 644 is owner read/write, others read. chmod 600 is owner only. chmod -R 777 makes a tree world-writable. Do not use it as a fix for a container that should drop root. The Docker and Kubernetes articles cover the runtime side.
sudo -n true checks whether passwordless sudo works, and does not run your command. If it fails, you need a password or you are not in sudoers. sudo logs on many distros. It is not a way to skip reading the error.
ACLs (getfacl / setfacl) exist on some Linux filesystems and not on a default macOS APFS workflow. If getfacl is missing, you do not have that tool. Do not invent an ACL to explain a permission error.
umask prints the mask for new files. A umask of 022 creates files as 644 and directories as 755, subject to the creating program.
Processes, memory, disk, network
| Question | Linux (typical) | macOS (this host) | Risk |
|---|---|---|---|
| Load and CPU | uptime, top -bn1 or ps aux | uptime, top -l 1 | Read-only |
| Memory | free -h | memory_pressure or vm_stat | Read-only |
| Disk space | df -h | df -h | Read-only |
| Inodes | df -i | df -i (column layout differs) | Read-only |
| Directory size | du -sh DIR | du -sh DIR | Read-only |
| Listeners | ss -lntp | netstat -anv or lsof -nP -iTCP -sTCP:LISTEN | Read-only |
| DNS | getent hosts NAME or dig NAME | dig NAME if installed | Read-only |
| HTTP | curl -sS -o /dev/null -w '%{http_code}\n' URL | same, if curl is installed | Read-only for GET |
free is not on macOS. The lab host has no systemctl, so service status is not systemctl status. Launchctl is the Mac equivalent and is outside this article’s Linux service section.
kill PID sends SIGTERM. The process can catch it and shut down. kill -9 PID sends SIGKILL. The kernel stops the process without cleanup. Identify the command line first. Killing a database or a queue worker during a write is how you get a longer outage.
fuser and lsof show who holds a file or port. Useful when a deploy says the port is taken. Read-only until you kill something.
SSH and files between hosts
ssh -G HOST prints the effective SSH config and does not connect. Read-only.
ssh HOST 'uptime' runs one command. That remote command has the remote user’s privileges. Read it before you approve an agent that generated it.
scp and sftp copy files. rsync -n is a dry run. Drop -n only after the file list looks right. Remote mutation when the destination is another host.
Do not pipe curl into bash for an install script you have not read. Download, read, then run. A coding agent that suggests curl URL | bash is asking you to execute unseen code.
Logs and services
On a host where command -v systemctl succeeds, systemd is the service manager. systemd manuals document:
systemctl status SERVICE
systemctl cat SERVICE
journalctl -u SERVICE -n 100 --no-pagerThose are read-only. systemctl restart is a remote or local mutation of the running service. Restart after you have the eight reads, not before.
systemctl --user is a different bus from system services. Check which one the unit belongs to.
Hosts without systemd (containers based on Alpine openrc, older Amazon Linux variants, macOS) will not have these commands. The lab prints systemd=absent in that case. Use the supervisor that host actually runs: the process manager in the container image, launchd on macOS, or the platform’s service tool. Do not install systemd inside a container to get journalctl.
Cron: crontab -l lists a user’s crontab and does not edit it. crontab -e edits. Package timers on systemd are systemctl list-timers.
Boot: journalctl -b is the current boot on systemd. last -x shows shutdowns where the last command exists.
Packages, env, checksums
Package installs change the system and can start services. Local change, sometimes potential cost if the host is metered. Prefer the distro’s package manager over a random shell installer.
env and printenv dump the environment. Secrets are often in that dump. Do not paste env into a ticket. Ask for one variable: printenv PATH.
sha256sum FILE on GNU, shasum -a 256 FILE on macOS. Compare checksums from the vendor’s site, not from the same page that offered the binary if you do not trust that page.
gzip -t FILE tests an archive and does not extract.
Scenario: a catalog API is slow, and you do not restart it yet
Work on the host that runs the process, or from a bastion with SSH. Read-only until a human decides otherwise.
uptimefor load average versus CPU count (nprocon Linux,sysctl -n hw.ncpuon macOS).- Memory:
free -hon Linux. Swap activity means you are past RAM. df -handdf -i. A full disk or a full inode table stops writes and can stall logs.pssorted by CPU or RSS. Name the pid and the command. A runaway is evidence. Killing it is a second decision.- Listeners: is the API port open on the expected address?
- DNS: does the database hostname resolve to the address you expect?
- One request:
curlwith a timeout (curl --max-time 5) and the HTTP code. A hang is different from an HTTP 500. - Logs:
tailorjournalctl -ufor the last errors. Look for connection refused, timeout, and disk errors.
If the host is on AWS and the process is a container or a Lambda, move to AWS CLI, Docker, or Kubernetes with the host notes in hand. Distributed tracing is covered in debugging production AWS systems.
Safety list
- Recursive delete:
echothe path,ls -ldit, thenrm. Refuse an empty variable. sudo: identify the user withidfirst.chmodandchown: prefer a specific mode over-R 777.- Globs:
echothe expansion. find -execandxargs: print the list before you delete.>overwrites. Point it at a new file name when you are unsure.kill: SIGTERM, then check the process is gone, then SIGKILL if you accept the lack of cleanup.- Piped remote scripts: read the file, then run it.
Working with a coding agent
Ask the agent to propose the read-only command and to explain the field you will look at (%iused, load average, HTTP code). Approve rm, chmod -R, kill -9, package upgrades, and sudo only after the preview. Run echo on any command that contains a glob or a variable. Then run the command yourself if it is production.
The agent’s permission dialog is not file-system permission. sudo and IAM are separate. See AI agent tools.
Five labs
- Run
check-host.sh. Recordls_familyandsystemd. That is your local baseline. - In
/tmp,mkdir,cp,mv, andrmone file you created.ls -lafter each step. find /tmp -name 'fm-lab-*' -printand confirm it prints nothing you do not recognize. Do not add-delete.psand find your shell’s pid. Do not kill it. Write down the command line so you can see how easy it is to target the wrong pid.curl --max-time 5 -sS -o /dev/null -w '%{http_code}\n' https://example.comand read the code. Expected: a three-digit HTTP status, often 200. If curl is missing, the lesson is that the tool is optional and you install it on purpose.
Progression: navigation and quoting, then read-only inspection, then process and disk diagnosis, then service restarts only after the eight reads.
What this post does not cover
Performance tuning of a specific database, eBPF, and SELinux policy authoring. Container images and kubectl are the next two articles. It also does not document every flag of awk.
What to do this week
- Run the lab script on your laptop and on one non-production Linux host. Keep the two outputs. They will differ.
- Add
echobefore any generatedrmorchmod -R. - Find where the API logs live before the next incident.
- If the API runs in AWS, pair this list with the AWS CLI identity check.
Quick reference
| I need to | Command | Risk |
|---|---|---|
| Know the OS | uname -srm | Read-only |
| See a full disk | df -h and df -i | Read-only |
| See who listens | ss or lsof | Read-only |
| Page a file | less | Read-only |
| Delete | rm after ls | Potentially destructive |
| Service logs on systemd | journalctl -u SERVICE | Read-only |
You should be able to tell a builtin from an external command, refuse a recursive delete you have not previewed, and collect the eight reads before a restart.
Further reading
- GNU coreutils manual
- Linux man-pages
- Bash manual
- systemd
- Series: Git, AWS CLI, Docker, Kubernetes, Bedrock CLIs, AI agent tools
Contact us or see DevOps pipeline setup if you want this inspection habit in a runbook your on-call can follow.
Frequently asked questions
When should you not run rm -rf on a path an agent suggested?
Do Linux commands work the same on macOS?
Is sudo a way to fix permission denied?
What should I check before killing a process?
Does this page list every Linux command?

AWS Cloud Architect & AI Expert
AWS-certified cloud architect and AI expert with deep expertise in cloud migrations, cost optimization, and generative AI on AWS.




