Java:通过Runtime.getRuntime().exec()为依赖操作系统的调用转义字符串的正确方法

Java:通过Runtime.getRuntime().exec()为依赖操作系统的调用转义字符串的正确方法,java,operating-system,escaping,Java,Operating System,Escaping,在我的Java应用程序中,我需要调用另一个可运行的jar。看起来是这样的: String path_to_jar_file = "/path/to/app.jar"; String some_params = "-par1 -par2 -par3"; //-- perform system call Process pr = Runtime.getRuntime().exec("java -jar " + path_to_jar_file + " " + some_params);

在我的Java应用程序中,我需要调用另一个可运行的jar。看起来是这样的:

String path_to_jar_file = "/path/to/app.jar";
String some_params      = "-par1 -par2 -par3";

//-- perform system call
Process pr = Runtime.getRuntime().exec("java -jar " + path_to_jar_file + " " + some_params);

//-- echo output
BufferedReader input = new BufferedReader(
      new InputStreamReader(pr.getInputStream())
      );
String line = null;
while ((line = input.readLine()) != null){
   System.out.println(line);
}

//-- wait until process is finished and get its exit code
int exitVal = pr.waitFor();
Runtime.getRuntime().exec("java -jar \"" + path_to_jar_file + "\" " + some_params);
但是
path\u to\u jar\u file
实际上是由用户提供的,所以这个路径可以包含空格或其他内容。 在Windows上,我可以这样引用:

String path_to_jar_file = "/path/to/app.jar";
String some_params      = "-par1 -par2 -par3";

//-- perform system call
Process pr = Runtime.getRuntime().exec("java -jar " + path_to_jar_file + " " + some_params);

//-- echo output
BufferedReader input = new BufferedReader(
      new InputStreamReader(pr.getInputStream())
      );
String line = null;
while ((line = input.readLine()) != null){
   System.out.println(line);
}

//-- wait until process is finished and get its exit code
int exitVal = pr.waitFor();
Runtime.getRuntime().exec("java -jar \"" + path_to_jar_file + "\" " + some_params);
它是有效的。但在Linux上,令人惊讶的是,它不起作用。(没有抛出异常,没有回声,只是退出代码是1,这表示错误)

奇怪的是,如果我在终端中键入这个命令(带引号),它就会工作!但是,如果我通过
Runtime.getRuntime().exec()
调用它,它只在没有引号的情况下工作

我提出的唯一解决方案是使用Apache Common的
SystemUtils.is_OS_WINDOWS
:在WINDOWS上,引用路径,在linux上引用转义空格和其他符号


但可能有现成的解决方案吗?

我测试了您的代码,发现与您在OSX上遇到的问题相同

您的问题似乎与空格有关,我可以通过使用a来回避这个问题,因为它与空格的关系更好

    //Create and start process builder
    ProcessBuilder builder = new ProcessBuilder("java", "-jar", path_to_jar_file, param1, param2, param3);
    Process process = builder.start();

    //Create reader to get error messages (Just in case you have another issue)
    BufferedReader errinput = new BufferedReader(new InputStreamReader(
        process.getErrorStream()));

    //Print errors to the terminal/console
    String s = null;
    while ((s = errinput.readLine()) != null)
    {
        System.out.println(s);
    }
上面的代码在Windows和OSX上工作,Linux的行为应该与OSX相同


请记住在完成时取出错误报告代码,因为它将锁定主线程。

首先尝试在linux终端上手动运行该命令,然后复制该字符串并将其粘贴到exec中(作为一个字符串,与终端中的字符串完全相同),然后重试。如果这两种方法都有效,那么您就知道在程序中创建字符串/路径/参数的方式有问题。@sorifiend,在我的Java程序中,在调用exec()之前,我实际上回显了命令:
System.out.println(command)然后我在终端复制粘贴这个命令,它在那里工作!但是,当我通过
exec()
执行它时,它不会出现。非常感谢!我在linux上用包含空格和一些特殊字符的路径对它进行了测试,效果很好。还没有在Windows上测试过它(路径中包含空格),希望它能正常工作。