Java Runtime.getRuntime(): getting output from executing a command line program

前端 未结 12 1355
清歌不尽
清歌不尽 2020-11-22 00:18

I\'m using the runtime to run command prompt commands from my Java program. However, I\'m not aware of how I can get the output the command returns.

Here is my code:

相关标签:
12条回答
  • 2020-11-22 00:35

    Besides using ProcessBuilder as suggested Senthil, be sure to read and implement all the recommendations of When Runtime.exec() won't.

    0 讨论(0)
  • 2020-11-22 00:39

    If you write on Kotlin, you can use:

    val firstProcess = ProcessBuilder("echo","hello world").start()
    val firstError = firstProcess.errorStream.readBytes().decodeToString()
    val firstResult = firstProcess.inputStream.readBytes().decodeToString()
    
    0 讨论(0)
  • 2020-11-22 00:40
    Process p = Runtime.getRuntime().exec("ping google.com");
    
    p.getInputStream().transferTo(System.out);
    
    p.getErrorStream().transferTo(System.out);
    
    0 讨论(0)
  • 2020-11-22 00:42

    At the time of this writing, all other answers that include code may result in deadlocks.

    Processes have a limited buffer for stdout and stderr output. If you don't listen to them concurrently, one of them will fill up while you are trying reading the other. For example, you could be waiting to read from stdout while the process is waiting to write to stderr. You cannot read from the stdout buffer because it is empty and the process cannot write to the stderr buffer because it is full. You are each waiting on each other forever.

    Here is a possible way to read the output of a process without a risk of deadlocks:

    public final class Processes
    {
        private static final String NEWLINE = System.getProperty("line.separator");
    
        /**
         * @param command the command to run
         * @return the output of the command
         * @throws IOException if an I/O error occurs
         */
        public static String run(String... command) throws IOException
        {
            ProcessBuilder pb = new ProcessBuilder(command).redirectErrorStream(true);
            Process process = pb.start();
            StringBuilder result = new StringBuilder(80);
            try (BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream())))
            {
                while (true)
                {
                    String line = in.readLine();
                    if (line == null)
                        break;
                    result.append(line).append(NEWLINE);
                }
            }
            return result.toString();
        }
    
        /**
         * Prevent construction.
         */
        private Processes()
        {
        }
    }
    

    The key is to use ProcessBuilder.redirectErrorStream(true) which will redirect stderr into the stdout stream. This allows you to read a single stream without having to alternate between stdout and stderr. If you want to implement this manually, you will have to consume the streams in two different threads to make sure you never block.

    0 讨论(0)
  • 2020-11-22 00:48

    Pretty much the same as other snippets on this page but just organizing things up over an function, here we go...

    String str=shell_exec("ls -l");
    

    The Class function:

    public String shell_exec(String cmd)
           {
           String o=null;
           try
             {
             Process p=Runtime.getRuntime().exec(cmd);
             BufferedReader b=new BufferedReader(new InputStreamReader(p.getInputStream()));
             String r;
             while((r=b.readLine())!=null)o+=r;
             }catch(Exception e){o="error";}
           return o;
           }
    
    0 讨论(0)
  • 2020-11-22 00:48

    Try reading the InputStream of the runtime:

    Runtime rt = Runtime.getRuntime();
    String[] commands = {"system.exe", "-send", argument};
    Process proc = rt.exec(commands);
    BufferedReader br = new BufferedReader(
        new InputStreamReader(proc.getInputStream()));
    String line;
    while ((line = br.readLine()) != null)
        System.out.println(line);
    

    You might also need to read the error stream (proc.getErrorStream()) if the process is printing error output. You can redirect the error stream to the input stream if you use ProcessBuilder.

    0 讨论(0)
提交回复
热议问题