从Java执行未加标记的命令行

我目前正在使用ProcessBuilder从java服务器运行命令。 此服务器将替换旧的Perl服务器,并且许多遗留代码指定特定于平台的命令行。

例如,在Windows上它可能会:

command -option "hello world" 

在unix上它可能会:

 command -option 'hello world' 

问题是ProcessBuilder和Runtime.exec都为unix和windows接受了标记化的命令行(例如,{“command”,“ – option”,“hello world”})。

虽然我更喜欢平台独立的方式,但我们的代码库中有大约3000万行perl代码。 如果没有我为不同的平台编写一个标记器(真的不是很重要,我只是不想制作WTF),有没有办法让操作系统上的shell标记命令行?

您是否能够使用重载的Runtime.exec(String)获取单个String并将其作为整个命令运行?


以下适用于Windows:

 Process p = Runtime.getRuntime().exec("perl -e \"print 5\""); System.out.println(IOUtils.toString(p.getInputStream())); p.destroy(); 

这或多或少是Runtime.exec(String)正在做的事情:

 public static void main(String [] args) throws Exception { Process p = new ProcessBuilder(getCommand("perl -e \"print 5\"")).start(); System.out.println(IOUtils.toString(p.getInputStream())); p.destroy(); } private static String[] getCommand(String input) { StringTokenizer tokenizer = new StringTokenizer(input); String[] result = new String[tokenizer.countTokens()]; for (int i = 0; tokenizer.hasMoreTokens(); i++) { result[i] = tokenizer.nextToken(); } return result; } 

我认为引用是由shell解释的。 相反,将命令放在shell脚本中:

 $ cat temp.sh #!/bin/sh perl -e "print 5" 

并执行它:

 import java.io.BufferedReader; import java.io.InputStreamReader; public class PBTest { public static void main(String[] args) { ProcessBuilder pb = new ProcessBuilder("./temp.sh"); pb.redirectErrorStream(true); try { Process p = pb.start(); String s; BufferedReader stdout = new BufferedReader ( new InputStreamReader(p.getInputStream())); while ((s = stdout.readLine()) != null) { System.out.println(s); } System.out.println("Exit value: " + p.waitFor()); p.getInputStream().close(); p.getOutputStream().close(); p.getErrorStream().close(); } catch (Exception ex) { ex.printStackTrace(); } } } 

安慰:

 5 Exit value: 0