/user/kayd @ devops :~$ cat bash-cli.md

Bash CLI One-Liners Cheatsheet Bash CLI One-Liners Cheatsheet

QR Code linking to: Bash CLI One-Liners Cheatsheet
Karandeep Singh
Karandeep Singh
• 6 minutes

Summary

The command-line one-liners I use daily. find/xargs, grep, curl, jq, tar, disk and process triage, network checks, ssh/rsync, history tricks, and job control.

These are the one-liners I actually type on production boxes. Muscle-memory commands for finding files, chasing disk usage, poking APIs, and triaging misbehaving processes. When a one-liner turns into a script, the Bash Basics Cheatsheet covers making it robust.

find + xargs

Docs: find(1) man page

find /var/log -name '*.gz' -mtime +30 -delete        # old compressed logs
find . -type f -size +100M                           # large files
find . -name '*.sh' -exec chmod +x {} +              # batch chmod
find . -type f -name '*.yaml' | xargs grep -l 'image:'
find . -name '*.log' -print0 | xargs -0 rm --        # -print0/-0: safe with spaces
find . -type d -empty -delete                        # remove empty dirs
find /etc -newer /etc/hostname -type f               # changed since that file
ls *.png | xargs -P4 -I{} convert {} {}.webp         # -P4: 4 parallel jobs

grep

Docs: grep(1) man page

grep -r 'TODO' src/                    # recursive
grep -rn --include='*.tf' 'aws_s3' .   # line numbers, filter by glob
grep -E 'error|fatal|panic' app.log    # extended regex, alternation
grep -o 'req_id=[a-f0-9]*' app.log     # print only the match
grep -c '500' access.log               # count matching lines
grep -v '^#' config | grep -v '^$'     # strip comments and blanks
grep -B2 -A5 'Traceback' app.log       # context: 2 before, 5 after
grep -i -l 'password' -r . 2>/dev/null # files containing, case-insensitive

sort / uniq / wc Pipelines

Docs: sort(1) man page

sort file | uniq -c | sort -rn | head            # frequency count, descending
sort -t: -k3 -n /etc/passwd                      # numeric sort on field 3
sort -u hosts.txt                                # sort + dedupe in one
sort -h                                          # human sizes: 1K < 2M < 3G
uniq -d sorted.txt                               # only duplicated lines
wc -l < file                                     # line count, no filename
comm -23 <(sort a.txt) <(sort b.txt)             # lines in a but not b
awk '{print $1}' access.log | sort | uniq -c | sort -rn | head   # top IPs

For heavier field surgery in these pipelines, see the Bash sed & awk Cheatsheet.

tar / gzip / zstd

Docs: tar(1) man page

tar czf app.tar.gz app/                # create gzip archive
tar xzf app.tar.gz -C /opt/           # extract to a directory
tar tzf app.tar.gz                    # list contents without extracting
tar czf - /data | ssh host 'cat > /backup/data.tar.gz'   # archive over ssh
tar --exclude='.git' --exclude='node_modules' -czf src.tar.gz .
tar caf app.tar.zst app/              # -a: pick compressor by extension
zstd -T0 bigfile                      # zstd on all cores; much faster than gzip
gzip -dk file.gz                      # decompress, keep original
zcat access.log.gz | grep ' 500 '     # search inside without extracting

curl

Docs: curl manpage on curl.se

curl -I https://example.com                       # headers only
curl -sfSL https://example.com/health             # silent, fail on HTTP errors
curl -o out.bin -L https://example.com/dl         # follow redirects, save
curl -w '%{http_code} %{time_total}s\n' -o /dev/null -s https://api.example.com
curl -X POST https://api.example.com/v1/deploys \
  -H 'Content-Type: application/json' \
  -H "Authorization: Bearer $TOKEN" \
  -d '{"service": "web", "version": "1.4.2"}'
curl --retry 5 --retry-delay 2 --retry-all-errors -sf https://flaky.example.com
curl -u user:pass ftp://host/file                 # basic auth
curl -x http://proxy:3128 https://example.com     # via proxy

jq Basics

Docs: jq Manual on jqlang.org

curl -s https://api.example.com/pods | jq .              # pretty-print
jq '.items[].metadata.name' pods.json                    # extract a field
jq -r '.token' resp.json                                 # -r: raw, no quotes
jq '.items | length' pods.json                           # count
jq '.[] | select(.status == "failed") | .id' jobs.json   # filter
jq '.[] | {name: .metadata.name, ip: .status.podIP}'     # reshape
jq -r '.[] | [.name, .cpu] | @tsv' nodes.json            # TSV for awk/column
jq -n --arg env "$ENV" '{environment: $env}'             # build JSON from shell
jq 'keys' obj.json                                       # what fields exist?

Disk & Process Triage

Docs: ps(1) man page

df -h                                  # filesystem usage
du -sh /var/* | sort -rh | head        # what's eating this disk
du -xh --max-depth=2 / | sort -rh | head -20   # -x: don't cross filesystems
ncdu /var                              # interactive, if installed

ps aux --sort=-%mem | head             # top memory hogs
ps aux --sort=-%cpu | head             # top CPU hogs
ps -ef --forest                        # process tree
top -o %MEM                            # top sorted by memory (htop if you can)
lsof -p 1234                           # files open by PID
lsof +D /var/log                       # who has files open under a dir
lsof -i :8080                          # what's listening on 8080
kill -TERM 1234 && sleep 5 && kill -0 1234 && kill -KILL 1234

Network

Docs: ss(8) man page

ss -tlnp                               # listening TCP sockets + owning process
ss -s                                  # socket summary (state counts)
dig +short example.com                 # just the A record
dig example.com MX                     # specific record type
dig @1.1.1.1 example.com               # query a specific resolver
dig -x 93.184.216.34                   # reverse lookup
nc -zv host 5432                       # is that port open?
nc -l 9000                             # quick listener for testing
timeout 3 bash -c '</dev/tcp/host/443' && echo open   # no nc? pure bash
curl -sv telnet://host:6379 </dev/null # handshake check via curl
ip -br addr; ip route                  # interfaces and routing at a glance

ssh / scp / rsync

Docs: rsync(1) man page

ssh -J bastion.example.com user@10.0.2.15        # jump host
ssh -L 5432:db.internal:5432 bastion             # local port forward
ssh host 'sudo journalctl -u nginx -n 50'        # run remote command
ssh-copy-id user@host                            # install your key

scp file.tar.gz user@host:/tmp/                  # simple copy
scp -r user@host:/var/log/app ./logs/            # recursive pull

rsync -avz --progress ./site/ user@host:/var/www/site/   # sync (mind the slashes)
rsync -avz --delete src/ dst/                    # exact mirror; deletes extras
rsync -avzn --delete src/ dst/                   # -n: ALWAYS dry-run first
rsync -avz -e 'ssh -J bastion' data/ user@internal:/data/

Trailing slash on the source means “contents of”; no slash copies the directory itself.

History Tricks

Docs: History Expansion, GNU Bash manual

TrickEffect
!!Re-run the last command (sudo !! is the classic)
!$Last argument of the previous command
!*All arguments of the previous command
!grepRe-run the most recent command starting with grep
^old^newRe-run last command with first old replaced by new
Ctrl-rReverse-search history incrementally (press again to cycle)
Alt-.Insert last argument, keep pressing to go further back
$_Last argument, as a variable in scripts
mkdir -p /opt/app/releases/v2 && cd !$    # !$ expands to the new path
history | awk '{print $2}' | sort | uniq -c | sort -rn | head   # your top commands

Job Control

Docs: Job Control, GNU Bash manual

long_build.sh &                # run in background
jobs -l                        # list jobs with PIDs
fg %1                          # bring job 1 to foreground
bg %1                          # resume a Ctrl-Z'd job in background
kill %2                        # kill by job number
Ctrl-Z                         # suspend current foreground job

nohup ./migrate.sh > migrate.log 2>&1 &   # survive hangup on logout
./worker.sh & disown           # background + detach from the shell
wait                           # block until all background jobs finish
wait -n                        # until any one finishes (bash 4.3+)

For anything long-running over ssh, prefer tmux over nohup; you get your session back, output included.

0
  • Bash Basics: set -euo pipefail, parameter expansion, traps, and arrays, everything needed to turn these one-liners into scripts that survive production
  • Bash sed & awk: heavier text processing, meaning in-place edits, column sums, extracting text between markers, and the GNU vs BSD gotchas
  • tmux: session, window, and pane keybindings plus scripted layouts, so long-running pipelines outlive a dropped SSH connection

There’s more in the Bash group, and the whole cheatsheet library is one level up.

Similar Articles

More from development

Go (Golang) Cheatsheet

Go cheatsheet covering the go toolchain, syntax essentials, goroutines and channels, table-driven …

tmux Cheatsheet

Quick-reference tmux cheatsheet: sessions, windows, panes, copy mode, synchronize-panes, .tmux.conf …

Jenkins Cheatsheet

Jenkins cheatsheet with declarative pipeline syntax, credentials, parameters, parallel stages, …

Bash Basics Cheatsheet

Quick-reference Bash basics cheatsheet: variables, parameter expansion, conditionals, loops, arrays, …