The Unix commands every developer should know

Unix command line tools are small, composable programs for inspecting files, transforming text, moving data and controlling processes. You do not need to memorise every option, bu…

Unix command line tools are small, composable programs for inspecting files, transforming text, moving data and controlling processes. You do not need to memorise every option, but you should know the reliable defaults, the sharp edges and when to compose tools through pipes. This is a broad primer covering the commands you will reach for most days.

Start with navigation and inspection

Use pwd, ls, cd and stat to understand where you are and what a file is before changing it. Prefer explicit paths in scripts and automation. In an interactive shell, relative paths are convenient. In a script, they are a common source of accidental writes.

pwd
ls -la
stat README.md

Use file when the extension is not enough. It reads file content and reports a detected type, which helps before piping binary data through text tools.

file archive.tar.gz
file ./bin/tool

Use readlink or realpath when symbolic links matter. readlink reports a link target. realpath resolves a path to an absolute canonical name, expanding symbolic links and removing . and .. components.

readlink ~/.config/editor/config
realpath ./src/../src/index.ts

Read files without editing them

Use cat for short files and for feeding data into another command. Use less for reading longer output, because it does not require loading the whole result into the terminal scrollback.

cat package.json
less logs/app.log

Use head and tail to sample. tail -f follows appended data, which is useful for logs.

head -n 20 logs/app.log
tail -n 50 logs/app.log
tail -f logs/app.log

Use wc to count lines, words and bytes. In build and data checks, wc -l is often enough to catch an empty or unexpectedly large result.

wc -l src/**/*.ts

Move, copy and remove files deliberately

Use cp, mv, mkdir and rm with explicit operands. For directories, use mkdir -p when intermediate directories may not exist.

mkdir -p dist/assets
cp README.md dist/README.md
mv dist/README.md dist/readme.txt

Be careful with rm -r, which removes directory trees. The -- marker tells the command to stop parsing options, which matters when a path may begin with a hyphen. Safe deletion in scripts is covered in more depth in the post on writing safe, readable Bash scripts.

rm -rf -- "$target"
rm -- "-temporary-file"

Search names and content

Use find when the primary question is about paths or file metadata, and grep when the primary question is about matching lines in text.

find . -type f -name '*.md'
grep -R "TODO" src

Use find with -exec ... {} + to run a command once over a batch of matched paths rather than spawning a new process per file. For more on fast searching, see the post on finding things fast.

find . -type f -name '*.log' -exec wc -l {} +

Transform text in pipelines

Use sort to order lines. Set LC_ALL=C when bytewise, reproducible ordering matters more than locale-aware collation, since this forces byte-order comparison rather than the rules of the current locale.

LC_ALL=C sort names.txt

Use uniq only after sorting, unless you only want to collapse adjacent duplicates.

LC_ALL=C sort names.txt | uniq -c

Use cut for simple column extraction from delimited text. Use awk when the transformation needs fields, conditions or arithmetic.

cut -d ':' -f 1 /etc/passwd
awk -F ',' '$3 == "active" { print $1 }' users.csv

Use sed for simple stream edits, especially substitution. Keep complex parsing out of sed and use a real parser for structured formats.

sed 's/foo/bar/g' input.txt

Inspect processes and resources

Use ps to inspect processes, kill to send signals and df or du to inspect storage.

ps aux | grep '[n]ode'
df -h
du -sh node_modules

Use env to inspect environment variables and to run a command with a controlled environment.

env | sort
env NODE_ENV=production node server.js

Compose commands carefully

Pipes connect the standard output of one command to the standard input of the next. Redirection writes output to files.

grep -R "deprecated" src | wc -l
sort input.txt > sorted.txt

Use tee when you need to see output and write it to a file.

npm test 2>&1 | tee test.log

By default the exit status of a pipeline is the exit status of its last command, so a failure earlier in the pipeline can go unnoticed. In Bash scripts, use set -o pipefail so the pipeline reports a non-zero status if any command in it fails.

Prefer boring commands in automation

Interactive shortcuts are fine at the prompt. Scripts should be more conservative. Quote variables, use explicit paths, choose commands with stable semantics and make destructive operations easy to review.

A good habit is to ask three questions before running a command: what input will it read, what output will it write and what will happen if a filename contains whitespace or starts with a hyphen.

Conclusion

The most useful Unix commands are not obscure. They are the small tools that let you inspect state, filter text, move files and compose repeatable pipelines. Learn the common cases first, then learn the safety rules that keep those commands predictable in scripts and production shells.