Making a system call that returns the stdout output as a string

前端 未结 27 903
误落风尘
误落风尘 2020-11-27 05:13

Perl and PHP do this with backticks. For example,

$output = `ls`;

Returns a directory listing. A similar function, system(\"foo\")

相关标签:
27条回答
  • 2020-11-27 05:30

    [At the request of Alexman and dreeves -- see comments --, you will find at this DZones Java Snippet page a full version Os-independent for making, in this instance, a 'ls'. This is a direct answer to their code-challenge.
    What follows below is just the core: Runtime.exec, plus 2 thread to listen to stdout and stderr. ]

    Java "Simple!":

    E:\classes\com\javaworld\jpitfalls\article2>java GoodWindowsExec "dir *.java"
    Executing cmd.exe /C dir *.java
    ...
    

    Or in java code

    String output = GoodWindowsExec.execute("dir");
    

    But to do that, you need to code...
    ... this is embarrassing.

    import java.util.*;
    import java.io.*;
    class StreamGobbler extends Thread
    {
        InputStream is;
        String type;
        StringBuffer output = new StringBuffer();
    
        StreamGobbler(InputStream is, String type)
        {
            this.is = is;
            this.type = type;
        }
    
        public void run()
        {
            try
            {
                InputStreamReader isr = new InputStreamReader(is);
                BufferedReader br = new BufferedReader(isr);
                String line=null;
                while ( (line = br.readLine()) != null)
                    System.out.println(type + ">" + line);
                    output.append(line+"\r\n")
                } catch (IOException ioe)
                  {
                    ioe.printStackTrace();  
                  }
        }
        public String getOutput()
        {
            return this.output.toString();
        }
    }
    public class GoodWindowsExec
    {
        public static void main(String args[])
        {
            if (args.length < 1)
            {
                System.out.println("USAGE: java GoodWindowsExec <cmd>");
                System.exit(1);
            }
        }
        public static String execute(String aCommand)
        {
            String output = "";
            try
            {            
                String osName = System.getProperty("os.name" );
                String[] cmd = new String[3];
                if( osName.equals( "Windows 95" ) )
                {
                    cmd[0] = "command.com" ;
                    cmd[1] = "/C" ;
                    cmd[2] = aCommand;
                }
                else if( osName.startsWith( "Windows" ) )
                {
                    cmd[0] = "cmd.exe" ;
                    cmd[1] = "/C" ;
                    cmd[2] = aCommand;
                }
    
                Runtime rt = Runtime.getRuntime();
                System.out.println("Executing " + cmd[0] + " " + cmd[1] 
                                   + " " + cmd[2]);
                Process proc = rt.exec(cmd);
                // any error message?
                StreamGobbler errorGobbler = new 
                    StreamGobbler(proc.getErrorStream(), "ERROR");            
    
                // any output?
                StreamGobbler outputGobbler = new 
                    StreamGobbler(proc.getInputStream(), "OUTPUT");
    
                // kick them off
                errorGobbler.start();
                outputGobbler.start();
    
                // any error???
                int exitVal = proc.waitFor();
                System.out.println("ExitValue: " + exitVal);   
    
                output = outputGobbler.getOutput();
                System.out.println("Final output: " + output);   
    
            } catch (Throwable t)
              {
                t.printStackTrace();
              }
            return output;
        }
    }
    
    0 讨论(0)
  • 2020-11-27 05:36

    Python

    from subprocess import check_output as qx
    
    output = qx(['ls', '-lt'])
    

    Python <2.7 or <3.1

    Extract subprocess.check_output() from subprocess.py or adapt something similar to:

    import subprocess
    
    def cmd_output(args, **kwds):
      kwds.setdefault("stdout", subprocess.PIPE)
      kwds.setdefault("stderr", subprocess.STDOUT)
      p = subprocess.Popen(args, **kwds)
      return p.communicate()[0]
    
    print cmd_output("ls -lt".split())
    

    The subprocess module has been in the stdlib since 2.4.

    0 讨论(0)
  • 2020-11-27 05:36

    Erlang:

    os:cmd("ls")
    
    0 讨论(0)
  • 2020-11-27 05:37

    Don't forget Tcl:

    set result [exec ls]
    
    0 讨论(0)
  • 2020-11-27 05:37

    Perl, another way:

    use IPC::Run3
    
    my ($stdout, $stderr);
    run3 ['ls'], undef, \$stdout, \$stderr
        or die "ls failed";
    

    Useful because you can feed the command input, and get back both stderr and stdout separately. Nowhere near as neat/scary/slow/disturbing as IPC::Run, which can set up pipes to subroutines.

    0 讨论(0)
  • 2020-11-27 05:39

    Granted, it is not the smaller ( from all the languages available ) but it shouldn't be that verbose.

    This version is dirty. Exceptions should be handled, reading may be improved. This is just to show how a java version could start.

    Process p = Runtime.getRuntime().exec( "cmd /c " + command );
    InputStream i = p.getInputStream();
    StringBuilder sb = new StringBuilder();
    for(  int c = 0 ; ( c =  i.read() ) > -1  ; ) {
        sb.append( ( char ) c );
    }
    

    Complete program below.

    import java.io.*;
    
    public class Test { 
        public static void main ( String [] args ) throws IOException { 
            String result = execute( args[0] );
            System.out.println( result );
        }
        private static String execute( String command ) throws IOException  { 
            Process p = Runtime.getRuntime().exec( "cmd /c " + command );
            InputStream i = p.getInputStream();
            StringBuilder sb = new StringBuilder();
            for(  int c = 0 ; ( c =  i.read() ) > -1  ; ) {
                sb.append( ( char ) c );
            }
            i.close();
            return sb.toString();
        }
    }
    

    Sample ouput ( using the type command )

    C:\oreyes\samples\java\readinput>java Test "type hello.txt"
    This is a sample file
    with some
    lines
    

    Sample output ( dir )

     C:\oreyes\samples\java\readinput>java Test "dir"
     El volumen de la unidad C no tiene etiqueta.
     El número de serie del volumen es:
    
     Directorio de C:\oreyes\samples\java\readinput
    
    12/16/2008  05:51 PM    <DIR>          .
    12/16/2008  05:51 PM    <DIR>          ..
    12/16/2008  05:50 PM                42 hello.txt
    12/16/2008  05:38 PM             1,209 Test.class
    12/16/2008  05:47 PM               682 Test.java
                   3 archivos          1,933 bytes
                   2 dirs            840 bytes libres
    

    Try any

    java Test netstat
    java Test tasklist
    java Test "taskkill /pid 416"
    

    EDIT

    I must admit I'm not 100% sure this is the "best" way to do it. Feel free to post references and/or code to show how can it be improved or what's wrong with this.

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