从命令行运行时,JVM变量转义等于

时间:2014-06-02 17:33:03

标签: java jvm escaping flags

运行

等Java应用程序时
java -Dme.unroll.url=unroll.me?param=val -jar my.jar

=中的param=val是否需要转义?这对谷歌来说非常困难,因为大多数结果都是为了逃避Unix shell特殊值。 =不是shell中的特殊字符,所以

-Dme.unroll.url='unroll.me?param=val'

将完全相同。在此上下文中必须转义=,如果是,如何转义?

1 个答案:

答案 0 :(得分:2)

我能找到的最规范的参考是Oracle java man page,其中陈述

  

-Dproperty =值

     

设置系统属性值。 property变量是一个没有空格的字符串,表示属性的名称。 value变量是表示属性值的字符串。如果value是带空格的字符串,则将其用引号括起来(例如-Dfoo =“foo bar”)。

因为它提到空格而不是=,我将其解释为意味着不需要=转义。这有点令人不满意,所以我决定看看OpenJDK的作用。作为广泛使用的参考实现,其行为设置了事实上的标准。

至少在OpenJDK / HotSpot 8中,在解析-D选项时,第一次出现=后的所有字符都被视为值的一部分,因此后来出现的=不会需要(并且不应该)逃脱。见the source code,其相关部分是

bool Arguments::add_property(const char* prop) {
  const char* eq = strchr(prop, '=');
  char* key;
  // ns must be static--its address may be stored in a SystemProperty object.
  const static char ns[1] = {0};
  char* value = (char *)ns;

  size_t key_len = (eq == NULL) ? strlen(prop) : (eq - prop);
  key = AllocateHeap(key_len + 1, mtInternal);
  strncpy(key, prop, key_len);
  key[key_len] = '\0';

  if (eq != NULL) {
    size_t value_len = strlen(prop) - key_len - 1;
    value = AllocateHeap(value_len + 1, mtInternal);
    strncpy(value, &prop[key_len + 1], value_len + 1);
  }

strchr的调用会找到第一个=,它被视为键和值之间的分隔符。

代码的其他部分在VM启动过程的早期查找特定的属性参数,但我发现的所有地方都没有对=执行任何特殊处理。例如,the Java launcher设置并检查一些属性参数但不转义或unescape =