Cheatsheets
Quick reference for commands I use daily. No fluff.
Search results
Setup and Config
git config --global user.name "Name" git config --global user.email "email@example.com" git config --global core.editor vim git config --global init.defaultBranch main git config --global pull.rebase true git config --global alias.co checkout git config --list --show-origin git config --global credential.helper cache git config --global core.autocrlf input git config --global diff.tool vscode && git config --global difftool.vscode.cmd 'code --wait --diff $LOCAL $REMOTE' Basics
git init git clone <url> git clone --depth 1 <url> git add <file> git add -p git commit -m "message" git commit --amend git status git status -s git diff git diff --staged git diff <branch1>..<branch2> Branching
git branch git branch -a git branch <name> git branch -d <name> git branch -D <name> git branch -m <old> <new> git switch <branch> git switch -c <branch> git checkout -b <branch> git branch --merged git branch -vv Merging and Rebasing
git merge <branch> git merge --no-ff <branch> git merge --squash <branch> git merge --abort git rebase <branch> git rebase -i HEAD~3 git rebase --onto main feature bugfix git rebase --abort git rebase --continue git config --global rerere.enabled true Stashing
git stash git stash -u git stash push -m "description" git stash list git stash pop git stash apply stash@{2} git stash drop stash@{0} git stash clear git stash show -p git stash branch <name> Remote
git remote -v git remote add origin <url> git remote remove <name> git remote rename origin upstream git fetch git fetch --prune git pull git pull --rebase git push git push -u origin <branch> git push origin --delete <branch> git push --force-with-lease Undoing Changes
git restore <file> git restore --staged <file> git reset HEAD~1 git reset --soft HEAD~1 git reset --hard HEAD~1 git reset --hard origin/main git revert <commit> git revert HEAD --no-edit git clean -fd git clean -fdn git checkout -- . Logging and History
git log --oneline git log --oneline --graph --all git log -n 5 git log --author="Name" git log --since="2 weeks ago" git log -p <file> git log --grep="fix" git reflog git blame <file> git show <commit> git shortlog -sn Tags
git tag git tag v1.0.0 git tag -a v1.0.0 -m "Release 1.0" git tag -a v1.0.0 <commit> git tag -d v1.0.0 git push origin v1.0.0 git push origin --tags git push origin --delete v1.0.0 git describe --tags git tag -l "v1.*" Advanced
git cherry-pick <commit> git cherry-pick --no-commit <commit> git bisect start git bisect good <commit> git bisect bad <commit> git bisect reset git worktree add ../hotfix hotfix-branch git worktree list git submodule add <url> <path> git submodule update --init --recursive git archive --format=zip HEAD > archive.zip git rev-parse --short HEAD git clean -fdx git commit --fixup <commit> git rebase -i --autosquash HEAD~5 git log --all --full-history -- <file> Common Pipelines
git branch --merged | grep -v '\*\|main\|master' | xargs git branch -d git log --all --oneline --graph --decorate git diff --name-only HEAD~5..HEAD git log --format='%an' | sort | uniq -c | sort -rn git log --diff-filter=D --summary | grep 'delete mode' git stash list | while read s; do echo "$s"; git stash show "$(echo $s | cut -d: -f1)"; echo; done git log --oneline --since='last monday' --author="$(git config user.name)" git for-each-ref --sort=-committerdate refs/heads/ --format='%(committerdate:short) %(refname:short)' git log -S 'functionName' --oneline git diff HEAD~1 --stat git remote prune origin && git branch -vv | grep 'gone]' | awk '{print $1}' | xargs git branch -d git log --pretty=format:'%h %ad %s' --date=short --all -- <file> Navigation and Filesystem
cd <dir> cd - cd ~ pwd ls -la ls -lh ls -lt tree -L 2 du -sh <dir> stat <file> File Operations
cp <src> <dst> cp -r <src> <dst> mv <src> <dst> rm <file> rm -rf <dir> mkdir -p path/to/dir touch <file> ln -s <target> <link> rsync -avz <src> <dst> rsync -avz --delete <src> <dst> file <file> basename /path/to/file.txt Text Processing
grep -r "pattern" . grep -rn "pattern" --include="*.ts" grep -i "pattern" <file> grep -v "pattern" <file> sed 's/old/new/g' <file> sed -i 's/old/new/g' <file> awk '{print $1, $3}' <file> awk -F: '{print $1}' /etc/passwd cut -d',' -f1,3 <file> sort <file> | uniq -c | sort -rn wc -l <file> tr '[:lower:]' '[:upper:]' < <file> File Viewing
cat <file> cat -n <file> less <file> head -n 20 <file> tail -n 20 <file> tail -f <file> tail -f <file> | grep "error" diff <file1> <file2> diff -u <file1> <file2> column -t -s',' <file> Permissions
chmod 755 <file> chmod 644 <file> chmod +x <file> chmod -R 755 <dir> chown user:group <file> chown -R user:group <dir> chgrp <group> <file> umask 022 ls -la <file> id Process Management
ps aux ps aux | grep <name> top htop kill <pid> kill -9 <pid> killall <name> jobs bg %1 fg %1 nohup <command> & lsof -i :3000 System Monitoring
df -h df -h / df -i du -sh * du -sh * | sort -rh | head -10 du -d 1 -h /var/log | sort -rh ncdu / free -h free -h -s 5 cat /proc/meminfo cat /proc/cpuinfo | grep 'model name' | head -1 nproc lscpu uptime w last reboot lsblk fdisk -l iostat -x 1 5 vmstat 1 5 sar -u 1 5 dmesg | tail -20 cat /etc/os-release uname -a Archives and Compression
tar -czf archive.tar.gz <dir> tar -xzf archive.tar.gz tar -xzf archive.tar.gz -C /target/dir tar -tf archive.tar.gz gzip <file> gunzip <file>.gz zip -r archive.zip <dir> unzip archive.zip unzip -l archive.zip tar -cjf archive.tar.bz2 <dir> Environment and Variables
export VAR="value" echo $VAR env printenv PATH unset VAR source ~/.bashrc alias ll='ls -la' alias unalias ll which <command> export PATH="$PATH:/new/path" Redirection and Pipes
command > file.txt command >> file.txt command 2> error.log command &> all.log command 2>&1 command1 | command2 command | tee file.txt command | xargs <other> cat urls.txt | xargs -I {} curl -s {} command < input.txt Search and Find
find . -name "*.log" find . -type f -mtime -7 find . -type f -size +100M find . -name "*.tmp" -delete find . -type f -exec grep -l "pattern" {} + find . -empty -type f find . -type f -name "*.js" ! -path "*/node_modules/*" locate <filename> whereis <command> type <command> Service Management (systemd)
systemctl status <service> systemctl start <service> systemctl stop <service> systemctl restart <service> systemctl reload <service> systemctl enable <service> systemctl disable <service> systemctl enable --now <service> systemctl list-units --type=service --state=running systemctl list-units --type=service --state=failed systemctl is-active <service> systemctl is-enabled <service> systemctl daemon-reload systemctl mask <service> systemctl unmask <service> systemctl cat <service> systemctl edit <service> --force systemctl list-timers Journalctl (Logs)
journalctl -u <service> journalctl -u <service> -f journalctl -u <service> --since '1 hour ago' journalctl -u <service> --since today journalctl -u <service> -n 100 journalctl -p err journalctl -p warning..err journalctl -k journalctl --disk-usage journalctl --vacuum-size=500M journalctl --vacuum-time=7d journalctl -b journalctl -b -1 journalctl --no-pager -u <service> | grep error Cron and Scheduling
crontab -l crontab -e crontab -l -u <user> cat /etc/crontab ls /etc/cron.d/ ls /etc/cron.daily/ * * * * * /path/to/script.sh 0 */2 * * * /path/to/script.sh 0 9 * * 1-5 /path/to/script.sh at now + 30 minutes atq atrm <job-id> User and Group Management
useradd -m -s /bin/bash <user> usermod -aG sudo <user> usermod -aG <group> <user> userdel -r <user> passwd <user> groups <user> getent passwd <user> visudo su - <user> whoami last faillog -a Debugging and Tracing
strace -p <pid> strace -c <command> strace -e trace=network <command> ltrace <command> lsof +D /path lsof -p <pid> openssl s_client -connect <host>:443 openssl x509 -in cert.pem -text -noout md5sum <file> sha256sum <file> Common Pipelines
ps aux | sort -rnk 4 | head -10 ps aux | sort -rnk 3 | head -10 find . -name '*.log' -mtime +30 -delete find . -type f -name '*.js' | xargs wc -l | sort -n | tail -20 du -sh */ | sort -rh | head -10 history | awk '{$1=""; print}' | sort | uniq -c | sort -rn | head -20 curl -s https://api.example.com/data | jq '.items[] | {name, id}' tail -f /var/log/syslog | grep --line-buffered 'error' | tee errors.log find . -name '*.md' -exec grep -l 'TODO' {} + | sort cat access.log | awk '{print $1}' | sort | uniq -c | sort -rn | head -20 for f in *.jpg; do convert "$f" -resize 800x "resized_$f"; done diff <(sort file1.txt) <(sort file2.txt) watch -n 5 'df -h /' for f in *\ *; do mv "$f" "${f// /_}"; done ss -tlnp | awk 'NR>1 {print $4}' | rev | cut -d: -f1 | rev | sort -n | uniq jq (JSON Processing)
jq '.' <file> jq -r '.key' <file> jq '.nested.key' <file> jq '.[0]' <file> jq '.[]' <file> jq '.[] | .name' <file> jq '[.[] | .name]' <file> jq '.[] | {name, id}' <file> jq '.[] | select(.age > 30)' <file> jq '.[] | select(.name == "foo")' <file> jq '.[] | select(.name | test("^foo"))' <file> jq '.[] | select(.tags | contains(["urgent"]))' <file> jq 'map(select(.status == "active"))' <file> jq 'map(.price * .quantity)' <file> jq '[.[] | .amount] | add' <file> jq '.items | length' <file> jq '.items | sort_by(.date)' <file> jq '.items | sort_by(.date) | reverse' <file> jq '.items | group_by(.category)' <file> jq '.items | unique_by(.id)' <file> jq 'keys' <file> jq 'to_entries[] | "\(.key)=\(.value)"' <file> jq 'from_entries' <file> jq '.a + .b' <file> jq '.items |= map(. + {processed: true})' <file> jq 'del(.unwanted)' <file> jq '.[] | @csv' <file> jq '.[] | @tsv' <file> jq -r '.[] | [.name, .email] | @csv' <file> jq -s '.' *.json jq -s 'add' file1.json file2.json jq -n '{name: "foo", count: 42}' jq --arg name "foo" '.[] | select(.name == $name)' <file> jq -r '.results[] | "\(.id)\t\(.name)"' <file> jq 'if .status == "ok" then .data else empty end' <file> jq '.value // "default"' <file> jq 'paths(scalars)' <file> jq '[paths(scalars) as $p | {path: ($p | join(".")), value: getpath($p)}]' <file> curl -s <url> | jq '.data[] | {id, name}' jq -c '.[]' <file> jq -e '.key' <file> One-Liners
python3 -m http.server 8000 openssl rand -hex 32 date +%s date -d @1700000000 echo 'SELECT 1' | xclip -selection clipboard xclip -selection clipboard -o > file.txt yes 'confirm' | head -5 time <command> !! | xclip -selection clipboard curl -w '%{http_code}' -o /dev/null -s <url> hostname -I nc -zv <host> <port> curl
curl -s <url> curl -o <file> <url> curl -O <url> curl -X POST -H "Content-Type: application/json" -d '{"key":"val"}' <url> curl -I <url> curl -L <url> curl -u user:pass <url> curl -H "Authorization: Bearer <token>" <url> curl -w '%{http_code}' -o /dev/null -s <url> curl -w '%{time_total}' -o /dev/null -s <url> curl -x http://proxy:8080 <url> curl -k https://<url> curl --retry 3 --retry-delay 5 <url> wget <url> wget -q <url> wget -r -l 2 <url> wget -c <url> wget --mirror <url> wget -i urls.txt SSH and SCP
ssh user@host ssh -p 2222 user@host ssh -i ~/.ssh/key.pem user@host ssh -L 8080:localhost:3000 user@host ssh -R 9090:localhost:3000 user@host ssh -D 1080 user@host ssh -J jumphost user@target ssh-keygen -t ed25519 -C "email@example.com" ssh-copy-id user@host ssh-add ~/.ssh/key scp <file> user@host:/path/ scp -r user@host:/path/ . rsync -avz -e ssh <src> user@host:/dst DNS
dig <domain> dig +short <domain> dig MX <domain> dig NS <domain> dig TXT <domain> dig @8.8.8.8 <domain> dig +trace <domain> nslookup <domain> host <domain> cat /etc/resolv.conf resolvectl status Ports and Connections
ss -tlnp ss -tunap ss -s ss state established '( dport = :443 )' netstat -tlnp lsof -i :8080 nc -zv <host> <port> nc -zv <host> 1-1000 nc -l 8080 IP and Routing
ip addr show ip -4 addr show ip link show ip route show ip route get <ip> ip neigh show hostname -I hostname -f ping -c 4 <host> traceroute <host> mtr <host> Firewall (iptables/nftables)
iptables -L -n -v iptables -A INPUT -p tcp --dport 80 -j ACCEPT iptables -A INPUT -s <ip> -j DROP iptables -D INPUT <rule-number> iptables-save > rules.bak iptables-restore < rules.bak ufw status ufw allow 22/tcp ufw deny from <ip> firewall-cmd --list-all firewall-cmd --add-port=8080/tcp --permanent firewall-cmd --reload Packet Capture and Analysis
tcpdump -i eth0 tcpdump -i eth0 port 80 tcpdump -i eth0 host <ip> tcpdump -i eth0 -w capture.pcap tcpdump -r capture.pcap tcpdump -i eth0 -c 100 tcpdump -i eth0 'tcp[tcpflags] & (tcp-syn) != 0' nmap -sT <host> nmap -sT -p 1-65535 <host> nmap -sV <host> nmap -O <host> Images
docker images docker pull <image>:<tag> docker build -t <name>:<tag> . docker build -t <name>:<tag> -f Dockerfile.prod . docker build --no-cache -t <name>:<tag> . docker tag <image> <registry>/<name>:<tag> docker push <registry>/<name>:<tag> docker rmi <image> docker image prune docker image prune -a docker history <image> docker inspect <image> Containers
docker run -d --name <name> <image> docker run -it <image> /bin/bash docker run -d -p 8080:80 <image> docker run -d -v /host/path:/container/path <image> docker run -d --env-file .env <image> docker run -d --restart unless-stopped <image> docker run --rm <image> docker ps docker ps -a docker stop <container> docker start <container> docker restart <container> docker rm <container> docker rm -f <container> docker rename <old> <new> Exec and Logs
docker exec -it <container> /bin/bash docker exec -it <container> sh docker exec <container> <command> docker logs <container> docker logs -f <container> docker logs --tail 100 <container> docker logs --since 1h <container> docker logs -f <container> 2>&1 | grep error docker cp <container>:/path/file . docker cp file.txt <container>:/path/ docker top <container> docker stats docker stats <container> Docker Compose
docker compose up -d docker compose up -d --build docker compose down docker compose down -v docker compose ps docker compose logs -f <service> docker compose exec <service> /bin/bash docker compose restart <service> docker compose pull docker compose config docker compose up -d --scale <service>=3 docker compose --profile debug up -d Volumes
docker volume ls docker volume create <name> docker volume inspect <name> docker volume rm <name> docker volume prune docker run -v <volume>:/data <image> docker run -v $(pwd):/app <image> docker run --tmpfs /tmp <image> Networks
docker network ls docker network create <name> docker network create --driver overlay <name> docker network inspect <name> docker network connect <network> <container> docker network disconnect <network> <container> docker network rm <name> docker network prune Cleanup
docker system df docker system prune docker system prune -a --volumes docker container prune docker image prune -a docker volume prune docker ps -aq --filter status=exited | xargs docker rm docker images -q --filter dangling=true | xargs docker rmi Buildx (Multi-Platform)
docker buildx ls docker buildx create --name mybuilder --use docker buildx use mybuilder docker buildx inspect --bootstrap docker buildx build --platform linux/amd64,linux/arm64 -t <name>:<tag> . docker buildx build --platform linux/amd64,linux/arm64 -t <name>:<tag> --push . docker buildx build --load -t <name>:<tag> . docker buildx build --cache-from type=registry,ref=<image>:cache -t <name>:<tag> . docker buildx build --cache-to type=registry,ref=<image>:cache,mode=max . docker buildx build --output type=local,dest=./out . docker buildx build --secret id=mysecret,src=secret.txt . docker buildx build --ssh default . docker buildx build --progress=plain . docker buildx rm mybuilder docker buildx prune docker buildx bake docker buildx bake --print docker buildx imagetools inspect <image>:<tag> Debugging
docker inspect <container> docker inspect -f '{{.State.Status}}' <container> docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' <container> docker diff <container> docker events docker port <container> docker wait <container> docker commit <container> <image>:<tag>