Apache Commons Exec为包含空格的参数生成了太多引号?

要么Apache Commons Exec中存在错误,要么我错误地使用API​​,但是当我使用CommandLine类添加包含空格的参数时,会添加一些引号,然后是给定参数的一部分。

例如:当我调用java "what version"我得到java.lang.NoClassDefFoundError: what version ,当我调用java "\"what version\"" (包含转义引号,它们是命令行参数本身的一部分) ),我得到java.lang.NoClassDefFoundError: "what version"

因此,以下测试失败,因为正如您在最后一行中所看到的,Apache Exec正在生成后一版本,它应该生成第一个版本:

 @Test public void testArgumentQuoting() throws Exception { DefaultExecutor executor = new DefaultExecutor(); DefaultExecuteResultHandler resultHandler = new DefaultExecuteResultHandler(); ByteArrayOutputStream out = new ByteArrayOutputStream(); PumpStreamHandler streamHandler = new PumpStreamHandler(out, out); executor.setStreamHandler(streamHandler); CommandLine cmdLine = new CommandLine("java"); cmdLine.addArgument("what version"); executor.execute(cmdLine, resultHandler); resultHandler.waitFor(); String resultPattern = "Exception in thread \"main\" java\\.lang\\.NoClassDefFoundError: ([\\w \"]+)"; Pattern pattern = Pattern.compile(resultPattern); Matcher matcher = pattern.matcher(out.toString()); Assert.assertTrue(matcher.find()); // Note: Result should be  and NOT ! Assert.assertEquals("what version", matcher.group(1)); } 

现在我想知道:

  • 这是一个错误吗?
  • 如果是这样的话:有没有办法规避这个问题(一种解决方法)?
  • 如果不是:我做错了什么?

编辑:我正在尝试执行一个过程,我认为他们的机器上会有最少的人。 所以我使用的是java因为这个命令应该可以在人们开发Java的所有机器上使用。 我的观点是错误的运行时参数传递给外部进程,包含转义引号,它不应该。

编辑:我把它变成了Jira的公共执行官提交的错误。

这似乎是Apache Commons Exec中的一个真正的错误 ,迄今为止还没有修复。

Apache common exec具有带handleQuoting标志的addArgument方法。 如果它已打开,则它将参数包装在引号中。

默认情况下,它已打开

 public CommandLine addArgument(final String argument, boolean handleQuoting) 

你可以尝试下一个适合我的例子:

  CommandLine cmdLine = new CommandLine("mco"); cmdLine.addArgument("shellcmd" ); cmdLine.addArguments( puppetAgents.split(" ") ); cmdLine.addArgument("-t"); cmdLine.addArgument(timeout); // When writing a command with space use double " cmdLine.addArgument("\"\"puppet agent -t\"\"",false); 

你想要执行什么课? 您没有准确指定您希望Java执行的内容。 这需要成为你的第二个论点。

换句话说,如果您尝试运行com.mycompany.MyExecutable,您的代码应如下所示:

 CommandLine cmdLine = new CommandLine("java com.mycompany.MyExecutable"); 

您可以在创建CommandLine对象后附加参数。

如在教程中那样尝试它,看看是否有所作为?

 ... String line = "java what version"; CommandLine cmdLine = CommandLine.parse(line); executor.execute(cmdLine, resultHandler); ...