写给"会用但记不住"的同行 —— 经常 SSH 上服务器排个查、改个配置,但每次 find -exec 的语法都要查一下。
下面按场景分组,每个命令 1-2 行示例 + 一句"为什么这么写"。直接收藏到浏览器书签或者 Markdown 字数统计工具 之类地方备用。
演示均基于 Linux(bash / zsh)。macOS 大部分通用,但 BSD 版的
sed、grep、date等参数和 GNU 版有差异,我会标注 ⚠️。
文件 / 目录
pwd # 当前所在目录
ls -lah # 长列表 + 隐藏文件 + 人类可读大小
ls -lt # 按修改时间倒序(最新的在最前)
cd - # 回到上一次的目录(神器)
mkdir -p a/b/c # 递归建目录,父目录不存在也不报错
cp -r src dst # 递归复制目录
cp -a src dst # 完整保留属性(权限/时间戳/链接),备份/迁移用这个
mv old new # 改名 / 移动(同一文件系统是原子操作)
rm -rf path # 删 ⚠️ 不可恢复,加 -i 让它每个文件都问你-a 比 -r 多保留权限和时间,搬数据用 -a,临时复制用 -r 即可。
find:文件搜索
find . -name "*.log" # 当前目录递归找 .log
find . -type f -name "*.ts" -size +1M # 找大于 1MB 的 .ts 文件
find . -mtime -7 # 7 天内修改过的
find . -name "*.tmp" -delete # 找到顺手删掉
# 找到再批处理(-exec 用法)
find . -name "*.png" -exec mogrify -resize 800x {} \;
# {} 是占位符,\; 是结束符(注意要转义)
-mtime -7是 < 7 天,+7是 > 7 天,7刚好 7 天。容易记反。
文本查看 / 编辑
cat file # 打印整个文件(短文件用)
less file # 分页查看(长文件)— 用 / 搜索,q 退出
head -n 50 file # 前 50 行
tail -n 50 file # 后 50 行
tail -f log # 实时追踪日志(写入啥就显示啥)— 看运行日志神器
tail -F log # 文件被 logrotate 切割也能继续追(更鲁棒)
wc -l file # 行数
wc -c file # 字节数grep / sed / awk(三件套)
grep "ERROR" app.log # 直接搜
grep -i "error" app.log # 不区分大小写
grep -r "TODO" src/ # 递归整个目录
grep -v "^#" config.conf # 排除注释行
grep -A 3 -B 1 "Error" log # 匹配行 + 前 1 行 + 后 3 行(看上下文)
# 替换文件内容(GNU sed)
sed -i 's/old/new/g' file.txt # ⚠️ macOS 要写 sed -i '' '...'
sed -i 's|/old/path|/new/path|g' file # 路径里有 /,用 | 当分隔符更干净
# awk 提列(默认按空格切)
ps aux | awk '{print $2, $11}' # 取第 2 列 PID 和第 11 列命令
df -h | awk 'NR>1 {print $5, $6}' # 跳过第 1 行表头,打印用量和挂载点写代码批量改配置优先用
rg(ripgrep)+ 编辑器,比sed -i安全得多。线上紧急改才用 sed。
权限 / 用户
whoami # 当前用户
id # 用户 ID + 所在组
sudo -i # 切换到 root(全套环境变量)
su - someone # 切换到指定用户
chmod 644 file # 6=rw,4=r,4=r → 文件
chmod 755 dir # 7=rwx,5=rx,5=rx → 目录(必须有 x 才能进)
chmod +x script.sh # 加可执行权限
chmod -R 755 path # 递归改
chown -R user:group path # 改属主和属组数字权限速查
| 数字 | 含义 | 常用场景 |
|---|---|---|
644 |
rw-r--r-- | 普通文件(配置 / 网页) |
600 |
rw------- | 私钥 / 敏感配置(.env) |
755 |
rwxr-xr-x | 目录 / 可执行脚本 |
700 |
rwx------ | 私有目录(~/.ssh) |
777 |
全开 | ⚠️ 永远不要用,出问题找不到根因 |
进程 / 服务
ps aux # 看所有进程
ps aux | grep node # 找特定进程(grep 自身那一行可以忽略)
pgrep -af node # 更精准:打印 PID + 完整命令行
top # 实时进程监控(按 q 退出)
htop # 比 top 好看(需要单独装)
kill PID # 优雅退出(SIGTERM)
kill -9 PID # ⚠️ 强杀(SIGKILL)— 程序可能没机会清理
pkill -f "node app.js" # 按命令行匹配杀进程
# 后台 / 前台
command & # 后台跑
nohup command & # 后台跑,关闭终端也不退出
jobs # 看当前 shell 的后台任务
fg %1 # 把 1 号后台任务拉回前台systemctl(systemd 服务管理)
systemctl status nginx # 看状态
systemctl start nginx # 启动
systemctl stop nginx # 停止
systemctl restart nginx # 重启
systemctl reload nginx # 重载配置(不中断连接)
systemctl enable nginx # 开机自启
systemctl disable nginx # 取消自启
journalctl -u nginx -f # 跟踪服务日志
journalctl -u nginx --since "1 hour ago"
reload优于restart:reload 是给进程发信号让它重读配置,连接不中断;restart 是真的杀了再起,客户端会断。
网络 / 端口
ss -tlnp # 看哪些端口在监听(谁在监听)
ss -tnp | grep :3306 # 谁连了 MySQL
# (老命令 netstat 已经过时,优先用 ss)
curl -I https://example.com # 只看响应头
curl -v https://example.com # 详细输出(含 TLS 握手 / 请求 / 响应头)
curl -X POST -H "Content-Type: application/json" \
-d '{"k":"v"}' http://api/ # POST JSON
curl -o file.zip URL # 下载到指定文件
curl -L URL # 跟随重定向
wget URL # 简单下载(默认跟随重定向)
wget -c URL # 断点续传
ping -c 4 example.com # 测连通性(发 4 个包就停)
dig example.com # 查 DNS(想看 A 记录就这条)
dig example.com +short # 只输出 IP,适合脚本
nslookup example.com # 老牌 DNS 工具,够用就行
# 看进程在监听哪些端口
sudo lsof -i :3000 # 谁占了 3000 端口磁盘 / 资源
df -h # 各分区使用情况(人类可读)
df -i # inode 用量(小文件多了会爆 inode)
du -sh path # 单个目录总大小
du -sh */ # 当前目录下每个子目录大小
du -h --max-depth=1 /var | sort -h # 按大小排序,找谁占空间
free -h # 内存使用
uptime # 负载 + 开机时长(load average)
lscpu # CPU 信息
lsblk # 块设备(磁盘 / 分区)树状图找谁在占空间(经典套路)
# 1) 先 df 定位是哪个分区满了
df -h
# 2) 再 du 钻进去找大目录
sudo du -h --max-depth=1 / 2>/dev/null | sort -hr | head -20
# 3) 找日志大文件
sudo find / -type f -size +500M 2>/dev/null压缩 / 打包
# tar(最常用)
tar -czf out.tar.gz path/ # 压缩(c = create, z = gzip, f = file)
tar -xzf in.tar.gz # 解压(x = extract)
tar -xzf in.tar.gz -C /tmp # 解到指定目录
tar -tzf in.tar.gz # 只看里面有啥(不解压)
# zip
zip -r out.zip path/
unzip in.zip -d /tmp/
# 单文件 gzip
gzip file # → file.gz(原文件被删除!)
gzip -k file # 保留原文件
gunzip file.gz # 解压记忆口诀:c = compress(压),x = extract(解),z = gzip,f = file。每次拼出来
czf或xzf就行。
SSH / 文件传输
ssh user@host # 连接
ssh -p 2222 user@host # 指定端口
ssh -i ~/.ssh/id_ed25519 user@host # 指定密钥
ssh user@host "ls -la" # 远程跑一条命令就退出
# 一次性把本地公钥推到远程 ~/.ssh/authorized_keys
ssh-copy-id user@host
# scp 复制文件
scp file.txt user@host:/tmp/ # 本地 → 远程
scp user@host:/tmp/file.txt . # 远程 → 本地
scp -r dir/ user@host:/tmp/ # 整个目录
# rsync(增量同步,大量文件远胜 scp)
rsync -avz --progress src/ user@host:/dst/
# -a 保权限,-v verbose,-z 传输压缩,--progress 进度条
rsync -avz --delete src/ user@host:/dst/ # ⚠️ --delete 让目标和源完全一致(目标多余的删掉)环境变量 / 路径
echo $PATH # 查看 PATH
env # 看所有环境变量
which node # 找命令在哪
type ll # 看 ll 是命令、别名还是函数
export FOO=bar # 当前 shell 设置
echo "export FOO=bar" >> ~/.bashrc # 持久化(下次登录还在)
source ~/.bashrc # 应用改动(等价 . ~/.bashrc)一些高频组合技
1. 找占内存最多的 5 个进程
ps aux --sort=-%mem | head -62. 看某条 URL 的真实最终地址(跟随所有重定向)
curl -sIL https://t.co/xxx | grep -i location3. 批量重命名(去掉文件名前缀)
for f in IMG_*.jpg; do mv "$f" "${f#IMG_}"; done4. 把多文件合并去重
cat *.txt | sort -u > merged.txt5. 实时统计访问日志中各 IP 的请求数
tail -f access.log | awk '{print $1}' | sort | uniq -c | sort -rn | head
# 但 awk 在 tail -f 里不会按行实时输出,生产用建议:
goaccess access.log -c6. 一键把当前目录打成 tar 包发到远程
tar -czf - . | ssh user@host "cd /tmp && tar -xzf -"这条很妙:左侧 tar 输出到 stdout(
-占位 stdout),通过 ssh 管道直接喂给远端的 tar,不落本地中间文件,大目录传输神技。
7. 删除 30 天前的备份文件
find /var/backups -type f -mtime +30 -delete8. 看 80 端口被谁占了
sudo lsof -iTCP:80 -sTCP:LISTEN
# 或
sudo ss -tlnp | grep :80一些"被坑过"的细节
| 现象 | 原因 | 怎么办 |
|---|---|---|
rm -rf /* 把根目录干了 |
空格打错位置 | 永远不要 root 下 rm -rf 任何带变量 / 通配符的路径,先 echo 一遍看路径对不对 |
chmod 777 -R / 修了一晚上 |
想"快速解决权限问题" | 永远不要 777,出错了用 find ... -exec chmod ... 精准修 |
tail -f 看不到新内容 |
文件被 cp 替换了(inode 变了) |
用 tail -F(大写) |
| Cron 里命令找不到 | Cron 的 PATH 很穷 | 命令写绝对路径,或在脚本开头 source /etc/profile |
| sed 在 Mac 报错 | macOS 是 BSD sed | sed -i '' 's/.../.../'(空字符串 backup 后缀) |
| 中文乱码 | locale 没配 | export LANG=en_US.UTF-8 或装 zh_CN.UTF-8 |
接下来学什么
如果上面这些都顺手了,推荐继续往下挖:
- Shell 脚本:if / for / case / 函数 /
set -euo pipefail(让脚本"出错就停") - 进程信号:
kill -l看所有信号,trap捕获 SIGINT / SIGTERM 优雅退出 - iptables / nftables:防火墙的本质,云服务器面板背后就是它
- strace / ltrace:看进程在调用什么系统调用 / 库函数,排诡异问题用
- tmux / screen:断网了不丢 SSH 会话,长任务必备
或者翻翻博客的 运维 / 后端 标签,后续会写一些"线上一个真实问题怎么排查"的具体案例。
下次见。