Использование CMD как процесса - PullRequest
0 голосов
/ 18 июля 2011

Я пытаюсь запускать команды прямо через CMD в Windows (Терминал в Linux). У меня есть следующий код. Это действует очень странно. Во-первых, при запуске программа ничего не печатает. Во-вторых, при отладке и пошаговом выполнении программа печатает текст CMD по умолчанию и строку ввода. Наконец, я не могу писать в CMD, чтобы он выполнял команды. Вот мой код Я предполагаю, что это может быть проблема с многопоточностью, но я не знаком с Runtime.

    Runtime r = Runtime.getRuntime();
    try {
        Process p = r.exec("cmd");
        InputStream iStream = p.getInputStream();
        BufferedReader sReader = new BufferedReader(new InputStreamReader(iStream));
        while(sReader.ready()) {
            System.out.print((char)sReader.read());
        }

        OutputStream oStream = p.getOutputStream();
        BufferedWriter sWriter = new BufferedWriter(new OutputStreamWriter(oStream));
        sWriter.write("mkdir test");
        sWriter.newLine();

        while(sReader.ready()) {
            System.out.print((char)sReader.read());
        }
    } catch(Exception e) {
        e.printStackTrace();
    }

И мой вывод при отладке и пошаговом выполнении (вывод не отображается при запуске)

Microsoft Windows XP [Version 5.1.2600]
(C) Copyright 1985-2001 Microsoft Corp.

D:\workspaces\Maven\Command Line>

Ответы [ 6 ]

1 голос
/ 18 июля 2011

Там может быть несколько вещей, происходящих.Один из них заключается в том, что аргументы не передаются правильно, как вы выполняете процесс.Другое, как упомянутое @zacheusz, заключается в том, что выходные данные могут поступать из потока ошибок, а не из входного потока.

ProcessBuilder помогает в обоих случаях, позволяя легко составлять список команд и возможностьобъединить вход и поток ошибок.Я рекомендую попробовать использовать его:

Process p = null;
try {
    List<String> cmd = new LinkedList<String>();
    cmd.add("executable");
    cmd.add("-arg1");
    cmd.add("value1");
    cmd.add("-arg2");
    ProcessBuilder pb = new ProcessBuilder(cmd);
    pb.redirectErrorStream(true);
    p = pb.start();
    BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream()));
    while (input.ready()) {
        String line = input.readLine();
        System.out.println("From process: "+line);
    }
    input.close();
} catch (IOException e) {
    this.logMessage("IOException caught: "+e.getMessage());
    e.printStackTrace();
}
1 голос
/ 18 июля 2011

Я нашел этот код в сети несколько лет назад. Я не могу вспомнить где. Он довольно старый, поэтому сейчас может быть что-то лучше.

 private void executeCommand(String cmd) {
        try {
            Runtime rt = Runtime.getRuntime();

            Process proc = rt.exec(cmd);

            // any error message?
            StreamHandler errorGobbler = new StreamHandler(proc.getErrorStream(), "ERR");

            // any output?
            StreamHandler outputGobbler = new StreamHandler(proc.getInputStream(), "OUT");

            // kick them off
            errorGobbler.start();
            outputGobbler.start();

            // any error???
            int exitVal = proc.waitFor();
            System.out.println("ExitValue: " + exitVal);
        } catch (Exception e) {
            e.printStackTrace();
        }


    }

И класс:

import java.util.*;
import java.io.*;

public class StreamHandler extends Thread {
    InputStream is;
    String type;
    OutputStream os;

    StringBuffer output;

    StreamHandler(InputStream is, String type) {
        this(is, type, null);
    }

    StreamHandler(InputStream is, String type, OutputStream redirect) {

        this.is = is;
        this.type = type;
        this.os = redirect;
        output = new StringBuffer(100);
    }

    public void run() {
        try {
            PrintWriter pw = null;
            if (os != null)
                pw = new PrintWriter(os);

            InputStreamReader isr = new InputStreamReader(is);
            BufferedReader br = new BufferedReader(isr);
            String line=null;
            while ( (line = br.readLine()) != null) {
                if (pw != null)
                    pw.println(line);
                System.out.println(type + ">" + line);
            }
            if (pw != null)
                pw.flush();
        } catch (IOException ioe) {
            ioe.printStackTrace();
        }
    }
}
1 голос
/ 18 июля 2011

Вы должны сделать эту работу в потоке. Например, чтобы записать стандартный вывод:

Process process = Runtime.getRuntime().exec(command);
LogStreamReader lsr = new LogStreamReader(process.getInputStream());
Thread thread = new Thread(lsr, "LogStreamReader");
thread.start();


public class LogStreamReader implements Runnable {

    private BufferedReader reader;

    public LoggingStreamReader(InputStream is) {
        this.reader = new BufferedReader(new InputStreamReader(is));
    }

    public void run() {
        try {
            String line = reader.readLine();
            while (line != null) {
                System.out.println(line);
                line = reader.readLine();
            }
            reader.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Тогда вам нужен второй поток для обработки ввода. И вы можете иметь дело с stderr точно так же, как с stdout.

0 голосов
/ 18 июля 2011

cmd пытается запустить командную строку,

, чтобы правильно запустить команду, вам нужна следующая командная строка

cmd.exe -c ipconfig.exe

the -c означает выполнить команду в оставшейся части командной строки

0 голосов
/ 18 июля 2011

Вы можете выполнять команды, не вводя в код cmd.exe.

public static void main(String[] args) {

      //cmd = the command youw ill be using            
    String cmd = "ipconfig";      
    Runtime r = Runtime.getRuntime();      
    Process p;   
    try {       
        p = r.exec(cmd);

    BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));    
    String inputLine;       
    while ((inputLine = in.readLine()) != null) {     
        System.out.println(inputLine);
          }       
    }     


catch (IOException ex) {      
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);  
             }
       }
0 голосов
/ 18 июля 2011

Обычно cmd или terminal отвечают за установку стандартного ввода-вывода для программ, которые они выполняют, поэтому я не думаю, что вы можете просто общаться с ними через поток ввода-вывода.В случае Linux на самом деле команда запускается внутри терминала, который выполняет команды, а не сам терминал.Windows, вероятно, тоже делает некоторые забавные вещи.

...