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); ...