Perl和PHP用反引号做到这一点.例如,
$output = `ls`;
返回目录列表.类似的函数system("foo")
返回给定命令foo的操作系统返回码.我在谈论一个将foo打印返回到stdout的变体.
其他语言如何做到这一点?这个函数有一个规范名称吗?(我要用"反击";但也许我可以用"syslurp"硬币.)
from subprocess import check_output as qx output = qx(['ls', '-lt'])
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中.
蟒蛇:
import os output = os.popen("foo").read()
[应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; } }
另一种在Perl中做到这一点的方法(TIMTOWTDI)
$output = <<`END`; ls END
在Perl程序中嵌入相对较大的shell脚本时,这特别有用
Ruby:反引号或'%x'内置语法.
puts `ls`; puts %x{ls};
perl中的另一种方法
$output = qx/ls/;
这样做的好处是你可以选择你的分隔符,这样就可以在命令中使用`(尽管恕我直言,你应该重新考虑你的设计,如果你真的需要这样做).另一个重要的优点是,如果使用单引号作为分隔符,则不会插入变量(非常有用)
哈斯克尔:
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不是.
在壳中
OUTPUT=`ls`
或者
OUTPUT=$(ls)
第二种方法更好,因为它允许嵌套,但与第一种方法不同,所有shell都不支持.
二郎:
os:cmd("ls")
好吧,因为这是依赖于系统的,所以有许多语言没有内置的包装器来满足所需的各种系统调用.
例如,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"))