dsh-linux-commander 0.0.0-stage → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/nl.js ADDED
@@ -0,0 +1,228 @@
1
+ // Linux 指令器 — 自然语言 → 指令规则(纯数据,无依赖、无副作用)
2
+ // NL_RULES 为有序数组:具体(含数字/名称)在前,泛化在后;第一条命中即返回。
3
+ // re 为 RegExp 字面量(含捕获组);cmd 为字符串或 (m)=>string;note/warn 可选。
4
+ // 未提供具体值时使用 <路径> <文件> <用户名> <服务名> <进程名> <端口> <URL> 等占位符。
5
+
6
+ export const NL_RULES = [
7
+ // ===== 结束进程(先于查看进程;强制先于普通)=====
8
+ { re: /强制(?:结束|杀死|杀掉|终止)\s*(?:进程|pid)?\s*(\d{1,7})/i, cmd: m => `kill -9 ${m[1]}`, warn: '强制终止可能导致数据丢失' },
9
+ { re: /强制(?:结束|杀死|杀掉|终止)\s*([a-zA-Z][\w.\-]*)\s*(?:进程|process)/i, cmd: m => `pkill -9 ${m[1]}`, warn: '会强制终止所有同名进程' },
10
+ { re: /(?:进程|pid)\s*(\d{1,7})\s*(?:结束|杀掉|杀死|终止|关闭)/i, cmd: m => `kill ${m[1]}`, warn: '终止进程可能导致未保存数据丢失' },
11
+ { re: /(?:结束|杀死|杀掉|终止|关闭|kill)\s*(?:进程|pid)?\s*(\d{1,7})/i, cmd: m => `kill ${m[1]}`, warn: '终止进程可能导致未保存数据丢失' },
12
+ { re: /强制(?:结束|杀死|杀掉|终止)(?:进程)?/i, cmd: 'kill -9 <PID>', warn: '强制终止可能导致数据丢失' },
13
+ { re: /(?:结束|杀死|杀掉|终止|关闭)\s*(?:所有)?\s*([a-zA-Z][\w.\-]*)\s*(?:进程|process)/i, cmd: m => `pkill ${m[1]}`, warn: '会终止所有同名进程' },
14
+ { re: /(?:结束|杀死|杀掉|终止)\s*(?:进程|process)\s*([a-zA-Z][\w.\-]*)/i, cmd: m => `pkill ${m[1]}`, warn: '会终止所有同名进程' },
15
+
16
+ // ===== 端口(含数字,先于泛化)=====
17
+ { re: /(\d{1,5})\s*(?:号?端口|port)\s*(?:被谁占用|被占用|占用|被谁使用|谁在用|监听|使用情况|占用情况)/i, cmd: m => `ss -lntp | grep ':${m[1]}'`, note: '查看指定端口的监听进程' },
18
+ { re: /(?:端口|port)\s*(\d{1,5})\s*(?:被谁|占用|监听|使用)/i, cmd: m => `ss -lntp | grep ':${m[1]}'`, note: '查看指定端口的监听进程' },
19
+ { re: /(?:查看|查询|检查)\s*(?:端口|port)\s*(\d{1,5})/i, cmd: m => `ss -lntp | grep ':${m[1]}'`, note: '查看指定端口的监听进程' },
20
+ { re: /(?:查看|查询)\s*(?:端口|port)\s*(\d{1,5})\s*(?:打开|占用)的?(?:文件|进程)/i, cmd: m => `lsof -i :${m[1]}`, note: '查看占用该端口的进程与文件' },
21
+ { re: /(?:打开|占用)\s*(?:端口|port)\s*(\d{1,5})\s*的?(?:文件|进程)/i, cmd: m => `lsof -i :${m[1]}`, note: '查看占用该端口的进程与文件' },
22
+ { re: /(?:测试|检查|探测)\s*(?:端口|port)\s*(\d{1,5})\s*(?:连通|通不通|是否开放|开没开)/i, cmd: m => `nc -zv <主机> ${m[1]}`, note: '测试目标主机端口是否可达' },
23
+ { re: /抓包.*?(\d{1,5})|tcpdump.*?port\s*(\d{1,5})/i, cmd: m => `sudo tcpdump -i any port ${m[1] || m[2]}`, note: '抓取指定端口的数据包' },
24
+
25
+ // ===== 查看进程 =====
26
+ { re: /(?:查看|查询|看看|检查)\s*([a-zA-Z][\w.\-]*)\s*(?:进程|process)/i, cmd: m => `ps aux | grep ${m[1]}`, note: '按名称过滤进程' },
27
+ { re: /([a-zA-Z][\w.\-]*)\s*(?:进程|process)\s*(?:的)?(?:状态|信息|占用|情况|运行)/i, cmd: m => `ps aux | grep ${m[1]}`, note: '按名称过滤进程' },
28
+ { re: /进程树|pstree/i, cmd: 'pstree -p', note: '树状显示进程及 PID' },
29
+ { re: /(?:查看|显示|列出|看看)(?:所有|全部)?(?:正在运行的)?进程(?:列表|情况)?/i, cmd: 'ps aux', note: '列出所有进程详情' },
30
+ { re: /(?:查看|显示|列出|查询|看看)(?:一下)?(?:所有|全部)?(?:正在)?(?:监听|开放)?(?:的)?端口(?:占用|列表|情况)?/i, cmd: 'ss -lntp', note: '列出所有 TCP 监听端口及进程' },
31
+ { re: /抓包|tcpdump/i, cmd: 'sudo tcpdump -i any', note: '抓取所有网卡的数据包' },
32
+ { re: /查看打开的文件|^lsof$/i, cmd: 'lsof', note: '列出进程打开的文件' },
33
+
34
+ // ===== 磁盘 / 内存 / CPU / 系统信息 =====
35
+ { re: /(?:各|每个)(?:子)?目录(?:的)?(?:大小|占用)|(?:当前|本)目录.*子目录.*大小/i, cmd: 'du -h --max-depth=1', note: '统计当前目录各子目录大小' },
36
+ { re: /(?:当前|本)目录(?:的)?(?:大小|占用)/i, cmd: 'du -sh .', note: '统计当前目录总大小' },
37
+ { re: /(?:查看|统计|看看|计算)\s*([\/~.\w][\w.\-\/~]*)\s*(?:目录|文件夹)?(?:的)?(?:大小|占用空间|占用)/i, cmd: m => `du -sh ${m[1]}`, note: '统计指定目录大小' },
38
+ { re: /(?:目录|文件夹)(?:的)?(?:大小|占用|容量)/i, cmd: 'du -sh <路径>', note: '统计目录占用的磁盘空间' },
39
+ { re: /(?:磁盘|硬盘|分区)(?:空间|容量|使用(?:情况|率)?|占用)|(?:磁盘|硬盘)(?:满|不足|快满)/i, cmd: 'df -h', note: '查看各分区磁盘空间使用' },
40
+ { re: /(?:实时|动态)(?:监控|查看|显示)|(?:监控|查看)(?:系统)?资源|资源占用|^top$|^htop$/i, cmd: m => (/htop/i.test(m[0]) ? 'htop' : 'top'), note: '实时监控系统资源与进程' },
41
+ { re: /(?:内存|memory|ram)(?:使用|占用|情况|大小|剩余|不足)?/i, cmd: 'free -h', note: '查看内存与交换使用' },
42
+ { re: /cpu\s*温度|温度.*传感器|sensors/i, cmd: 'sensors', note: '查看温度等传感器读数' },
43
+ { re: /cpu\s*(?:信息|型号|核数|架构|详情|规格)/i, cmd: 'lscpu', note: '查看 CPU 架构信息' },
44
+ { re: /电池(?:电量|状态|信息|健康)?/i, cmd: 'upower -i $(upower -e | grep -i battery)', note: '查看电池详情' },
45
+ { re: /(?:系统|发行版|linux)(?:版本|信息)|os-release/i, cmd: 'cat /etc/os-release', note: '查看发行版版本信息' },
46
+ { re: /内核版本|uname/i, cmd: 'uname -r', note: '查看内核版本' },
47
+ { re: /主机名|hostname/i, cmd: 'hostname', note: '查看主机名' },
48
+ { re: /(?:系统)?(?:运行|开机)(?:了)?(?:多久|多长时间|时间)/i, cmd: 'uptime -p', note: '查看系统运行时长' },
49
+ { re: /(?:系统)?负载|load\s*average|^uptime$/i, cmd: 'uptime', note: '查看系统负载与运行时长' },
50
+ { re: /(?:启动|开机)(?:耗时|速度|用了多久)|systemd-analyze/i, cmd: 'systemd-analyze', note: '分析系统启动耗时' },
51
+ { re: /失败(?:的)?服务|服务.*启动失败/i, cmd: 'systemctl --failed', note: '列出启动失败的服务' },
52
+ { re: /内核日志|dmesg/i, cmd: 'dmesg | tail -50', note: '查看最近的内核日志' },
53
+ { re: /系统日志|journalctl(?!\s+-u)/i, cmd: 'journalctl -xe', note: '查看系统日志末尾' },
54
+ { re: /锁屏|锁定屏幕|lock\s*screen/i, cmd: 'loginctl lock-session', note: '锁定当前会话' },
55
+ { re: /网卡(?:流量|统计|收发包)|(?:网络|接口)(?:流量|统计)/i, cmd: 'ip -s link', note: '查看网卡收发统计' },
56
+ { re: /ldd\s+(\S+)/i, cmd: m => `ldd ${m[1]}`, note: '查看共享库依赖' },
57
+ { re: /(?:共享库|动态库)(?:依赖|链接)/i, cmd: 'ldd <文件>', note: '查看可执行文件的共享库依赖' },
58
+ { re: /type\s+(\S+)/i, cmd: m => `type ${m[1]}`, note: '查看命令类型' },
59
+ { re: /命令类型|(?:是|属于)(?:什么|哪种)(?:命令|类型)/i, cmd: 'type <命令>', note: '区分别名、内置与可执行文件' },
60
+
61
+ // ===== 文件操作(具体在前)=====
62
+ { re: /(?:查找|找到|搜索|找出).*?(?:并|然后|后)?\s*删除.*?\.?([a-zA-Z0-9]{1,10})\s*(?:文件|后缀)?/i, cmd: m => `find . -name "*.${m[1] || 'log'}" -delete`, warn: '会直接删除匹配文件,不可恢复' },
63
+ { re: /删除(?:所有|全部)\s*\.?([a-zA-Z0-9]{1,10})\s*文件/i, cmd: m => `find . -name "*.${m[1]}" -delete`, warn: '会直接删除匹配文件,不可恢复' },
64
+ { re: /(?:批量)?(?:重命名|修改|转换|更改|改)\s*(?:扩展名|后缀)\s*(?:从)?\s*\.?([a-zA-Z0-9]+)\s*(?:为|成|到|->|→)\s*\.?([a-zA-Z0-9]+)/i, cmd: m => `for f in *.${m[1] || '旧'}; do mv "$f" "\${f%.${m[1] || '旧'}}.${m[2] || '新'}"; done`, note: '批量把旧扩展名改为新扩展名' },
65
+ { re: /(?:把|将)\s*["']?([^"'\s]+)["']?\s*(?:替换|换)(?:为|成)\s*["']?([^"'\s]+)["']?/i, cmd: m => `sed -i 's/${m[1]}/${m[2]}/g' <文件>`, warn: '直接修改原文件,建议先备份' },
66
+ { re: /(?:文本|内容|字符串)?替换|sed\s+-i/i, cmd: "sed -i 's/<旧>/<新>/g' <文件>", warn: '直接修改原文件,建议先备份' },
67
+ { re: /(?:清空|清除)\s*(?:文件)?\s*([\/~.\w][\w.\-\/~]*)/i, cmd: m => `truncate -s 0 ${m[1]}`, warn: '会清空文件内容' },
68
+ { re: /清空(?:文件)?(?:的)?内容|清空文件/i, cmd: 'truncate -s 0 <文件>', warn: '会清空文件内容' },
69
+ { re: /(?:查找|搜索|找)\s*(?:大文件|大的文件)|大于\s*(\d+)\s*[MG]?\s*的文件/i, cmd: m => (m[1] ? `find . -type f -size +${m[1]}M` : 'find . -type f -size +100M'), note: '查找大文件' },
70
+ { re: /(?:查找|搜索|找|找出)(?:所有|全部)?日志文件/i, cmd: 'find . -type f -name "*.log"', note: '查找所有 log 文件' },
71
+ { re: /扩展名(?:为|是)?\s*\.?([a-zA-Z0-9]+)/i, cmd: m => `find . -type f -name "*.${m[1]}"`, note: '按扩展名查找文件' },
72
+ { re: /(?:查找|搜索|找|找出|寻找)\s*(?:所有|全部)?\s*(?:\.)?([a-zA-Z0-9]{1,10})\s*(?:文件|后缀|扩展名)/i, cmd: m => `find . -type f -name "*.${m[1] || 'log'}"`, note: '按扩展名查找文件' },
73
+ { re: /(?:查找|搜索|找)\s*(?:文件)?\s*(?:名为|名字叫|名称为)?\s*["']?([\w.\-*]+)["']?\s*(?:的)?文件/i, cmd: m => `find <路径> -name "${m[1]}"`, note: '按名称查找文件' },
74
+ { re: /tail\s+-f\s+(\S+)/i, cmd: m => `tail -f ${m[1]}`, note: '实时跟踪文件新增内容' },
75
+ { re: /(?:实时|动态|持续)?(?:跟踪|追踪|监控)\s*(?:日志|log|文件)\s*(\S+)?/i, cmd: m => `tail -f ${m[1] || '<文件>'}`, note: '实时跟踪日志' },
76
+ { re: /(?:查看|显示)\s*([\/~.\w][\w.\-\/~]*)\s*(?:的)?(?:开头|前|头部)\s*(\d+)\s*行/i, cmd: m => `head -n ${m[2]} ${m[1]}`, note: '查看文件开头 N 行' },
77
+ { re: /(?:开头|前|头部)\s*(\d+)\s*行/i, cmd: m => `head -n ${m[1]} <文件>`, note: '查看文件开头 N 行' },
78
+ { re: /(?:查看|显示)\s*([\/~.\w][\w.\-\/~]*)\s*(?:的)?(?:末尾|最后|结尾|尾部)\s*(\d+)\s*行/i, cmd: m => `tail -n ${m[2]} ${m[1]}`, note: '查看文件末尾 N 行' },
79
+ { re: /(?:末尾|最后|结尾|尾部)\s*(\d+)\s*行/i, cmd: m => `tail -n ${m[1]} <文件>`, note: '查看文件末尾 N 行' },
80
+ { re: /(?:查看|显示)?(?:文件)?(?:开头|头部|前几行)/i, cmd: 'head -n 10 <文件>', note: '查看文件开头' },
81
+ { re: /(?:查看|显示)?(?:文件)?(?:末尾|结尾|最后几行)/i, cmd: 'tail -n 10 <文件>', note: '查看文件末尾' },
82
+ { re: /(?:分页|翻页)(?:查看|显示)?\s*(\S+)?|less\s+(\S+)/i, cmd: m => `less ${m[1] || m[2] || '<文件>'}`, note: '分页查看文件' },
83
+ { re: /隐藏文件|(?:含|包括|包含)隐藏/i, cmd: 'ls -la', note: '列出含隐藏文件的所有文件' },
84
+ { re: /(?:查看|显示|列出|看看)(?:当前|本)?(?:目录|文件夹)(?:中|下|里)?(?:的)?(?:所有|全部)文件/i, cmd: 'ls -la', note: '列出当前目录所有文件(含隐藏)' },
85
+ { re: /(?:复制|拷贝|copy|cp)\s*(\S+)\s*(?:到|至|->|→)\s*(\S+)/i, cmd: m => `cp -r ${m[1]} ${m[2]}`, note: '复制文件或目录' },
86
+ { re: /(?:复制|拷贝)(?:文件|目录|文件夹)?/i, cmd: 'cp -r <源> <目标>', note: '复制文件或目录' },
87
+ { re: /(?:移动|mv)\s*(\S+)\s*(?:到|至|->|→)\s*(\S+)/i, cmd: m => `mv ${m[1]} ${m[2]}`, note: '移动文件或目录' },
88
+ { re: /(?:重命名|改名|rename)\s*(\S+)\s*(?:为|成|->|→)\s*(\S+)/i, cmd: m => `mv ${m[1]} ${m[2]}`, note: '重命名文件或目录' },
89
+ { re: /重命名|改名/i, cmd: 'mv <旧名> <新名>', note: '重命名文件或目录' },
90
+ { re: /(?:删除|移除|删掉|rm)\s*(?:文件|目录|文件夹)?\s*([\/~.\w][\w.\-\/~]*)/i, cmd: m => `rm -rf ${m[1]}`, warn: '删除后难以恢复,请确认路径' },
91
+ { re: /(?:递归|强制)?删除(?:文件|目录|文件夹)/i, cmd: 'rm -rf <路径>', warn: '删除后难以恢复,请确认路径' },
92
+ { re: /(?:创建|新建|建立|mkdir)\s*(?:一个)?(?:多级)?(?:目录|文件夹)\s*([\/~.\w][\w.\-\/~]*)?/i, cmd: m => `mkdir -p ${m[1] || '<路径>'}`, note: '创建目录(含多级)' },
93
+ { re: /(?:创建|建立|添加)?\s*(?:软链接|符号链接|快捷方式)|ln\s+-s/i, cmd: 'ln -s <目标> <链接名>', note: '创建软链接' },
94
+ { re: /(?:查看|判断|识别)\s*(\S+)?\s*(?:的)?文件类型|file\s+(\S+)/i, cmd: m => `file ${m[1] || m[2] || '<文件>'}`, note: '识别文件类型' },
95
+ { re: /(?:统计|计算|数)\s*(\S+)?\s*(?:的)?行数|wc\s+-l\s+(\S+)/i, cmd: m => `wc -l ${m[1] || m[2] || '<文件>'}`, note: '统计文件行数' },
96
+ { re: /词频|单词频率|统计.*出现次数/i, cmd: 'sort <文件> | uniq -c | sort -rn', note: '统计词频并按次数排序' },
97
+ { re: /(?:去重|去除重复|去掉重复)(?:行)?\s*(\S+)?/i, cmd: m => `sort ${m[1] || '<文件>'} | uniq`, note: '排序后去重' },
98
+ { re: /(?:排序|sort)\s*(\S+)?/i, cmd: m => `sort ${m[1] || '<文件>'}`, note: '对文本行排序' },
99
+ { re: /(?:比较|对比|diff)\s*(\S+)\s*(?:和|与|跟|,|,)\s*(\S+)/i, cmd: m => `diff ${m[1]} ${m[2]}`, note: '比较两个文件差异' },
100
+ { re: /比较文件|对比文件|^diff$/i, cmd: 'diff <文件1> <文件2>', note: '比较两个文件差异' },
101
+ { re: /md5\s*(?:值|校验|摘要)?\s*(\S+)?/i, cmd: m => `md5sum ${m[1] || '<文件>'}`, note: '计算 MD5 摘要' },
102
+ { re: /sha-?256\s*(?:值|校验|摘要)?\s*(\S+)?/i, cmd: m => `sha256sum ${m[1] || '<文件>'}`, note: '计算 SHA256 摘要' },
103
+ { re: /base64\s*(?:解码|decode|-d)/i, cmd: 'base64 -d <文件>', note: 'Base64 解码' },
104
+ { re: /base64\s*(?:编码|encode)?\s*(\S+)?/i, cmd: m => `base64 ${m[1] || '<文件>'}`, note: 'Base64 编码' },
105
+ { re: /(?:随机|生成)(?:一个)?(?:密码|口令|密钥)/i, cmd: 'openssl rand -base64 16', note: '生成随机密码' },
106
+ { re: /递归(?:修改|设置)?权限|chmod\s+-R/i, cmd: 'chmod -R <模式> <路径>', warn: '递归修改权限影响范围大,请谨慎' },
107
+ { re: /(?:修改|设置)\s*(\S+)?\s*权限(?:为|成)\s*(\d{3,4})/i, cmd: m => `chmod ${m[2]} ${m[1] || '<文件>'}`, note: '修改文件权限' },
108
+ { re: /(?:修改|更改|设置|chmod)\s*(?:权限)?\s*(\d{3,4})\s*([\/~.\w][\w.\-\/~]*)?/i, cmd: m => `chmod ${m[1]} ${m[2] || '<文件>'}`, note: '修改文件权限' },
109
+ { re: /(?:查看|显示)\s*([\/~.\w][\w.\-\/~]*)?\s*(?:的)?(?:文件)?权限/i, cmd: m => `ls -l ${m[1] || '<文件>'}`, note: '查看文件权限' },
110
+ { re: /(?:修改|更改|设置)\s*(\S+)?\s*(?:的)?属主|chown\s+(\S+)/i, cmd: 'chown <用户>:<组> <文件>', note: '修改文件属主与属组' },
111
+ { re: /cat\s+(\S+)/i, cmd: m => `cat ${m[1]}`, note: '查看文件内容' },
112
+ { re: /(?:查看|显示|打开|看看|cat)\s*(?:文件)?\s*([\/~.\w][\w.\-\/~]*)?\s*(?:的)?内容/i, cmd: m => `cat ${m[1] || '<文件>'}`, note: '查看文件内容' },
113
+
114
+ // ===== 用户 / 环境 / 历史 / 定时 / 服务 / 软件包 =====
115
+ { re: /(?:当前|现在)(?:登录)?(?:用户|是谁)|我是谁|whoami/i, cmd: 'whoami', note: '查看当前用户' },
116
+ { re: /(?:查看|查询)\s*(\w+)\s*的?\s*(?:id|uid|gid)/i, cmd: m => `id ${m[1]}`, note: '查看用户 ID' },
117
+ { re: /用户id|^id\s+(\w+)/i, cmd: m => `id ${m[1] || '<用户名>'}`, note: '查看用户 ID' },
118
+ { re: /(?:切换|su)\s*(?:到)?(?:用户)?\s*(\w+)/i, cmd: m => `su - ${m[1]}`, note: '切换用户' },
119
+ { re: /切换用户/i, cmd: 'su - <用户名>', note: '切换用户' },
120
+ { re: /(?:修改|更改|重置|设置)\s*(\w+)?\s*(?:的)?密码|passwd\s+(\w+)/i, cmd: m => `passwd ${m[1] || m[2] || '<用户名>'}`, note: '修改用户密码' },
121
+ { re: /(?:添加|新增|创建|建立)\s*(?:一个)?用户\s*(\w+)?/i, cmd: m => `useradd -m ${m[1] || '<用户名>'}`, note: '添加用户并创建家目录' },
122
+ { re: /(?:删除|移除|删掉)\s*用户\s*(\w+)?/i, cmd: m => `userdel -r ${m[1] || '<用户名>'}`, warn: '会连同家目录一起删除,请谨慎' },
123
+ { re: /(?:查看|显示|看看)?\s*(?:当前|在线|登录)(?:的)?用户|^who$/i, cmd: 'who', note: '查看登录用户' },
124
+ { re: /最近登录|登录记录|^last$/i, cmd: 'last', note: '查看最近登录记录' },
125
+ { re: /(?:设置|导出|export)\s*(?:环境)?变量\s*([A-Za-z_]\w*)\s*(?:=|为|成)\s*(\S+)/i, cmd: m => `export ${m[1]}=${m[2]}`, note: '设置环境变量' },
126
+ { re: /(?:查看|显示|输出)\s*(?:环境)?变量\s*\$?([A-Za-z_]\w*)|echo\s+\$(\w+)/i, cmd: m => `echo $${m[1] || m[2] || '<名称>'}`, note: '查看指定环境变量' },
127
+ { re: /(?:查看|显示|列出)?\s*(?:所有|全部)?环境变量/i, cmd: 'env', note: '查看所有环境变量' },
128
+ { re: /(?:查看|查找|查询)\s*(\S+)?\s*(?:命令)?(?:的位置|在哪|路径|安装位置)|which\s+(\S+)/i, cmd: m => `which ${m[1] || m[2] || '<命令>'}`, note: '查看命令位置' },
129
+ { re: /(?:查看|显示)\s*(\S+)?\s*(?:命令)?(?:的)?(?:帮助|手册|文档|用法)|man\s+(\S+)/i, cmd: m => `man ${m[1] || m[2] || '<命令>'}`, note: '查看命令帮助' },
130
+ { re: /(?:搜索|查找|grep)\s*(?:命令)?历史\s*(\S+)?|history\s*\|\s*grep\s+(\S+)/i, cmd: m => `history | grep ${m[1] || m[2] || '<关键词>'}`, note: '搜索历史命令' },
131
+ { re: /清空(?:命令)?历史|history\s+-c/i, cmd: 'history -c', warn: '会清空命令历史' },
132
+ { re: /(?:查看|显示)?\s*(?:命令)?历史(?:记录)?/i, cmd: 'history', note: '查看历史命令' },
133
+ { re: /(?:后台|nohup)(?:运行|执行)\s*(.+)/i, cmd: m => `nohup ${m[1]} > /dev/null 2>&1 &`, note: '后台运行并忽略挂断信号' },
134
+ { re: /后台运行|后台执行/i, cmd: 'nohup <命令> > /dev/null 2>&1 &', note: '后台运行命令' },
135
+ { re: /每天\s*(\d{1,2})[:点时](\d{1,2})?\s*(?:分)?\s*(?:执行|运行)\s*(.+)/i, cmd: m => `# crontab 示例:${m[2] || '0'} ${m[1] || '3'} * * * ${m[3] || '<命令>'}`, note: '分 时 日 月 周,用 crontab -e 添加' },
136
+ { re: /(?:编辑|修改|添加|新增)\s*(?:定时|计划)任务/i, cmd: 'crontab -e', note: '编辑定时任务' },
137
+ { re: /(?:查看|显示|列出)?\s*(?:当前)?(?:定时|计划|cron)(?:任务|作业)/i, cmd: 'crontab -l', note: '查看定时任务' },
138
+ { re: /服务日志\s*(\w[\w.\-]*)|(?:查看|显示|跟踪)?\s*(\w[\w.\-]*)\s*服务(?:的)?日志|journalctl\s+-u\s+(\S+)/i, cmd: m => `journalctl -u ${m[1] || m[2] || m[3] || '<服务名>'} -f`, note: '实时跟踪服务日志' },
139
+ { re: /服务状态\s*(\w[\w.\-]*)|(?:查看|查询|检查)\s*(\w[\w.\-]*)\s*服务(?:的)?(?:状态|运行情况)?|systemctl\s+status\s+(\S+)/i, cmd: m => `systemctl status ${m[1] || m[2] || m[3] || '<服务名>'}`, note: '查看服务状态' },
140
+ { re: /(\w[\w.\-]*)\s*服务(?:的)?状态/i, cmd: m => `systemctl status ${m[1]}`, note: '查看服务状态' },
141
+ { re: /(?:重启|重新启动|restart)\s*(\w[\w.\-]*)\s*服务/i, cmd: m => `systemctl restart ${m[1]}`, warn: '重启会短暂中断服务' },
142
+ { re: /(?:启动|开启|start)\s*(\w[\w.\-]*)\s*服务/i, cmd: m => `systemctl start ${m[1]}`, note: '启动服务' },
143
+ { re: /(?:停止|关闭|stop)\s*(\w[\w.\-]*)\s*服务/i, cmd: m => `systemctl stop ${m[1]}`, warn: '停止服务会中断其功能' },
144
+ { re: /(?:设置)?\s*(\w[\w.\-]*)\s*(?:服务)?(?:开机)?自启|开机自启\s*(\w[\w.\-]*)?|systemctl\s+enable\s+(\S+)/i, cmd: m => `systemctl enable ${m[1] || m[2] || m[3] || '<服务名>'}`, note: '设置开机自启' },
145
+ { re: /服务状态|systemctl\s+status/i, cmd: 'systemctl status <服务名>', note: '查看服务状态' },
146
+ { re: /(?:安装|install)\s*(?:软件|包|程序)?\s*([\w.\-]+)/i, cmd: m => `sudo apt install ${m[1]}`, note: '安装软件包(apt 优先)' },
147
+ { re: /(?:更新|刷新)\s*(?:软件源|源|apt)/i, cmd: 'sudo apt update', note: '刷新软件源索引' },
148
+ { re: /(?:升级|更新)(?:系统|所有软件|全部软件)/i, cmd: 'sudo apt upgrade', note: '升级已安装软件包' },
149
+ { re: /(?:卸载|移除|remove)\s*(?:软件|包|程序)?\s*([\w.\-]+)/i, cmd: m => `sudo apt remove ${m[1]}`, note: '卸载软件包' },
150
+ { re: /(?:查看|列出|查询)?\s*(?:已安装|已经安装)(?:的)?(?:软件|包)(?:\s*(\S+))?|dpkg\s+-l/i, cmd: m => (m[1] ? `dpkg -l | grep ${m[1]}` : 'dpkg -l'), note: '查看已安装软件包' },
151
+
152
+ // ===== Docker / Git =====
153
+ { re: /docker\s+run.*-p\s*(\d{1,5}):(\d{1,5})\s+(\S+)/i, cmd: m => `docker run -d -p ${m[1]}:${m[2]} ${m[3]}`, note: '运行容器并映射端口' },
154
+ { re: /(?:运行|启动|run)\s*(\S+)\s*(?:镜像|容器)?\s*(?:端口|映射)?\s*(\d{1,5})/i, cmd: m => `docker run -d -p ${m[2]}:${m[2]} ${m[1]}`, note: '运行容器并映射端口' },
155
+ { re: /(?:构建|build|打包)\s*(?:docker)?镜像\s*(\S+)?/i, cmd: m => `docker build -t ${m[1] || '<名称>'} .`, note: '构建镜像' },
156
+ { re: /(?:进入|登录|exec)\s*容器\s*(\S+)?/i, cmd: m => `docker exec -it ${m[1] || '<容器>'} /bin/bash`, note: '进入运行中的容器' },
157
+ { re: /(?:查看|显示|跟踪)?\s*(?:([a-zA-Z][\w.\-]*)\s*)?容器(?:的)?日志\s*(\S+)?|docker\s+logs(?:\s+-f)?\s*(\S+)?/i, cmd: m => `docker logs -f ${m[1] || m[2] || m[3] || '<容器>'}`, note: '查看容器日志' },
158
+ { re: /(?:启动|start)\s*容器\s*(\S+)?/i, cmd: m => `docker start ${m[1] || '<容器>'}`, note: '启动容器' },
159
+ { re: /(?:停止|关闭|stop)\s*容器\s*(\S+)?/i, cmd: m => `docker stop ${m[1] || '<容器>'}`, warn: '停止容器会中断其服务' },
160
+ { re: /(?:删除|移除|rm)\s*容器\s*(\S+)?/i, cmd: m => `docker rm ${m[1] || '<容器>'}`, warn: '删除后未持久化数据会丢失' },
161
+ { re: /(?:删除|移除|rmi)\s*镜像\s*(\S+)?/i, cmd: m => `docker rmi ${m[1] || '<镜像>'}`, warn: '删除后需重新拉取或构建' },
162
+ { re: /(?:清理|清除|净化)\s*docker|docker\s+system\s+prune/i, cmd: 'docker system prune', warn: '会删除停止的容器、无用镜像和网络' },
163
+ { re: /(?:查看|显示|列出)?\s*(?:所有|全部)?(?:docker)?容器(?:列表)?|docker\s+ps/i, cmd: 'docker ps -a', note: '列出所有容器' },
164
+ { re: /(?:查看|显示|列出)?\s*(?:docker)?镜像(?:列表)?|docker\s+images/i, cmd: 'docker images', note: '列出镜像' },
165
+ { re: /(?:撤销|还原|丢弃)修改\s*(\S+)|(?:撤销|还原|丢弃|恢复)\s*(\S+)?\s*(?:的)?(?:修改|改动)|git\s+checkout\s+--\s+(\S+)/i, cmd: m => `git checkout -- ${m[1] || m[2] || m[3] || '<文件>'}`, warn: '会丢弃未提交的修改,不可恢复' },
166
+ { re: /git\s*stash\s*pop|恢复暂存/i, cmd: 'git stash pop', note: '恢复最近一次暂存' },
167
+ { re: /git\s*stash|暂存(?:当前)?(?:改动|修改|现场)/i, cmd: 'git stash', note: '暂存当前改动' },
168
+ { re: /git\s*(?:提交|commit)\s*(?:"([^"]+)"|'([^']+)'|(.+))?|提交(?:代码|改动)\s*["']?([^"']+)["']?/i, cmd: m => `git add . && git commit -m "${m[1] || m[2] || m[3] || m[4] || '<信息>'}"`, note: '暂存并提交改动' },
169
+ { re: /(?:克隆|clone)\s*(\S+)|git\s+clone\s+(\S+)/i, cmd: m => `git clone ${m[1] || m[2] || '<URL>'}`, note: '克隆仓库' },
170
+ { re: /(?:删除|移除)\s*分支\s*(\S+)?/i, cmd: m => `git branch -d ${m[1] || '<分支>'}`, warn: '删除分支前请确认已合并' },
171
+ { re: /(?:切换|checkout)\s*(?:到)?分支\s*(\S+)?|git\s+checkout\s+(\S+)/i, cmd: m => `git checkout ${m[1] || m[2] || '<分支>'}`, note: '切换分支' },
172
+ { re: /(?:新建|创建|新增)\s*分支\s*(\S+)?/i, cmd: m => `git checkout -b ${m[1] || '<分支>'}`, note: '新建并切换分支' },
173
+ { re: /git\s*(?:查看)?分支(?:列表)?|列出.*分支/i, cmd: 'git branch -a', note: '列出所有分支' },
174
+ { re: /git\s*(?:日志|log|提交历史|历史)/i, cmd: 'git log --oneline -20', note: '查看最近提交历史' },
175
+ { re: /git\s*(?:拉取|pull|更新代码)/i, cmd: 'git pull', note: '拉取并合并远程改动' },
176
+ { re: /git\s*(?:推送|push)/i, cmd: 'git push', note: '推送到远程' },
177
+ { re: /git\s*(?:状态|status)|(?:查看)?git工作区/i, cmd: 'git status', note: '查看工作区状态' },
178
+
179
+ // ===== 网络 / 传输 =====
180
+ { re: /(?:ssh|登录|连接)\s*(?:到)?\s*(\w+)@([\w.\-]+)/i, cmd: m => `ssh ${m[1] || '<用户>'}@${m[2] || '<主机>'}`, note: 'SSH 登录远程主机' },
181
+ { re: /ssh\s+([\w.\-]+)/i, cmd: m => `ssh ${m[1]}`, note: 'SSH 登录远程主机' },
182
+ { re: /ssh登录|远程登录/i, cmd: 'ssh <用户>@<主机>', note: 'SSH 登录远程主机' },
183
+ { re: /(?:上传|scp)\s*(\S+)\s*(?:到|至)\s*(\w+)@([\w.\-]+):(\S+)/i, cmd: m => `scp ${m[1]} ${m[2]}@${m[3]}:${m[4]}`, note: '上传文件到远程' },
184
+ { re: /上传文件到远程|上传.*远程/i, cmd: 'scp <文件> <用户>@<主机>:<路径>', note: '上传文件到远程' },
185
+ { re: /(?:从|自)\s*(\w+)@([\w.\-]+):(\S+)\s*(?:下载|拉取|复制)/i, cmd: m => `scp ${m[1]}@${m[2]}:${m[3]} .`, note: '从远程下载文件' },
186
+ { re: /从远程下载/i, cmd: 'scp <用户>@<主机>:<文件> .', note: '从远程下载文件' },
187
+ { re: /(?:同步|rsync)\s*(\S+)\s*(?:到|至|->|→)\s*(\S+)/i, cmd: m => `rsync -avz ${m[1]} ${m[2]}`, note: '同步目录' },
188
+ { re: /同步目录|rsync/i, cmd: 'rsync -avz <源> <目标>', note: '同步目录' },
189
+ { re: /(?:发送|发|post)\s*(?:一个)?post\s*(?:请求)?\s*(https?:\/\/\S+)?/i, cmd: m => `curl -X POST -H 'Content-Type: application/json' -d '<数据>' ${m[1] || '<URL>'}`, note: '发送 POST 请求' },
190
+ { re: /(?:查看|获取)?\s*(?:http|https)?\s*(?:响应头|头部|headers?)\s*(https?:\/\/\S+)?/i, cmd: m => `curl -I ${m[1] || '<URL>'}`, note: '查看 HTTP 响应头' },
191
+ { re: /(?:下载|download|wget|curl).*?(https?:\/\/\S+)/i, cmd: m => `curl -O ${m[1]}`, note: '下载文件(也可用 wget)' },
192
+ { re: /下载文件|下载/i, cmd: 'curl -O <URL>', note: '下载文件(也可用 wget)' },
193
+ { re: /(?:dns|解析|dig|nslookup)\s*(?:查询)?\s*([\w.\-]+\.[a-z]{2,})/i, cmd: m => `dig ${m[1]}`, note: 'DNS 查询' },
194
+ { re: /dns查询|dns解析|域名解析/i, cmd: 'dig <域名>', note: 'DNS 查询' },
195
+ { re: /(?:测试|检查|ping)\s*(?:网络)?(?:连通|连接)?\s*(?:到)?\s*([\w.\-]+)/i, cmd: m => `ping ${m[1]}`, note: '测试网络连通' },
196
+ { re: /测试网络连通|网络连通|^ping$/i, cmd: 'ping <主机>', note: '测试网络连通' },
197
+ { re: /(?:跟踪|追踪)\s*路由\s*(\S+)?|traceroute\s+(\S+)/i, cmd: m => `traceroute ${m[1] || m[2] || '<主机>'}`, note: '跟踪路由' },
198
+ { re: /(?:查看|显示|查询)?\s*(?:本机|本地|服务器)?\s*ip\s*(?:地址)?|ifconfig/i, cmd: 'ip addr', note: '查看 IP 地址' },
199
+ { re: /(?:查看|显示)?\s*(?:路由|网关)(?:表)?/i, cmd: 'ip route', note: '查看路由表' },
200
+ { re: /防火墙(?:状态|情况)|ufw\s*status/i, cmd: 'sudo ufw status', note: '查看防火墙状态' },
201
+ { re: /(?:开放|放行|允许|开启)\s*(?:端口|port)\s*(\d{1,5})|(?:开放|放行|允许|开启)\s*(\d{1,5})\s*(?:号?端口|port)/i, cmd: m => `sudo ufw allow ${m[1] || m[2]}`, note: '放行指定端口' },
202
+ { re: /selinux|getenforce/i, cmd: 'getenforce', note: '查看 SELinux 状态' },
203
+
204
+ // ===== 压缩 / 挂载 / 电源 / 杂项 =====
205
+ { re: /(?:压缩|打包)(?:为|成)?\s*([\w.\-]+)\.tar\.gz\s*(\S+)?/i, cmd: m => `tar -czf ${m[1]}.tar.gz ${m[2] || '<路径>'}`, note: '压缩为 tar.gz' },
206
+ { re: /(?:压缩|打包)(?:为|成)?\s*(?:tar\.gz|tgz|tar包)/i, cmd: 'tar -czf <名称>.tar.gz <路径>', note: '压缩为 tar.gz' },
207
+ { re: /(?:压缩|打包)(?:为|成)?\s*zip/i, cmd: 'zip -r <名称>.zip <路径>', note: '压缩为 zip' },
208
+ { re: /(?:解压|解包|解开)\s*(\S+\.(?:tar\.gz|tgz|tar\.xz|tar\.bz2))/i, cmd: m => { const f = m[1] || '<文件>'; const z = /\.xz$/.test(f) ? 'J' : /\.bz2$/.test(f) ? 'j' : 'z'; return `tar -x${z}f ${f}`; }, note: '解压 tar 归档' },
209
+ { re: /(?:解压|解包)\s*(\S+\.zip)/i, cmd: m => `unzip ${m[1]}`, note: '解压 zip' },
210
+ { re: /解压\s*(?:tar\.gz|tgz)/i, cmd: 'tar -xzf <文件>', note: '解压 tar.gz' },
211
+ { re: /解压zip/i, cmd: 'unzip <文件>', note: '解压 zip' },
212
+ { re: /(?:查看|列出)\s*(\S+)?\s*(?:压缩包|tar包|归档)(?:的)?(?:内容|列表)|tar\s+-tzf/i, cmd: m => `tar -tzf ${m[1] || '<文件>'}`, note: '查看压缩包内容' },
213
+ { re: /(?:查看|显示)?\s*(?:磁盘|分区|块设备)(?:挂载|列表)|lsblk/i, cmd: 'lsblk', note: '查看磁盘与分区挂载' },
214
+ { re: /(?:挂载|mount)\s*(\S+)\s*(?:到|至)?\s*(\S+)?/i, cmd: m => `sudo mount ${m[1]} ${m[2] || '<路径>'}`, note: '挂载设备' },
215
+ { re: /(?:卸载|umount|解除挂载)\s*(\S+)?/i, cmd: m => `sudo umount ${m[1] || '<路径>'}`, warn: '设备使用中卸载可能丢失数据' },
216
+ { re: /(\d+)\s*分钟?后关机|(?:定时|预约)关机/i, cmd: m => (m[1] ? `sudo shutdown -h +${m[1]}` : 'sudo shutdown -h +<分钟>'), warn: '会中断当前所有会话' },
217
+ { re: /(?:重启|重新启动|reboot)\s*(?:系统|机器|服务器|电脑)?/i, cmd: 'sudo reboot', warn: '会中断当前所有会话' },
218
+ { re: /关机|shutdown|poweroff/i, cmd: 'sudo shutdown -h now', warn: '会中断当前所有会话' },
219
+ { re: /(?:现在|当前)?(?:时间|日期|几点|今天几号)/i, cmd: 'date', note: '查看当前时间日期' },
220
+ { re: /日历|calendar|\bcal\b/i, cmd: 'cal', note: '查看日历' },
221
+ { re: /(?:延时|等待|暂停|sleep)\s*(\d+)\s*(秒|s|分钟|分)?/i, cmd: m => `sleep ${m[1] || '<秒>'}${/分/.test(m[2] || '') ? 'm' : ''}`, note: '延时指定时长' },
222
+ { re: /清屏|^clear$/i, cmd: 'clear', note: '清屏' },
223
+ { re: /退出(?:终端|shell|登录)?|^exit$|^logout$/i, cmd: 'exit', note: '退出当前 Shell' },
224
+ { re: /(?:切换|进入|转到|跳到|cd)\s*(?:到)?\s*(?:目录|文件夹)?\s*([\/~.\w][\w.\-\/~]*)/i, cmd: m => `cd ${m[1]}`, note: '切换目录' },
225
+ { re: /切换目录|进入目录/i, cmd: 'cd <路径>', note: '切换目录' },
226
+ { re: /(?:当前|现在)(?:所在)?(?:路径|目录|位置)|^pwd$/i, cmd: 'pwd', note: '显示当前路径' },
227
+ { re: /(?:查看|显示|列出|看看)\s*(?:当前)?(?:目录|文件夹)(?:内容|列表|下)?(?:的)?(?:文件|内容)?|列出(?:当前目录)?(?:所有)?文件/i, cmd: 'ls', note: '查看目录内容' },
228
+ ];