You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Spring Shell中获取上一条命令输出以实现自定义命令逻辑?

在Spring Shell中读取上一条命令输出的实现方案

Spring Shell本身没有内置读取上一条命令输出的能力,需要通过自定义组件实现输出拦截和存储,以下是具体步骤:

1. 实现输出存储的单例Bean

创建一个全局可访问的存储Bean,用来保存上一条命令的输出内容:

@Component
public class LastCommandOutputStorage {
    private String lastOutput;

    public String getLastOutput() {
        return lastOutput;
    }

    public void setLastOutput(String lastOutput) {
        this.lastOutput = lastOutput;
    }
}

2. 自定义输出拦截器

继承Spring Shell的默认结果处理器,拦截命令的正常输出和错误输出,并存入存储Bean:

@Component
public class StoringResultHandler extends DefaultResultHandler {
    private final LastCommandOutputStorage storage;

    public StoringResultHandler(ResultHandlerConfigurer configurer, LastCommandOutputStorage storage) {
        super(configurer);
        this.storage = storage;
    }

    @Override
    public void handleResult(Object result) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        PrintStream originalOut = System.out;
        System.setOut(new PrintStream(baos));
        try {
            super.handleResult(result);
            storage.setLastOutput(baos.toString());
        } finally {
            System.setOut(originalOut);
        }
    }

    @Override
    public void handleError(Throwable error) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        PrintStream originalErr = System.err;
        System.setErr(new PrintStream(baos));
        try {
            super.handleError(error);
            storage.setLastOutput(baos.toString());
        } finally {
            System.setErr(originalErr);
        }
    }
}

3. 封装外部系统命令(如cat、javac)

如果要捕获cat、javac这类外部命令的输出,需要在Spring Shell中封装这些命令,通过ProcessBuilder执行并捕获输出:

@ShellComponent
public class SystemCommandWrapper {
    private final LastCommandOutputStorage storage;

    public SystemCommandWrapper(LastCommandOutputStorage storage) {
        this.storage = storage;
    }

    @ShellMethod(key = "cat", value = "执行cat命令")
    public String cat(String filePath) {
        try {
            Process process = new ProcessBuilder("cat", filePath).start();
            String output = new String(process.getInputStream().readAllBytes());
            String error = new String(process.getErrorStream().readAllBytes());
            String fullOutput = output + error;
            storage.setLastOutput(fullOutput);
            return fullOutput;
        } catch (IOException e) {
            String errorMsg = "执行cat命令失败:" + e.getMessage();
            storage.setLastOutput(errorMsg);
            return errorMsg;
        }
    }

    @ShellMethod(key = "javac", value = "执行javac编译命令")
    public String javac(String javaFile) {
        try {
            Process process = new ProcessBuilder("javac", javaFile).start();
            String output = new String(process.getInputStream().readAllBytes());
            String error = new String(process.getErrorStream().readAllBytes());
            String fullOutput = output + error;
            storage.setLastOutput(fullOutput);
            return fullOutput;
        } catch (IOException e) {
            String errorMsg = "执行javac命令失败:" + e.getMessage();
            storage.setLastOutput(errorMsg);
            return errorMsg;
        }
    }
}

4. 实现自定义solve命令

注入存储Bean,读取上一条命令的输出并生成对应解决方案:

@ShellComponent
public class CmdzenCommands {
    private final LastCommandOutputStorage storage;

    public CmdzenCommands(LastCommandOutputStorage storage) {
        this.storage = storage;
    }

    @ShellMethod(key = "cmdzen solve", value = "根据上一条命令输出提供解决方案")
    public String solve() {
        String lastOutput = storage.getLastOutput();
        if (lastOutput == null || lastOutput.isEmpty()) {
            return "没有找到上一条命令的输出";
        }

        if (lastOutput.contains("No such file or directory")) {
            return "解决方案:检查文件路径是否正确,或创建缺失文件:`touch hi.txt`";
        } else if (lastOutput.contains("non-static method cannot be referenced from a static context")) {
            return "解决方案:将`hi()`改为静态方法,或创建类实例后调用:\n" +
                   "```java\n" +
                   "new YourClass().hi();\n" +
                   "```";
        } else {
            return "无法识别当前输出类型";
        }
    }
}

内容的提问来源于stack exchange,提问作者swaruph

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 04:23:10