进行系统调用,以字符串形式返回 stdout 输出

发布于 2024-07-07 12:41:19 字数 259 浏览 4 评论 0 原文

Perl 和 PHP 通过反引号来实现这一点。 例如,

$output = `ls`;

返回目录列表。 类似的函数 system("foo") 返回给定命令 foo 的操作系统返回代码。 我说的是一个变体,它将 foo 打印的任何内容返回到标准输出。

其他语言是如何做到这一点的? 这个函数有规范的名称吗? (我将使用“反引号”;尽管也许我可以创造“syslurp”。)

Perl and PHP do this with backticks. For example,

$output = `ls`;

Returns a directory listing. A similar function, system("foo"), returns the operating system return code for the given command foo. I'm talking about a variant that returns whatever foo prints to stdout.

How do other languages do this? Is there a canonical name for this function? (I'm going with "backtick"; though maybe I could coin "syslurp".)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(27

┼── 2024-07-14 12:41:19

Python

from subprocess import check_output as qx

output = qx(['ls', '-lt'])

Python <2.7 或 <3.1

subprocess.check_output() ="http://svn.python.org/view/python/trunk/Lib/subprocess.py?view=markup" rel="noreferrer">subprocess.py 或采用类似以下内容:

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())

subprocess 模块自 2.4 起就已存在于 stdlib 中。

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.

北音执念 2024-07-14 12:41:19

Python:

import os
output = os.popen("foo").read()

Python:

import os
output = os.popen("foo").read()
不必在意 2024-07-14 12:41:19

[应 Alexmandreeves -- 查看评论 --,您会在此DZones 找到Java Snippet 页面 一个独立于操作系统的完整版本,用于在本例中创建“ls”。 这是对他们的代码挑战
下面的只是核心:Runtime.exec,加上2个线程来监听stdout和stderr。 ]

Java“简单!”:

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

或者用java代码

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

但是要做到这一点,你需要编码...
……这就尴尬了。

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;
    }
}

[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;
    }
}
一世旳自豪 2024-07-14 12:41:19

在 Perl 中执行此操作的另一种方法 (TIMTOWTDI)

$output = <<`END`;
ls
END

当在 Perl 程序中嵌入相对较大的 shell 脚本时,这特别有用

Yet another way to do it in Perl (TIMTOWTDI)

$output = <<`END`;
ls
END

This is specially useful when embedding a relatively large shell script in a Perl program

浅听莫相离 2024-07-14 12:41:19

Ruby:反引号或“%x”内置语法。

puts `ls`;
puts %x{ls};

Ruby: either backticks or the '%x' builtin syntax.

puts `ls`;
puts %x{ls};
霊感 2024-07-14 12:41:19

perl 中的另一种方法

$output = qx/ls/;

这样做的优点是您可以选择分隔符,从而可以在命令中使用`(尽管恕我直言,如果您确实需要这样做,您应该重新考虑您的设计)。 另一个重要的优点是,如果使用单引号作为分隔符,变量将不会被插值(非常有用)

An alternative method in perl

$output = qx/ls/;

This had the advantage that you can choose your delimiters, making it possible to use ` in the command (though IMHO you should reconsider your design if you really need to do that). Another important advantage is that if you use single quotes as delimiter, variables will not be interpolated (a very useful)

凉世弥音 2024-07-14 12:41:19

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

安装了 MissingH

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

这是“粘合”语言中的一个简单操作就像 Perl 和 Ruby,但 Haskell 不是。

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.

冷情妓 2024-07-14 12:41:19

在 shell 中

OUTPUT=`ls`

或其他

OUTPUT=$(ls)

方法 第二种方法更好,因为它允许嵌套,但与第一种方法不同,并非所有 shell 都支持。

In shell

OUTPUT=`ls`

or alternatively

OUTPUT=$(ls)

This second method is better because it allows nesting, but isn't supported by all shells, unlike the first method.

爱已欠费 2024-07-14 12:41:19

埃尔兰:

os:cmd("ls")

Erlang:

os:cmd("ls")
听不够的曲调 2024-07-14 12:41:19

好吧,由于这是依赖于系统的,因此许多语言没有用于所需的各种系统调用的内置包装器。

例如,Common Lisp 本身并不是为了在任何特定系统上运行而设计的。 不过,SBCL(Steel Banks Common Lisp 实现)确实为类 Unix 系统提供了扩展,就像大多数其他 CL 实现一样。 当然,这比仅仅获得输出要“强大”得多(您可以控制运行过程,可以指定各种流方向等,请参阅SBCL手册,第6.3章),但很容易为此特定目的编写一个小宏:

(defmacro with-input-from-command ((stream-name command args) &body body)
  "Binds the output stream of command to stream-name, then executes the body
   in an implicit progn."
  `(with-open-stream
       (,stream-name
         (sb-ext:process-output (sb-ext:run-program ,command
                                                    ,args
                                                    :search t
                                                    :output :stream)))
     ,@body))

现在,您可以像这样使用它:

(with-input-from-command (ls "ls" '("-l"))
  ;;do fancy stuff with the ls stream
  )

也许您想将其全部放入一个字符串中。 该宏很简单(尽管也许可以使用更简洁的代码):

(defmacro syslurp (command args)
  "Returns the output from command as a string. command is to be supplied
   as string, args as a list of strings."
  (let ((istream (gensym))
        (ostream (gensym))
        (line (gensym)))
    `(with-input-from-command (,istream ,command ,args)
       (with-output-to-string (,ostream)
         (loop (let ((,line (read-line ,istream nil)))
                 (when (null ,line) (return))
                 (write-line ,line ,ostream)))))))

现在您可以通过此调用获取一个字符串:

(syslurp "ls" '("-l"))

Well, since this is system dependent, there are many languages that do not have a built-in wrapper for the various system calls needed.

For example, Common Lisp itself was not designed to run on any specific system. SBCL (the Steel Banks Common Lisp implementation), though, does provide an extension for Unix-like systems, as do most other CL implementations. This is much more "mighty" than just getting the output, of course (you have control over the running process, can specify all kinds of stream directions, etc., confer to the SBCL manual, chapter 6.3), but it is easy to write a little macro for this specific purpose:

(defmacro with-input-from-command ((stream-name command args) &body body)
  "Binds the output stream of command to stream-name, then executes the body
   in an implicit progn."
  `(with-open-stream
       (,stream-name
         (sb-ext:process-output (sb-ext:run-program ,command
                                                    ,args
                                                    :search t
                                                    :output :stream)))
     ,@body))

Now, you can use it like this:

(with-input-from-command (ls "ls" '("-l"))
  ;;do fancy stuff with the ls stream
  )

Perhaps you want to slurp it all into one string. The macro is trivial (though perhaps more concise code is possible):

(defmacro syslurp (command args)
  "Returns the output from command as a string. command is to be supplied
   as string, args as a list of strings."
  (let ((istream (gensym))
        (ostream (gensym))
        (line (gensym)))
    `(with-input-from-command (,istream ,command ,args)
       (with-output-to-string (,ostream)
         (loop (let ((,line (read-line ,istream nil)))
                 (when (null ,line) (return))
                 (write-line ,line ,ostream)))))))

Now you can get a string with this call:

(syslurp "ls" '("-l"))
爱已欠费 2024-07-14 12:41:19

数学:

output = Import["!foo", "Text"];

Mathematica:

output = Import["!foo", "Text"];
删除会话 2024-07-14 12:41:19

几年前,我为 插件 “nofollow noreferrer">jEdit 连接到本机应用程序。 这就是我用来从正在运行的可执行文件中获取流的方法。 唯一要做的就是 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;
    }
}

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;
    }
}
怪我太投入 2024-07-14 12:41:19

不要忘记TCL:

set result [exec ls]

Don't forget Tcl:

set result [exec ls]
清引 2024-07-14 12:41:19

C# 3.0,比 这个

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());
    }
}

警告:生产代码应该正确处理 Process 对象...

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...

孤城病女 2024-07-14 12:41:19

Perl 中的另一种方式(或 2!)...

open my $pipe, 'ps |';
my @output = < $pipe >;
say @output;

open 也可以是像这样写...

open my $pipe, '-|', 'ps'

Yet another way (or 2!) in Perl....

open my $pipe, 'ps |';
my @output = < $pipe >;
say @output;

open can also be written like so...

open my $pipe, '-|', 'ps'
不顾 2024-07-14 12:41:19

在 PHP 中

$output = `ls`;

$output = shell_exec('ls');

In PHP

$output = `ls`;

or

$output = shell_exec('ls');
擦肩而过的背影 2024-07-14 12:41:19

C(带有glibc扩展):

#define _GNU_SOURCE
#include <stdio.h>
int main() {
    char *s = NULL;
    FILE *p = popen("ls", "r");
    getdelim(&s, NULL, '\0', p);
    pclose(p);
    printf("%s", s);
    return 0;
}

好的,不是很简洁或干净。 这就是C的生活...

C (with glibc extension):

#define _GNU_SOURCE
#include <stdio.h>
int main() {
    char *s = NULL;
    FILE *p = popen("ls", "r");
    getdelim(&s, NULL, '\0', p);
    pclose(p);
    printf("%s", s);
    return 0;
}

Okay, not really concise or clean. That's life in C...

听不够的曲调 2024-07-14 12:41:19

在 Posix 兼容系统上的 C 中:

#include <stdio.h> 

FILE* stream = popen("/path/to/program", "rw");
fprintf(stream, "foo\n"); /* Use like you would a file stream. */
fclose(stream);

In C on Posix conformant systems:

#include <stdio.h> 

FILE* stream = popen("/path/to/program", "rw");
fprintf(stream, "foo\n"); /* Use like you would a file stream. */
fclose(stream);
撩起发的微风 2024-07-14 12:41:19

为什么这里仍然没有 C# 人员:)

这是在 C# 中执行此操作的方法。 内置方式。

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);
        }

    }
}

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);
        }

    }
}
七分※倦醒 2024-07-14 12:41:19

Perl:

$output = `foo`;

添加:这确实是多方面的联系。 上面的 PHP 也是有效的,例如 Ruby 也使用相同的反引号表示法。

Perl:

$output = `foo`;

ADDED: This is really a multi-way tie. The above is also valid PHP, and Ruby, for example, uses the same backtick notation as well.

情何以堪。 2024-07-14 12:41:19

这是另一种 Lisp 方式:

(defun execute (program parameters &optional (buffer-size 1000))
  (let ((proc (sb-ext:run-program program parameters :search t :output :stream))
        (output (make-array buffer-size :adjustable t :fill-pointer t 
                            :element-type 'character)))
    (with-open-stream (stream (sb-ext:process-output proc))
      (setf (fill-pointer output) (read-sequence output stream)))
    output))

然后,获取字符串:

(execute "cat" '("/etc/hosts"))

如果您想运行一个命令,将大量信息打印到 STDOUT,您可以像这样运行它:

(execute "big-writer" '("some" "parameters") 1000000)

最后一个参数为输出预先分配大量空间大作家。 我猜想这个函数可能比一次一行读取输出流更快。

Here's another Lisp way:

(defun execute (program parameters &optional (buffer-size 1000))
  (let ((proc (sb-ext:run-program program parameters :search t :output :stream))
        (output (make-array buffer-size :adjustable t :fill-pointer t 
                            :element-type 'character)))
    (with-open-stream (stream (sb-ext:process-output proc))
      (setf (fill-pointer output) (read-sequence output stream)))
    output))

Then, to get your string:

(execute "cat" '("/etc/hosts"))

If you want to run a command that creates prints a great deal of info to STDOUT, you can run it like this:

(execute "big-writer" '("some" "parameters") 1000000)

The last parameter preallocates a large amount of space for the output from big-writer. I'm guessing this function could be faster than reading the output stream one line at a time.

骄兵必败 2024-07-14 12:41:19

Lua

    foo = io.popen("ls"):read("*a")

Lua:

    foo = io.popen("ls"):read("*a")
箹锭⒈辈孓 2024-07-14 12:41:19

J

output=:2!:0'ls'

J:

output=:2!:0'ls'
趴在窗边数星星i 2024-07-14 12:41:19

Perl,另一种方式:

use IPC::Run3

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

很有用,因为您可以提供命令输入,并分别返回 stderr 和 stdout。 远没有IPC::Run那么整洁/可怕/缓慢/令人不安,它可以为子例程设置管道。

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.

爱要勇敢去追 2024-07-14 12:41:19

Icon/Unicon:

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

文档称其为管道。 好处之一是它使输出看起来就像您正在读取文件一样。 这也意味着如果需要,您可以写入应用程序的标准输入。

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.

埋情葬爱 2024-07-14 12:41:19

Clozure Common Lisp:

(with-output-to-string (stream)
   (run-program "ls" '("-l") :output stream))

LispWorks

(with-output-to-string (*standard-output*)
  (sys:call-system-showing-output "ls -l" :prefix "" :show-cmd nil))

Clozure Common Lisp:

(with-output-to-string (stream)
   (run-program "ls" '("-l") :output stream))

LispWorks

(with-output-to-string (*standard-output*)
  (sys:call-system-showing-output "ls -l" :prefix "" :show-cmd nil))
清眉祭 2024-07-14 12:41:19

当然,它不是较小的(从所有可用的语言来看),但它不应该那么冗长。

这个版本很脏。 应该处理异常情况,阅读能力可能会得到提高。 这只是为了展示 java 版本如何启动。

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 );
}

完整程序如下。

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();
    }
}

示例输出(使用 type 命令)

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

示例输出(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

尝试任何

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

编辑

我必须承认我不能 100% 确定这是“最佳”方法。 请随意发布参考资料和/或代码来展示如何改进它或者有什么问题。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文