如何执行相关的控制台命令序列?(How do I execute a sequence of rel

2019-10-18 01:40发布

我目前正在对其中一个客户端从服务器接收外壳/控制台命令一个项目,必须执行。

如何获取Java来,无论是从壳或命令提示符中运行这些命令? 我希望能够忽略的平台类型 - 并没有指定shell或命令提示符 - 但如果我不能,那也没关系。

我必须能够发送相关命令的序列 ,而不仅仅是一个命令。 这意味着,壳/提示不能退出或命令之间接近。

我的当前代码,如下所示,允许节目的序列的执行,但这些命令必须以某种方式通过管道输送到壳/命令提示,从该输出必须被读取。

ArrayList<String> comDat = new ArrayList<>();

while(true) {
    String input = con.recv();
    System.out.println("> " + input);

    if(!input.equals("EOF")) comDat.add(input); else {
        String[] s = new String[comDat.size()];
        for(int i = 0; i < comDat.size(); i++) s[i] = comDat.get(i);

        System.out.println("---Command sequence executing---");
        Process p = Runtime.getRuntime().exec(s);
        p.waitFor();

        System.out.println("---ErrorStream output---"); String line = "";
        BufferedReader errStream = new BufferedReader(new InputStreamReader(p.getErrorStream()));
        while((line = errStream.readLine()) != null) System.out.println("< " + line);

        System.out.println("\n---OutputStream output---"); line = "";
        BufferedReader outStream = new BufferedReader(new InputStreamReader(p.getInputStream()));
        while((line = errStream.readLine()) != null) System.out.println("< " + line);
    }
    Thread.sleep(200);
}

谢谢您的帮助!

Answer 1:

回避的事实的基本前提revoles的dir不是一个外部命令,但功能cmd

我会避免BufferedReaders阅读过程的输出时,因为不是所有的进程发送输出(如进度指标)时使用的新生产线,而不是你应该阅读的字符(恕我直言)字符。

你应该我们ProcessBuilder ,而不是Runtime#exec 。 它提供了更好的管理,并允许您重定向错误流进输入流,使其更容易读取输入。

import java.io.IOException;
import java.io.InputStream;

public class TestProcessBuilder {

    public static void main(String[] args) {

        try {
            ProcessBuilder pb = new ProcessBuilder("cmd", "/c", "dir");
            pb.redirectError();
            Process p = pb.start();
            InputStreamConsumer isc = new InputStreamConsumer(p.getInputStream());
            isc.start();
            int exitCode = p.waitFor();

            isc.join();
            System.out.println("Process terminated with " + exitCode);
        } catch (IOException | InterruptedException exp) {
            exp.printStackTrace();
        }

    }

    public static class InputStreamConsumer extends Thread {

        private InputStream is;

        public InputStreamConsumer(InputStream is) {
            this.is = is;
        }

        @Override
        public void run() {

            try {
                int value = -1;
                while ((value = is.read()) != -1) {
                    System.out.print((char)value);
                }
            } catch (IOException exp) {
                exp.printStackTrace();
            }

        }

    }
}


文章来源: How do I execute a sequence of related console commands?