160 comandos Linux/Shell agrupados por arquivos, texto, permissões, processos, rede, compactação e sistema, com tabelas de opções e exemplos reais; índice reverso «o que quero ver → qual comando usar»; busca, cópia, favoritos e terminal de prática
Esta ferramenta ainda não está totalmente traduzida; parte do conteúdo usa o idioma de origem ou um idioma de reserva.
Busca reversa pelo objetivo de saída: primeiro você diz o que quer saber e recebe 2–3 comandos que mostram isso, do mais novo ao mais antigo e do recomendado ao compatível.
pwd # /var/www/site
ls -la # 详细 + 隐藏文件 ls -lh # 人类可读的大小 ls -lt | head # 按修改时间倒序看最新的
| -l | 长格式:权限、所有者、大小、时间 |
| -a | 含以 . 开头的隐藏文件 |
| -h | 大小用 K/M/G |
| -t | 按修改时间排序 |
| -S | 按大小排序 |
| -R | 递归子目录 |
| -d | 只列目录本身不进入 |
cd /var/log cd .. # 上一级 cd - # 回到上一个目录 cd # 回家目录(同 cd ~)
mkdir -p app/src/{components,utils}
mkdir -m 700 private| -p | 递归创建,已存在不报错 |
| -m | 指定权限 |
| -v | 显示创建了什么 |
touch README.md touch -d "2026-01-01" old.log # 指定时间
cp a.txt b.txt cp -r src/ backup/ # 目录要 -r cp -a /etc/nginx ~/nginx-bak # 保留权限与时间
| -r / -R | 递归复制目录 |
| -a | 归档:等于 -dR --preserve=all |
| -i | 覆盖前询问 |
| -n | 不覆盖已存在文件 |
| -u | 只在源更新时复制 |
| -v | 显示过程 |
mv old.txt new.txt # 重命名 mv *.log logs/ # 批量移动 mv -i a.txt dir/ # 覆盖前询问
| -i | 覆盖前询问 |
| -n | 不覆盖 |
| -f | 强制覆盖 |
| -v | 显示过程 |
rm file.txt rm -r build/ # 删目录 rm -rf node_modules # 不确认、忽略不存在
rm 不进回收站。rm -rf 前先 echo 一下路径变量是否为空:rm -rf "$DIR"/ 在 DIR 为空时等于 rm -rf /。
| -r | 递归删除目录 |
| -f | 不询问、忽略不存在 |
| -i | 逐个确认 |
| -d | 删除空目录 |
| -- | 之后的参数不当选项(删以 - 开头的文件) |
rmdir empty-dir rmdir -p a/b/c # 连同变空的父目录
ln -s /opt/app/current ~/app ln -sf new-target link # 覆盖已有链接 readlink -f link # 看链接指向哪
find . -name "*.log"
find /var -type f -size +100M # 大于 100MB 的文件
find . -mtime -7 -name "*.js" # 7 天内修改过
find . -name "*.tmp" -delete
find . -type f -exec chmod 644 {} \;| -name / -iname | 按名字(-iname 忽略大小写) |
| -type f|d|l | 文件 / 目录 / 链接 |
| -size +10M / -1k | 按大小 |
| -mtime -N / +N | N 天内 / N 天前修改 |
| -maxdepth N | 限制深度 |
| -exec cmd {} \; | 对每个结果执行命令 |
| -delete | 删除匹配项 |
| -empty | 空文件或空目录 |
sudo updatedb locate nginx.conf
which python3 type ls # bash 内建,能看出别名 / 内建 / 外部命令 command -v node # 脚本里判断命令是否存在
tree -L 2 tree -a -I "node_modules|.git" # 排除
file photo.bin # photo.bin: JPEG image data, ...
stat app.log stat -c "%s %n" * # 只要大小和名字
du -sh . du -sh * | sort -rh | head # 谁最占地方 du -h --max-depth=1 /var
| -s | 只显示总计 |
| -h | 人类可读 |
| --max-depth=N | 限制层级 |
| -a | 含文件 |
df -h df -h /home df -i # inode 用量(文件数太多时满)
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/ # 目标多余文件也删 rsync -avn src/ dst/ # -n 只预演
源目录末尾有无 / 含义不同:src/ 同步内容,src 同步目录本身。
| -a | 归档模式(递归 + 保留属性) |
| -v | 显示过程 |
| -z | 传输压缩 |
| --delete | 删除目标端多余文件 |
| -n / --dry-run | 只预演 |
| --exclude=PAT | 排除 |
| -P | 进度 + 断点续传 |
scp app.tar.gz user@1.2.3.4:/tmp/ scp -r user@host:/var/log/app ./logs scp -P 2222 file user@host:~ # 指定端口(大写 P)
cat config.yml cat -n app.js # 带行号 cat a.txt b.txt > all.txt # 拼接
| -n | 行号 |
| -A | 显示不可见字符(^M 就是 CRLF) |
| -s | 压缩连续空行 |
less /var/log/syslog # /关键词 搜索 n 下一个 G 到末尾 g 到开头 q 退出 F 跟随(像 tail -f)
| -N | 显示行号 |
| -S | 不折行 |
| +F | 进入即跟随模式 |
| -i | 搜索忽略大小写 |
head -n 20 app.log head -c 100 file.bin # 前 100 字节 head -n -5 file # 除了最后 5 行
tail -n 50 app.log tail -f /var/log/nginx/access.log tail -F app.log # 文件被轮转后继续跟随
| -n N | 后 N 行 |
| -f | 跟随追加 |
| -F | 跟随并处理文件重建 |
| -n +N | 从第 N 行起到末尾 |
wc -l access.log ls | wc -l # 目录下有多少项 cat *.py | wc -l # 代码行数
diff -u old.conf new.conf diff -r dir1 dir2 # 比较目录 diff <(sort a) <(sort b) # 比较排序后的内容
| -u | 统一格式 |
| -r | 递归比较目录 |
| -q | 只报告是否不同 |
| -w | 忽略空白 |
| -i | 忽略大小写 |
cmp a.bin b.bin
nl -ba script.sh # 空行也编号
tac app.log | less
strings app.bin | grep -i version
xxd file.bin | head -20 xxd -r dump.txt > file.bin # 还原
nano /etc/hosts # Ctrl+O 保存 Ctrl+X 退出 Ctrl+W 搜索 Ctrl+K 剪切行
vim app.conf # :wq 保存退出 :q! 不保存退出 /词 搜索 dd 删行 u 撤销 :set nu 行号
make 2>&1 | tee build.log echo "text" | sudo tee /etc/file # 用 sudo 写受保护文件 cmd | tee -a log.txt # 追加
ls > list.txt echo "line" >> notes.txt cmd > out.log 2>&1 # 全部进日志 cmd 2>/dev/null # 丢掉错误 cmd &> all.log # bash 简写
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 "^$" # 去掉注释与空行
grep -E "5[0-9]{2}" access.log # 扩展正则
grep -l "main" *.c # 只列文件名
grep -A3 -B1 "Exception" app.log # 前 1 后 3 行上下文| -r / -R | 递归目录 |
| -n | 显示行号 |
| -i | 忽略大小写 |
| -v | 反选(不含模式的行) |
| -E | 扩展正则(同 egrep) |
| -F | 当作固定字符串 |
| -w | 整词匹配 |
| -c | 只数行数 |
| -l | 只列匹配的文件名 |
| -o | 只输出匹配部分 |
| -A/-B/-C N | 后 / 前 / 前后 N 行上下文 |
| --include="*.js" | 递归时限制文件名 |
rg "TODO" --type ts
rg -n "fetch\(" src/sed 's/foo/bar/g' a.txt # 输出替换结果 sed -i 's/foo/bar/g' a.txt # 直接修改文件(GNU) sed -i.bak 's/8080/80/' app.conf # 改前留备份 sed 's#/usr/local#/opt#g' f # 分隔符可换
| -i | 就地修改(macOS 需 -i '') |
| -n | 只打印被 p 命令选中的行 |
| -e | 多个脚本 |
| -E | 扩展正则 |
| g 标志 | 一行内全部替换 |
sed -n '10,20p' app.log # 第 10–20 行 sed '5d' f.txt # 删第 5 行 sed '/^$/d' f.txt # 删空行 sed '3i\新的一行' f.txt # 第 3 行前插入
awk '{print $1}' access.log | sort | uniq -c | sort -rn | head # 访问最多的 IP
awk -F: '{print $1}' /etc/passwd # 用户名
awk '$3 > 100 {print $0}' data.txt # 第三列大于 100 的行
awk '{sum += $2} END {print sum}' f # 求和| -F <分隔符> | 字段分隔符(默认空白) |
| $0 / $1 / $NF | 整行 / 第 1 列 / 最后一列 |
| NR | 当前行号 |
| BEGIN{} / END{} | 开始前 / 结束后执行 |
| /正则/ {…} | 只处理匹配的行 |
cut -d, -f1,3 data.csv cut -d: -f1 /etc/passwd cut -c1-8 file # 按字符位置
sort names.txt sort -n nums.txt # 按数值 sort -k2 -t, -r data.csv # 按第 2 列倒序 sort -u list.txt # 排序并去重 sort -h sizes.txt # 按 K/M/G 大小
| -n | 按数值 |
| -r | 倒序 |
| -k N | 按第 N 列 |
| -t <分隔符> | 列分隔符 |
| -u | 去重 |
| -h | 人类可读大小 |
| -V | 版本号排序(1.2 < 1.10) |
sort words.txt | uniq -c | sort -rn sort a.txt | uniq -d # 只显示重复的 sort a.txt | uniq -u # 只显示唯一的
echo hello | tr a-z A-Z # HELLO tr -d '\r' < win.txt > unix.txt # 去掉 CR tr -s ' ' < f # 压缩连续空格 echo $PATH | tr ':' '\n' # 一行一个
find . -name "*.log" | xargs rm
find . -name "*.txt" -print0 | xargs -0 wc -l # 文件名含空格
cat urls.txt | xargs -n1 -P4 curl -sO # 4 路并行
echo a b c | xargs -I{} echo "item: {}"| -0 | 以 NUL 分隔(配 find -print0) |
| -n N | 每次传 N 个参数 |
| -I {} | 用 {} 占位 |
| -P N | N 个并行 |
| -r | 输入为空时不执行 |
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 在空格处折
iconv -f GBK -t UTF-8 gbk.txt > utf8.txt iconv -l | grep -i gb # 列出支持的编码
dos2unix script.sh sed -i "s/\r$//" script.sh # 没装 dos2unix 时
curl -s https://api.github.com/repos/git/git | jq .stargazers_count jq ".items[] | .name" data.json jq -r ".[].id" list.json # -r 原始字符串不带引号 cat a.json | jq . # 格式化
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 # 一行一个文件名
seq 1 10 seq 0 5 100 # 步长 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 # 转十六进制
chmod 755 script.sh # rwxr-xr-x chmod 644 file.txt # rw-r--r-- chmod 600 ~/.ssh/id_ed25519 # 只有自己可读写 chmod -R 755 public/ # 递归
| 755 | 目录 / 可执行文件的常见值 |
| 644 | 普通文件常见值 |
| 600 | 私钥、密码文件 |
| 700 | 私有目录(如 ~/.ssh) |
| -R | 递归 |
chmod +x deploy.sh # 加可执行 chmod u+w,go-w file # 所有者可写、其他不可写 chmod a-x file chmod g+s shared/ # 目录 setgid:新文件继承组
sudo chown www-data:www-data -R /var/www/site sudo chown $USER file.txt chgrp developers project/ # 只改组
umask umask 027 # 组只读、其他无权限
sudo apt update sudo -i # 切到 root 交互 shell sudo -u postgres psql # 以其他用户执行 sudo !! # 用 sudo 重跑上一条
su - deploy exit # 回来
whoami id id deploy # 看别的用户
sudo useradd -m -s /bin/bash deploy sudo passwd deploy sudo usermod -aG sudo deploy # 加入 sudo 组
sudo usermod -aG docker $USER newgrp docker # 或重新登录生效
sudo userdel -r olduser
passwd sudo passwd deploy sudo passwd -l deploy # 锁定账号
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 # 把公钥装到服务器
ssh user@1.2.3.4 ssh -p 2222 user@host # 指定端口 ssh -i ~/.ssh/key.pem ubuntu@host ssh -L 8080:localhost:80 user@host # 端口转发 ssh user@host "uptime" # 只执行一条命令
| -p | 端口 |
| -i | 私钥文件 |
| -L 本地:目标:端口 | 本地端口转发 |
| -N | 只转发不开 shell |
| -v | 调试连接问题 |
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 # 最吃内存的 ps -p 1234 -o pid,etime,cmd # 某进程运行了多久
| aux | BSD 风格:所有用户、含无终端、详细 |
| -ef | UNIX 风格:全部进程含父进程 |
| --sort=-%cpu | 按 CPU 倒序 |
| -p PID | 指定进程 |
| -o 字段 | 自定义列 |
pgrep -f "node server.js" pgrep -l nginx # 带名字 pkill -f "node server.js" # 找到并杀
top top -o %MEM top -p 1234 # 只看某进程
htop htop -u www-data
kill 1234 kill -9 1234 # 不听话就强杀 kill -HUP 1234 # 让服务重载配置 kill -l # 信号列表
| -15 / -TERM | 默认:请求正常退出 |
| -9 / -KILL | 强制结束,不给清理机会 |
| -1 / -HUP | 常用于重载配置 |
| -2 / -INT | 等于 Ctrl+C |
| -STOP / -CONT | 暂停 / 继续 |
killall node killall -9 chrome
npm run build & jobs fg %1 # Ctrl+Z 暂停当前前台任务,再 bg 让它后台继续
nohup python server.py > server.log 2>&1 & echo $! # 刚启动的 PID
tmux new -s work # Ctrl+B 然后 d 分离 tmux ls tmux attach -t work tmux kill-session -t work
systemctl status nginx systemctl status --failed # 失败的服务
sudo systemctl restart nginx sudo systemctl reload nginx # 不中断连接重载配置
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 # 本次开机以来的错误 sudo journalctl --vacuum-size=500M # 清理
| -u <单元> | 某服务 |
| -f | 跟随 |
| -n N | 最近 N 行 |
| --since / --until | 时间范围 |
| -p err | 按级别过滤 |
| -b | 本次启动 |
| -k | 内核消息 |
crontab -e # 每天 3:30 备份 30 3 * * * /opt/scripts/backup.sh >> /var/log/backup.log 2>&1 # 每 5 分钟 */5 * * * * /usr/bin/curl -s https://example.com/ping crontab -l # 查看
echo "systemctl restart app" | at 03:00 atq # 队列 atrm 3 # 删除
watch -n 2 "df -h" watch -d free -m # -d 高亮变化
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 # 谁在用这个目录的文件 lsof | grep deleted # 已删除但被占用的文件(磁盘不释放)
strace -p 1234 strace -f -e trace=network node app.js strace -c ./cmd # 统计
nice -n 19 tar czf big.tgz data/ renice -n 10 -p 1234
ss -tulnp ss -tlnp | grep :80 ss -s # 连接统计 ss -tan state established
| -t / -u | TCP / UDP |
| -l | 只看监听 |
| -n | 数字端口不解析服务名 |
| -p | 显示进程(需 root 看全部) |
| -a | 全部连接 |
netstat -tulnp | grep 3000 netstat -an | grep ESTABLISHED | wc -l
lsof -i :8080 lsof -i tcp -sTCP:LISTEN kill -9 $(lsof -t -i :3000) # 直接杀掉占用者
ip addr ip -4 -br addr # 精简 hostname -I # 只要 IP
ip route ip route get 8.8.8.8 # 去某地址走哪条路
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 # 只看响应头
curl -sS https://api.example.com/x | jq . # 静默但报错
curl -o file.zip -L https://…/file.zip # 下载并跟随重定向
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 | 只请求头(HEAD) |
| -L | 跟随重定向 |
| -o 文件 / -O | 保存到文件 / 用远程文件名 |
| -X 方法 | 请求方法 |
| -H "头: 值" | 请求头 |
| -d 数据 | 请求体(默认 POST) |
| -s / -S | 静默 / 静默但显示错误 |
| -v | 显示完整交互 |
| -k | 忽略证书错误(调试用) |
| -w 格式 | 输出状态码、耗时等 |
wget https://example.com/file.tar.gz wget -c https://…/big.iso # 续传 wget -qO- https://example.com | head # 输出到屏幕 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 # 指定 DNS dig -x 93.184.216.34 # 反查
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 # 监听 8080 echo "hi" | nc host 8080 # 发数据
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
开启前务必先放行 22,否则 SSH 会被自己关在外面。
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 # 存文件给 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 压得更小更慢
| -c | 创建 |
| -x | 解开 |
| -t | 列出内容 |
| -z / -j / -J | gzip / bzip2 / xz |
| -v | 显示文件 |
| -f 文件 | 归档文件名(必须紧跟文件名) |
| -C 目录 | 切换到目录再操作 |
| --exclude=PAT | 排除 |
tar -xzvf site.tar.gz tar -xzvf site.tar.gz -C /var/www/ tar -xf any.tar.* # 新版 tar 自动识别压缩格式 tar -tzvf site.tar.gz # 先看看里面有什么
gzip big.log # 得到 big.log.gz gzip -k big.log # 保留原文件 gunzip big.log.gz zcat big.log.gz | grep ERROR # 不解压直接看
zip -r project.zip project/ -x "*/node_modules/*" zip -e secret.zip file.txt # 加密
unzip archive.zip unzip archive.zip -d out/ unzip -l archive.zip # 只看列表 unzip -O gbk cn.zip # Windows 中文文件名乱码时
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 测试文件
of= 写错设备会直接抹掉磁盘,执行前 lsblk 三次确认。
uname -a uname -m # x86_64 / aarch64 cat /etc/os-release # 发行版
hostnamectl sudo hostnamectl set-hostname web-01
uptime # 负载 > CPU 核数(nproc)说明在排队
free -h free -m -s 2 # 每 2 秒刷新
nproc lscpu | grep -E "Model name|^CPU\(s\)"
lsblk lsblk -f # 带文件系统与 UUID sudo fdisk -l
sudo mount /dev/sdb1 /mnt/usb sudo umount /mnt/usb mount | column -t # 已挂载 cat /etc/fstab # 开机自动挂载
vmstat 1 10
iostat -x 1 5
sudo dmesg -T | tail -50 sudo dmesg -T | grep -i "killed process" # 谁被 OOM 了
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 # 列出
history | grep ssh !105 sudo !! history -c # 清空
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 | 刷新软件源索引 |
| upgrade | 升级已装包 |
| install / remove | 安装 / 卸载 |
| search / show | 搜索 / 详情 |
| autoremove | 清理不再需要的依赖 |
| list --installed | 已安装列表 |
sudo dnf install -y git sudo dnf update dnf search nginx sudo yum install epel-release # 老系统
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 # 包装了哪些文件
sudo shutdown -h now sudo reboot sudo shutdown -r +10 "10 分钟后重启维护" sudo shutdown -c # 取消
date date "+%Y-%m-%d %H:%M:%S" date -d "yesterday" +%F date +%s # 时间戳 date -d @1700000000 # 时间戳转日期
timedatectl sudo timedatectl set-timezone Asia/Shanghai timedatectl list-timezones | grep Asia
cal cal 2026 cal -3 # 前后各一月
lsmod | grep nvidia sudo modprobe br_netfilter
lspci | grep -i vga lsusb
ulimit -n ulimit -n 65535 # 当前会话 cat /proc/sys/fs/file-max
chsh -s $(which zsh) echo $SHELL
source ~/.bashrc . ~/.zshrc # 同义
#!/usr/bin/env bash set -euo pipefail # 出错即停、未定义变量报错、管道错误传递 for f in *.log; do echo "处理 $f" done
man tar man 5 crontab # 第 5 节:文件格式 tar --help | less tldr tar # 社区示例版(需安装)
Um pequeno sistema de arquivos e um interpretador de shell em memória: aceita ls / cd / cat / grep / sed / awk / find / chmod / tar e mais de 60 comandos, com pipes, redirecionamentos e curingas; 8 níveis vão de “criar uma árvore de diretórios” a “estatísticas com pipes”. Não acessa a rede nem toca nos seus arquivos reais. A prática de comandos Git está emReferência de comandos do Git.