当前位置:  开发笔记 > 编程语言 > 正文

进行系统调用,将stdout输出作为字符串返回

如何解决《进行系统调用,将stdout输出作为字符串返回》经验,为你挑选了10个好方法。

Perl和PHP用反引号做到这一点.例如,

$output = `ls`;

返回目录列表.类似的函数system("foo")返回给定命令foo的操作系统返回码.我在谈论一个将foo打印返回到stdout的变体.

其他语言如何做到这一点?这个函数有一个规范名称吗?(我要用"反击";但也许我可以用"syslurp"硬币.)



1> jfs..:

蟒蛇

from subprocess import check_output as qx

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

Python < 2.7或< 3.1

subprocess.check_output()从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())

自2.4以来,子进程模块一直在stdlib中.



2> dreeves..:

蟒蛇:

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


从python 2.5开始,您应该使用子进程模块.

3> VonC..:

[应Alexman和dreeves的请求- 请参阅评论 - ,您将在此DZones Java Snippet页面上找到完全版本的Os独立,在本例中为"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 ");
            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;
    }
}


AbstractFactoryBuilderFactory.buildExecFactory()调用在哪里?

4> Leon Timmerm..:

另一种在Perl中做到这一点的方法(TIMTOWTDI)

$output = <<`END`;
ls
END

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


"在Perl程序中嵌入一个相对较大的shell脚本" - 这句话肯定会成为许多噩梦的来源!

5> Ovid..:

Ruby:反引号或'%x'内置语法.

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



6> Leon Timmerm..:

perl中的另一种方法

$output = qx/ls/;

这样做的好处是你可以选择你的分隔符,这样就可以在命令中使用`(尽管恕我直言,你应该重新考虑你的设计,如果你真的需要这样做).另一个重要的优点是,如果使用单引号作为分隔符,则不会插入变量(非常有用)



7> ephemient..:

哈斯克尔:

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



8> Leon Timmerm..:

在壳中

OUTPUT=`ls`

或者

OUTPUT=$(ls)

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


实际上,你可以使用反引号进行嵌套,但你不想去那里.

9> JesperE..:

二郎:

os:cmd("ls")



10> Svante..:

好吧,因为这是依赖于系统的,所以有许多语言没有内置的包装器来满足所需的各种系统调用.

例如,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"))


哦,有很多图书馆.有关系统交互的一些信息列在http://www.cliki.net/compatibility%20layers中
推荐阅读
k78283381
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有