运行多个系统命令

时间:2016-10-17 17:18:00

标签: java

我已经玩了一段时间的java进程并且卡住了。我想要做的是同时运行多个系统命令并将其输出打印到控制台。

例如,ls -l ; cat someFile ; quit ; grep foo someOtherFile应该同时运行。我在某处读过这些命令的输出应该是混合的。另外,如果字符串中的任何地方都有quit命令,继续执行其他命令然后退出。

现在,他们正在按顺序执行。如何同时运行它们并在它到达时打印输出。

String st = "ls -l ; cat someFile ; quit ; grep foo someOtherFile";

String[] rows = st.split(";");

String[][] strArray = new String[rows.length][];
int index = 0;
for(int i = 0; i < rows.length; i++) {
    rows[index] = rows[index].trim();
    strArray[index] = rows[index].split(" ");
    index++;
}
for(int i = 0; i < strArray.length; i++) {
    if(rows[i].equalsIgnoreCase("quit")) {
        System.out.println("Abort");
        break;
    }
    if(rows[i].equals("")) {
        continue;
    }
    ProcessBuilder pb = new ProcessBuilder(strArray[i]);
    pb.redirectErrorStream(true);
    Process process = pb.start();

    InputStream is = process.getInputStream();
            InputStreamReader isr = new InputStreamReader(is);
            BufferedReader br = new BufferedReader(isr);

    String line;
    while ( (line = br.readLine()) != null) {
        System.out.println(line);
    }
    br.close();
}

3 个答案:

答案 0 :(得分:1)

只需将循环的内容放在新线程的run()函数中,循环的每次迭代都将在一个单独的线程中运行:

new Thread() {
    public void run() {
        // loop guts go here
    }
}.start();

您可能必须将一些变量声明为终结,以便在此匿名内部类中访问它们。

答案 1 :(得分:0)

你应该查看一些关于并发性的文档,如此http://docs.oracle.com/javase/tutorial/essential/concurrency/

这里是对您的代码的编辑,可能有效,未经过测试。

    String st = "ls -l ; cat someFile ; quit ; grep foo someOtherFile";

    String[] rows = st.split(";");

    String[][] strArray = new String[rows.length][];
    int index = 0;
    for(int i = 0; i < rows.length; i++) {
        rows[index] = rows[index].trim();
        strArray[index] = rows[index].split(" ");
        index++;
    }

    List<Thread> threads = new ArrayList<Thread>();

    for(int i = 0; i < strArray.length; i++) {
        if(rows[i].equalsIgnoreCase("quit")) {
            System.out.println("Abort");
            break;
        }
        if(rows[i].equals("")) {
            continue;
        }

        final int iForThread = i;

        Thread thread = new Thread() {

            public void run(){
                try{
                    ProcessBuilder pb = new ProcessBuilder(strArray[iForThread]);
                    pb.redirectErrorStream(true);
                    Process process = pb.start();

                    InputStream is = process.getInputStream();
                    InputStreamReader isr = new InputStreamReader(is);
                    BufferedReader br = new BufferedReader(isr);

                    String line;
                    while ( (line = br.readLine()) != null) {
                        System.out.println(line);
                    }
                    br.close();
                }catch(IOException e){
                    //Log some awesome error
                    //Clean up
                    //Do whatever
                }
            }
        };

        threads.add(thread);

    }

    final CyclicBarrier gate = new CyclicBarrier(threads.size() + 1); //+1 is a tip from other post

    for(Thread thread : threads){
        thread.start();
    }

    try {
        gate.await();
        System.out.println("all threads started");
    } catch (InterruptedException | BrokenBarrierException e) {
        e.printStackTrace();
        /* RONALDO OF ERROS
         * MESSI OF HANDLERS*/
    }

}

它创造了一个胎面并在现场执行。 我,如果你只是搞乱我认为这就够了。

编辑:在&#34;同一时间&#34;

添加了开始线程

基于:How to start two threads at "exactly" the same time

请参阅:https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/CyclicBarrier.html

答案 2 :(得分:0)

您可以尝试与此类似的代码:

// command list
String st = "ls -la; cat someFile";

String[] commands = st.split(";");

for (int i = 0; i < commands.length; i++) {
    String currentCommand = commands[i].trim();

    System.out.println("Command: " + currentCommand);

    Thread thread = new Thread(() -> {
        try {
            ProcessBuilder command = new ProcessBuilder(currentCommand);
            Process process = command.start();
            InputStream is = process.getInputStream();
            BufferedReader br = new BufferedReader(new InputStreamReader(is));

            String line;

            while((line = br.readLine()) != null)    {
                System.out.println(line);
            }
            br.close();

        } catch (IOException e) {
            e.printStackTrace();
        }
    });

    thread.start();
}

免责声明:未在Linux机器上测试过。 Windows机器可能无法正常工作。有关Windows命令行流程执行的信息,请参阅this link