Java命令行参数中的空格

时间:2009-04-13 09:37:11

标签: java

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

java test.AskGetCampaignByName "Dummy books"

我将第一个参数(args [0])仅作为“Dummy”。单引号也没有帮助。 有解决方法/解决方法吗?可能是因为我的终端设置?

我的$ TERM是xterm,而$ LANG是“en_IN”。

5 个答案:

答案 0 :(得分:54)

参数由shell处理(我假设你在Linux下使用Bash?),所以任何终端设置都不应该影响它。

既然你已经引用了这个论点,它应该有效。我能想到的唯一可能的解释是,如果你的java命令是一个包装脚本,并且在传递给真正的程序时会弄乱参数的转义。这很容易做到,或者可能有点难以正确完成。

正确的包装器脚本应该将所有参数传递为${1+"$@"},而任何其他版本很可能是关于能够正确处理嵌入空间的错误。这种做法并不罕见,但是$2或类似的任何事件都很麻烦,必须写成"$2"(或可能是${2+"$2"})才能正确处理嵌入空间,这是犯了很多罪。

不太直观的语法${1+"$@"}的原因是原始$*将所有参数加入为"$1 $2 $3 ...",这些参数不适用于嵌入空间。然后引入"$@"(正确)扩展到"$1" "$2" "$3" ...所有参数,如果没有给出参数,它应该扩展为空。不幸的是,一些Unix供应商搞砸了,即使没有参数,"$@"也会扩展到"",为了解决这个问题,发明了${1+"$@"}的聪明(但不那么可读)黑客,使"$@"仅在设置参数$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 :(得分:1)

你必须逃离这样的空间:

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

这对我有用。

我的环境:

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

答案 2 :(得分:0)

如果您的程序需要的不仅仅是位置参数(=当命令行使用很重要时),您应该考虑选项和开关。 Apache Commons为此提供了很好的library

答案 3 :(得分:0)

听起来您正在使用操作系统分发,其中用户可用的java命令是一个包装器,它可以“找到合适的JVM”并相应地调用它。

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

您使用什么发行版?

答案 4 :(得分:-3)

重新组装Java程序中的参数:

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