“Port already in use” on a server
The first line of the reverse lookup: ss -tulnp | grep :8080 to find the PID, then kill <PID>, or straight to kill -9 $(lsof -t -i :8080).
Guide
Linux Cheat Sheet orders the 160 commands you type in a terminal every day into eight groups — files and directories, viewing and editing content, text processing, permissions and users, processes and services, networking, compression and archiving, and system information and administration — each with a one-line explanation and a few lines of copy-ready examples; commands with a large option set such as ls, find, grep, sed, awk, tar, curl, ss and journalctl also carry a common-options table that expands in place.
Updated 2026-09-094 sources9 min read
Linux Cheat Sheet orders the 160 commands you type in a terminal every day into eight groups — files and directories, viewing and editing content, text processing, permissions and users, processes and services, networking, compression and archiving, and system information and administration — each with a one-line explanation and a few lines of copy-ready examples; commands with a large option set such as ls, find, grep, sed, awk, tar, curl, ss and journalctl also carry a common-options table that expands in place.
It solves two kinds of lookup. One is knowing the command name but forgetting the arguments (search tar, chmod). The other is knowing only what you want to see — “which process is on port 8080”, “which directory is using the most disk”, “why did this service fail to start” — and for that there is a dedicated “I want to see… → which command” reverse lookup: the goal comes first, then 2–3 commands that get you there, ordered from recommended to compatible.
At the bottom of the page there is a simulated terminal that runs in the browser: an in-memory file system plus a shell interpreter for 60+ commands, with pipes, redirection, wildcards and a common subset of sed/awk, and 8 practice levels from building a directory tree to counting logs with pipes. It never touches your computer and has no network, so a mistyped rm -rf only resets a level.
help lists all commands the simulator supports, and Tab completes file names.Searching “port” matches both the command table and the reverse lookup:
A complete solution to level 8, “pipeline combos”, in the simulated terminal:
I want to see: which process is using a port
ss -tulnp | grep :8080
lsof -i :8080
netstat -tulnp | grep 8080 older systems
Networking › ss -tulnp listening ports and their processes (replaces netstat)
Networking › lsof -i :<port> which process is using a portuser@toolun-lab:~$ awk '{print $2}' access.log | sort | uniq -c | sort -rn
3 /index.html
2 /api/list
2 /about
✔ Passed: pipeline combos: the most visited paths.Two Unix design principles shape this table. “Everything is a file”: devices, process information (/proc) and sockets are all exposed as files, which is why odd-looking uses such as cat /proc/cpuinfo, ls -l /dev/sd* and echo > /dev/tcp/host/port all work. “Each program does one thing and does it well”: grep only filters, sort only sorts, uniq only merges adjacent duplicates, wc only counts — each is small on its own, and their power comes from chaining them with pipes.
That is why | appears so often in the examples: awk '{print $1}' access.log | sort | uniq -c | sort -rn | head builds “the most visited IPs” out of five small programs. Understanding the input and output of each stage is more useful than memorizing the whole command.
Every process starts with three open “files”: standard input (0), standard output (1) and standard error (2). > writes standard output to a file, 2> handles the error stream, 2>&1 merges errors into output and &> is bash shorthand. The most common everyday combination is cmd > out.log 2>&1 &: normal output and errors both go to the log, and the job goes to the background. Forgetting 2>&1 is the number one reason for “why is there no error in the log”.
The first column of ls -l, such as -rwxr-xr-x, has four parts: the type (- file, d directory, l link), then read (4), write (2) and execute (1) for the owner, the group and everyone else. Adding the three digits gives the numeric form: rwx=7, r-x=5, r--=4, so 755 is “full control for me, read and execute for everyone else” and 644 is “read and write for me, read-only for the rest”. For a directory, x means “may enter”: a directory without x cannot be listed even if it has r. 600/700 are for private keys and ~/.ssh — SSH clients reject key files that are too broadly readable. More combinations can be assembled with the chmod calculator.
The name of kill is misleading: it only sends a signal to a process. The default TERM (15) means “please exit”, giving the program a chance to save its state; KILL (9) is the kernel terminating it with no chance at all — so kill first, wait a few seconds, and only then kill -9. HUP (1) is conventionally “reload the configuration” for daemons; nginx -s reload uses it underneath.
Modern distributions manage services with systemd: systemctl starts, stops and enables them at boot, and journalctl collects their logs in one place. The fixed path for “the service will not start” is systemctl status for the state and the last few log lines → journalctl -u <service> -n 100 for the full error → ss -tlnp to see whether the port is already taken.
ifconfig, netstat, route and arp belong to the unmaintained net-tools and are no longer installed by default on new systems; their replacements in iproute2 are ip addr, ss, ip route and ip neigh. The cheat sheet lists both, and the reverse lookup puts the new tools first. The five letters of ss -tulnp stand for TCP, UDP, listening, numeric ports and processes — almost always the opening move for a port problem.
GNU sed accepts -i without an argument; BSD sed (the one macOS ships) requires a backup suffix after -i, so you write sed -i '' 's/a/b/' file. Similar differences include date -d (GNU) versus date -v (BSD), and readlink -f not existing on older macOS. The cheat sheet follows the GNU versions and notes macOS differences in the entry remarks; brew install coreutils gnu-sed installs the GNU ones.
yast), desktop-environment commands and language-specific CLIs are not included.sed only covers s///, N,Mp and Nd, and awk only {print $N}; there is no network (curl, ssh and apt explain why), no real processes (ps, top and kill return fixed demo data) and no interactive editors (write files with echo > or cat >>).The first line of the reverse lookup: ss -tulnp | grep :8080 to find the PID, then kill <PID>, or straight to kill -9 $(lsof -t -i :8080).
The text-processing group is a complete kit, from grep -A3 -B1 for context through awk/sort/uniq -c for statistics to tail -F for logs that rotate; practice levels 3 and 8 are exactly these two jobs.
tar -czvf → scp / rsync -avz → tar -xzvf -C /var/www/, three adjacent entries; the trap in rsync --delete is in the remarks.
Walk the system information and administration group in order — cat /etc/os-release, nproc, free -h, df -h, ss -tlnp, systemctl list-units — and you have a working picture in ten minutes.
Essentially no. Linux has no recycle bin, and rm releases the inode directly. Before touching an important directory, confirm the path with ls; in scripts, quote variables and guard against empty ones (rm -rf "${DIR:?}"/), or replace rm with a tool such as trash-cli.
Usually the terminal or the file encoding does not match. Run file <filename> first to see the encoding, convert GBK files to UTF-8 with iconv -f GBK -t UTF-8 and search again; grep -a treats files that were misdetected as binary as text.
The columns of ss -tulnp are Netid, State, Recv-Q, Send-Q, Local Address:Port, Peer Address:Port and Process. To find a port, look at Local Address:Port (*:8080 or 0.0.0.0:8080 means all interfaces); to find the process, look at the last column, users:(("node",pid=842,fd=18)).
It runs in the browser, has no network stack and should not send requests on your behalf; those commands return an explanation and point to the matching entry in the cheat sheet. The focus of the levels is files, text and permissions, all of which work fully in the in-memory file system.
Reading files you already have permission for needs nothing; changing system directories (/etc, /usr), binding to ports below 1024, reading other users' process details, and managing services and packages all need root. sudo runs one command as root, which is safer than switching to root for a long session.
The cheat data, the reverse lookup and the simulated terminal are all static content downloaded with the page and run locally in your browser; searching, copying and practicing send no requests. Favorites are stored in this browser's localStorage. The file system of the simulated terminal exists only in the current page's memory, clears on refresh, and never reads or writes your real files.
ls, cp, sort and cut.ss(8), ip(8), find(1) and grep(1).Updated 2026-09-09
160 Linux and shell commands grouped by files, text, permissions, processes, networking, archives, and system tasks, with examples and a practice terminal
Look up by output goal: say what you want to know and you get 2–3 commands that show it, newest first and recommended before compatible.
pwd # /var/www/site
ls -la # verbose + hidden files ls -lh # human readable size ls -lt | head # View the latest in reverse order of modification time
| -l | Long form: permissions, owner, size, time |
| -a | Contains hidden files starting with . |
| -h | Size in K/M/G |
| -t | Sort by modification time |
| -S | Sort by size |
| -R | Recursive subdirectory |
| -d | Only list the directory itself and do not enter it |
cd /var/log cd .. # Previous level cd - # Return to the previous directory cd # Home directory (same as cd ~)
mkdir -p app/src/{components,utils}
mkdir -m 700 private| -p | Create recursively, no error will be reported if it already exists |
| -m | Specify permissions |
| -v | Show what was created |
touch README.md touch -d "2026-01-01" old.log # Specify time
cp a.txt b.txt cp -r src/ backup/ # Directory requires -r cp -a /etc/nginx ~/nginx-bak # Reserve permissions and time
| -r / -R | Copy directories recursively |
| -a | Archive: equal to -dR --preserve=all |
| -i | Ask before coverage |
| -n | Do not overwrite existing files |
| -u | Only copy when source is updated |
| -v | show process |
mv old.txt new.txt # Rename mv *.log logs/ # Batch move mv -i a.txt dir/ # Ask before overwriting
| -i | Ask before coverage |
| -n | Not covered |
| -f | Force coverage |
| -v | show process |
rm file.txt rm -r build/ # Delete directory rm -rf node_modules # Do not confirm or ignore non-existence
rm does not enter the recycle bin. Before rm -rf, echo the path variable to see if it is empty: rm -rf "$DIR"/ is equal to rm -rf / when DIR is empty.
| -r | Recursively delete directories |
| -f | Don’t ask, ignore that it doesn’t exist |
| -i | Confirm one by one |
| -d | Delete empty directories |
| -- | The following parameters are inappropriate options (delete files starting with -) |
rmdir empty-dir rmdir -p a/b/c # along with the empty parent directory
ln -s /opt/app/current ~/app ln -sf new-target link # Overwrite existing links readlink -f link # See where the link points
find . -name "*.log"
find /var -type f -size +100M # Files larger than 100MB
find . -mtime -7 -name "*.js" # Modified within 7 days
find . -name "*.tmp" -delete
find . -type f -exec chmod 644 {} \;| -name / -iname | By name (-iname ignores case) |
| -type f|d|l | File/Directory/Link |
| -size +10M / -1k | by size |
| -mtime -N / +N | Modified within N days/N days ago |
| -maxdepth N | limit depth |
| -exec cmd {} \; | Execute command for each result |
| -delete | Remove matches |
| -empty | Empty file or directory |
sudo updatedb locate nginx.conf
which python3 type ls # bash built-in, you can see aliases / built-in / external commands command -v node # Determine whether the command exists in the script
tree -L 2 tree -a -I "node_modules|.git" # exclude
file photo.bin # photo.bin: JPEG image data, ...
stat app.log stat -c "%s %n" * # Just size and name
du -sh . du -sh * | sort -rh | head # Who takes up the most space du -h --max-depth=1 /var
| -s | Show total only |
| -h | human readable |
| --max-depth=N | Restriction level |
| -a | Contains files |
df -h df -h /home df -i # inode usage (full when there are too many files)
basename /var/log/syslog # syslog basename report.pdf .pdf # report dirname /var/log/syslog # /var/log
realpath ../config.yml
rsync -avz --progress src/ user@host:/srv/app/ rsync -av --delete ./dist/ /var/www/site/ # Also delete redundant files in the target rsync -avn src/ dst/ # -n preview only
The presence or absence of / at the end of the source directory has different meanings: src/ synchronizes the content, and src synchronizes the directory itself.
| -a | Archive mode (recursive + retain attributes) |
| -v | show process |
| -z | transmission compression |
| --delete | Delete redundant files on the target side |
| -n / --dry-run | Only preview |
| --exclude=PAT | exclude |
| -P | Progress + resume from breakpoint |
scp app.tar.gz user@1.2.3.4:/tmp/ scp -r user@host:/var/log/app ./logs scp -P 2222 file user@host:~ # Specify port (capital P)
cat config.yml cat -n app.js # with line number cat a.txt b.txt > all.txt # Splicing
| -n | Line number |
| -A | Display invisible characters (^M is CRLF) |
| -s | Compress consecutive blank lines |
less /var/log/syslog #/keyword search n next G to end g to beginning q exit F follow (like tail -f)
| -N | Show line number |
| -S | Do not break the line |
| +F | Enter follow mode |
| -i | Search ignores case |
head -n 20 app.log head -c 100 file.bin # first 100 bytes head -n -5 file # except the last 5 lines
tail -n 50 app.log tail -f /var/log/nginx/access.log tail -F app.log # Continue to follow after the file is rotated
| -n N | Next N lines |
| -f | Follow and add |
| -F | Follow along and handle file reconstruction |
| -n +N | From line N to the end |
wc -l access.log ls | wc -l #How many items are there in the directory? cat *.py | wc -l # Number of lines of code
diff -u old.conf new.conf diff -r dir1 dir2 # Compare directories diff <(sort a) <(sort b) # Compare the sorted content
| -u | unified format |
| -r | Compare directories recursively |
| -q | Report only if it differs |
| -w | ignore whitespace |
| -i | Ignore case |
cmp a.bin b.bin
nl -ba script.sh # Empty lines are also numbered
tac app.log | less
strings app.bin | grep -i version
xxd file.bin | head -20 xxd -r dump.txt > file.bin # Restore
nano /etc/hosts # Ctrl+O Save Ctrl+X Exit Ctrl+W Search Ctrl+K Cut line
vim app.conf # :wq Save and exit :q! Exit without saving /word search dd delete line u undo :set nu line number
make 2>&1 | tee build.log echo "text" | sudo tee /etc/file # Use sudo to write protected files cmd | tee -a log.txt # Append
ls > list.txt echo "line" >> notes.txt cmd > out.log 2>&1 # Log all cmd 2>/dev/null # discard errors cmd &> all.log # bash abbreviation
ps aux | grep nginx cat log | grep ERROR | wc -l history | tail -20
grep -rn "TODO" src/
grep -i error app.log
grep -v "^#" nginx.conf | grep -v "^$" # Remove comments and blank lines
grep -E "5[0-9]{2}" access.log # Extended regular expression
grep -l "main" *.c # List only file names
grep -A3 -B1 "Exception" app.log # First 1 and last 3 lines of context| -r / -R | recursive directory |
| -n | Show line number |
| -i | Ignore case |
| -v | Invert selection (rows without pattern) |
| -E | Extended regular expression (same as egrep) |
| -F | as fixed string |
| -w | whole word match |
| -c | Just count the number of lines |
| -l | List only matching file names |
| -o | Only output the matching part |
| -A/-B/-C N | After/before/before and after N lines of context |
| --include="*.js" | Limit file names when recursing |
rg "TODO" --type ts
rg -n "fetch\(" src/sed 's/foo/bar/g' a.txt # Output the replacement result sed -i 's/foo/bar/g' a.txt # Modify files directly (GNU) sed -i.bak 's/8080/80/' app.conf # Make a backup before making changes sed 's#/usr/local#/opt#g' f # The delimiter can be replaced
| -i | Modify in place (macOS requires -i '') |
| -n | Print only the lines selected by the p command |
| -e | multiple scripts |
| -E | extended regular |
| g flag | Replace all in one line |
sed -n '10,20p' app.log # Lines 10–20 sed '5d' f.txt # Delete line 5 sed '/^$/d' f.txt # Delete empty lines sed '3i\new line' f.txt # Insert before line 3
awk '{print $1}' access.log | sort | uniq -c | sort -rn | head # The most visited IPs
awk -F: '{print $1}' /etc/passwd # username
awk '$3 > 100 {print $0}' data.txt # The third column is greater than 100 rows
awk '{sum += $2} END {print sum}' f # Sum| -F <separator> | Field separator (default blank) |
| $0 / $1 / $NF | Entire row / 1st column / last column |
| NR | Current line number |
| BEGIN{} / END{} | Execute before start/after end |
| /regular/{…} | Only process matching rows |
cut -d, -f1,3 data.csv cut -d: -f1 /etc/passwd cut -c1-8 file # by character position
sort names.txt sort -n nums.txt # By numerical value sort -k2 -t, -r data.csv # Sort by column 2 in reverse order sort -u list.txt # Sort and remove duplicates sort -h sizes.txt # According to K/M/G size
| -n | by value |
| -r | reverse order |
| -k N | by column N |
| -t <separator> | Column separator |
| -u | Remove duplicates |
| -h | human readable size |
| -V | Version number sorting (1.2 < 1.10) |
sort words.txt | uniq -c | sort -rn sort a.txt | uniq -d # Show only duplicates sort a.txt | uniq -u # Display only the unique ones
echo hello | tr a-z A-Z # HELLO tr -d '\r' < win.txt > unix.txt # Remove CR tr -s ' ' < f # Compress consecutive spaces echo $PATH | tr ':' '\n' # One per line
find . -name "*.log" | xargs rm
find . -name "*.txt" -print0 | xargs -0 wc -l # The file name contains spaces
cat urls.txt | xargs -n1 -P4 curl -sO # 4-way parallel
echo a b c | xargs -I{} echo "item: {}"| -0 | NUL separated (with find -print0) |
| -n N | Pass N parameters each time |
| -I {} | Use {} to occupy space |
| -P N | N parallel |
| -r | Do not execute when input is empty |
paste -d, names.txt emails.txt
join -t, -1 1 -2 1 <(sort a.csv) <(sort b.csv)
cat /etc/fstab | column -t mount | column -t
echo abc | rev # cba
fold -w 80 -s long.txt # -s fold at spaces
iconv -f GBK -t UTF-8 gbk.txt > utf8.txt iconv -l | grep -i gb # List supported encodings
dos2unix script.sh sed -i "s/\r$//" script.sh # When dos2unix is not installed
curl -s https://api.github.com/repos/git/git | jq .stargazers_count jq ".items[] | .name" data.json jq -r ".[].id" list.json # -r original string without quotes cat a.json | jq . # Formatting
echo "Hello" echo -e "a\tb\nc" echo $HOME echo "PATH=$PATH" >> ~/.bashrc
printf "%-10s %5d\n" name 42 printf "%.2f\n" 3.14159 printf "%s\n" *.txt # One file name per line
seq 1 10 seq 0 5 100 # step size 5 for i in $(seq 1 3); do echo $i; done
echo "2^10" | bc echo "scale=3; 10/3" | bc echo "obase=16; 255" | bc # Convert to hexadecimal
chmod 755 script.sh # rwxr-xr-x chmod 644 file.txt # rw-r--r-- chmod 600 ~/.ssh/id_ed25519 # Only you can read and write chmod -R 755 public/ # recursive
| 755 | Common values for directory/executable |
| 644 | Common values for ordinary files |
| 600 | Private key and password files |
| 700 | Private directory (such as ~/.ssh) |
| -R | recursion |
chmod +x deploy.sh # Add executable chmod u+w,go-w file # The owner can write, others cannot chmod a-x file chmod g+s shared/ # Directory setgid: new file inheritance group
sudo chown www-data:www-data -R /var/www/site sudo chown $USER file.txt chgrp developers project/ # only shuffle
umask umask 027 # Group read-only, others have no permissions
sudo apt update sudo -i # Switch to root interactive shell sudo -u postgres psql # Execute as another user sudo !! # Use sudo to rerun the previous one
su - deploy exit # come back
whoami id id deploy # View other users
sudo useradd -m -s /bin/bash deploy sudo passwd deploy sudo usermod -aG sudo deploy # Join sudo group
sudo usermod -aG docker $USER newgrp docker # Or log in again to take effect
sudo userdel -r olduser
passwd sudo passwd deploy sudo passwd -l deploy # Lock account
groups groups www-data cat /etc/group | grep docker
who w last -n 10 lastlog
ssh-keygen -t ed25519 -C "me@example.com" cat ~/.ssh/id_ed25519.pub ssh-copy-id user@host # Install the public key to the server
ssh user@1.2.3.4 ssh -p 2222 user@host #Specify port ssh -i ~/.ssh/key.pem ubuntu@host ssh -L 8080:localhost:80 user@host # Port forwarding ssh user@host "uptime" # Execute only one command
| -p | port |
| -i | private key file |
| -L local:target:port | local port forwarding |
| -N | Only forwarding does not open the shell |
| -v | Debugging connection issues |
Host prod
HostName 1.2.3.4
User deploy
Port 2222
IdentityFile ~/.ssh/prod_keyps aux | grep nginx ps -ef | grep java ps aux --sort=-%mem | head # The most memory-consuming ps -p 1234 -o pid,etime,cmd # How long has a process been running?
| aux | BSD style: all users, including terminals, verbose |
| -ef | UNIX style: all processes including parent process |
| --sort=-%cpu | Sort by CPU in reverse order |
| -p PID | Specify process |
| -o field | Custom columns |
pgrep -f "node server.js" pgrep -l nginx # with name pkill -f "node server.js" # Find and kill
top top -o %MEM top -p 1234 # Only view a certain process
htop htop -u www-data
kill 1234 kill -9 1234 # Kill if disobedient kill -HUP 1234 # Let the service reload the configuration kill -l # signal list
| -15 / -TERM | Default: Request normal exit |
| -9 / -KILL | Forced end without giving a chance to clean up |
| -1 / -HUP | Commonly used for overloading configuration |
| -2 / -INT | Equal to Ctrl+C |
| -STOP / -CONT | Pause / Resume |
killall node killall -9 chrome
npm run build & jobs fg %1 # Ctrl+Z pauses the current foreground task, then bg to continue it in the background
nohup python server.py > server.log 2>&1 & echo $! # PID just started
tmux new -s work # Ctrl+B then d to separate tmux ls tmux attach -t work tmux kill-session -t work
systemctl status nginx systemctl status --failed # Failed service
sudo systemctl restart nginx sudo systemctl reload nginx # Reload configuration without interrupting the connection
sudo systemctl enable --now docker sudo systemctl disable apache2 systemctl is-enabled nginx
systemctl list-units --type=service --state=running systemctl list-unit-files | grep enabled
journalctl -u nginx -f journalctl -u app -n 200 --no-pager journalctl --since "1 hour ago" journalctl -p err -b # Errors since this boot sudo journalctl --vacuum-size=500M # Clean up
| -u <unit> | a service |
| -f | follow |
| -n N | Last N lines |
| --since / --until | time range |
| -p err | Filter by level |
| -b | This startup |
| -k | Kernel messages |
crontab -e # Backup every day at 3:30 30 3 * * * /opt/scripts/backup.sh >> /var/log/backup.log 2>&1 # every 5 minutes */5 * * * * /usr/bin/curl -s https://example.com/ping crontab -l # View
echo "systemctl restart app" | at 03:00 atq #queue atrm 3 # delete
watch -n 2 "df -h" watch -d free -m # -d highlight changes
time ./build.sh time curl -s https://example.com > /dev/null
timeout 10 ping example.com timeout -s KILL 30 ./stuck.sh
lsof -p 1234 lsof +D /var/log # Who is using the files in this directory? lsof | grep deleted # Deleted but occupied files (the disk is not released)
strace -p 1234 strace -f -e trace=network node app.js strace -c ./cmd # Statistics
nice -n 19 tar czf big.tgz data/ renice -n 10 -p 1234
ss -tulnp ss -tlnp | grep :80 ss -s # connection statistics ss -tan state established
| -t / -u | TCP / UDP |
| -l | Only monitor |
| -n | Numeric port does not resolve service name |
| -p | Show processes (requires root to see all) |
| -a | Connect all |
netstat -tulnp | grep 3000 netstat -an | grep ESTABLISHED | wc -l
lsof -i :8080 lsof -i tcp -sTCP:LISTEN kill -9 $(lsof -t -i :3000) # Kill the occupier directly
ip addr ip -4 -br addr # streamline hostname -I # Only IP
ip route ip route get 8.8.8.8 # Which way to go to a certain address?
ping -c 4 example.com ping -i 0.2 -c 20 10.0.0.1
traceroute example.com mtr -rw example.com
curl -I https://example.com # Only read response headers
curl -sS https://api.example.com/x | jq . # Silent but reporting an error
curl -o file.zip -L https://…/file.zip # Download and follow redirects
curl -X POST -H "Content-Type: application/json" -d '{"a":1}' https://api.example.com/items
curl -u user:pass https://…
curl -w "%{http_code} %{time_total}\n" -o /dev/null -s https://example.com| -I | Request header only (HEAD) |
| -L | follow redirect |
| -o file / -O | Save to file / using remote filename |
| -X method | Request method |
| -H "header:value" | Request header |
| -d data | Request body (default POST) |
| -s / -S | Silent/Quiet with errors |
| -v | Show full interaction |
| -k | Ignore certificate errors (for debugging) |
| -w format | Output status code, time consumption, etc. |
wget https://example.com/file.tar.gz wget -c https://…/big.iso # Continue download wget -qO- https://example.com | head # Output to the screen wget -r -np -nH --cut-dirs=1 https://example.com/docs/
dig example.com dig +short example.com dig MX example.com dig @8.8.8.8 example.com # Specify DNS dig -x 93.184.216.34 # Reverse check
nslookup example.com nslookup -type=txt example.com
host example.com
sudo nano /etc/hosts 127.0.0.1 dev.example.com
nc -zv example.com 443 nc -l 8080 # Monitor 8080 echo "hi" | nc host 8080 # Send data
telnet smtp.example.com 25
sudo ufw status sudo ufw allow 22 sudo ufw allow 80/tcp sudo ufw allow from 10.0.0.0/8 to any port 5432 sudo ufw enable
Be sure to release 22 before opening it, otherwise SSH will be locked out by itself.
sudo firewall-cmd --list-all sudo firewall-cmd --add-port=8080/tcp --permanent sudo firewall-cmd --reload
sudo iptables -L -n -v --line-numbers sudo iptables -A INPUT -p tcp --dport 8080 -j ACCEPT
sudo tcpdump -i eth0 port 80 -nn sudo tcpdump -i any host 10.0.0.5 -w cap.pcap # Save the file to Wireshark
sudo iftop -i eth0 nload
ip neigh arp -a
tar -czvf site.tar.gz site/ tar -czf logs.tgz --exclude="*.tmp" logs/ tar -cJvf site.tar.xz site/ # xz compresses smaller and slower
| -c | create |
| -x | Untie |
| -t | list content |
| -z / -j / -J | gzip / bzip2 / xz |
| -v | show file |
| -f file | Archive file name (must follow file name) |
| -C directory | Switch to the directory and then operate |
| --exclude=PAT | exclude |
tar -xzvf site.tar.gz tar -xzvf site.tar.gz -C /var/www/ tar -xf any.tar.* # New version of tar automatically recognizes compression format tar -tzvf site.tar.gz # Let’s see what’s inside first
gzip big.log # get big.log.gz gzip -k big.log # Keep the original file gunzip big.log.gz zcat big.log.gz | grep ERROR # View directly without decompressing
zip -r project.zip project/ -x "*/node_modules/*" zip -e secret.zip file.txt # Encryption
unzip archive.zip unzip archive.zip -d out/ unzip -l archive.zip # only view the list unzip -O gbk cn.zip # When Windows Chinese file names are garbled
7z x archive.7z 7z a -mx9 out.7z dir/ 7z x file.rar
xz -9 big.sql xz -d big.sql.xz bzip2 -k file
split -b 100M big.iso part_ cat part_* > big.iso
sha256sum ubuntu.iso sha256sum -c SHA256SUMS md5sum file.zip
sudo dd if=ubuntu.iso of=/dev/sdX bs=4M status=progress && sync dd if=/dev/zero of=test.bin bs=1M count=100 # 100MB test file
of= If you write the wrong device, the disk will be erased directly. Please confirm with lsblk three times before executing.
uname -a uname -m # x86_64 / aarch64 cat /etc/os-release # Release version
hostnamectl sudo hostnamectl set-hostname web-01
uptime # Load > Number of CPU cores (nproc) indicates queuing
free -h free -m -s 2 # Refresh every 2 seconds
nproc lscpu | grep -E "Model name|^CPU\(s\)"
lsblk lsblk -f # With file system and UUID sudo fdisk -l
sudo mount /dev/sdb1 /mnt/usb sudo umount /mnt/usb mount | column -t # Mounted cat /etc/fstab # Automatically mount on boot
vmstat 1 10
iostat -x 1 5
sudo dmesg -T | tail -50 sudo dmesg -T | grep -i "killed process" # Who was OOMed?
env | sort printenv HOME echo $PATH | tr ":" "\n"
export JAVA_HOME=/usr/lib/jvm/java-17 export PATH="$HOME/.local/bin:$PATH" echo 'export EDITOR=vim' >> ~/.bashrc && source ~/.bashrc
alias ll="ls -alF" alias gs="git status" unalias ll alias # list
history | grep ssh !105 sudo !! history -c # Clear
sudo apt update && sudo apt upgrade sudo apt install htop apt search nginx apt show nginx sudo apt remove --purge pkg && sudo apt autoremove
| update | Refresh software source index |
| upgrade | Upgrade installed package |
| install / remove | Install/uninstall |
| search / show | Search / Details |
| autoremove | Clean up dependencies no longer needed |
| list --installed | Installed list |
sudo dnf install -y git sudo dnf update dnf search nginx sudo yum install epel-release # Old system
sudo pacman -Syu sudo pacman -S neovim pacman -Ss keyword sudo pacman -Rns pkg
brew install jq brew upgrade brew list brew search ripgrep
sudo snap install code --classic snap list
sudo dpkg -i app.deb sudo apt -f install dpkg -l | grep nginx dpkg -L nginx #Which files are packaged?
sudo shutdown -h now sudo reboot sudo shutdown -r +10 "Restart maintenance after 10 minutes" sudo shutdown -c # Cancel
date date "+%Y-%m-%d %H:%M:%S" date -d "yesterday" +%F date +%s # timestamp date -d @1700000000 # Convert timestamp to date
timedatectl sudo timedatectl set-timezone Asia/Shanghai timedatectl list-timezones | grep Asia
cal cal 2026 cal -3 # one month before and after
lsmod | grep nvidia sudo modprobe br_netfilter
lspci | grep -i vga lsusb
ulimit -n ulimit -n 65535 # Current session cat /proc/sys/fs/file-max
chsh -s $(which zsh) echo $SHELL
source ~/.bashrc . ~/.zshrc # Synonym
#!/usr/bin/env bash set -euo pipefail # Stop on error, undefined variable error, pipe error transmission for f in *.log; do echo "process $f" done
man tar man 5 crontab # Section 5: File Format tar --help | less tldr tar # Community sample version (requires installation)
A small in-memory filesystem and shell interpreter: it supports ls / cd / cat / grep / sed / awk / find / chmod / tar and more than 60 other commands, with pipes, redirection and wildcards; 8 stages run from "build a directory tree" to "counting with pipes". Nothing goes online and your real files are never touched. Git practice is inthe Git command reference.