【问题标题】:How to run a standalone/interactive Spring Boot CRaSH Shell application?如何运行独立/交互式 Spring Boot CRaSH Shell 应用程序?
【发布时间】:2015-07-01 15:02:12
【问题描述】:

我想运行一个嵌入 CRaSH shell 的 Spring Boot 应用程序,但不是通过 SSH/Telnet 访问,而是希望 CRaSH shell 在没有任何密码的情况下在当前控制台(即直接/独立)中启动,只要Spring 完成了所有 bean 的初始化。

当用户键入exit 或按Ctrl+D 时,应用程序应关闭。

此外,应禁用 SSH 和 Telnet 支持。

PS。如果应用程序可以从标准输入读取命令,则加分,例如

./crshapp < somefile.cmd

cat somefile.cmd | ./crshapp

【问题讨论】:

    标签: spring shell spring-boot spring-boot-actuator crash-shell


    【解决方案1】:

    我遇到了同样的问题,所以我实现了以下代码以附加到由 boot 配置的正在运行的 shell。

    我通过从 org.crsh.standalone.CRaSH 复制一些代码来完成此操作,该代码加载了一个独立的 shell。

    import org.crsh.console.jline.JLineProcessor;
    import org.crsh.console.jline.Terminal;
    import org.crsh.console.jline.TerminalFactory;
    import org.crsh.console.jline.console.ConsoleReader;
    import org.crsh.plugin.PluginLifeCycle;
    import org.crsh.shell.Shell;
    import org.crsh.shell.ShellFactory;
    import org.crsh.util.InterruptHandler;
    import org.fusesource.jansi.AnsiConsole;
    import org.springframework.beans.factory.DisposableBean;
    import org.springframework.beans.factory.InitializingBean;
    import org.springframework.boot.CommandLineRunner;
    
    import java.io.*;
    
    public class InteractiveShellRunner implements CommandLineRunner, InitializingBean, DisposableBean {
    
        final private PluginLifeCycle crshBootstrapBean;
        private Shell shell;
        private Terminal term;
    
    
        public InteractiveShellRunner(PluginLifeCycle crshBootstrapBean) {
            this.crshBootstrapBean = crshBootstrapBean;
        }
    
        @Override
        public void afterPropertiesSet() throws Exception {
            ShellFactory shellFactory = crshBootstrapBean.getContext().getPlugin(ShellFactory.class);
            shell = shellFactory.create(null);
        }
    
        @Override
        public void destroy() throws Exception {
            try {
                if (term != null) {
                    term.restore();
                }
            } catch (Exception ignore) {
            }
        }
    
        @Override
        public void run(String... args) throws Exception {
    
            if (shell != null) {
    
                term = TerminalFactory.create();
    
                //
                String encoding = jline.internal.Configuration.getEncoding();
    
                // Use AnsiConsole only if term doesnt support Ansi
                PrintStream out;
                PrintStream err;
                boolean ansi;
                if (term.isAnsiSupported()) {
                    out = new PrintStream(new BufferedOutputStream(term.wrapOutIfNeeded(new FileOutputStream(FileDescriptor.out)), 16384), false, encoding);
                    err = new PrintStream(new BufferedOutputStream(term.wrapOutIfNeeded(new FileOutputStream(FileDescriptor.err)), 16384), false, encoding);
                    ansi = true;
                } else {
                    out = AnsiConsole.out;
                    err = AnsiConsole.err;
                    ansi = false;
                }
    
                //
                FileInputStream in = new FileInputStream(FileDescriptor.in);
                ConsoleReader reader = new ConsoleReader(null, in, out, term);
    
                //
                final JLineProcessor processor = new JLineProcessor(ansi, shell, reader, out);
    
                //
                InterruptHandler interruptHandler = new InterruptHandler(processor::interrupt);
                interruptHandler.install();
    
                //
                Thread thread = new Thread(processor);
                thread.setDaemon(true);
                thread.start();
    
    
                try {
                    processor.closed();
                } catch (Throwable t) {
                    t.printStackTrace();
                }
    
            }
    
        }
    
    }
    

    剩下的就是像这样将它加载到上下文中:

    @Configuration
    @AutoConfigureAfter(CrshAutoConfiguration.class)
    public static class ShellConfiguration {
    
        @Bean
        InteractiveShellRunner runner(@Qualifier("shellBootstrap") PluginLifeCycle crshBootstrapBean){
            return new InteractiveShellRunner(crshBootstrapBean);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2023-01-25
      • 1970-01-01
      • 2016-07-04
      • 2017-10-14
      • 1970-01-01
      • 2017-05-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多