2011-02-07 26 views
9

要麼存在於Apache的百科全書Exec的一個bug,或我使用的API錯誤,但是當我使用CommandLine類添加包含空格的說法,一些報價相加,然後被賦予參數的一部分。Apache Commons Exec爲包含空格的參數產生太多引號?

例如:當我打電話java "what version"我得到java.lang.NoClassDefFoundError: what version,當我打電話java "\"what version\""(其中包含轉義引號,是命令行參數本身的一部分),我得到java.lang.NoClassDefFoundError: "what version"

所以下面的測試失敗,因爲你可以在最後一行看到,阿帕奇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 <what version> and NOT <"what version">! 
    Assert.assertEquals("what version", matcher.group(1)); 
} 

現在我想知道:

  • 這是一個錯誤?
  • 如果是這樣:是否有辦法規避這個問題(一種解決方法)?
  • 如果不是:我做錯了什麼?

編輯:我試圖執行一個我認爲最少的人會在他們的機器上的過程。所以我使用的是java,因爲這個命令應該在所有人們開發Java的機器上都可用。我的觀點是,錯誤的運行時參數傳遞給外部進程,包含轉義引號,它不應該。

編輯:我在Jira使這個爲公共EXEC已備案的錯誤。

回答

5

這似乎是在Apache的百科全書Exec的,到目前爲止還沒有一個固定real bug

+1

令人難以置信的是,這還沒有得到解決 - 是否沒有人使用commons-exec與實際需要引用的論據? – Miles 2012-12-19 02:15:26

0

什麼課是你想執行?你沒有確切地指定你想要Java執行的內容。這需要成爲你的第二個論點。

換句話說,如果你想運行com.mycompany.MyExecutable,你的代碼應該是這樣的:

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

您可以添加參數創建命令行對象之後。

+0

你好,感謝回答。其實我並不是想要執行一個Java類,而是一個完全不同的過程。但是由於這是非常具體的,我不想爲此寫一個測試用例,因爲我認爲他的機器上沒有人有這個。另一方面,每個人都在談論Java的`java`安裝在他的機器上,因此這個測試案例... – roesslerj 2011-02-08 07:34:24

0

如何在tutorial嘗試這種方式爲,看看是否有差別?

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

這根本不起作用,因爲Apache Commons Exec正確地將這兩個單詞作爲單獨的參數對待,因爲它們是分開的由一個空間。但在我的情況下,我需要一個包含空格的參數......但無論如何,感謝您的意見。 – roesslerj 2011-02-24 12:28:07

5

阿帕奇共同EXEC具有addArgument方法與handleQuoting標誌。 如果它已打開,那麼它將參數包含在引號中。

默認情況下它是開啓

public CommandLine addArgument(final String argument, boolean handleQuoting) 
1

你可以試試它爲我的下一個例子:

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