Files
2026-08-31 21:53:57 +08:00

16 KiB
Raw Permalink Blame History

aiagent.sh — 100% POSIX-sh 自然语言运维 Agent

一行英文句子 = 一条运维命令。不用背参数,不用记 flag。

aiagent.sh 是一个纯 /bin/sh 实现的轻量级"AI Agent"。它不需要 Python、不需要 node、不需要任何运行时——单文件、零依赖,却能把你输入的自然英语句子解析成真实的运维操作。

$ ./aiagent.sh
aiagent> please show disk usage
[INFO] Disk usage:
Filesystem      Size  Used Avail Use% Mounted on
/dev/sda1       100G   42G   58G  42% /

aiagent> what is the uptime
[INFO] System uptime:
 14:32:11 up 12 days, 3:17,  2 users,  load average: 0.12, 0.08, 0.01

aiagent> check port 8080
[INFO] Checking port 8080 ...
[OK] Port 8080 is IN USE

✨ 核心特性

特性 说明
🗣️ 自然语言输入 接受完整英文句子,不需要任何特殊语法
🧠 意图识别 自动提取动词、名词、路径、端口、服务名
🔄 同义词归一 show/display/list → 统一处理,kill/stop/terminate → 统一处理
🎯 名词推断动作 只说 uptime 也能理解成"show uptime"
🔒 安全确认 所有破坏性操作(删除、杀进程、装包)强制 y/N 二次确认
🛡️ 零 eval 注入 没有任何字符串拼接执行,包管理器直接调用
⚙️ 自动适配环境 自动检测 systemctl/service、ss/netstat、apt/dnf/yum/apk/pacman
🧩 可扩展 每个 do_xxx() 函数独立,新增操作只需加一个 case 分支和一个函数
📦 单文件分发 约 1050 行,直接 cp 到目标机就能跑

🚀 快速上手

1. 获取脚本

# 从git仓库获取
  git clone https://github.com/CancerXiaoAi/shell-ai.git
  git clone https://git.cancerai.top/cancerai/shell-ai.git

2. 两种使用方式

# 方式 A:交互式 REPL(推荐日常使用)
./aiagent.sh

# 方式 B:一行命令模式(适合脚本/CI)
./aiagent.sh "please check port 443"
./aiagent.sh "what is the kernel version"
./aiagent.sh "health check"

3. 最简示例

# 系统一句话
./aiagent.sh uptime          # 直接说名词就行
./aiagent.sh disk
./aiagent.sh health

# 完整句子也没问题
./aiagent.sh "please help me show memory usage"
./aiagent.sh "could you ping google.com for me"
./aiagent.sh "i want to restart nginx"

📖 完整命令参考

💡 语法约定

脚本对输入的容忍度极高。以下写法全部等价:

please help me check disk usage
help me check disk
check disk
disk

规则:

  • please、help me、to、a、the、can you、would you 等纯语法词全部自动忽略
  • 只带名词(如 uptime)会被自动推断为"show + 该名词"
  • 只带动词加短语(如 check port 80)直接路由

🖥️ 系统信息 — System Info

输入示例 实际调用 说明
show disk usage / disk df -h 磁盘使用情况
check memory / memory / ram /proc/meminfo 或 free -h 内存占用
check cpu load / cpu / load /proc/loadavg CPU 负载
what is the uptime / uptime uptime 系统运行时长
show kernel version / version /etc/os-release + uname OS 和内核版本
show listening ports ss -tulnp 或 netstat -tulnp 监听端口
who is logged in / show users who 当前登录用户
health check / check 一键跑 uptime + CPU + 内存 + 磁盘 健康检查

📂 文件操作 — Files

输入示例 实际调用 说明
list files in /var/log ls -lah /var/log 列出目录
show me content of /etc/hosts ls /etc/hosts 查看文件
find files named *.log in /tmp find /tmp -type f -name "*.log" 查找文件
find process nginx `ps aux grep nginx`
create directory /data mkdir -p /data 创建目录
create file /tmp/hello.txt : > /tmp/hello.txt 创建空文件
copy /etc/hosts /tmp/hosts.bak cp -r/-f 自动判断文件/目录复制
move /tmp/a.log /var/log/ mv -f 移动/重命名

⚠️ 破坏性操作 — Destructive(强制 y/N 确认)

输入示例 实际调用 说明
please remove /tmp/cache rm -rf(确认后) 递归删目录
delete file /tmp/bad.log rm -f(确认后) 删除文件
clean old log files in /var/log find -delete(确认后) 清理日志
kill process nginx kill + PID 列表(确认后) 按名字杀进程
kill the process on port 8080 先 lsof/ss 找 PID(确认后) 按端口杀进程
stop nginx systemctl stop(确认后) 停服务

🔌 服务管理 — Services

输入示例 实际调用 说明
check status of sshd systemctl status 查看服务状态
start docker service systemctl start 启动服务
restart nginx systemctl restart 重启服务
nginx 自动识别服务名 → 查状态 裸服务名默认查状态

🌐 网络 — Network

输入示例 实际调用 说明
check port 443 / port 443 ss/netstat/nc 检查端口监听状态
ping google.com ping -c 3 -W 2 连通性测试(3 包)
show listening ports ss -tulnp 所有监听端口

📦 包管理 — Packages

输入示例 实际调用 说明
please install package htop 自动检测 apt-get/dnf/yum/apk/pacman 并调用 安装系统包(确认后)

📜 日志 — Logs

输入示例 实际调用 说明
tail /var/log/syslog tail -30 直接路径
tail nginx log 自动匹配 /var/log/nginx/access.log 按服务名猜路径
follow docker log glob /var/log/*docker* 模糊匹配

🎛️ 其他

输入 说明
help 打印帮助手册
quit / exit / bye 退出 REPL

🧠 自然语言解析原理

整个解析管线分为 5 层,每一层都只使用 POSIX sh 原语实现:

用户输入:please help me check port 8080
    │
    ▼
┌─────────────────────────────────┐
│ 第 1 层:strip_fillers()         │
│ 丢弃纯语法词:please, help, me   │
└─────────────────────────────────┘
    │ 得到:check port 8080
    ▼
┌─────────────────────────────────┐
│ 第 2 层:跳过引导词              │
│ 跳过开头的 help/what/can 等客气词│
└─────────────────────────────────┘
    │ 得到:check port 8080
    ▼
┌─────────────────────────────────┐
│ 第 3 层:canonical_verb()       │
│ 动词→同义词归一                  │
│ 名词→推断动作(health→check)    │
└─────────────────────────────────┘
    │ verb=check, phrase="port 8080"
    ▼
┌─────────────────────────────────┐
│ 第 4 层:dispatch() 一级匹配     │
│ case "$phrase" in *port*)        │
│   do_check_port; _matched=1 ;;   │
└─────────────────────────────────┘
    │
    ▼
┌─────────────────────────────────┐
│ 第 5 层:do_check_port()         │
│ 从短语中提取 "8080"              │
│ 依次尝试 ss → netstat → nc      │
│ 输出 [OK]/[WARN] 状态           │
└─────────────────────────────────┘

动词同义词映射(canonical_verb)

show  ← show, display, list, print, tell, what, reveal, dump
check ← check, monitor, verify, inspect, diagnose
find  ← find, locate, search, lookup, track
remove← remove, delete, erase, rm, wipe, cleanup, clean
kill  ← kill, stop, terminate, shutdown, halt
start ← start, launch, run, begin, enable
...

名词 → 推断动作

uptime, disk, memory, cpu, version, port, process ... → 自动当作 show
health, status, connection, reachability             → 自动当作 check

三级 fallback 匹配机制

每个规范动词的路由都有三级兜底:

  1. 一级关键词匹配:*disk* → do_show_disk,*port* → do_check_port
  2. 二级兜底:短语是纯数字 → 当作端口号;短语含已知服务名 → do_service_status
  3. 三级兜底:check 空短语 → do_health_check;其他 → 提示用户重述

🔒 安全设计

强制二次确认

以下操作必须输入 y 或 yes 才会继续,其他任何输入都视为取消:

  • 删除目录/文件(remove, delete)
  • 杀进程(kill)
  • 停服务(stop service)
  • 安装系统包(install)
[CONFIRM] Recursively remove directory '/tmp/cache' ? (y/N):

零 eval 注入

整个脚本没有任何 eval 调用。包管理器的调用采用直接分支方式:

if command -v apt-get >/dev/null 2>&1; then
    apt-get install -y -- "$_pkg"   # 直接调用,参数安全引用
elif command -v dnf >/dev/null 2>&1; then
    dnf install -y -- "$_pkg"
...

路径安全

rm -rf、mv、cp 等危险操作都使用了 -- 分隔符,防止路径以 - 开头被解释为选项。

信号处理

REPL 模式下按 Ctrl+C 会优雅退出,不会留下终端异常状态:

trap 'echo; printf "Bye.\n"; exit 130' INT TERM

🏗️ 架构总览

aiagent.sh (~1050 lines, 单文件)
├── 辅助函数层
│   ├── info() / warn() / error() / success()     # 带颜色的日志输出
│   └── confirm()                                  # y/N 安全确认
│
├── 解析层(第 1–3 层)
│   ├── strip_fillers()                            # 丢弃纯语法词
│   ├── canonical_verb()                            # 同义词归一 + 名词推断
│   ├── _extract_path()                            # 从短语中提取路径
│   ├── _extract_svcname()                         # 从短语中提取服务名
│   └── _SERVICES_RE                               # 已知服务名正则
│
├── 路由层(第 4 层)
│   └── dispatch()                                 # 大 case 分支,三级 fallback
│
├── 执行层(第 5 层)
│   ├── do_show_disk / _memory / _cpu / _uptime / _version / ...
│   ├── do_check_port / do_ping_host / do_service_status / do_health_check
│   ├── do_find_process / do_find_file
│   ├── do_remove_dir / _file / _log
│   ├── do_kill_process / do_kill_by_port
│   ├── do_service_start / _restart / _stop
│   ├── do_create_dir / _file
│   ├── do_copy_path / do_move_path
│   ├── do_install_pkg
│   └── do_tail_log
│
├── REPL 层
│   ├── run_one()                                  # 单次命令处理管线
│   └── repl()                                     # 交互式循环
│
└── 入口
    └── main()                                     # 分交互式/一行模式

依赖关系图

main() ─→ repl() 或 run_one()
              │
              ▼
         dispatch()
              │
    ┌─────────┼─────────────┬──────────┬────────────┐
    ▼         ▼             ▼          ▼            ▼
 show()    check()       find()     remove()    install()
    │         │             │          │            │
    ▼         ▼             ▼          ▼            ▼
 do_show_*  do_check_*   do_find_*   do_remove_*  do_install_pkg
                                       │
                                       ▼
                                   confirm()  ←── 所有 destructive 函数必经

⚙️ 运行要求

最低要求

项目 要求
Shell 解释器 /bin/sh(POSIX sh,任何实现均可:dash / busybox / bash --posix)
操作系统 Linux(主要目标);macOS 可读但部分功能受限(无 systemctl/ss)
权限 普通用户即可运行,执行破坏性/管理类命令时需要相应权限

可选依赖(根据操作自动探测)

操作 依赖(择一)
磁盘/内存/CPU df, /proc/meminfo 或 free, /proc/loadavg
服务管理 systemctl 或 service
端口检查 ss / netstat / nc
进程查找 ps, pgrep(可选)
进程/端口杀 pgrep, lsof, fuser(择一)
网络 ping
文件查找 find
包安装 apt-get / dnf / yum / apk / pacman(择一)

跨包管理器支持

发行版 自动使用
Debian / Ubuntu apt-get
RHEL 8+ / Fedora / CentOS 8+ dnf
RHEL 7 / CentOS 7 yum
Alpine apk
Arch / Manjaro pacman

⚡ 性能

解析管线全部使用 POSIX sh 内建实现(case / for / if / read / printf),不 fork 任何外部进程——除了 grep -qE 和 awk 在少数 fallback 分支里会被调用。整个"strip → canonical → dispatch → route"管线的纯解析开销可以忽略不计,实际耗时主要来自底层命令本身(如 df -h、ps aux、systemctl 等)。


🧪 快速验证

在 Docker 容器里跑一下(无需在本机安装任何东西):

# Debian
docker run --rm -it -v $(pwd)/aiagent.sh:/aiagent.sh debian:latest \
    sh -c 'chmod +x /aiagent.sh && /aiagent.sh "health check"'

# Alpine
docker run --rm -it -v $(pwd)/aiagent.sh:/aiagent.sh alpine:latest \
    sh -c 'chmod +x /aiagent.sh && /aiagent.sh "check port 22"'

# CentOS / Rocky / AlmaLinux
docker run --rm -it -v $(pwd)/aiagent.sh:/aiagent.sh rocky:9 \
    sh -c 'chmod +x /aiagent.sh && /aiagent.sh "restart sshd"'

🛠️ 扩展指南

想新增一个操作(比如"备份数据库")?三个步骤:

步骤 1:加一个规范动词映射(如果是新动词)

canonical_verb() {
    ...
    backup|dump) echo "backup" ;;
    ...
}

步骤 2:在 dispatch() 的 case 分支里加路由

dispatch() {
    ...
    backup)
        do_backup_db "$phrase" ;;
    ...
}

步骤 3:实现 do_backup_db() 函数

do_backup_db() {
    _db=""
    for _tok in $1; do
        case "$_tok" in mysql|postgres|redis|mongodb) _db="$_tok" ;; esac
    done
    [ -z "$_db" ] && { error "No DB type. Example: 'backup mysql'"; return 1; }
    confirm "Backup $_db ?" || return 1
    # 实际备份逻辑
    case "$_db" in
        mysql)    mysqldump ... ;;
        postgres) pg_dump ... ;;
        ...
    esac
}

完成。现在 ./aiagent.sh "please backup mysql database" 就能工作了。


🐛 已知限制

限制 说明
只能识别英文 整个关键词库是英语 hardcode 的,不支持中文
正则只支持 POSIX ERE 不支持 PCRE(但对运维场景已足够)
交互式 REPL 不支持命令历史 POSIX sh 的 read 没有 readline;可以通过 rlwrap ./aiagent.sh 获得历史
端口号从短语提取用的是 [0-9]* 如果句子里有多个数字,会取最后一个(对"check port 80 on server 192.168.1.1"这种会取 1)
macOS 功能受限 没有 systemctl/ss//proc/*,部分操作会降级或报依赖缺失
包管理器自动检测 只是检测命令是否存在,不检查是否真的可用(例如在 chroot 里)

📄 License

MIT License. 复制、修改、商用均自由,唯一要求保留版权声明。


🙏 致谢

  • POSIX 标准委员会:没有你们就没有可移植的 shell
  • 所有写出漂亮运维命令的前辈:你们的 df -h、ps aux、ss -tulnp 是这个项目的基石