2009-04-13 93 views
28

在我的Java命令行参数中,空格后的任何字符都被忽略。例如,Java命令行参数中的空间

java test.AskGetCampaignByName "Dummy books" 

我只将第一个参数(args [0])作为“Dummy”。单引号也没有帮助。 有没有人知道任何解决方法/修复?可能是因为我的终端设置? 我的$ TERM是xterm,$ LANG是“en_IN”。

回答

53

参数由shell处理(我假设你在linux下使用bash?),所以任何终端设置都不应该影响这个。既然你已经引用了它应该工作的论点。我能想到的唯一可能的解释是,如果你的java命令是一个包装脚本,并在传递给真实程序时混淆了参数的转义。这很容易做到,或者可能难以正确执行。

一个正确的包装脚本应该将其所有参数作为${1+"[email protected]"}传递,任何其他版本最有可能是一个关于能够正确处理嵌入空间的错误。这种做法并不少见,但是任何发生的$2或类似事件都很麻烦,必须写为"$2"(或可能为${2+"$2"})才能正确处理嵌入的空间,这是非常有罪的。

不是那么直观的语法${1+"[email protected]"}的原因是原来的$*加入所有参数作为"$1 $2 $3 ..."这对嵌入式空间不起作用。然后"[email protected]"被引入(正确地)扩展到"$1" "$2" "$3" ...的所有参数,如果没有给出参数,它应该扩展到无。不幸的是一些UNIX供应商搞砸并提出"[email protected]"扩大到""即使在没有参数的情况下,并解决这个聪明的(但不是那么可读)写${1+"[email protected]"}的黑客被发明,使得"[email protected]"仅在参数$1设置扩大(即避免在没有参数的情况下进行扩展)。

如果我的包装的假设是错误的,你可以尝试用strace的

strace -o outfile -f -ff -F java test.AskGetCampaignByName "Dummy books" 

调试,并找出参数传递给execve的。从运行“strace /bin/echo '1 2' 3

execve("/bin/echo", ["/bin/echo", "1 2", "3"], [/* 93 vars */]) = 0 
brk(0)         = 0x2400000 
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f420075b000 
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f420075a000 
access("/etc/ld.so.preload", R_OK)  = -1 ENOENT (No such file or directory) 
open("/usr/lib64/alliance/lib/tls/x86_64/libc.so.6", O_RDONLY) = -1 ENOENT (No such file or directory) 
stat("/usr/lib64/alliance/lib/tls/x86_64", 0x7fff08757cd0) = -1 ENOENT (No such file or directory) 
open("/usr/lib64/alliance/lib/tls/libc.so.6", O_RDONLY) = -1 ENOENT (No such file or directory) 
... 
+1

非常感谢! 就是这样。我们通过ant build生成一个可执行文件来设置类路径等。我们在脚本中使用了“java @”。用你的$ {1 +“@”}来代替问题。对不起,在我的示例中直接使用java会导致误导。我认为它意味着相同 – ashweta 2009-04-13 13:45:39

0

如果你的程序需要的不止是位置参数(=当命令行用法很重要),你应该考虑选项和开关。 Apache Commons对此有很好的library

0

听起来就像您正在使用的操作系统发行版,其中可用于用户的java命令是一个包装器,它可以找到正确的JVM“某处”并相应地调用它。

如果是这样,那么在调用实际的java可执行文件时,它很可能不会正确地转义参数。

你使用什么样的分布?

+0

在我的Windows机器'的 “Hello World”, “Hello World” 的 “世界你好”'传递的命令行参数将有所回升为ARGS [0(/ 1)(/2)] ==“hello world”,在Linux上这根本不起作用(我不记得它做了什么*,因为我并不太在意)。但我很乐意看到任何解决方案。感谢您的问题。 @ThorbjørnRavn Andersen,请详细说明。我如何改变JVM的调用方式? – 2009-04-13 10:43:29

-3

这个问题的例子是有点老了,但你为什么不只是重新组装在Java程序中的ARGS?

StringBuilder allArgs = new StringBuilder(); 
for (int i=0; i < args.length; i++) 
{ 
    //System.out.println("arg"+i+": "+args[i]); 
    allArgs.append(args[i]+" "); 
} 
//Parse out the args the way you wish using allArgs 
+0

由于`java test.AskGetCampaignByName“虚拟书籍”`Dummy`和`books`之间有多个空格将会失败(Stack Overflow输出为单个空间,所以在这里你看不到它。 ..) – leemes 2012-07-16 00:23:49

+0

因为`java`应该从shell中正确地获取命令行参数。 – Olathe 2013-03-03 14:50:27

1

你一定要逃出这样的空间:

normal String: "Hello World!" 
escaped String: "Hello" "World!" 

为我工作。

我的环境:

23:39:19 [email protected]:/Users/Zarathustra~$bash -version 
GNU bash, version 3.2.48(1)-release (x86_64-apple-darwin11) 
Copyright (C) 2007 Free Software Foundation, Inc.