VPS 状态一键报告:用 Shell 脚本让 AI Agent 快速理解服务器全貌
起因
我的 VPS(162.43.92.249)上跑了很多东西:
- PM2:3 个 Node.js 应用
- Docker:8 个容器(n8n、one-api、ArcReel、Excalidraw、RustDesk 等)
- k3s:WordPress、K8s Dashboard、Traefik
- Nginx:多个站点的反向代理
- Tailscale:4 台设备的私有网络
每次让新的 AI Agent 接手工作时,都要花大量时间解释「什么在跑、跑在哪、怎么访问」。于是写了一个 Shell 脚本,一条命令输出完整状态。
脚本设计思路
报告需要覆盖 15 个维度,让读者无需额外提问就能理解全貌:
| # | 维度 | 内容 |
|---|---|---|
| 1 | 系统基本 | OS、内核、CPU、内存、磁盘 |
| 2 | 网络 | 接口、Tailscale 设备 |
| 3 | 公开端口 | LISTEN 中的 TCP/UDP |
| 4 | 防火墙 | ufw 规则 |
| 5 | systemd | 主要服务 |
| 6 | PM2 | 进程、cwd、端口 |
| 7 | Docker | 容器、卷、磁盘占用 |
| 8 | k3s | Namespace、Deployment、Pod、Service、PVC |
| 9 | Nginx | sites-enabled、server_name |
| 10 | 域名 | DNS 解析结果 |
| 11 | 磁盘占用 | /root 下 Top 15 |
| 12 | workspace | .openclaw/workspace 的构成 |
| 13 | 内存占用 | Top 10 进程 |
| 14 | 大文件 | 100MB 以上 |
| 15 | 错误日志 | Nginx 最近 5 条 |
脚本正文
保存到 /root/vps-report.sh:
bash
#!/bin/bash
# ============================================================
# VPS 全体状態レポート
# 実行: bash /root/vps-report.sh
# 保存: bash /root/vps-report.sh 2>&1 | tee /root/vps-report-$(date +%Y%m%d).txt
# ============================================================
REPORT_DATE=$(date '+%Y-%m-%d %H:%M:%S %Z')
HOSTNAME=$(hostname)
PUBLIC_IP=$(curl -s --max-time 5 ifconfig.me 2>/dev/null)
TAILSCALE_IP=$(tailscale ip -4 2>/dev/null | head -1)
cat << EOF
################################################################
# VPS 全体状態レポート
# 実行日時: ${REPORT_DATE}
# ホスト名: ${HOSTNAME}
# 公開IP: ${PUBLIC_IP}
# Tailscale IP: ${TAILSCALE_IP}
################################################################
EOF
echo "=========================================="
echo "1. システム基本情報"
echo "=========================================="
cat /etc/os-release | grep -E "PRETTY_NAME|VERSION="
echo "カーネル: $(uname -r)"
echo "CPU: $(nproc) cores"
echo ""
free -h
echo ""
df -h / | tail -1
echo ""
echo "=========================================="
echo "2. ネットワーク"
echo "=========================================="
ip -br addr | grep -vE "^veth|^br-|^docker|^cni|^flannel"
echo ""
echo "--- Tailscale ---"
tailscale status 2>/dev/null || echo "未接続"
echo ""
echo "=========================================="
echo "3. 公開ポート(LISTEN中)"
echo "=========================================="
echo "--- TCP ---"
ss -tlnp | grep LISTEN | awk '{print $4}' | sort -u | grep -vE "^127\.|^\[::1\]"
echo ""
echo "--- UDP ---"
ss -ulnp | grep UNCONN | awk '{print $4}' | sort -u | grep -vE "^127\.|^\[::1\]"
echo ""
echo "=========================================="
echo "4. ファイアウォール(ufw)"
echo "=========================================="
ufw status 2>/dev/null | grep -E "Status|ALLOW"
echo ""
echo "=========================================="
echo "5. systemd 主要サービス"
echo "=========================================="
systemctl list-units --type=service --state=running --no-pager 2>/dev/null | grep -E "docker|k3s|nginx|pm2|tailscale|ssh|cron|dsh|ollama" | head -15
echo ""
echo "=========================================="
echo "6. PM2 プロセス"
echo "=========================================="
pm2 list 2>/dev/null | grep -E "id|online|stopped|errored"
echo ""
echo "=========================================="
echo "7. Docker コンテナ"
echo "=========================================="
docker ps --format "table {{.Names}}\t{{.Image}}\t{{.Ports}}\t{{.Status}}" 2>/dev/null
echo ""
echo "--- Docker ボリューム ---"
docker volume ls 2>/dev/null
echo ""
echo "--- Docker ディスク使用量 ---"
docker system df 2>/dev/null
echo ""
echo "=========================================="
echo "8. Kubernetes (k3s)"
echo "=========================================="
if command -v kubectl >/dev/null 2>&1; then
echo "--- Namespaces ---"
kubectl get namespaces 2>/dev/null
echo ""
echo "--- Deployments ---"
kubectl get deployments -A 2>/dev/null
echo ""
echo "--- Pods (Running) ---"
kubectl get pods -A 2>/dev/null | grep -v "Completed"
echo ""
echo "--- Services (NodePort/LoadBalancer) ---"
kubectl get svc -A 2>/dev/null | grep -E "NodePort|LoadBalancer|NAMESPACE"
echo ""
echo "--- PVC ---"
kubectl get pvc -A 2>/dev/null
else
echo "kubectl 未インストール"
fi
echo ""
echo "=========================================="
echo "9. Nginx 設定"
echo "=========================================="
ls -la /etc/nginx/sites-enabled/ 2>/dev/null
echo ""
echo "--- 全 server_name ---"
nginx -T 2>/dev/null | grep -E "server_name" | grep -v "^\s*#" | sort -u
echo ""
echo "=========================================="
echo "10. ドメインとDNS"
echo "=========================================="
for domain in helloai.jp traffic.helloai.jp fbinjapan.xvps.jp; do
ip=$(dig +short $domain A 2>/dev/null | head -1)
echo " $domain → ${ip:-解決失敗}"
done
echo ""
echo "=========================================="
echo "11. ディスク使用量トップ15(/root)"
echo "=========================================="
du -sh /root/* 2>/dev/null | sort -rh | head -15
echo ""
echo "=========================================="
echo "12. .openclaw/workspace の内訳"
echo "=========================================="
if [ -d /root/.openclaw/workspace ]; then
du -sh /root/.openclaw/workspace 2>/dev/null
echo ""
du -sh /root/.openclaw/workspace/* 2>/dev/null | sort -rh | head -10
else
echo "存在しません"
fi
echo ""
echo "=========================================="
echo "13. メモリ使用量トップ10"
echo "=========================================="
ps aux --sort=-%mem | head -11 | awk '{printf "%-10s %-8s %5s%% %8s %s\n", $1, $2, $4, $6, $11}'
echo ""
echo "=========================================="
echo "14. 大きなファイル(100MB以上、/root配下)"
echo "=========================================="
find /root -type f -size +100M -exec ls -lh {} \; 2>/dev/null | awk '{print $5, $9}' | sort -rh | head -10
echo ""
echo "=========================================="
echo "15. 最近のエラーログ(Nginx)"
echo "=========================================="
tail -5 /var/log/nginx/error.log 2>/dev/null || echo "ログなし"
echo ""
echo "################################################################"
echo "# レポート完了"
echo "################################################################"
使用方法
1. スクリプトの作成
bash
cat > /root/vps-report.sh << 'SCRIPT_EOF' (上記のスクリプトを貼り付け) SCRIPT_EOF chmod +x /root/vps-report.sh
2. 実行
bash
# 画面に表示 bash /root/vps-report.sh # ファイルに保存(推奨) bash /root/vps-report.sh 2>&1 | tee /root/vps-report-$(date +%Y%m%d).txt
3. 定期的に実行(オプション)
bash
# cron に追加(毎日9時) crontab -e # 以下を追加 0 9 * * * bash /root/vps-report.sh > /root/vps-report-$(date +\%Y\%m\%d).txt 2>&1
输出示例
以下是实际运行结果的摘要:
text
################################################################
# VPS 全体状態レポート
# 実行日時: 2026-09-26 19:56:31 JST
# ホスト名: x162-43-92-249
# 公開IP: 162.43.92.249
# Tailscale IP: 100.99.4.120
################################################################
==========================================
1. システム基本情報
==========================================
PRETTY_NAME="Ubuntu 22.04.5 LTS"
カーネル: 5.15.0-181-generic
CPU: 4 cores
total used free
Mem: 5.8Gi 3.5Gi 175Mi
Swap: 2.0Gi 1.9Gi 118Mi
/dev/vda1 146G 103G 43G 71% /
==========================================
3. 公開ポート(LISTEN中)
==========================================
--- TCP ---
*:3002 ← my-dashboard
*:6443 ← k3s API
*:8002 ← photo-gem-map
0.0.0.0:22 ← SSH
0.0.0.0:80 ← Nginx
0.0.0.0:3000 ← one-api
0.0.0.0:5678 ← n8n
0.0.0.0:8000 ← photo-gem-map (Nginx)
0.0.0.0:8001 ← tokyo-traffic
0.0.0.0:8080 ← OpenClaw
0.0.0.0:8088 ← Dify
100.99.4.120:8081 ← WordPress (Tailscale)
...
==========================================
8. Kubernetes (k3s)
==========================================
--- Deployments ---
default wordpress 1/1
default wordpress-mysql 1/1
kube-system traefik 1/1
kubernetes-dashboard kubernetes-dashboard 1/1
wordpress-prod wordpress 1/1
--- Services (NodePort/LoadBalancer) ---
kube-system traefik LoadBalancer 162.43.92.249 80:31340/TCP,443:31026/TCP
default wordpress NodePort 80:30080/TCP
wordpress-prod wordpress NodePort 80:30081/TCP
kubernetes-dashboard kubernetes-dashboard NodePort 443:30082/TCP
==========================================
10. ドメインとDNS
==========================================
helloai.jp → 85.131.207.20 ← 別サーバー
traffic.helloai.jp → 85.131.207.20 ← 別サーバー
fbinjapan.xvps.jp → 162.43.92.249 ← このVPS
==========================================
11. ディスク使用量トップ15(/root)
==========================================
905M /root/my-dashboard
414M /root/one-api
174M /root/hermes-agent
137M /root/ArcReel
...
==========================================
14. 大きなファイル(100MB以上)
==========================================
5.6G /root/.ollama/models/blobs/sha256-a99b...
4.8G /root/.openclaw/workspace-backup-20260403-101753.tar.gz
4.4G /root/.ollama/models/blobs/sha256-6a07...
4.4G /root/.ollama/models/blobs/sha256-60e0...
...
脚本能发现的问题
运行报告后,一眼就能看出:
- 磁盘占用分布:哪些目录最占空间
- Docker 卷的浪费:
RECLAIMABLE提示可回收大小 - k3s 里停摆的 Deployment:
0/0就是没在跑 - 域名与服务器不符:
helloai.jp指向85.131.207.20,不是这台 VPS - 内存瓶颈:Swap 用到 1.9/2.0GB,说明内存紧张
- 大文件残留:Ollama 模型、旧备份、Hugging Face 缓存
成本
| 项目 | 成本 |
|---|---|
| 脚本开发 | 0 元(一次编写) |
| 执行时间 | 约 10〜20 秒 |
| 输出大小 | 约 5〜10 KB |
| 运行成本 | 0 元 |
当前状态
| 项目 | 状态 |
|---|---|
| 脚本位置 | ✅ /root/vps-report.sh |
| 最新报告 | ✅ /root/vps-report-20260926.txt |
| 磁盘使用 | ✅ 71%(空き43GB) |
| 执行时间 | ✅ 约15秒 |
| 15个维度 | ✅ 全部输出 |
可优化的方向
- JSON 输出:增加
--json选项,便于程序解析 - 差分报告:与上次报告对比,高亮变化
- 告警阈值:磁盘 > 90%、内存 > 90% 时标红
- 定时执行:cron 每天自动生成
- 推送到 Slack/邮件:异常时自动通知
一句话总结
一条命令,15 个维度,让任何 AI Agent 或协作者在 15 秒内理解整台 VPS 的全貌。 从端口、容器、K8s 到域名解析和磁盘占用,交接和排查都变得有据可查。
