feat: 新增 proc.list/user.list/pkg.list 命令

proc.list 列出所有进程(ps aux/tasklist)
user.list 列出系统用户(getent passwd/net user)
pkg.list 列出已安装软件包(dpkg/rpm/apk/brew/winget)
This commit is contained in:
2026-11-03 21:28:15 +08:00
parent b4590bbffd
commit aa1f592bf3
9 changed files with 221 additions and 5 deletions
+3
View File
@@ -70,7 +70,9 @@ var builtins = map[string]Builtin{
"net.ports": runNetPorts,
"net.speed": runNetSpeed,
"net.trace": runNetTrace,
"pkg.list": runPkgList,
"proc.killname": runProcKillName,
"proc.list": runProcList,
"proc.nohup": runNohup,
"proc.topcpu": runProcTopCPU,
"proc.topmem": runProcTopMem,
@@ -84,6 +86,7 @@ var builtins = map[string]Builtin{
"sysinfo": runSysInfo,
"user.grant": runUserGrant,
"user.info": runUserInfo,
"user.list": runUserList,
"user.revoke": runUserRevoke,
}
+77
View File
@@ -0,0 +1,77 @@
package executor
import (
"context"
"fmt"
"os/exec"
"runtime"
"strings"
"gitea.odboy.cn/odboy/kenaito-kopsc/internal/platform"
)
// runPkgList implements `kopsc pkg list`: list installed packages.
func runPkgList(ctx context.Context, req BuiltinRequest) error {
switch runtime.GOOS {
case "linux":
return pkgListLinux(ctx, req)
case "darwin":
cmd := exec.CommandContext(ctx, "brew", "list")
cmd.Stdout = req.Stdout
cmd.Stderr = req.Stderr
return cmd.Run()
case "windows":
cmd := exec.CommandContext(ctx, "winget", "list")
cmd.Stdout = req.Stdout
cmd.Stderr = req.Stderr
return cmd.Run()
default:
return fmt.Errorf("不支持的操作系统: %s", runtime.GOOS)
}
}
func pkgListLinux(ctx context.Context, req BuiltinRequest) error {
info := platform.System().Detect()
// Debian/Ubuntu: dpkg -l
if distroLikeContains(info, "debian", "ubuntu") {
cmd := exec.CommandContext(ctx, "dpkg", "-l")
cmd.Stdout = req.Stdout
cmd.Stderr = req.Stderr
return cmd.Run()
}
// CentOS/RHEL/Fedora: rpm -qa
if distroLikeContains(info, "rhel", "fedora") || info.Distro == "centos" {
cmd := exec.CommandContext(ctx, "rpm", "-qa", "--qf", "%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}\n")
cmd.Stdout = req.Stdout
cmd.Stderr = req.Stderr
return cmd.Run()
}
// Alpine: apk list --installed
if info.Distro == "alpine" {
cmd := exec.CommandContext(ctx, "apk", "list", "--installed")
cmd.Stdout = req.Stdout
cmd.Stderr = req.Stderr
return cmd.Run()
}
return fmt.Errorf("不支持的 Linux 发行版: %s", info.Distro)
}
func distroLikeContains(info platform.Info, values ...string) bool {
all := make([]string, 0, 1+len(info.DistroLike))
if info.Distro != "" {
all = append(all, info.Distro)
}
all = append(all, info.DistroLike...)
for _, a := range all {
for _, v := range values {
if strings.EqualFold(a, v) {
return true
}
}
}
return false
}
+26
View File
@@ -0,0 +1,26 @@
package executor
import (
"context"
"fmt"
"os/exec"
"runtime"
)
// runProcList implements `kopsc proc list`: list all processes.
func runProcList(ctx context.Context, req BuiltinRequest) error {
switch runtime.GOOS {
case "linux", "darwin":
cmd := exec.CommandContext(ctx, "ps", "aux")
cmd.Stdout = req.Stdout
cmd.Stderr = req.Stderr
return cmd.Run()
case "windows":
cmd := exec.CommandContext(ctx, "tasklist")
cmd.Stdout = req.Stdout
cmd.Stderr = req.Stderr
return cmd.Run()
default:
return fmt.Errorf("不支持的操作系统: %s", runtime.GOOS)
}
}
+51
View File
@@ -0,0 +1,51 @@
package executor
import (
"context"
"fmt"
"os/exec"
"runtime"
"strings"
)
// runUserList implements `kopsc user list`: list all users.
func runUserList(ctx context.Context, req BuiltinRequest) error {
switch runtime.GOOS {
case "linux", "darwin":
return userListUnix(ctx, req)
case "windows":
cmd := exec.CommandContext(ctx, "net", "user")
cmd.Stdout = req.Stdout
cmd.Stderr = req.Stderr
return cmd.Run()
default:
return fmt.Errorf("不支持的操作系统: %s", runtime.GOOS)
}
}
func userListUnix(ctx context.Context, req BuiltinRequest) error {
// Try getent first (more portable), fall back to reading /etc/passwd
if path, err := exec.LookPath("getent"); err == nil {
cmd := exec.CommandContext(ctx, path, "passwd")
cmd.Stdout = req.Stdout
cmd.Stderr = req.Stderr
return cmd.Run()
}
// Fall back to /etc/passwd
out, err := exec.CommandContext(ctx, "cat", "/etc/passwd").Output()
if err != nil {
return fmt.Errorf("读取用户列表失败: %w", err)
}
fmt.Fprintln(req.Stdout, "用户名:UID:GID:描述:家目录:Shell")
for _, line := range strings.Split(string(out), "\n") {
if line == "" {
continue
}
fields := strings.Split(line, ":")
if len(fields) >= 7 {
fmt.Fprintf(req.Stdout, "%s:%s:%s:%s:%s:%s\n",
fields[0], fields[2], fields[3], fields[4], fields[5], fields[6])
}
}
return nil
}
+24
View File
@@ -513,6 +513,15 @@ func Builtin() *Registry {
},
},
},
{
ID: "pkg.list",
Group: "pkg",
Summary: "列出已安装的软件包",
Action: "列出系统中已安装的软件包。" +
"Linux: dpkg -l(Debian/Ubuntu)/ rpm -qa(CentOS/RHEL)/ apk list(Alpine);" +
"macOS: brew list;Windows: winget list",
Variants: threePlatformBuiltins("pkg.list"),
},
{
ID: "pkg.refreshindex",
Group: "pkg",
@@ -551,6 +560,14 @@ func Builtin() *Registry {
},
},
},
{
ID: "user.list",
Group: "user",
Summary: "列出系统用户",
Action: "列出系统中所有用户账户。" +
"Linux/macOS: getent passwd 或 /etc/passwd;Windows: net user",
Variants: threePlatformBuiltins("user.list"),
},
{
ID: "user.grant",
Group: "user",
@@ -720,6 +737,13 @@ func Builtin() *Registry {
},
// ----- proc additions -----
{
ID: "proc.list",
Group: "proc",
Summary: "列出所有进程",
Action: "列出系统中所有正在运行的进程。Linux/macOS: ps aux;Windows: tasklist",
Variants: threePlatformBuiltins("proc.list"),
},
{
ID: "proc.topmem",
Group: "proc",
+3 -3
View File
@@ -25,13 +25,13 @@ func TestBuiltinIDsStable(t *testing.T) {
"docker.prunebuilder", "docker.prunevolumes", "docker.clearall",
"docker.compose.up", "docker.compose.down", "docker.compose.ps", "docker.compose.logs",
"diagnose",
"disk.usage", "net.pids", "net.ports", "proc.nohup", "proc.wait", "java.run", "git.retime", "pkg.refreshindex",
"user.grant", "user.revoke",
"disk.usage", "net.pids", "net.ports", "proc.nohup", "proc.wait", "java.run", "git.retime", "pkg.list", "pkg.refreshindex",
"user.list", "user.grant", "user.revoke",
"file.findbig", "file.findrecent", "file.findname",
"svc.list", "svc.status", "svc.enable", "svc.disable", "svc.logs",
"archive.extract",
"sysinfo",
"proc.topmem", "proc.topcpu", "proc.killname",
"proc.list", "proc.topmem", "proc.topcpu", "proc.killname",
"net.ping", "net.trace", "net.dns", "net.curl",
"log.list", "log.search", "log.last",
"fw.status", "fw.allow", "fw.deny",