从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