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

前端 未结 27 918
误落风尘
误落风尘 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:47

    Haskell:

    import Control.Exception
    import System.IO
    import System.Process
    main = bracket (runInteractiveCommand "ls") close $ \(_, hOut, _, _) -> do
        output <- hGetContents hOut
        putStr output
      where close (hIn, hOut, hErr, pid) =
              mapM_ hClose [hIn, hOut, hErr] >> waitForProcess pid
    

    With MissingH installed:

    import System.Cmd.Utils
    main = do
        (pid, output) <- pipeFrom "ls" []
        putStr output
        forceSuccess pid
    

    This is an easy operation in "glue" languages like Perl and Ruby, but Haskell isn't.

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

    J:

    output=:2!:0'ls'
    
    0 讨论(0)
  • 2020-11-27 05:48

    Icon/Unicon:

    stream := open("ls", "p")
    while line := read(stream) do { 
        # stuff
    }
    

    The docs call this a pipe. One of the good things is that it makes the output look like you're just reading a file. It also means you can write to the app's stdin, if you must.

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

    Years ago I wrote a plugin for jEdit that interfaced to a native application. This is what I used to get the streams off the running executable. Only thing left to do is while((String s = stdout.readLine())!=null){...}:

    /* File:    IOControl.java
     *
     * created: 10 July 2003
     * author:  dsm
     */
    package org.jpop.io;
    
    import java.io.BufferedReader;
    import java.io.InputStreamReader;
    import java.io.PrintStream;
    
    /**
     *  Controls the I/O for a process. When using the std[in|out|err] streams, they must all be put on
     *  different threads to avoid blocking!
     *
     * @author     dsm
     * @version    1.5
     */
    public class IOControl extends Object {
        private Process process;
        private BufferedReader stdout;
        private BufferedReader stderr;
        private PrintStream stdin;
    
        /**
         *  Constructor for the IOControl object
         *
         * @param  process  The process to control I/O for
         */
        public IOControl(Process process) {
            this.process = process;
            this.stdin = new PrintStream(process.getOutputStream());
            this.stdout = new BufferedReader(new InputStreamReader(process.getInputStream()));
            this.stderr = new BufferedReader(new InputStreamReader(process.getErrorStream()));
        }
    
        /**
         *  Gets the stdin attribute of the IOControl object
         *
         * @return    The stdin value
         */
        public PrintStream getStdin() {
            return this.stdin;
        }
    
        /**
         *  Gets the stdout attribute of the IOControl object
         *
         * @return    The stdout value
         */
        public BufferedReader getStdout() {
            return this.stdout;
        }
    
        /**
         *  Gets the stderr attribute of the IOControl object
         *
         * @return    The stderr value
         */
        public BufferedReader getStderr() {
            return this.stderr;
        }
    
        /**
         *  Gets the process attribute of the IOControl object. To monitor the process (as opposed to
         *  just letting it run by itself) its necessary to create a thread like this: <pre>
         *. IOControl ioc;
         *.
         *. new Thread(){
         *.     public void run(){
         *.         while(true){    // only necessary if you want the process to respawn
         *.             try{
         *.                 ioc = new IOControl(Runtime.getRuntime().exec("procname"));
         *.                 // add some code to handle the IO streams
         *.                 ioc.getProcess().waitFor();
         *.             }catch(InterruptedException ie){
         *.                 // deal with exception
         *.             }catch(IOException ioe){
         *.                 // deal with exception
         *.             }
         *.
         *.             // a break condition can be included here to terminate the loop
         *.         }               // only necessary if you want the process to respawn
         *.     }
         *. }.start();
         *  </pre>
         *
         * @return    The process value
         */
        public Process getProcess() {
            return this.process;
        }
    }
    
    0 讨论(0)
  • 2020-11-27 05:49

    Why there is still no c# guy here :)

    This is how to do it in C#. The built-in way.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Diagnostics;
    
    namespace TestConsole
    {
        class Program
        {
            static void Main(string[] args)
            {
                Process p = new Process();
    
                p.StartInfo.UseShellExecute = false;
                p.StartInfo.CreateNoWindow = true;
                p.StartInfo.RedirectStandardOutput = true;
                p.StartInfo.RedirectStandardError = true;
                p.StartInfo.FileName = "cmd";
                p.StartInfo.Arguments = "/c dir";
                p.Start();
    
                string res = p.StandardOutput.ReadToEnd();
                Console.WriteLine(res);
            }
    
        }
    }
    
    0 讨论(0)
  • 2020-11-27 05:50

    C# 3.0, less verbose than this one:

    using System;
    using System.Diagnostics;
    
    class Program
    {
        static void Main()
        {
            var info = new ProcessStartInfo("cmd", "/c dir") { UseShellExecute = false, RedirectStandardOutput = true };
            Console.WriteLine(Process.Start(info).StandardOutput.ReadToEnd());
        }
    }
    

    Caveat: Production code should properly dispose the Process object...

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