文件与目录
登录服务器第一件事是确认自己在哪、周围有什么:
pwd # 当前目录
ls -lh # 列出文件,大小用 K/M/G 显示
ls -lht # 按修改时间倒序,最新在前
cd /opt/app # 切换目录
mkdir -p /data/logs/app # 递归建目录,父目录不存在也能建
cp -r conf conf.bak # 递归复制
mv app.jar app.jar.bak # 重命名或移动
find /data -name "*.log" -mtime +7 # 找 7 天前的日志
find 是排查时的利器,按名字、时间、大小都能筛。别在根目录直接 find /,磁盘大的机器能跑几分钟,先缩小到具体目录。
跨机器传文件用 scp 或 rsync -avz。小文件偶尔传一次用 scp 就行,大目录、需要断点续传或只同步增量时用 rsync,它默认会跳过没变的文件。
打包压缩用 tar -czvf app.tar.gz app/,解压是 tar -xzvf app.tar.gz,-C 可以指定解压目录。记住 c 是创建、x 是解压、z 是 gzip、v 显示过程、f 指定文件名,顺序不用死记。
看日志时管道很常用:grep "ERROR" app.log | tail -n 50 先筛再取最后 50 条,grep -c 统计条数,grep -v 排除噪音。管道把上一条命令的输出交给下一条,组合起来比写脚本快。
需要后台长期运行用 nohup java -jar app.jar > app.log 2>&1 &,2>&1 把标准错误也重定向到同一个文件,否则报错信息不会进日志。退出 SSH 前用 jobs 或 ps 确认进程还在。
查看文本
tail -f app.log # 实时看日志
tail -n 200 app.log # 看最后 200 行
grep -n "ERROR" app.log # 带行号搜索
grep -C 3 "NullPointer" app.log # 显示前后 3 行上下文
less app.log # 分页查看,/ 搜索,q 退出
wc -l app.log # 统计行数
看日志优先用 less,不要用 cat 刷屏。less 里按 G 跳到末尾、/关键字 搜索、F 进入跟随模式,比来回敲命令高效。日志文件特别大时,先 tail 再看,别一上来就 less 整个文件。
权限:rwx 到底代表什么
ls -l 的输出里,-rw-r--r-- 分三组:属主、属组、其他人,每组三位,分别是读(4)、写(2)、执行(1)。
| 命令 | 含义 |
|---|---|
chmod 755 文件 |
属主可读写执行,其他人可读可执行 |
chmod 644 文件 |
属主可读写,其他人只读 |
chmod +x start.sh |
给所有人加执行权限 |
chown app:app 文件 |
修改属主和属组 |
目录的 x 权限表示“能进入”,r 表示“能列出内容”,这两个经常被混淆。Web 目录一般设成 755,让 Nginx 能读能进;日志目录让应用用户可写即可,不要图省事给 777。
改权限前先确认文件属主。应用以 app 用户运行、日志却属于 root,重启后应用写不进去,这类问题用 ls -l 一眼就能看出来。批量改目录用 chown -R app:app /data/app,别对 / 用 -R。
进程、端口与资源
ps -ef | grep java # 找 Java 进程
top # 看 CPU 和内存占用,q 退出
ss -lntp # 列出监听端口和对应进程
lsof -i:8080 # 谁占用了 8080
kill 12345 # 正常停止,发给进程 TERM 信号
df -h # 磁盘使用率
du -sh /data/logs/* # 各目录占用大小
free -h # 内存使用情况
ss 是 netstat 的替代品,新版发行版默认都装了。ps -ef | grep java 在进程多的时候会把人看花,加 --color=auto 或者配合 grep -v grep 过滤掉自己。
常见坑
1. rm -rf 的路径变量为空
rm -rf $APP_DIR/ 在变量为空时会变成 rm -rf /,后果不用多说。脚本里先判断变量非空,再执行删除;路径一定加引号:rm -rf -- "$APP_DIR"。手敲命令时,删之前先 ls 看一眼目标。
2. 权限一律 777
777 意味着任何用户都能改你的程序、日志和配置。正确做法是让文件属主是运行应用的用户,按需给 755 或 644。遇到权限问题要查清楚是哪个用户、缺哪一位权限,而不是直接 chmod -R 777。
3. 命令找不到
java: command not found 通常是 PATH 没配,或者当前用户的环境变量没生效。先 echo $PATH,再 which java。自己写的脚本要用 ./start.sh 执行,当前目录默认不在 PATH 里。
4. 用 kill -9 代替正常停止
kill -9 直接杀进程,不给应用做优雅停机、刷新缓冲、关闭连接池的机会。先 kill PID 发 TERM 信号,等十几秒还没退出再考虑 -9。
5. 磁盘满了却找不到大文件
df -h 显示 100%,du -sh /* 加起来却对不上,常见原因是“文件被删除但进程还持有句柄”。用 lsof +L1 能找到这类已删除但仍占空间的日志,重启对应进程即可释放。
排查步骤
- 服务起不来:
ps -ef | grep 应用名看进程在不在,ss -lntp | grep 端口看端口有没有监听; - 端口被占:
lsof -i:8080找到 PID,确认是不是旧进程没退干净; - 磁盘告警:
df -h定位分区,du -sh逐层下钻,最后用lsof +L1兜底; - 权限报错:
ls -l看属主和权限位,id看当前用户属于哪些组; - 内存不足:
free -h看剩余,top按M按内存排序,找占用最高的进程。
评论